STM32采集温湿度
文章目錄
- 寫作目的
- 一、I2C基礎(chǔ)
- 1.什么是I2C協(xié)議?
- I2C協(xié)議的物理層
- I2C的協(xié)議層
- 二、采集溫濕度
- 1.使用儀器:
- 2.代碼實(shí)現(xiàn)
- 實(shí)現(xiàn)效果
- 總結(jié)
寫作目的
幫助讀者掌握I2C總線通信協(xié)議,使用STM32F103完成基于I2C協(xié)議的AHT20溫濕度傳感器的數(shù)據(jù)采集,并將采集的溫度-濕度值通過串口輸出。
編程實(shí)現(xiàn):每隔2秒鐘采集一次溫濕度數(shù)據(jù),并通過串口發(fā)送到上位機(jī)(win10)。
一、I2C基礎(chǔ)
1.什么是I2C協(xié)議?
在嵌入式系統(tǒng)內(nèi)部電路中,眾多功能需要用到許多集成電路IC來實(shí)現(xiàn),包括主控器件微控制器和眾多外圍設(shè)備器件,如:PLL合成器、非易失性存儲(chǔ)器、音頻處理器、視頻處理器、屏幕顯示器等。這些器件相互之間要傳遞數(shù)據(jù)信息,那么就需要用導(dǎo)線相互連接,如此眾多IC器件的互連,勢(shì)必導(dǎo)致芯片引腳、PCB走線以及連接導(dǎo)線變得數(shù)量龐大,錯(cuò)綜復(fù)雜,這會(huì)導(dǎo)致IC芯片體積增大、功耗增大、成本增加,給IC芯片設(shè)計(jì)制造廠商帶來不利影響,同時(shí)也給IC芯片應(yīng)用廠商和應(yīng)用工程師們?cè)斐蓸O大不便。
1982年,從事電燈泡、電剃刀、電唱機(jī)、收音機(jī)、電視機(jī)等研發(fā)制造已久的荷蘭飛利浦公司,為解決電視機(jī)的上述問題,從而發(fā)明了一種集成電路互連通信電路,該電路的優(yōu)點(diǎn)就是僅用兩條線就可以實(shí)現(xiàn)芯片之間的互連通信,使硬件電路最簡(jiǎn)化,硬件效益最大化,給芯片設(shè)計(jì)制造者和芯片應(yīng)用者帶來極大益處。
飛利浦公司給這種集成電路互連通信電路命名為Inter-Integrated Circuit,簡(jiǎn)稱為Inter-IC,或I2C(數(shù)字“2”為上標(biāo),讀作英文讀作“I squared C”,中文讀作“I平方C”)。
I2C協(xié)議的物理層
所有主從器件的SDA線全部連在一根線上,這些器件分時(shí)占用這根公共數(shù)據(jù)線,來實(shí)現(xiàn)兩兩互傳數(shù)據(jù),那么SDA符合了數(shù)據(jù)總線的特征;所有主從器件的SCL線全部連在一根線上,它們分時(shí)占用這根公共時(shí)鐘線,來實(shí)現(xiàn)兩兩互傳時(shí)鐘,那么SCL符合了時(shí)鐘總線的特征。
因?yàn)镮2C中的兩根導(dǎo)線(SDA和SCL)構(gòu)成了兩根Bus,實(shí)現(xiàn)了Bus的功能;由于I2C電路能實(shí)現(xiàn)Bus的功能,故把I2C 電路稱為 I2C-bus,中文叫I2C總線(I2C總線是一個(gè)兩線總線)。
I2C的協(xié)議層
主要是定義了通訊的起始和停止信號(hào)、數(shù)據(jù)有效性、響應(yīng)、仲裁、時(shí)鐘同步和地址廣播等
通訊的起始和停止信號(hào)
數(shù)據(jù)有效性
從圖中可以看出I2C在通訊的時(shí)候,只有在SCL處于高電平時(shí),SDA的數(shù)據(jù)傳輸才是有效的。SDA 信號(hào)線是用于傳輸數(shù)據(jù),SCL 信號(hào)線是保證數(shù)據(jù)同步。
響應(yīng)
當(dāng)SDA傳輸數(shù)據(jù)后,接收方對(duì)接受到的數(shù)據(jù)進(jìn)行一個(gè)應(yīng)答。如果希望繼續(xù)進(jìn)行傳輸數(shù)據(jù),則回應(yīng)應(yīng)答信號(hào)(低電平),否則回應(yīng)非應(yīng)答信號(hào)(高電平)。
I2C總線的特點(diǎn)
①只需要兩條總線;串行數(shù)據(jù)線(SDA)和串行時(shí)鐘線(SCL)。
②連接到總線的每個(gè)設(shè)備都是可通過唯一地址進(jìn)行軟件尋址的,并且始終存在簡(jiǎn)單的控制器/目標(biāo)關(guān)系;控制器可以作為控制器發(fā)送器或控制器接收器運(yùn)行。
③這是一種真正的多控制器總線,包括沖突檢測(cè)和仲裁,以防止兩個(gè)或更多控制器同時(shí)啟動(dòng)數(shù)據(jù)傳輸時(shí)出現(xiàn)數(shù)據(jù)損壞。
④面向8位的串行雙向數(shù)據(jù)傳輸速率在標(biāo)準(zhǔn)模式下最高可達(dá)100 kbit/s,在快速模式下最高可達(dá)400 kbit/s,在快速增強(qiáng)模式下最高可達(dá)1 Mbit/s,在高速模式下最高可達(dá)3.4 Mbit/s。
⑤串行、面向8位、單向數(shù)據(jù)傳輸,在超快速模式下最高可達(dá)5 Mbit/s。
⑥片內(nèi)濾波可抑制總線數(shù)據(jù)線上的尖峰信號(hào),以保持?jǐn)?shù)據(jù)完整性。
⑦可以連接到同一總線的IC數(shù)量?jī)H受最大總線電容的限制。在某些條件下(如簡(jiǎn)化SCL時(shí)鐘頻率、增加輸出驅(qū)動(dòng)力、增加緩沖器件、改進(jìn)上拉電阻等),可以允許更大的電容。
⑧極低的電流消耗,高抗擾度,寬電源電壓范圍,寬工作溫度范圍。
⑨硬件的最簡(jiǎn)化,給芯片設(shè)計(jì)師減輕了節(jié)省輸出引腳的壓力,給芯片應(yīng)用商帶來了成本降低、空間減小、測(cè)試方便、易于升級(jí)等諸多好處,為芯片應(yīng)用工程師的產(chǎn)品開發(fā)帶來靈活多樣的選擇方案、方便快捷的調(diào)試手段、開發(fā)周期的縮短、開發(fā)效率的提高等好處。
二、采集溫濕度
1.使用儀器:
AHT20芯片
具體信息請(qǐng)到官方下載對(duì)應(yīng)產(chǎn)品介紹文檔,資料鏈接如下
http://www.aosong.com/class-36.html
硬件連接:
產(chǎn)品實(shí)拍:
對(duì)應(yīng)管腳:
實(shí)物連接:
ATH20 —— STM32
VDD——5V
SDA——B7
GND——GND
SCL——B6
(GND和5V任意模塊都可以)
2.代碼實(shí)現(xiàn)
本次實(shí)驗(yàn)將會(huì)使用到KEIL的固件庫(kù)模板,如果你還不會(huì)搭建固件庫(kù)模板請(qǐng)看這篇文章:固件庫(kù)模板
或者固件庫(kù)教程
main.c
#include "delay.h" #include "usart.h" #include "bsp_i2c.h"int main(void) { delay_init(); //?óê±oˉêy3?ê??ˉ uart_init(115200); //′??ú3?ê??ˉ?a115200IIC_Init();while(1){printf("?aê?2aá?£???é?μè£o");read_AHT20_once();delay_ms(1500);} }然后把以下代碼文件和main.c放到一起
usart.c
usart.h
#ifndef __USART_H #define __USART_H #include "stdio.h" #include "sys.h" //STM32F103o?D?°?ày3ì //?aoˉêy°?±?ày3ì /********** mcudev.taobao.com 3??· ********/// //STM32?a·¢°? //′??ú13?ê??ˉ #define USART_REC_LEN 200 //?¨ò?×?′ó?óê?×??úêy 200 #define EN_USART1_RX 1 //ê1?ü£¨1£?/???1£¨0£?′??ú1?óê?extern u8 USART_RX_BUF[USART_REC_LEN]; //?óê??o3?,×?′óUSART_REC_LEN??×??ú.??×??ú?a??DD·? extern u16 USART_RX_STA; //?óê?×′ì?±ê?? //è?1???′??ú?D???óê?£???2?òa×¢êíò???oê?¨ò? void uart_init(u32 bound); #endifbsp_i2c.c
#include "bsp_i2c.h" #include "delay.h"uint8_t ack_status=0; uint8_t readByte[6]; uint8_t AHT20_status=0;uint32_t H1=0; //Humility uint32_t T1=0; //Temperatureuint8_t AHT20_OutData[4]; uint8_t AHT20sendOutData[10] = {0xFA, 0x06, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF};void IIC_Init(void) { GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //í?íìê?3?GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);IIC_SCL=1;IIC_SDA=1;} //2úéúIIC?eê?D?o? void IIC_Start(void) {SDA_OUT(); //sda??ê?3?IIC_SDA=1; IIC_SCL=1;delay_us(4);IIC_SDA=0;//START:when CLK is high,DATA change form high to low delay_us(4);IIC_SCL=0;//?ˉ×?I2C×ü??£?×?±?·¢?í?ò?óê?êy?Y } //2úéúIICí£?1D?o? void IIC_Stop(void) {SDA_OUT();//sda??ê?3?IIC_SCL=0;IIC_SDA=0;//STOP:when CLK is high DATA change form low to highdelay_us(4);IIC_SCL=1; IIC_SDA=1;//·¢?íI2C×ü???áê?D?o?delay_us(4); } //μè′yó|′eD?o?μ?à′ //·μ???μ£o1£??óê?ó|′eê§°ü // 0£??óê?ó|′e3é1| u8 IIC_Wait_Ack(void) {u8 ucErrTime=0;SDA_IN(); //SDAéè???aê?è? IIC_SDA=1;delay_us(1); IIC_SCL=1;delay_us(1); while(READ_SDA){ucErrTime++;if(ucErrTime>250){IIC_Stop();return 1;}}IIC_SCL=0;//ê±?óê?3?0 return 0; } //2úéúACKó|′e void IIC_Ack(void) {IIC_SCL=0;SDA_OUT();IIC_SDA=0;delay_us(2);IIC_SCL=1;delay_us(2);IIC_SCL=0; } //2?2úéúACKó|′e void IIC_NAck(void) {IIC_SCL=0;SDA_OUT();IIC_SDA=1;delay_us(2);IIC_SCL=1;delay_us(2);IIC_SCL=0; } //IIC·¢?íò???×??ú //·μ??′ó?úóD?Tó|′e //1£?óDó|′e //0£??Tó|′e void IIC_Send_Byte(u8 txd) { u8 t; SDA_OUT(); IIC_SCL=0;//à-μíê±?ó?aê?êy?Y′?ê?for(t=0;t<8;t++){ IIC_SDA=(txd&0x80)>>7;txd<<=1; delay_us(2); //??TEA5767?aèy???óê±??ê?±?D?μ?IIC_SCL=1;delay_us(2); IIC_SCL=0; delay_us(2);} } //?á1??×??ú£?ack=1ê±£?·¢?íACK£?ack=0£?·¢?ínACK u8 IIC_Read_Byte(unsigned char ack) {unsigned char i,receive=0;SDA_IN();//SDAéè???aê?è?for(i=0;i<8;i++ ){IIC_SCL=0; delay_us(2);IIC_SCL=1;receive<<=1;if(READ_SDA)receive++; delay_us(1); } if (!ack)IIC_NAck();//·¢?ínACKelseIIC_Ack(); //·¢?íACK return receive; }void IIC_WriteByte(uint16_t addr,uint8_t data,uint8_t device_addr) {IIC_Start(); if(device_addr==0xA0) //eepromμ??·′óóú1×??úIIC_Send_Byte(0xA0 + ((addr/256)<<1));//·¢?í??μ??·elseIIC_Send_Byte(device_addr); //·¢?÷?tμ??·IIC_Wait_Ack(); IIC_Send_Byte(addr&0xFF); //·¢?íμíμ??·IIC_Wait_Ack(); IIC_Send_Byte(data); //·¢?í×??ú IIC_Wait_Ack(); IIC_Stop();//2úéúò???í£?1ì??t if(device_addr==0xA0) //delay_ms(10);elsedelay_us(2); }uint16_t IIC_ReadByte(uint16_t addr,uint8_t device_addr,uint8_t ByteNumToRead) //?á??′??÷?ò?áêy?Y { uint16_t data;IIC_Start(); if(device_addr==0xA0)IIC_Send_Byte(0xA0 + ((addr/256)<<1));elseIIC_Send_Byte(device_addr); IIC_Wait_Ack();IIC_Send_Byte(addr&0xFF); //·¢?íμíμ??·IIC_Wait_Ack(); IIC_Start(); IIC_Send_Byte(device_addr+1); //·¢?÷?tμ??·IIC_Wait_Ack();if(ByteNumToRead == 1)//LM75???èêy?Y?a11bit{data=IIC_Read_Byte(0);}else{data=IIC_Read_Byte(1);data=(data<<8)+IIC_Read_Byte(0);}IIC_Stop();//2úéúò???í£?1ì??t return data; }/********** *é???2?·??aIO?ú?£?éI2C???? * *′ó?aò????aê??aAHT20μ?????I2C *oˉêy??óDIICoíI2Cμ???±e£???×¢òa£?£?£?£?£? * *2020/2/23×?oóDT??è??ú * ***********/ void read_AHT20_once(void) {delay_ms(10);reset_AHT20();delay_ms(10);init_AHT20();delay_ms(10);startMeasure_AHT20();delay_ms(80);read_AHT20();delay_ms(5); }void reset_AHT20(void) {I2C_Start();I2C_WriteByte(0x70);ack_status = Receive_ACK();if(ack_status) printf("1");else printf("1-n-");I2C_WriteByte(0xBA);ack_status = Receive_ACK();if(ack_status) printf("2");else printf("2-n-");I2C_Stop();/*AHT20_OutData[0] = 0;AHT20_OutData[1] = 0;AHT20_OutData[2] = 0;AHT20_OutData[3] = 0;*/ }void init_AHT20(void) {I2C_Start();I2C_WriteByte(0x70);ack_status = Receive_ACK();if(ack_status) printf("3");else printf("3-n-"); I2C_WriteByte(0xE1);ack_status = Receive_ACK();if(ack_status) printf("4");else printf("4-n-");I2C_WriteByte(0x08);ack_status = Receive_ACK();if(ack_status) printf("5");else printf("5-n-");I2C_WriteByte(0x00);ack_status = Receive_ACK();if(ack_status) printf("6");else printf("6-n-");I2C_Stop(); }void startMeasure_AHT20(void) {//------------I2C_Start();I2C_WriteByte(0x70);ack_status = Receive_ACK();if(ack_status) printf("7");else printf("7-n-");I2C_WriteByte(0xAC);ack_status = Receive_ACK();if(ack_status) printf("8");else printf("8-n-");I2C_WriteByte(0x33);ack_status = Receive_ACK();if(ack_status) printf("9");else printf("9-n-");I2C_WriteByte(0x00);ack_status = Receive_ACK();if(ack_status) printf("10");else printf("10-n-");I2C_Stop(); }void read_AHT20(void) {uint8_t i;for(i=0; i<6; i++){readByte[i]=0;}//-------------I2C_Start();I2C_WriteByte(0x71);ack_status = Receive_ACK();readByte[0]= I2C_ReadByte();Send_ACK();readByte[1]= I2C_ReadByte();Send_ACK();readByte[2]= I2C_ReadByte();Send_ACK();readByte[3]= I2C_ReadByte();Send_ACK();readByte[4]= I2C_ReadByte();Send_ACK();readByte[5]= I2C_ReadByte();SendNot_Ack();//Send_ACK();I2C_Stop();//--------------if( (readByte[0] & 0x68) == 0x08 ){H1 = readByte[1];H1 = (H1<<8) | readByte[2];H1 = (H1<<8) | readByte[3];H1 = H1>>4;H1 = (H1*1000)/1024/1024;T1 = readByte[3];T1 = T1 & 0x0000000F;T1 = (T1<<8) | readByte[4];T1 = (T1<<8) | readByte[5];T1 = (T1*2000)/1024/1024 - 500;AHT20_OutData[0] = (H1>>8) & 0x000000FF;AHT20_OutData[1] = H1 & 0x000000FF;AHT20_OutData[2] = (T1>>8) & 0x000000FF;AHT20_OutData[3] = T1 & 0x000000FF;}else{AHT20_OutData[0] = 0xFF;AHT20_OutData[1] = 0xFF;AHT20_OutData[2] = 0xFF;AHT20_OutData[3] = 0xFF;printf("ê§°üá?");}printf("\r\n");printf("???è:%d%d.%d",T1/100,(T1/10)%10,T1%10);printf("êa?è:%d%d.%d",H1/100,(H1/10)%10,H1%10);printf("\r\n"); }uint8_t Receive_ACK(void) {uint8_t result=0;uint8_t cnt=0;IIC_SCL = 0;SDA_IN(); delay_us(4);IIC_SCL = 1;delay_us(4);while(READ_SDA && (cnt<100)){cnt++;}IIC_SCL = 0;delay_us(4);if(cnt<100){result=1;}return result; }void Send_ACK(void) {SDA_OUT();IIC_SCL = 0;delay_us(4);IIC_SDA = 0;delay_us(4);IIC_SCL = 1;delay_us(4);IIC_SCL = 0;delay_us(4);SDA_IN(); }void SendNot_Ack(void) {SDA_OUT();IIC_SCL = 0;delay_us(4);IIC_SDA = 1;delay_us(4);IIC_SCL = 1;delay_us(4);IIC_SCL = 0;delay_us(4);IIC_SDA = 0;delay_us(4); }void I2C_WriteByte(uint8_t input) {uint8_t i;SDA_OUT();for(i=0; i<8; i++){IIC_SCL = 0;delay_ms(5);if(input & 0x80){IIC_SDA = 1;//delaymm(10);}else{IIC_SDA = 0;//delaymm(10);}IIC_SCL = 1;delay_ms(5);input = (input<<1);}IIC_SCL = 0;delay_us(4);SDA_IN();delay_us(4); } uint8_t I2C_ReadByte(void) {uint8_t resultByte=0;uint8_t i=0, a=0;IIC_SCL = 0;SDA_IN();delay_ms(4);for(i=0; i<8; i++){IIC_SCL = 1;delay_ms(3);a=0;if(READ_SDA){a=1;}else{a=0;}//resultByte = resultByte | a;resultByte = (resultByte << 1) | a;IIC_SCL = 0;delay_ms(3);}SDA_IN();delay_ms(10);return resultByte; }void set_AHT20sendOutData(void) {/* --------------------------* 0xFA 0x06 0x0A temperature(2 Bytes) humility(2Bytes) short Address(2 Bytes)* And Check (1 byte)* -------------------------*/AHT20sendOutData[3] = AHT20_OutData[0];AHT20sendOutData[4] = AHT20_OutData[1];AHT20sendOutData[5] = AHT20_OutData[2];AHT20sendOutData[6] = AHT20_OutData[3];// AHT20sendOutData[7] = (drf1609.shortAddress >> 8) & 0x00FF; // AHT20sendOutData[8] = drf1609.shortAddress & 0x00FF;// AHT20sendOutData[9] = getXY(AHT20sendOutData,10); }void I2C_Start(void) {SDA_OUT();IIC_SCL = 1;delay_ms(4);IIC_SDA = 1;delay_ms(4);IIC_SDA = 0;delay_ms(4);IIC_SCL = 0;delay_ms(4); }void I2C_Stop(void) {SDA_OUT();IIC_SDA = 0;delay_ms(4);IIC_SCL = 1;delay_ms(4);IIC_SDA = 1;delay_ms(4); }bsp_i2c.h
在這里插入代#ifndef __BSP_I2C_H #define __BSP_I2C_H#include "sys.h" #include "delay.h" #include "usart.h" //ê1ó?IIC1 1ò??M24C02,OLED,LM75AD,HT1382 PB6,PB7#define SDA_IN() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;} #define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}//IO2ù×÷oˉêy #define IIC_SCL PBout(6) //SCL #define IIC_SDA PBout(7) //SDA #define READ_SDA PBin(7) //ê?è?SDA //IIC?ùóD2ù×÷oˉêy void IIC_Init(void); //3?ê??ˉIICμ?IO?ú void IIC_Start(void); //·¢?íIIC?aê?D?o? void IIC_Stop(void); //·¢?íIICí£?1D?o? void IIC_Send_Byte(u8 txd); //IIC·¢?íò???×??ú u8 IIC_Read_Byte(unsigned char ack);//IIC?áè?ò???×??ú u8 IIC_Wait_Ack(void); //IICμè′yACKD?o? void IIC_Ack(void); //IIC·¢?íACKD?o? void IIC_NAck(void); //IIC2?·¢?íACKD?o?void IIC_WriteByte(uint16_t addr,uint8_t data,uint8_t device_addr); uint16_t IIC_ReadByte(uint16_t addr,uint8_t device_addr,uint8_t ByteNumToRead);//??′??÷μ??·£??÷?tμ??·£?òa?áμ?×??úêy void read_AHT20_once(void); void reset_AHT20(void); void init_AHT20(void); void startMeasure_AHT20(void); void read_AHT20(void); uint8_t Receive_ACK(void); void Send_ACK(void); void SendNot_Ack(void); void I2C_WriteByte(uint8_t input); uint8_t I2C_ReadByte(void); void set_AHT20sendOutData(void); void I2C_Start(void); void I2C_Stop(void); #endifdelay.c
#include "delay.h" #include "sys.h"//STM32F103o?D?°?ày3ì //?aoˉêy°?±?ày3ì /********** mcudev.taobao.com 3??· ********/// //è?1?ê1ó?ucos,?ò°üà¨????μ?í·???t?′?é. #if SYSTEM_SUPPORT_UCOS #include "includes.h" //ucos ê1ó? #endif // //STM32?a·¢°? //ê1ó?SysTickμ???í¨??êy?£ê????ó3ù??DD1üàí //°üà¨delay_us,delay_ms// static u8 fac_us=0;//us?óê±±?3?êy static u16 fac_ms=0;//ms?óê±±?3?êy #ifdef OS_CRITICAL_METHOD //è?1?OS_CRITICAL_METHOD?¨ò?á?,?μ?÷ê1ó?ucosIIá?. //systick?D??·t??oˉêy,ê1ó?ucosê±ó?μ? void SysTick_Handler(void) { OSIntEnter(); //??è??D??OSTimeTick(); //μ÷ó?ucosμ?ê±?ó·t??3ìDò OSIntExit(); //′¥·¢è????D??èí?D?? } #endif//3?ê??ˉ?ó3ùoˉêy //μ±ê1ó?ucosμ?ê±oò,′?oˉêy?á3?ê??ˉucosμ?ê±?ó?ú?? //SYSTICKμ?ê±?ó1ì?¨?aHCLKê±?óμ?1/8 //SYSCLK:?μí3ê±?ó void delay_init() {#ifdef OS_CRITICAL_METHOD //è?1?OS_CRITICAL_METHOD?¨ò?á?,?μ?÷ê1ó?ucosIIá?.u32 reload; #endifSysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //????ía2?ê±?ó HCLK/8fac_us=SystemCoreClock/8000000; //?a?μí3ê±?óμ?1/8 #ifdef OS_CRITICAL_METHOD //è?1?OS_CRITICAL_METHOD?¨ò?á?,?μ?÷ê1ó?ucosIIá?.reload=SystemCoreClock/8000000; //?????óμ???êy′?êy μ¥???aK reload*=1000000/OS_TICKS_PER_SEC;//?ù?YOS_TICKS_PER_SECéè?¨ò?3?ê±??//reload?a24????′??÷,×?′ó?μ:16777216,?ú72M??,??o?1.86s×óóò fac_ms=1000/OS_TICKS_PER_SEC;//′ú±íucos?éò??óê±μ?×?éùμ¥?? SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; //?a??SYSTICK?D??SysTick->LOAD=reload; //??1/OS_TICKS_PER_SEC???D??ò?′? SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //?a??SYSTICK #elsefac_ms=(u16)fac_us*1000;//·?ucos??,′ú±í????msDèòaμ?systickê±?óêy #endif } #ifdef OS_CRITICAL_METHOD //ê1ó?á?ucos //?óê±nus //nus?aòa?óê±μ?usêy. void delay_us(u32 nus) { u32 ticks;u32 told,tnow,tcnt=0;u32 reload=SysTick->LOAD; //LOADμ??μ ticks=nus*fac_us; //Dèòaμ??ú??êy tcnt=0;told=SysTick->VAL; //????è?ê±μ???êy?÷?μwhile(1){tnow=SysTick->VAL; if(tnow!=told){ if(tnow<told)tcnt+=told-tnow;//?aà?×¢òaò???SYSTICKê?ò???μY??μ???êy?÷?í?éò?á?.else tcnt+=reload-tnow+told; told=tnow;if(tcnt>=ticks)break;//ê±??3?1y/μèóúòa?ó3ùμ?ê±??,?òí?3?.} }; } //?óê±nms //nms:òa?óê±μ?msêy void delay_ms(u16 nms) { if(OSRunning==TRUE)//è?1?osò??-?ú?üá? { if(nms>=fac_ms)//?óê±μ?ê±??′óóúucosμ?×?éùê±???ü?ú {OSTimeDly(nms/fac_ms);//ucos?óê±}nms%=fac_ms; //ucosò??-?T·¨ìá1??a?′D?μ??óê±á?,2éó???í¨·?ê??óê± }delay_us((u32)(nms*1000)); //??í¨·?ê??óê±,′?ê±ucos?T·¨???ˉμ÷?è. } #else//2?ó?ucosê± //?óê±nus //nus?aòa?óê±μ?usêy. void delay_us(u32 nus) { u32 temp; SysTick->LOAD=nus*fac_us; //ê±???ó?? SysTick->VAL=0x00; //??????êy?÷SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //?aê?μ1êy do{temp=SysTick->CTRL;}while(temp&0x01&&!(temp&(1<<16)));//μè′yê±??μ?′? SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //1?±???êy?÷SysTick->VAL =0X00; //??????êy?÷ } //?óê±nms //×¢òanmsμ?·??§ //SysTick->LOAD?a24????′??÷,?ùò?,×?′ó?óê±?a: //nms<=0xffffff*8*1000/SYSCLK //SYSCLKμ¥???aHz,nmsμ¥???ams //??72Mì??t??,nms<=1864 void delay_ms(u16 nms) { u32 temp; SysTick->LOAD=(u32)nms*fac_ms;//ê±???ó??(SysTick->LOAD?a24bit)SysTick->VAL =0x00; //??????êy?÷SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //?aê?μ1êy do{temp=SysTick->CTRL;}while(temp&0x01&&!(temp&(1<<16)));//μè′yê±??μ?′? SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //1?±???êy?÷SysTick->VAL =0X00; //??????êy?÷ } #endifdelay.h
#ifndef __DELAY_H #define __DELAY_H #include "sys.h" // //STM32F103o?D?°?ày3ì //?aoˉêy°?±?ày3ì /********** mcudev.taobao.com 3??· ********///ê1ó?SysTickμ???í¨??êy?£ê????ó3ù??DD1üàí //°üà¨delay_us,delay_ms// void delay_init(void); void delay_ms(u16 nms); void delay_us(u32 nus);#endifsys.c
#include "sys.h"//STM32F103o?D?°?ày3ì //?aoˉêy°?±?ày3ì /********** mcudev.taobao.com 3??· ********/// //STM32?a·¢°? //?μí3?D??·?×ééè???ˉ //******************************************************************************** void NVIC_Configuration(void) {NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //éè??NVIC?D??·?×é2:2???à??ó??è??£?2???ìó|ó??è??}sys.h
#ifndef __SYS_H #define __SYS_H #include "stm32f10x.h" // //STM32F103o?D?°?ày3ì //?aoˉêy°?±?ày3ì /********** mcudev.taobao.com 3??· ********/// //0,2??§3?ucos //1,?§3?ucos #define SYSTEM_SUPPORT_UCOS 0 //?¨ò??μí3???t?Dê?·??§3?UCOS//??′?2ù×÷,êμ??51àà??μ?GPIO????1|?ü //??ì?êμ??????,2???<<CM3è¨ít????>>μú????(87ò3~92ò3). //IO?ú2ù×÷oê?¨ò? #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) #define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) #define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum)) //IO?úμ??·ó3é? #define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C #define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C #define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C #define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C #define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C #define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C #define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C #define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808 #define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08 #define GPIOC_IDR_Addr (GPIOC_BASE+8) //0x40011008 #define GPIOD_IDR_Addr (GPIOD_BASE+8) //0x40011408 #define GPIOE_IDR_Addr (GPIOE_BASE+8) //0x40011808 #define GPIOF_IDR_Addr (GPIOF_BASE+8) //0x40011A08 #define GPIOG_IDR_Addr (GPIOG_BASE+8) //0x40011E08 //IO?ú2ù×÷,????μ¥ò?μ?IO?ú! //è·±£nμ??μD?óú16! #define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //ê?3? #define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //ê?è? #define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //ê?3? #define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //ê?è? #define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //ê?3? #define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //ê?è? #define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //ê?3? #define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //ê?è? #define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //ê?3? #define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //ê?è?#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //ê?3? #define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //ê?è?#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //ê?3? #define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //ê?è?void NVIC_Configuration(void);#endif然后把usart.c,bsp_i2c.c,delay.c,sys.c加到工程文件中,如下圖。
實(shí)現(xiàn)效果
總結(jié)
本次實(shí)驗(yàn)中學(xué)會(huì)了一個(gè)經(jīng)典接口IIC的使用方法,在實(shí)驗(yàn)中體會(huì)到,作為物聯(lián)網(wǎng)工程師,學(xué)會(huì)閱讀各種接口協(xié)議有多么重要。IIC是一種僅用兩根線就能完成大部分?jǐn)?shù)據(jù)傳輸功能的協(xié)議,但是若想提高通信速度,還是需要增加數(shù)據(jù)線數(shù)量。
stm32通過I2C接口實(shí)現(xiàn)溫濕度(AHT20)的采集:https://blog.csdn.net/qq_43279579/article/details/111597278
總結(jié)
以上是生活随笔為你收集整理的STM32采集温湿度的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java多个文件压缩并加密
- 下一篇: ffmpeg 视频去水印