温湿度模块测试

本文介绍了I2C协议的基本原理,包括起始和结束信号的产生条件,并对比了软件I2C与硬件I2C的区别。通过AHT20温湿度模块的测试,展示了代码实现和运行结果,强调了实验中对芯片手册理解的重要性及代码修改的挑战。
摘要由CSDN通过智能技术生成

“软件I2C”和“硬件I2C”

I2C Bus(Inter-Integrated Circuit Bus) 最早是由Philips半导体(现被NXP收购)开发的两线时串行总线,常用于微控制器与外设之间的连接。

I2C协议规定,总线上数据的传输必须以一个起始信号作为开始条件,以一个结束信号作为传输的停止条件。起始和结束信号总是由主设备产生。
起始和结束信号产生条件:总线在空闲状态时,SCL和SDA都保持着高电平,当SCL为高电平而SDA由高到低的跳变,表示产生一个起始条件;当SCL为高而SDA由低到高的跳变,表示产生一个停止条件。

在起始条件产生后,总线处于忙状态,由本次数据传输的主从设备独占,其他I2C器件无法访问总线;而在停止条件产生后,本次数据传输的主从设备将释放总线,总线再次处于空闲状态。起始和结束如图所示:
在这里插入图片描述
在这里插入图片描述
软件I2C:
软件I2C一般是用GPIO管脚,用软件控制管脚状态以模拟I2C通信波形。
软件I2C:
硬件I2C对应芯片上的I2C外设,有相应I2C驱动电路,其所使用的I2C管脚也是专用的

AHT20温湿度模块测试

温湿度部分代码如下图所示:

代码

1、main.c

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "bsp_i2c.h"

uint8_t t;
uint8_t len;
uint16_t times=0;
	
//extern uint32_t H1;
//extern uint32_t T1;

int main(void)
{
   	
	delay_init();     //ÑÓʱº¯Êý³õʼ»¯	  
	uart_init(115200);	 //´®¿Ú³õʼ»¯Îª115200
	IIC_Init();
//	int i=0;
	
	while(1)
	{
   
		printf("start");
		read_AHT10_once();
		delay_ms(1500);

2、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;
#endif
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);	//Ñ¡ÔñÍⲿʱÖÓ  HCLK/8
	fac_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    
#else
	fac_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)))
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值