AHT20温度采集

AHT20温度采集

  • 1.“软件I2C”和“硬件I2C”
  • 2.stm32f103指南者外接AHT20进行温度采集。
    • 连接硬件
    • 代码实现

1.“软件I2C”和“硬件I2C”

所谓硬件I2C对应芯片上的I2C外设,有相应I2C驱动电路,其所使用的I2C管脚bai也是专用的;软件I2C一般是用GPIO管脚,用软件控制管脚状态以模拟I2C通信波形。
硬件I2C的效率要远高于软件的,而软件I2C由于不受管脚限制,接口比较灵活。
本次实验中使用的软件I2C

2.stm32f103指南者外接AHT20进行温度采集。

连接硬件

AHT20的SCL,GND,SDA,VCC分别对应接stm32f103指南者i2c模块的B6,GND,B7,5V。(GND和5V任意模块都可以)

代码实现

此处在固件库版的空白工程上进行添加代码,并实现以下功能:
每隔2秒钟采集一次温湿度数据,并通过串口发送到上位机

首先主函数如下:
main.c

#include "delay.h"
#include "usart.h"
#include "bsp_i2c.h"int main(void)
{	delay_init();     //ÑÓʱº¯Êý³õʼ»¯	  uart_init(115200);	 //´®¿Ú³õʼ»¯Îª115200IIC_Init();while(1){printf("¿ªÊ¼²âÁ¿£¬ÇëÉԵȣº");read_AHT20_once();delay_ms(1500);}
}

然后把以下代码文件和main.c放到一起
usart.c

#include "sys.h"
#include "usart.h"//STM32F103ºËÐÄ°åÀý³Ì
//¿âº¯Êý°æ±¾Àý³Ì
/********** mcudev.taobao.com ³öÆ·  ********/// 	 
//Èç¹ûʹÓÃucos,Ôò°üÀ¨ÏÂÃæµÄÍ·Îļþ¼´¿É.
#if SYSTEM_SUPPORT_UCOS
#include "includes.h"					//ucos ʹÓÃ	  
#endif
//	 
//STM32¿ª·¢°å
//´®¿Ú1³õʼ»¯		   // 	  //
//¼ÓÈëÒÔÏ´úÂë,Ö§³Öprintfº¯Êý,¶ø²»ÐèҪѡÔñuse MicroLIB	  
#if 1
#pragma import(__use_no_semihosting)             
//±ê×¼¿âÐèÒªµÄÖ§³Öº¯Êý                 
struct __FILE 
{ int handle; }; FILE __stdout;       
//¶¨Òå_sys_exit()ÒÔ±ÜÃâʹÓðëÖ÷»úģʽ    
void _sys_exit(int x) 
{ x = x; 
} 
//Öض¨Òåfputcº¯Êý 
int fputc(int ch, FILE *f)
{      while((USART1->SR&0X40)==0);//Ñ­»··¢ËÍ,Ö±µ½·¢ËÍÍê±Ï   USART1->DR = (u8) ch;      return ch;
}
#endif /*ʹÓÃmicroLibµÄ·½·¨*//* 
int fputc(int ch, FILE *f)
{USART_SendData(USART1, (uint8_t) ch);while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {}	return ch;
}
int GetKey (void)  { while (!(USART1->SR & USART_FLAG_RXNE));return ((int)(USART1->DR & 0x1FF));
}
*/#if EN_USART1_RX   //Èç¹ûʹÄÜÁ˽ÓÊÕ
//´®¿Ú1ÖжϷþÎñ³ÌÐò
//×¢Òâ,¶ÁÈ¡USARTx->SRÄܱÜÃâĪÃûÆäÃîµÄ´íÎó   	
u8 USART_RX_BUF[USART_REC_LEN];     //½ÓÊÕ»º³å,×î´óUSART_REC_LEN¸ö×Ö½Ú.
//½ÓÊÕ״̬
//bit15£¬	½ÓÊÕÍê³É±êÖ¾
//bit14£¬	½ÓÊÕµ½0x0d
//bit13~0£¬	½ÓÊÕµ½µÄÓÐЧ×Ö½ÚÊýÄ¿
u16 USART_RX_STA=0;       //½ÓÊÕ״̬±ê¼Ç	  void uart_init(u32 bound){//GPIO¶Ë¿ÚÉèÖÃGPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//ʹÄÜUSART1£¬GPIOAʱÖÓ//USART1_TX   PA.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//¸´ÓÃÍÆÍìÊä³öGPIO_Init(GPIOA, &GPIO_InitStructure);//USART1_RX	  PA.10GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//¸¡¿ÕÊäÈëGPIO_Init(GPIOA, &GPIO_InitStructure);  //Usart1 NVIC ÅäÖÃNVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//ÇÀÕ¼ÓÅÏȼ¶3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//×ÓÓÅÏȼ¶3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQͨµÀʹÄÜNVIC_Init(&NVIC_InitStructure);	//¸ù¾ÝÖ¸¶¨µÄ²ÎÊý³õʼ»¯VIC¼Ä´æÆ÷//USART ³õʼ»¯ÉèÖÃUSART_InitStructure.USART_BaudRate = bound;//Ò»°ãÉèÖÃΪ9600;USART_InitStructure.USART_WordLength = USART_WordLength_8b;//×Ö³¤Îª8λÊý¾Ý¸ñʽUSART_InitStructure.USART_StopBits = USART_StopBits_1;//Ò»¸öֹͣλUSART_InitStructure.USART_Parity = USART_Parity_No;//ÎÞÆæżУÑéλUSART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//ÎÞÓ²¼þÊý¾ÝÁ÷¿ØÖÆUSART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//ÊÕ·¢Ä£Ê½USART_Init(USART1, &USART_InitStructure); //³õʼ»¯´®¿ÚUSART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//¿ªÆôÖжÏUSART_Cmd(USART1, ENABLE);                    //ʹÄÜ´®¿Ú }void USART1_IRQHandler(void)                	//´®¿Ú1ÖжϷþÎñ³ÌÐò{u8 Res;
#ifdef OS_TICKS_PER_SEC	 	//Èç¹ûʱÖÓ½ÚÅÄÊý¶¨ÒåÁË,˵Ã÷ҪʹÓÃucosIIÁË.OSIntEnter();    
#endifif(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //½ÓÊÕÖжÏ(½ÓÊÕµ½µÄÊý¾Ý±ØÐëÊÇ0x0d 0x0a½áβ){Res =USART_ReceiveData(USART1);//(USART1->DR);	//¶ÁÈ¡½ÓÊÕµ½µÄÊý¾Ýif((USART_RX_STA&0x8000)==0)//½ÓÊÕδÍê³É{if(USART_RX_STA&0x4000)//½ÓÊÕµ½ÁË0x0d{if(Res!=0x0a)USART_RX_STA=0;//½ÓÊÕ´íÎó,ÖØпªÊ¼else USART_RX_STA|=0x8000;	//½ÓÊÕÍê³ÉÁË }else //»¹Ã»ÊÕµ½0X0D{	if(Res==0x0d)USART_RX_STA|=0x4000;else{USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;USART_RX_STA++;if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//½ÓÊÕÊý¾Ý´íÎó,ÖØпªÊ¼½ÓÊÕ	  }		 }}   		 } 
#ifdef OS_TICKS_PER_SEC	 	//Èç¹ûʱÖÓ½ÚÅÄÊý¶¨ÒåÁË,˵Ã÷ҪʹÓÃucosIIÁË.OSIntExit();  											 
#endif
} 
#endif	

usart.h

#ifndef __USART_H
#define __USART_H
#include "stdio.h"	
#include "sys.h" //STM32F103ºËÐÄ°åÀý³Ì
//¿âº¯Êý°æ±¾Àý³Ì
/********** mcudev.taobao.com ³öÆ·  ********///	 
//STM32¿ª·¢°å
//´®¿Ú1³õʼ»¯		   #define USART_REC_LEN  			200  	//¶¨Òå×î´ó½ÓÊÕ×Ö½ÚÊý 200
#define EN_USART1_RX 			1		    //ʹÄÜ£¨1£©/½ûÖ¹£¨0£©´®¿Ú1½ÓÊÕextern u8  USART_RX_BUF[USART_REC_LEN]; //½ÓÊÕ»º³å,×î´óUSART_REC_LEN¸ö×Ö½Ú.Ä©×Ö½ÚΪ»»Ðзû 
extern u16 USART_RX_STA;         		//½ÓÊÕ״̬±ê¼Ç	
//Èç¹ûÏë´®¿ÚÖжϽÓÊÕ£¬Ç벻ҪעÊÍÒÔϺ궨Òå
void uart_init(u32 bound);
#endif

bsp_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 ;   //ÍÆÍìÊä³öGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);IIC_SCL=1;IIC_SDA=1;}
//²úÉúIICÆðʼÐźÅ
void IIC_Start(void)
{SDA_OUT();     //sdaÏßÊä³ö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×ÜÏߣ¬×¼±¸·¢ËÍ»ò½ÓÊÕÊý¾Ý 
}	  
//²úÉúIICÍ£Ö¹ÐźÅ
void IIC_Stop(void)
{SDA_OUT();//sdaÏßÊä³ö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×ÜÏß½áÊøÐźÅdelay_us(4);							   	
}
//µÈ´ýÓ¦´ðÐźŵ½À´
//·µ»ØÖµ£º1£¬½ÓÊÕÓ¦´ðʧ°Ü
//        0£¬½ÓÊÕÓ¦´ð³É¹¦
u8 IIC_Wait_Ack(void)
{u8 ucErrTime=0;SDA_IN();      //SDAÉèÖÃΪÊäÈë  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;//ʱÖÓÊä³ö0 	   return 0;  
} 
//²úÉúACKÓ¦´ð
void IIC_Ack(void)
{IIC_SCL=0;SDA_OUT();IIC_SDA=0;delay_us(2);IIC_SCL=1;delay_us(2);IIC_SCL=0;
}
//²»²úÉúACKÓ¦´ð		    
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·¢ËÍÒ»¸ö×Ö½Ú
//·µ»Ø´Ó»úÓÐÎÞÓ¦´ð
//1£¬ÓÐÓ¦´ð
//0£¬ÎÞÓ¦´ð			  
void IIC_Send_Byte(u8 txd)
{                        u8 t;   SDA_OUT(); 	    IIC_SCL=0;//À­µÍʱÖÓ¿ªÊ¼Êý¾Ý´«Êäfor(t=0;t<8;t++){              IIC_SDA=(txd&0x80)>>7;txd<<=1; 	  delay_us(2);   //¶ÔTEA5767ÕâÈý¸öÑÓʱ¶¼ÊDZØÐëµÄ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ÉèÖÃΪÊäÈë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);	    //·¢Æ÷¼þµØÖ·IIC_Wait_Ack(); IIC_Send_Byte(addr&0xFF);   //·¢Ë͵͵ØÖ·IIC_Wait_Ack(); IIC_Send_Byte(data);     //·¢ËÍ×Ö½Ú							   IIC_Wait_Ack();  		    	   IIC_Stop();//²úÉúÒ»¸öÍ£Ö¹Ìõ¼þ if(device_addr==0xA0) //delay_ms(10);elsedelay_us(2);
}uint16_t IIC_ReadByte(uint16_t addr,uint8_t device_addr,uint8_t ByteNumToRead)  //¶Á¼Ä´æÆ÷»ò¶ÁÊý¾Ý
{	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);	    //·¢Æ÷¼þµØÖ·IIC_Wait_Ack();if(ByteNumToRead == 1)//LM75ζÈÊý¾ÝΪ11bit{data=IIC_Read_Byte(0);}else{data=IIC_Read_Byte(1);data=(data<<8)+IIC_Read_Byte(0);}IIC_Stop();//²úÉúÒ»¸öÍ£Ö¹Ìõ¼þ	    return data;
}/**********
*ÉÏÃ沿·ÖΪIO¿ÚÄ£¿éI2CÅäÖÃ
*
*´ÓÕâÒÔÏ¿ªÊ¼ÎªAHT20µÄÅäÖÃI2C
*º¯ÊýÃûÓÐIICºÍI2CµÄÇø±ð£¬Çë×¢Ò⣡£¡£¡£¡£¡
*
*2020/2/23×îºóÐÞ¸ÄÈÕÆÚ
*
***********/
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("ʪ¶È:%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"
//ʹÓÃIIC1 ¹ÒÔØ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;}//IO²Ù×÷º¯Êý	 
#define IIC_SCL    PBout(6) //SCL
#define IIC_SDA    PBout(7) //SDA	 
#define READ_SDA   PBin(7)  //ÊäÈëSDA //IICËùÓвÙ×÷º¯Êý
void IIC_Init(void);                //³õʼ»¯IICµÄIO¿Ú				 
void IIC_Start(void);				//·¢ËÍIIC¿ªÊ¼ÐźÅ
void IIC_Stop(void);	  			//·¢ËÍIICÍ£Ö¹ÐźÅ
void IIC_Send_Byte(u8 txd);			//IIC·¢ËÍÒ»¸ö×Ö½Ú
u8 IIC_Read_Byte(unsigned char ack);//IIC¶ÁÈ¡Ò»¸ö×Ö½Ú
u8 IIC_Wait_Ack(void); 				//IICµÈ´ýACKÐźÅ
void IIC_Ack(void);					//IIC·¢ËÍACKÐźÅ
void IIC_NAck(void);				//IIC²»·¢ËÍACKÐźÅ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);//¼Ä´æÆ÷µØÖ·£¬Æ÷¼þµØÖ·£¬Òª¶ÁµÄ×Ö½ÚÊý  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);
#endif

delay.c

#include "delay.h"
#include "sys.h"//STM32F103ºËÐÄ°åÀý³Ì
//¿âº¯Êý°æ±¾Àý³Ì
/********** mcudev.taobao.com ³öÆ·  ********/// 	 
//Èç¹ûʹÓÃucos,Ôò°üÀ¨ÏÂÃæµÄÍ·Îļþ¼´¿É.
#if SYSTEM_SUPPORT_UCOS
#include "includes.h"					//ucos ʹÓÃ	  
#endif
//	 //STM32¿ª·¢°å
//ʹÓÃSysTickµÄÆÕͨ¼ÆÊýģʽ¶ÔÑÓ³Ù½øÐйÜÀí
//°üÀ¨delay_us,delay_ms// 	 
static u8  fac_us=0;//usÑÓʱ±¶³ËÊý
static u16 fac_ms=0;//msÑÓʱ±¶³ËÊý
#ifdef OS_CRITICAL_METHOD 	//Èç¹ûOS_CRITICAL_METHOD¶¨ÒåÁË,˵Ã÷ʹÓÃucosIIÁË.
//systickÖжϷþÎñº¯Êý,ʹÓÃucosʱÓõ½
void SysTick_Handler(void)
{				   OSIntEnter();		//½øÈëÖжÏOSTimeTick();       //µ÷ÓÃucosµÄʱÖÓ·þÎñ³ÌÐò               OSIntExit();        //´¥·¢ÈÎÎñÇл»ÈíÖжÏ
}
#endif//³õʼ»¯ÑÓ³Ùº¯Êý
//µ±Ê¹ÓÃucosµÄʱºò,´Ëº¯Êý»á³õʼ»¯ucosµÄʱÖÓ½ÚÅÄ
//SYSTICKµÄʱÖӹ̶¨ÎªHCLKʱÖÓµÄ1/8
//SYSCLK:ϵͳʱÖÓ
void delay_init()	 
{#ifdef OS_CRITICAL_METHOD 	//Èç¹ûOS_CRITICAL_METHOD¶¨ÒåÁË,˵Ã÷ʹÓÃucosIIÁË.u32 reload;
#endifSysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);	//Ñ¡ÔñÍⲿʱÖÓ  HCLK/8fac_us=SystemCoreClock/8000000;	//ΪϵͳʱÖÓµÄ1/8  #ifdef OS_CRITICAL_METHOD 	//Èç¹ûOS_CRITICAL_METHOD¶¨ÒåÁË,˵Ã÷ʹÓÃucosIIÁË.reload=SystemCoreClock/8000000;		//ÿÃëÖӵļÆÊý´ÎÊý µ¥Î»ÎªK	   reload*=1000000/OS_TICKS_PER_SEC;//¸ù¾ÝOS_TICKS_PER_SECÉ趨Òç³öʱ¼ä//reloadΪ24λ¼Ä´æÆ÷,×î´óÖµ:16777216,ÔÚ72MÏÂ,Ô¼ºÏ1.86s×óÓÒ	fac_ms=1000/OS_TICKS_PER_SEC;//´ú±íucos¿ÉÒÔÑÓʱµÄ×îÉÙµ¥Î»	   SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;   	//¿ªÆôSYSTICKÖжÏSysTick->LOAD=reload; 	//ÿ1/OS_TICKS_PER_SECÃëÖжÏÒ»´Î	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;   	//¿ªÆôSYSTICK    
#elsefac_ms=(u16)fac_us*1000;//·ÇucosÏÂ,´ú±íÿ¸ömsÐèÒªµÄsystickʱÖÓÊý   
#endif
}								    #ifdef OS_CRITICAL_METHOD	//ʹÓÃÁËucos
//ÑÓʱnus
//nusΪҪÑÓʱµÄusÊý.		    								   
void delay_us(u32 nus)
{		u32 ticks;u32 told,tnow,tcnt=0;u32 reload=SysTick->LOAD;	//LOADµÄÖµ	    	 ticks=nus*fac_us; 			//ÐèÒªµÄ½ÚÅÄÊý	  		 tcnt=0;told=SysTick->VAL;        	//¸Õ½øÈëʱµÄ¼ÆÊýÆ÷Öµwhile(1){tnow=SysTick->VAL;	if(tnow!=told){	    if(tnow<told)tcnt+=told-tnow;//ÕâÀï×¢ÒâÒ»ÏÂSYSTICKÊÇÒ»¸öµÝ¼õµÄ¼ÆÊýÆ÷¾Í¿ÉÒÔÁË.else tcnt+=reload-tnow+told;	    told=tnow;if(tcnt>=ticks)break;//ʱ¼ä³¬¹ý/µÈÓÚÒªÑÓ³ÙµÄʱ¼ä,ÔòÍ˳ö.}  }; 									    
}
//ÑÓʱnms
//nms:ÒªÑÓʱµÄmsÊý
void delay_ms(u16 nms)
{	if(OSRunning==TRUE)//Èç¹ûosÒѾ­ÔÚÅÜÁË	    {		  if(nms>=fac_ms)//ÑÓʱµÄʱ¼ä´óÓÚucosµÄ×îÉÙʱ¼äÖÜÆÚ {OSTimeDly(nms/fac_ms);//ucosÑÓʱ}nms%=fac_ms;				//ucosÒѾ­ÎÞ·¨ÌṩÕâôСµÄÑÓʱÁË,²ÉÓÃÆÕͨ·½Ê½ÑÓʱ    }delay_us((u32)(nms*1000));	//ÆÕͨ·½Ê½ÑÓʱ,´ËʱucosÎÞ·¨Æô¶¯µ÷¶È.
}
#else//²»ÓÃucosʱ
//ÑÓʱnus
//nusΪҪÑÓʱµÄusÊý.		    								   
void delay_us(u32 nus)
{		u32 temp;	    	 SysTick->LOAD=nus*fac_us; //ʱ¼ä¼ÓÔØ	  		 SysTick->VAL=0x00;        //Çå¿Õ¼ÆÊýÆ÷SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;          //¿ªÊ¼µ¹Êý	 do{temp=SysTick->CTRL;}while(temp&0x01&&!(temp&(1<<16)));//µÈ´ýʱ¼äµ½´ï   SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;       //¹Ø±Õ¼ÆÊýÆ÷SysTick->VAL =0X00;       //Çå¿Õ¼ÆÊýÆ÷	 
}
//ÑÓʱnms
//×¢ÒânmsµÄ·¶Î§
//SysTick->LOADΪ24λ¼Ä´æÆ÷,ËùÒÔ,×î´óÑÓʱΪ:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLKµ¥Î»ÎªHz,nmsµ¥Î»Îªms
//¶Ô72MÌõ¼þÏÂ,nms<=1864 
void delay_ms(u16 nms)
{	 		  	  u32 temp;		   SysTick->LOAD=(u32)nms*fac_ms;//ʱ¼ä¼ÓÔØ(SysTick->LOADΪ24bit)SysTick->VAL =0x00;           //Çå¿Õ¼ÆÊýÆ÷SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;          //¿ªÊ¼µ¹Êý  do{temp=SysTick->CTRL;}while(temp&0x01&&!(temp&(1<<16)));//µÈ´ýʱ¼äµ½´ï   SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;       //¹Ø±Õ¼ÆÊýÆ÷SysTick->VAL =0X00;       //Çå¿Õ¼ÆÊýÆ÷	  	    
} 
#endif

delay.h

#ifndef __DELAY_H
#define __DELAY_H 			   
#include "sys.h"
//	 //STM32F103ºËÐÄ°åÀý³Ì
//¿âº¯Êý°æ±¾Àý³Ì
/********** mcudev.taobao.com ³öÆ·  ********///ʹÓÃSysTickµÄÆÕͨ¼ÆÊýģʽ¶ÔÑÓ³Ù½øÐйÜÀí
//°üÀ¨delay_us,delay_ms// 	 
void delay_init(void);
void delay_ms(u16 nms);
void delay_us(u32 nus);#endif

sys.c

#include "sys.h"//STM32F103ºËÐÄ°åÀý³Ì
//¿âº¯Êý°æ±¾Àý³Ì
/********** mcudev.taobao.com ³öÆ·  ********///	 //STM32¿ª·¢°å
//ϵͳÖжϷÖ×éÉèÖû¯		   //********************************************************************************  
void NVIC_Configuration(void)
{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	//ÉèÖÃNVICÖжϷÖ×é2:2λÇÀÕ¼ÓÅÏȼ¶£¬2λÏìÓ¦ÓÅÏȼ¶}

sys.h

#ifndef __SYS_H
#define __SYS_H	
#include "stm32f10x.h"
//	 //STM32F103ºËÐÄ°åÀý³Ì
//¿âº¯Êý°æ±¾Àý³Ì
/********** mcudev.taobao.com ³öÆ·  ********/// 	 //0,²»Ö§³Öucos
//1,Ö§³Öucos
#define SYSTEM_SUPPORT_UCOS		0		//¶¨ÒåϵͳÎļþ¼ÐÊÇ·ñÖ§³ÖUCOS//λ´ø²Ù×÷,ʵÏÖ51ÀàËƵÄGPIO¿ØÖƹ¦ÄÜ
//¾ßÌåʵÏÖ˼Ïë,²Î¿¼<<CM3ȨÍþÖ¸ÄÏ>>µÚÎåÕÂ(87Ò³~92Ò³).
//IO¿Ú²Ù×÷ºê¶¨Òå
#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¿ÚµØÖ·Ó³Éä
#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¿Ú²Ù×÷,Ö»¶Ôµ¥Ò»µÄIO¿Ú!
//È·±£nµÄֵСÓÚ16!
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //Êä³ö 
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //ÊäÈë #define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //Êä³ö 
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //ÊäÈë #define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //Êä³ö 
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //ÊäÈë #define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //Êä³ö 
#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //ÊäÈë #define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //Êä³ö 
#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //ÊäÈë#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //Êä³ö 
#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //ÊäÈë#define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //Êä³ö 
#define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //ÊäÈëvoid NVIC_Configuration(void);#endif

然后把usart.c,bsp_i2c.c,delay.c,sys.c加到工程文件中,如下图,
在这里插入图片描述
然后把产生的hex文件烧录到stm32中,打开串口调试助手,即可看到实验结果。
效果图如下:
在这里插入图片描述
对着芯片吹起发现温度湿度升高,实验成功。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/30649.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于CH32V307的温度显示功能

第一部分 设计概述 1.1 设计目的 在智能工业生产现场中&#xff0c;生产设备的控制依赖于传感器读数以及相关算法等。而传感器起着至关重要的作用&#xff0c;传感器的驱动和数据传输依赖于微控制器&#xff0c; 系统基于沁恒 CH32V307 微控制器进行数据收集、服务器进行数据处…

NetSuite nlapiRunReport隐秘的API

作为中国现金流量表剖析的后续篇&#xff0c;今朝我们谈一个隐秘函数。在几周之前&#xff0c;当用户问我&#xff1a;“SuiteScript能调用标准财务报表的运行结果么&#xff1f;”。我的答案是“No&#xff01;”&#xff0c;斩钉截铁。但是直到我们从代码堆里发现了这个API -…

被 ChatGPT 点燃的向量数据库们

主要观点&#xff1a; 向量数据库可以让开发者以向量嵌入的形式处理非结构化数据&#xff08;两个向量之间的距离代表了它们的关联性&#xff09;&#xff0c;这对于使用和扩展大型语言模型&#xff08;LLM&#xff09;尤为重要。 1、Pinecone 是个全托管的 SaaS 向量数据库厂商…

AI批改英语作文行不行?免费,覆盖雅思考研四六级,打分评语纠错都得有 | 测评...

茕茕 发自 凹非寺量子位 报道 | 公众号 QbitAI 我&#xff0c;一个科技小编&#xff0c;最近在跟国外大佬的邮件交流中&#xff0c;感到飘过六级后的自己英语写作水平那真是日渐捉急。 从句怎么用&#xff1f;时态对不对&#xff1f;看着对面主编犀利的目光&#xff0c;那一瞬间…

如何让ChatGPT成为你最佳的模拟面试官

正在上传…重新上传取消 ChatGPT云炬学长 1 人赞同了该文章 如何让ChatGPT成为你最佳的模拟面试官随着技术的不断发展&#xff0c;越来越多的企业开始使用人工智能面试官来帮助筛选候选人&#xff0c;ChatGPT作为其中的一种代表&#xff0c;正在受到越来越多的关注。那么如何…

春种一粒粟:企业如何修炼好云原生内功?

日月盈昃&#xff0c;辰宿列张。寒来暑往&#xff0c;秋收冬藏。 《千字文》里蕴藏了一种人与天地之间共处的智慧&#xff0c;那就是想要收获粮食&#xff0c;一定要提前播种。农耕如此&#xff0c;百业如此&#xff0c;数字化创新也是一样。 数字化技术&#xff0c;已经成为全…

《云原生构建数字世界》简介

云原生是在云计算时代指导企业基于云架构设计和开发应用&#xff0c;并将应用向云端迁移的一套全新的技术理念。与传统应用相比&#xff0c;所谓的云原生应用即为云而生。构筑数字世界新未来的关键是用云原生的思维去践行&#xff0c;未来数字世界的基础就是建立在云原生之上&a…

用云原生思维践行云原生,你做对了吗?

有了ChatGPT&#xff0c;你还会再用关键字进行搜索吗?这就像企业已经上了云&#xff0c;还会再退回老路&#xff0c;自己摆弄服务器、存储吗&#xff1f;无论从技术的持续演进&#xff0c;还是从应用现代化的需求来看&#xff0c;企业上云&#xff0c;开弓没有回头箭&#xff…

字符串 - 二进制和文本字符串 - 探究

1.应用场景 主要用于探究字符串中的二进制和文本字符串&#xff0c;以及它们的区别和应用场景。 2.学习/操作 1.文档阅读 重要来自于与chatgpt的对话问答 以及其他技术文章 2.整理输出 2.1 是什么 二进制和文本字符串都是计算机中常用的数据类型&#xff0c;前者主要用于存储…

chatgpt赋能python:用Python抢优惠券,快速低价购物!

用Python抢优惠券&#xff0c;快速低价购物&#xff01; 优惠券在购物时可以给我们带来很大的优惠&#xff0c;可是抢到优惠券的几率并不是那么高。有了Python&#xff0c;我们可以编写自己的优惠券抢购程序&#xff0c;快速抢到心仪的优惠券&#xff0c;无需反复手动尝试&…

chatgpt赋能python:长截图是什么?

长截图是什么&#xff1f; 长截图是一种比较新颖的网页截图方式&#xff0c;它的特点就是可以将整个页面的内容全部截取下来&#xff0c;让用户通过滚动鼠标来浏览这个页面的所有内容。这种截图方式在移动端比较常见&#xff0c;因为移动端的屏幕较小&#xff0c;往往需要滚动…

体外诊断(POCT)之软件介绍

这是2016上半年的研究成果,其中包括了概率统计,密码学,软件逆向,图像编解码,图像识别,多媒体指令优化等多个学科知识的交叉 下面即从技术角度,对所用得到的知识开发的这个产品进行一个简易的描述说明. 扩展阅读: 体外诊断(POCT)之软件入口配置修改 体外诊断(POCT)之系统配置文…

医疗信息管理系统(HIS)——>业务介绍

目录 一、项目背景 二、业务 三、门诊流程 四、住院流程 五、页面原型初稿&#xff08;门诊&#xff09;介绍 六、 页面原型初稿&#xff08;住院&#xff09;介绍 七、页面原型初稿&#xff08;药房药库&#xff09;介绍 一、项目背景 医疗信息系统是现代化医院运营的必…

三款实用分析诊断工具简介

当处理海量数据的时候&#xff0c;很容易出现各种异常和性能瓶颈&#xff0c;这时常常需要分析程序运行行为和性能瓶颈以优化系统性能。这里简单介绍了三种强大的分析诊断工具以帮助大家更快更好的完成优化工作。 1.Arthas Arthas是 阿里巴巴开源的一款 Java 线上诊断工具&…

玩转群晖NAS——前言

一直以来就有购置一台家用服务器的想法&#xff0c;趁着双十一赶紧购置一波&#xff0c;于是就买了个群晖DS920还有4个8T的希捷酷狼Pro硬盘&#xff0c;花了我一万多的钱&#xff0c;心疼归心疼&#xff0c;东西到手之后的兴奋还是远远大于剁手之痛的。迫不及待地安装上之后&am…

怎么把群晖个人用户空间相片映射到公共空间/photo

怎么把群晖个人用户空间相片映射到公共空间/photo 1.打开File Station 到homes 目录下对应用户名右键复制用户名路径 这里复制/volume1/home/user1 2.打开控制面板进入任务计划新增触发任务事件选开机用户账户选root 任务设置用户自定义脚本填入脚本点确定回到任务。 mkdir /…

有了群晖怎么玩,分享一下我的群晖中运行的服务

原文网址&#xff1a;https://post.smzdm.com/p/a07mk7z9/ 我前几篇文章中说了我在服务器中弄了个虚拟机群晖&#xff0c;很多朋友在没有入手群晖的时候不知道群晖这玩意买来干嘛&#xff0c;花这么多钱&#xff0c;这篇文章就讲讲群晖有那些好玩实用的东西 一、Drive-套件文…

如何使用群晖nas快速收集多份文件?

经常需要在工作中收集文件的小伙伴是否遇到了一个共同的问题⚠&#xff1a; 比如老板让你收集公司员工的工作报告时&#xff0c;你一打开邮箱&#xff0c;几十封、几百封邮件就会涌进来&#xff0c;需要进行下载上百封邮件需要下载。有时候一些同事通过QQ、微信等各种app发送&a…

群晖NAS与Windows系统实现共享文件夹同步方案

一、在Windows系统中创建需要共享的文件夹 操作步骤如下&#xff1a; ①选中需要共享的文件夹&#xff0c;选择“属性”。 ②在属性弹窗中选择“共享”-->“高级共享”-->“权限”-->"添加"-->"高级"-->"立即查找"选择合适的账…

3.3 利用群晖:群辉与PC电脑直连,实现万兆/2.5G速度文件互传(解决 直连后 网络/外网/网页 访问变慢,直连后群辉无网络 cloud sync无网络)

为黑群晖和电脑装备了万兆X540 T2网卡&#xff0c;为实现万兆速度的文件互传&#xff0c;决定将黑群晖直连PC&#xff0c;其需要注意的点有以下三点&#xff1a; 修改PC和群辉的IPv4&#xff1a; 为实现固定IP访问群辉&#xff0c;这里建议修改PC和群辉均为固定IP。 1&#xff…