AM2320 温湿度计 单总线读取数据
生活随笔
收集整理的這篇文章主要介紹了
AM2320 温湿度计 单总线读取数据
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?
溫濕度計 用單總線方式讀取數據?
?
AM2320支持IIC通信和單總線通信,這里只用單總線:
使用單總線時的接線方式時,只需接第二引腳SDA,SCL接地就行。
?
通信時序圖:
?
由時序可見通信非常簡單,關鍵點要把握好每個時序的時間。
程序思路:
1.握手:
先是發送0.8~20ms的開始信號,然后等待AM2320的應答,要確保應答信號是先是80us的低電平和80us的高電平。
2.數據傳輸。
AM2320發出應答后就會在跟著的低電平(48~50us)后返回數據位,用高電平的時間長短來區分信號‘1’和‘0’。手冊說'0'是22~30us,'1'是60~75us,本人測試時并不對,通過對電平時間的測量發現,'0'在4~8us之間,'1'在14~16us之間。可能是延時函數引起的誤差。一切以實際情況為準。
程序源碼:
?
#include "stm32f10x.h" #include "usart.h" #include "delay.h" #define AM2320_Pin GPIOB,GPIO_Pin_7 #define AM2320_Port GPIO_ReadInputDataBit(AM2320_Pin) #define AM2320_Port_H GPIO_SetBits(AM2320_Pin) #define AM2320_Port_L GPIO_ResetBits(AM2320_Pin)//void delay_us(uint32_t n) 延時多少微秒,n就輸入多少! //{ // SysTick->LOAD=72*n; //裝載計數值,因為時鐘72M,72次在1μs // SysTick->CTRL=0x00000005;//時鐘來源設為為HCLK(72M),打開定時器 // while(!(SysTick->CTRL&0x00010000)); //等待計數到0 // SysTick->CTRL=0x00000004;//關閉定時器 //} //void delay_ms(uint32_t n) 延時多少微秒,n就輸入多少! //{ // SysTick->LOAD=72000*n; //裝載計數值,因為時鐘72M,72次在1μs // SysTick->CTRL=0x00000005;//時鐘來源設為為HCLK(72M),打開定時器 // while(!(SysTick->CTRL&0x00010000)); //等待計數到0 // SysTick->CTRL=0x00000004;//關閉定時器 //} void AM2320_Init() {GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_8;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_Init(GPIOB,&GPIO_InitStructure);AM2320_Port_H; } unsigned char AM2320_start() {unsigned char status=0,wait;AM2320_Port_H;//_nop_();AM2320_Port_L;delay_ms(2);//>=800us,0.8~20msAM2320_Port_H;//releasewait=0;status=0x00;while(AM2320_Port==1&&wait<200)//主機釋放總線時間,20~200us{wait++;delay_us(1);}if(wait>=200)//沒回應status|=0x08;wait=0;while(AM2320_Port==0&&wait<90)//響應低電平 75~85us{delay_us(1);wait++;}if(wait>=90)//no ackstatus|=0x04;wait=0;while(AM2320_Port==1&&wait<200)//響應高電平時間 75~85us{delay_us(1);wait++;}if(wait>=200)//no ackstatus|=0x02;return status; } unsigned char AM2320_Read(unsigned char *dat)//讀40位 {unsigned char tmp=0,i,j,wait,status=0;for(i=0;i<5;i++)//5 byte, 40 bit{for(j=0;j<8;j++)//one byte{tmp<<=1;wait = 0;while(AM2320_Port==0&&wait<100)//信號間隔低電平時間48~55us{wait++;delay_us(1);}if(wait>=100)status|=0x10;wait=0;while(AM2320_Port==1&&wait<100)//22~75us{delay_us(1);wait++;}if(wait>=2&&wait<=8)//信號‘0’時間: 22~30us{tmp |=0x00;}if(wait>=9&&wait<=20)//信號‘1’時間: 68~75us {tmp |=0x01;}if(wait>=100){status|=0x20;}//printf("wait:%d\n",wait);//*****************************//如果數據不正確或者沒數據回來時,把時序的時間打印出來//此次數據時序在時間在 4~8us,14~15us范圍內,可能delay_us不準確!!!!!!!}*dat=tmp;dat++;tmp=0;}if((*dat+*(dat+1)+*(dat+2)+*(dat+3))==*(dat+4)){return status|=0x40;}elsereturn status|=0x80; } int main() {u8 status;u8 a=0;u16 H,T,C;u8 AM2320_Read_buff[5];AM2320_Init();SysTick_Init(1);USART_Config(115200);printf(" hello world\n");while(1){if(a){a=0;GPIO_SetBits(GPIOB,GPIO_Pin_8);}else{GPIO_ResetBits(GPIOB,GPIO_Pin_8);a=1;}status=AM2320_start();// printf("status1:%x\n",status);status|=AM2320_Read(AM2320_Read_buff);printf("status2:%x\n",status);H=AM2320_Read_buff[0]*256+AM2320_Read_buff[1];T=AM2320_Read_buff[2]*256+AM2320_Read_buff[3];C=AM2320_Read_buff[4];for(a=0;a<5;a++)printf("%x\t",AM2320_Read_buff[a]);printf("H:%f,T:%f C,C:%d\n",(float)H*0.1,(float)T*0.1,C); // while(1) // {delay_ms(100); // printf("test1\n");delay_ms(200); // printf("test2\n");delay_ms(200); // printf("test3\n"); // }} }AM2320
?
?
?
?
printf和delay函數請自行編寫
總結
以上是生活随笔為你收集整理的AM2320 温湿度计 单总线读取数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vivos1有红外线功能吗
- 下一篇: NTC温度检测程序