GPIOMode_TypeDef分析

本文详细介绍了GPIO的各种模式,包括浮空输入、带上拉输入、带下拉输入、模拟输入、开漏输出、推挽输出及复用功能输出等,并对比了推挽输出与开漏输出的区别。文中还提供了设置GPIO模式的具体实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

GPIOMode_TypeDef

① 浮空输入_IN_FLOATING                 //串口输入

② 带上拉输入_IPU

③ 带下拉输入_IPD

④ 模拟输入_AIN

⑤ 开漏输出_OUT_OD

⑥ 推挽输出_OUT_PP                      //置位

⑦ 复用功能的推挽输出_AF_PP             //串口输出

⑧ 复用功能的开漏输出_AF_OD
推挽输出与开漏输出的区别 

    推挽输出:可以输出高,低电平,连接数字器件;开漏输出:输出端相当于三极管的集电极. 要得到高电平状态需要上拉电阻才行. 适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内). 
    推挽结构一般是指两个三极管分别受两互补信号的控制,总是在一个三极管导通的时候另一个截止. 
    要实现 线与 需要用OC(open collector)门电路.是两个参数相同的三极管或MOSFET,以推挽方式存在于电路中,各负责正负半周的波形放大任务,电路工作时,两只对称的功率开关管每次只有一个导通,所以导通损耗小,效率高。输出既可以向负载灌电流,也可以从负载抽取电流。

Push-Pull输出就是一般所说的推挽输出,在CMOS电路里面应该较CMOS输出更合适,应为在CMOS里面的push-pull输出能力不可能做得双极那么大。输出能力看IC内部输出极N管P管的面积。和开漏输出相比,push-pull的高低电平由IC的电源低定,不能简单的做逻辑操作等。push-pull是现在CMOS电路里面用得最多的输出级设计方式。   
at91rm9200 GPIO 模拟I2C接口时注意!! 

漏级开路即高阻状态,适用于输入/输出,其可独立输入/输出低电平和高阻状态,若需要产生高电平,则需使用外部上拉电阻或使用如LCX245等电平转换芯片。有些朋友,尤其是未学过此方面知识的朋友,在实际工作中将I/O口设置为漏开,并想输出高电平,但向口线上写1后对方并未认出高电平,但用万用表测量引脚确有电压,这种认为是不对的,对于高阻状态来说,测量电压是无意义的,正确的方法应是外加上拉电阻,上拉电阻的阻值=上拉电压/芯片引脚最大灌(拉)电流。  
推挽方式可完全独立产生高低电平,推挽方式为低阻,这样,才能保证口线上不分走电压或分走极小的电压(可忽略),保证输出与电源相同的高电平,推挽适用于输出而不适用于输入,因为若对推挽(低阻)加高电平后,I=U/R,I会很大,将造成口的烧毁。 

对与C8051F的很多型号片子,将I/O口设置为推挽方式的做法为:PnMDOUT=0xff,Pn=0x00,这样设置I/O口为推挽,并输出低电平(可降低功耗) 将I/O口设置为漏开方式的做法为:PnMDOUT=0x00,Pn=0x11,这样设置I/O口为漏开。 

如果学过三极管放大电路一定知道,前置单管放大器和功放末级放大电路的区别。单片机内部的逻辑经过内部的逻辑运算后需要输出到外面,外面的器件可能需要较大的电流才能推动,因此在单片机的输出端口必须有一个驱动电路。

我正在编辑STM32代码,遇到了 不能获取DHT11的数据 ,请帮我检查并改正错误点。我的原始代码如下: void DHT11_Init(void) { //使能时钟(对PG引脚进行供电) RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE); //GPIO初始化 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;//输出模式 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;//开漏模式 GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;//上拉模式 GPIO_Init(GPIOG, &GPIO_InitStruct); //保证引脚为空闲状态 PGout(9) = 1; } void DHT11_Mode_Change(GPIOMode_TypeDef mode) { //GPIO初始化 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; GPIO_InitStruct.GPIO_Mode = mode;//选择模式 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;//开漏模式 GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;//上拉模式 GPIO_Init(GPIOG, &GPIO_InitStruct); } void DHT11_Start(void) { //确保主机是输出模式 DHT11_Mode_Change(GPIO_Mode_OUT); PGout(9) = 0; delay_ms(20);//主机拉低至少18ms PGout(9) = 1; delay_us(30);//主机拉高20-40us后,读取DHT11的响应信号 } int DHT11_Ack(void) { uint32_t t=0;//等待超时计数 //从机切换为输入模式 DHT11_Mode_Change(GPIO_Mode_IN); t=0; //判断是否有响应信号的出现 while( PGin(9) )//等待PG9引脚为0 { t++; delay_us(1); if(t >= 4000)//达到4000us时,还没有出现低电平 { return -1; } } //检测低电平的合法性 t = 0; while( PGin(9) == 0) { t++; delay_us(1); if(t >= 100) { return -2; } } //检测低电平的合法性 t = 0; while( PGin(9) ) { t++; delay_us(1); if(t >= 100) { return -3; } } return 0; } u8 DHT11_Readbyte(void) { uint32_t t = 0; int32_t i = 0; u8 data = 0; for(i=7;i>=0;i--) { //判断发送数据时是否超时 t=0; while( PGin(9) == 0) { t++; delay_us(1); if(t >= 100) { return -4; } } //等待高电平的出现 //从而得到接收到的是0还是1 delay_us(40); if( PGin(9) ) { data |= 1<<i; t=0; while( PGin(9) ) { t++; delay_us(1); if(t >= 100) { return -5; } } } } return data; } uint32_t DHT11_Read(uint8_t *buf) { int32_t i = 0; uint8_t check_sum = 0; //发送起始信号 DHT11_Start(); DHT11_Ack(); //开始读取温湿度的数据 5字节==40bit位 for(i=0;i<5;i++) { buf[i] = DHT11_Readbyte();//返回1字节 } delay_us(50); check_sum = (buf[0] + buf[1] + buf[2] + buf[3]) & 0xff; //数据传送正确时,校验和数据等于前4字节所得结果的后八位 if(buf[4] == check_sum) { return 0; } return -6; }
03-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值