|
本人在校學(xué)生一個(gè),最近做項(xiàng)目時(shí),用到了AM2311溫濕度檢測模塊,這個(gè)模塊支持IIC和單總線通信方式,IIC通信的例程網(wǎng)上一抓一大把,但是很不巧,小編就誤選了單總線通信的模塊。
進(jìn)入正題,如何進(jìn)行單總線數(shù)據(jù)通信來讀取數(shù)據(jù)呢?
顧名思義:單總線通信,就是通過一條數(shù)據(jù)線進(jìn)行通信.IIC擁有SDA(數(shù)據(jù)線)和SCL(時(shí)鐘線),單總線通信,可以理解為去掉了SCL線,通過固定的一套時(shí)間協(xié)議,達(dá)到數(shù)據(jù)傳輸?shù)哪康摹?br />
個(gè)人總結(jié):
1.項(xiàng)目實(shí)際操作能力有待加強(qiáng):以前做項(xiàng)目,在網(wǎng)上或多或少都可以找些模塊代碼進(jìn)行移植,但是,AM2311單總線通信模塊,網(wǎng)上沒有相關(guān)代碼,必須自己撰寫,只能依靠模塊的數(shù)據(jù)手冊。這一過程花費(fèi)小編接近2天時(shí)間,算是一個(gè)小小突破吧。
2.通信協(xié)議類的代碼,一般精度都很高,在US級(jí)別,不要嘗試去做一些與讀取數(shù)據(jù)無關(guān)的操作,比如延時(shí),比如串口輸出接受的某一個(gè)數(shù)據(jù)。(本來AM2311一次性傳輸數(shù)據(jù)為40個(gè),小編在其中加了一個(gè)pringtf函數(shù),導(dǎo)致接受數(shù)據(jù)只有24個(gè))
3.一點(diǎn)建議:雖說這樣的情況可以突破自我,鍛煉個(gè)人能力,但是在做一些緊急的項(xiàng)目開發(fā)時(shí),最好是選用一些常用的通信方式,更節(jié)省時(shí)間。
下面貼上幾張使用手冊的圖片。
S90721-090845.jpg (209.72 KB, 下載次數(shù): 76)
下載附件
2019-7-23 21:02 上傳
S90721-090629.jpg (156.31 KB, 下載次數(shù): 68)
下載附件
2019-7-23 21:02 上傳
S90721-090856.jpg (268.72 KB, 下載次數(shù): 63)
下載附件
2019-7-23 21:02 上傳
S90721-090904.jpg (252.81 KB, 下載次數(shù): 71)
下載附件
2019-7-23 21:02 上傳
S90721-090911.jpg (215.16 KB, 下載次數(shù): 76)
下載附件
2019-7-23 21:02 上傳
小編不太清楚具體圖片上傳是怎么回事,這個(gè)手冊去各大瀏覽器搜索,可能也會(huì)搜索到的。
話不多說,上代碼咯,保證編譯之后下載即可使用。
單片機(jī)源程序如下:
- #include "am2311.h"
- #include "stm32f10x.h"
- #include "sys.h"
- #include "delay.h"
- AM2311_Data_TypeDef AM2311_Data;
- void AM2311_GPIO_Init1(void)//推挽輸出
- {
- GPIO_InitTypeDef GPIO_Initstructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
- GPIO_Initstructure.GPIO_Mode=GPIO_Mode_Out_PP;
- GPIO_Initstructure.GPIO_Pin=GPIO_Pin_7;
- GPIO_Initstructure.GPIO_Speed=GPIO_Speed_50MHz;
- GPIO_Init(GPIOB,&GPIO_Initstructure);
- }
- void AM2311_GPIO_Init2(void)//上拉輸入
- {
- GPIO_InitTypeDef GPIO_Initstructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
- GPIO_Initstructure.GPIO_Mode=GPIO_Mode_IPU;
- GPIO_Initstructure.GPIO_Pin=GPIO_Pin_7;
- GPIO_Initstructure.GPIO_Speed=GPIO_Speed_50MHz;
- GPIO_Init(GPIOB,&GPIO_Initstructure);
- }
- void AM2311_GPIO_Init(void)
- {
-
- AM2311_GPIO_Init1();//推挽輸出模式配置
- AM2311_GPIO_Init2();//推挽輸出模式配置
-
- }
- static uint8_t Read_Byte(void)
- {
- uint8_t i, temp=0;
- for(i=0;i<8;i++)
- {
-
- /*每BIT以50us低電平標(biāo)志開始,輪詢從機(jī)發(fā)出的50us低電平結(jié)束*/
- while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)==0);//低電平就一直在這里循環(huán),除去開頭的低電平50us干擾
-
- delay_us(50); //延時(shí)50ms
- if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)==1)//如果此時(shí)檢測還是高電平,代表發(fā)送的數(shù)據(jù)1
- {
- // printf("1");
- while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)==1);//等待高電平結(jié)束
- temp|=(uint8_t)(0x01<<(7-i));//把第七位置一(發(fā)送的位是從高到低順序發(fā)送來的)
- }
- else //如果此時(shí)為低電平,表示接收到了0
- {
- temp&=(uint8_t)~(0x01<<(7-i)); //
- // printf("0");
- }
- }
- return temp;
- }
- uint8_t Read_AM2311(AM2311_Data_TypeDef *AM2311_Data)
- {
- /*輸出模式I*/
- delay_ms(1000);
- delay_ms(1000);
- //第二步:輸出1MS低電平,然后將32IO口設(shè)置為輸入
- AM2311_GPIO_Init1();//引腳設(shè)置為輸出
- PBout(7)=0;
- delay_ms(1);
- AM2311_GPIO_Init2();//引腳設(shè)置成上拉輸入,釋放總線
- //上邊部分應(yīng)該在read data前初始化一次
- delay_us(30);
- while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)==0);//低電平就一直在這里循環(huán)
- delay_us(50);//
- if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)==1)//表示此時(shí)模塊即將發(fā)送數(shù)據(jù),已經(jīng)成功響應(yīng),//問題在于總線電平依舊為低
- {
- // printf("應(yīng)答信號(hào)來了\n");
- while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)==1);//等待響應(yīng)信號(hào)結(jié)束
- //開始接受數(shù)據(jù)
- // printf("NO\n");
-
- AM2311_Data->humi_int=Read_Byte();
- AM2311_Data->humi_deci=Read_Byte();
- AM2311_Data->temp_int=Read_Byte();
- AM2311_Data->temp_deci=Read_Byte();
- AM2311_Data->check_sum=Read_Byte();
- /*讀取數(shù)據(jù)結(jié)束,引腳改為輸出模式*/
- AM2311_GPIO_Init1();
- PBout(7)=1;
- if(AM2311_Data->check_sum ==AM2311_Data->humi_int + AM2311_Data->humi_deci + AM2311_Data->temp_int+ AM2311_Data->temp_deci)
- //核對校驗(yàn)位是否正確
- {
- // printf("返回的數(shù)據(jù)為1");
- return 1;
-
- }
-
- else
- {
- // printf("返回?cái)?shù)據(jù)失敗");
- return 0;
-
- }
-
-
- }
- else
- {
- // printf("YES\n");
- return 0;
- }
-
- }
復(fù)制代碼- #include "led.h"
- #include "delay.h"
- #include "sys.h"
- #include "usart.h"
- #include <string.h>
- #include "timer.h"
- #include "am2311.h"
- #include <stdio.h>
- #include "stm32f10x.h"
- //#include <stm32f1xx_hal.h>
- //在int之前定義,代表是整個(gè)工程中的變量,定義在某個(gè)函數(shù)當(dāng)中,只能是在該函數(shù)內(nèi)部進(jìn)行使用,無法擴(kuò)展extern
- u8 n=0;
- u8 m=0;
- u8 len=0;
- u16 Send_Time=0; //發(fā)送次數(shù)
- int RH_Value=0;
- int RH_H,RH_L=0;
- int TEMP_Value=0;
- int TP_H,TP_L=0;
- extern AM2311_Data_TypeDef AM2311_Data;
- extern u8 receive[20];//用于接受傳輸過來的數(shù)組
- int main(void)
-
- {
- u8 keysign=0; //按鍵標(biāo)志
- u16 head=0x55aa; //發(fā)送變量
- u16 tail=0xaa55;
- u8 id_code[32]="174eec111de24bfaa1f3a8b12279dcd4"; //設(shè)備識(shí)別號(hào)
- u8 heart=0xff;
- u8 i=0;
- u8 sign_1s=0;
- u32 count_1s=0;
- delay_init(); //延時(shí)函數(shù)初始化
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設(shè)置NVIC中斷分組2:2位搶占優(yōu)先級(jí),2位響應(yīng)優(yōu)先級(jí)
- uart_init(115200); //串口初始化為115200
- LED_Init(); //LED端口初始化
- TIM4_Int_Init(99,7199); //1ms
- AM2311_GPIO_Init();
-
- // while(sign==0)
- while(1)
- {
- /*
- // if(Send_Time>=7) break;
- // delay_ms(2000);
- // if((USART_RX_STA&0x8000||Send_Time==0)&&(Send_Time<=7))//接收完成,對數(shù)據(jù)的內(nèi)容進(jìn)行判斷。
- // {
- // if(Send_Time<=7)
- // Send_Time++;
- // switch(Send_Time)
- // {
- // case 1:printf("\r\nAT+CWMODE=3\r\n"); break; //printf("\r\nAT+CWMODE=1\r\n");//station模式,連入WiFi
- // case 2:printf("\r\nAT+RST\r\n"); break; //設(shè)置模式后,重啟有效
- // case 3:printf("\r\nAT+CWJAP=\"ywx123\",\"87654321\"\r\n"); break;//Smart_Home_hbkj 11111111
- // case 4:printf("\r\nAT+CIPMUX=0\r\n"); break; //2350,2347 //單通道模式
- // case 5:printf("\r\nAT+CIPSTART=\"TCP\",\"39.96.179.213\",2347\r\n"); break; //連入的ip和端口號(hào)
- // //case 5:printf("\r\nAT+CIPSTART=\"TCP\",\"192.168.31.119\",1234\r\n"); break; //連入的ip和端口號(hào)
- // case 6:printf("\r\nAT+CIPMODE=1\r\n"); break; //透傳模式
- // case 7:printf("\r\nAT+CIPSEND\r\n"); break; //開始發(fā)送數(shù)據(jù)
- // case 8 :break;
- // }
- //
- // if(Send_Time%2==0) //每改變一個(gè)連接狀態(tài),led燈狀態(tài)改變一次
- // GPIO_ResetBits(GPIOC,GPIO_Pin_13);
- // else
- // GPIO_SetBits(GPIOC,GPIO_Pin_13 );//否則保持為同一個(gè)狀態(tài)
- // while(1)
- // {
- // delay_ms(3000);
- // strflag1 = strstr(USART_RX_BUF,str1); //判斷是否含有ready,如果有,則為1,否則為0
- // strflag2 = strstr(USART_RX_BUF,str2); //判斷是否含有OK
- // if(Send_Time==7)
- // {
- // for(n=0;n<3;n++)//輸出3次數(shù)據(jù)進(jìn)行檢查
- // {
- // printf("175240");
- // delay_ms(1000);
- // len=USART_RX_STA&0x3fff;//取出u16中的低16 位,得到此次接收到的數(shù)據(jù)長度
- // if(USART_RX_STA&0x8000)//判斷接收數(shù)組的最高位是否為一,本次接收是否完成如果接受完成,就執(zhí)行下列操作。
- // {
- // //if(USART_RX_BUF[1]=='h')
- // for(m=0;m<len;m++)
- // {
- // USART1->DR=USART_RX_BUF[m];//把每一個(gè)數(shù)據(jù)都在串口打印出來
- // while((USART1->SR&0X40)==0);//等待發(fā)送結(jié)束
- // }
- // }
- // }
- // sign=1;//
- // }
- // if(strflag1!=NULL||strflag2!=NULL|Send_Time==2)
- // {//兩個(gè)只要有一個(gè)不為空就說明是 有上面兩個(gè)值
- // memset(USART_RX_BUF,NULL,sizeof(USART_RX_BUF));//清空接收數(shù)組
- // USART_RX_STA=0x8000;//最高位強(qiáng)制為1、其他位不變、說明這次接收的數(shù)據(jù)中有OK和ready
- // break;//強(qiáng)行之一之后就進(jìn)入串口中斷。
- // }
- // }
- // }//執(zhí)行完數(shù)據(jù)接收
- */
- //計(jì)算出實(shí)際濕度值的10倍
- if(Read_AM2311(&AM2311_Data)==1)
- {
- RH_Value= AM2311_Data.humi_int*256 + AM2311_Data.humi_deci;
- RH_H = RH_Value/10;
- RH_L =(RH_Value%10);
- //?????????10?
- TEMP_Value = AM2311_Data.temp_int*256 + AM2311_Data.temp_deci;
- TP_H = TEMP_Value/10;
- TP_L = TEMP_Value%10;
-
- printf("RH_Value=%d,RH_H=%d,RH_L=%d\r\n",RH_Value,RH_H,RH_L);
- delay_ms(1000);
- printf("TEMP_Value=%d,TP_H=%d,TP_L=%d\r\n",TEMP_Value,TP_H,TP_L);
- delay_ms(1000);
- delay_ms(1000);
- }
- }
-
- }
復(fù)制代碼
所有資料51hei提供下載:
STM32F1 AM2311 單總線.7z
(192.03 KB, 下載次數(shù): 32)
2019-7-24 04:53 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
評分
-
查看全部評分
|