工程师为你讲解,如何看懂时序图!
扫描二维码
随时随地手机看文章
网站:bbs.21ic.com
比如常用的单线协议的温湿度传感器DHT21。
开始读取时候,假设传感器是空闲的,那么这个时候传感器就是在高电平,主控想要发起读取,要给传感器一个读取的信号,这个信号就是先拉低至少500us,然后拉高20到40us。
保持20us到40us。
Write_AM2301_PIN_Init();
RESET_AM2301_PIN();
HAL_Delay(2);
SET_AM2301_PIN();
rt_hw_us_delay(30);
读取相应,因为接下来器件会主动拉低总线80us,然后再拉高80us.
我们先切换主控的这个IO到输入模式,进行读取。然后判断
器件准备好的这个拉低拉高信号。
第一步,切断刀输入模式,准备读取IO信号
Read_AM2301_PIN_Init();Sensor_AnswerFlag=0;
判断是否传感器拉低了总线,拉低表示传感器要发送准备好信号了
==GPIO_PIN_RESET){Sensor_AnswerFlag=1;Sys_CNT=0;
while(Read_AM2301_PIN()==GPIO_PIN_RESET){if(++Sys_CNT>3000){Sensor_ErrorFlag=1;return 0;}}Sys_CNT=0;
while(Read_AM2301_PIN()==GPIO_PIN_SET){if(++Sys_CNT>3000){Sensor_ErrorFlag=1;return 0;}}
每次读取8BIT,一共5此,所以用个循环。方到准备好的变量数组里
for(i=0;i<5;i++){AM2301_Data = Read_AM2301_Data();i>}</i>
我们看到总线在传输数据时候,拉低都是50us,只有拉高长短不同,长的表示1,短的表示0.
因此我们读取每一位时候,只要先判断是不是低电平或者高电平,就行了。
在低电平时候我们等待,当高电平到来我们判断是否大于28us,因为26us~28us表示0,70us标志1.
所以我们找一个介于28到70us之间的判断阈值。
比如我以30us作为阈值,当低电平结束后,我延时30us,如果是0,这个时候高电平肯定结束了,
如果是1,高电平还在持续。
因此我通过这个思路判断是0还是1.
因为我要读取是8BIT,因此我用循环8次的操作。
unsigned char Read_AM2301_Data(void){unsigned char i,cnt,buffer,tmp;//要读取8次for (i = 0; i < 8; i++){cnt=0;//判断低电平是否结束while(!Read_AM2301_PIN()){if(++cnt>=3000)break;}//低电平结束后,进入高电平,开始计时30usrt_hw_us_delay(30);tmp=0;//如果此时还是高电平,那么肯定是大于28us,确定是1来了,赋值1if(Read_AM2301_PIN())tmp=1;cnt=0;//等待高电平结束,号进入下一位的读取while(Read_AM2301_PIN()){if(++cnt>=2000)break;}//移位写入刚刚得到的1个BITbuffer<<=1;buffer|=tmp;}return buffer;}
实现读取IO状态和写高低电平。
unsigned char Read_AM2301_PIN(void){return HAL_GPIO_ReadPin(AM2301_PORT, AM2301_PIN);}void SET_AM2301_PIN(void){HAL_GPIO_WritePin(AM2301_PORT, AM2301_PIN,GPIO_PIN_SET);}void RESET_AM2301_PIN(void){HAL_GPIO_WritePin(AM2301_PORT, AM2301_PIN,GPIO_PIN_RESET);}
//读传感器 端口位定义,可修改//*unsigned char Sensor_AnswerFlag; //收到起始标志位unsigned char Sensor_ErrorFlag; //读取传感器错误标志unsigned int Sys_CNT;unsigned char AM2301_Data[5]={0x00,0x00,0x00,0x00,0x00};void Read_AM2301_PIN_Init(void){AM2301_GPIO_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;GPIO_InitStruct.Pin = AM2301_PIN;HAL_GPIO_Init(AM2301_PORT, &GPIO_InitStruct);}void Write_AM2301_PIN_Init(void){AM2301_GPIO_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;GPIO_InitStruct.Pin = AM2301_PIN;HAL_GPIO_Init(AM2301_PORT, &GPIO_InitStruct);}unsigned char Read_AM2301_PIN(void){return HAL_GPIO_ReadPin(AM2301_PORT, AM2301_PIN);}void SET_AM2301_PIN(void){HAL_GPIO_WritePin(AM2301_PORT, AM2301_PIN,GPIO_PIN_SET);}void RESET_AM2301_PIN(void){HAL_GPIO_WritePin(AM2301_PORT, AM2301_PIN,GPIO_PIN_RESET);}unsigned char Read_AM2301_Data(void){unsigned char i,cnt,buffer,tmp;for (i = 0; i < 8; i++){cnt=0;while(!Read_AM2301_PIN()){if(++cnt>=3000)break;}rt_hw_us_delay(30);tmp=0;if(Read_AM2301_PIN())tmp=1;cnt=0;while(Read_AM2301_PIN()){if(++cnt>=2000)break;}buffer<<=1;buffer|=tmp;}return buffer;}unsigned char Read_Sensor(void){unsigned char i;Write_AM2301_PIN_Init();RESET_AM2301_PIN();// rt_thread_mdelay(2);HAL_Delay(2);SET_AM2301_PIN();rt_hw_us_delay(30);SET_AM2301_PIN();Read_AM2301_PIN_Init();Sensor_AnswerFlag=0;if(Read_AM2301_PIN()==GPIO_PIN_RESET){Sensor_AnswerFlag=1;Sys_CNT=0;while(Read_AM2301_PIN()==GPIO_PIN_RESET){if(++Sys_CNT>3000){Sensor_ErrorFlag=1;return 0;}}Sys_CNT=0;while(Read_AM2301_PIN()==GPIO_PIN_SET){if(++Sys_CNT>3000){Sensor_ErrorFlag=1;return 0;}}for(i=0;i<5;i++){AM2301_Data[i] = Read_AM2301_Data();}}else{Sensor_AnswerFlag=0;}return 1;}
本文系21ic论坛网友gaoyang9992006原创

免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!






