2443|2

7048

帖子

11

TA的资源

版主

楼主
 

【AT-START-F425测评】温湿度计(硬件I2C)AHT10 [复制链接]

  本帖最后由 lugl4313820 于 2022-3-29 14:08 编辑

前面驱动了SPI屏,今天学习了AT32F425的I2C硬件。参考学习了网友的例子,拆腾一天,终于把I2C硬件驱动好了温湿计,下面汇报如下:

【驱动的步骤】

1、在drivers目录下新建AHT驱动文件AHT10.c与头文件AHT10.h。

2、选择I2C1的IO为PB6—SCL,PB7—SDA 。查看数据手册为GPIO_MUX_1。

3、宏定义好I2C超时时间、通信速度、AHT10的器件地址以及CLK、GPIO端口引脚,复用序号等:

#define I2C_TIMEOUT                      0xFFFFFFF
                                         
//#define I2Cx_CLKCTRL                   0x2170FAFA   //10K
//#define I2Cx_CLKCTRL                   0x80E06565   //50K
#define I2Cx_CLKCTRL                     0x80E03030   //100K
//#define I2Cx_CLKCTRL                   0x20E0355F   //200K

#define I2Cx_ADDRESS                     0xA0
#define AHT10_ADDRESS                    0x70	               

#define I2Cx_PORT                        I2C1
#define I2Cx_CLK                         CRM_I2C1_PERIPH_CLOCK
#define I2Cx_DMA                         DMA1
#define I2Cx_DMA_CLK                     CRM_DMA1_PERIPH_CLOCK
//SCL 引脚配置重定义     
#define I2Cx_SCL_GPIO_CLK                CRM_GPIOB_PERIPH_CLOCK
#define I2Cx_SCL_GPIO_PIN                GPIO_PINS_6
#define I2Cx_SCL_GPIO_PinsSource         GPIO_PINS_SOURCE6  
#define I2Cx_SCL_GPIO_PORT               GPIOB
#define I2Cx_SCL_GPIO_MUX                GPIO_MUX_1     
//SDA 引脚配置重定义                                 
#define I2Cx_SDA_GPIO_CLK                CRM_GPIOB_PERIPH_CLOCK
#define I2Cx_SDA_GPIO_PIN                GPIO_PINS_7   
#define I2Cx_SDA_GPIO_PinsSource         GPIO_PINS_SOURCE7      
#define I2Cx_SDA_GPIO_PORT               GPIOB
#define I2Cx_SDA_GPIO_MUX                GPIO_MUX_1 

3、初始化i2c设备结构体 i2c_handle_type hi2cx; 

4、修改void i2c_lowlevel_init,去i2c例程中去复制一个函数。这里没有用的DMA以及中断,可以把中断与DMA配置的函数去掉:

/**
  * @brief  initializes peripherals used by the i2c.
  * @param  none
  * @retval none
  */
void i2c_lowlevel_init(i2c_handle_type* hi2c)
{
  gpio_init_type gpio_init_structure;
  if(hi2c->i2cx == I2Cx_PORT)
  {
    /* i2c 时钟使能 */
    crm_periph_clock_enable(I2Cx_CLK, TRUE);    
    crm_periph_clock_enable(I2Cx_SCL_GPIO_CLK, TRUE); 
    crm_periph_clock_enable(I2Cx_SDA_GPIO_CLK, TRUE);
    
    /* gpio 复用端口配置 */  
    gpio_pin_mux_config(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_GPIO_PinsSource, I2Cx_SCL_GPIO_MUX);
    gpio_pin_mux_config(I2Cx_SDA_GPIO_PORT, I2Cx_SDA_GPIO_PinsSource, I2Cx_SDA_GPIO_MUX);
    
    /* 配置 i2c pins: scl */
    gpio_init_structure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_init_structure.gpio_mode           = GPIO_MODE_MUX;
    gpio_init_structure.gpio_out_type       = GPIO_OUTPUT_OPEN_DRAIN;
    gpio_init_structure.gpio_pull           = GPIO_PULL_UP;  
                                            
    gpio_init_structure.gpio_pins           = I2Cx_SCL_GPIO_PIN;
    gpio_init(I2Cx_SCL_GPIO_PORT, &gpio_init_structure);

    /* 配置 i2c pins: sda */
    gpio_init_structure.gpio_pins           = I2Cx_SDA_GPIO_PIN;
    gpio_init(I2Cx_SDA_GPIO_PORT, &gpio_init_structure); 
    
    /* config i2c */ 
    i2c_init(hi2c->i2cx, 0, I2Cx_CLKCTRL);
    i2c_own_address1_set(hi2c->i2cx, I2C_ADDRESS_MODE_7BIT, AHT10_ADDRESS);
	i2c_enable(hi2c->i2cx,TRUE);
  }
}

5、AHT10写寄存器函数:

void AHT_Reset_REG(uint8_t addr)
{
	uint8_t dat1[2]={0};
	uint8_t dat2[3]={0};
//	i2c_status_type i2c_status;
	rt_thread_mdelay(100);
	i2c_memory_write(&hi2cx,AHT10_ADDRESS,addr,dat1,2,0xffffff);
	rt_thread_mdelay(5);
	i2c_master_receive(&hi2cx,AHT10_ADDRESS,dat2,3,0xffffff);
	dat2[0]=0xb0|addr;
	i2c_master_transmit(&hi2cx,AHT10_ADDRESS,dat2,3,0xffffff);
}

6、AHT10初始化函数:

void InitAHT10(void)
{
	  unsigned char rest_dat[2]={0,0},dat1[2]={0x00,0x80};
	  hi2cx.i2cx = I2Cx_PORT;
	  i2c_config(&hi2cx);
		//unsigned char status;	
		rt_thread_mdelay(150);
		AHT_Reset_REG(0x1b);
		rt_thread_mdelay(50);
		AHT_Reset_REG(0x1c);
		rt_thread_mdelay(50);
		AHT_Reset_REG(0x1e);
		rt_thread_mdelay(200);
		i2c_memory_write(&hi2cx,AHT10_ADDRESS,0xa8,rest_dat,2,0xffffff);//0xA8进入NOR工作模式
		rt_thread_mdelay(5);
		i2c_memory_write(&hi2cx,AHT10_ADDRESS,0xe1,dat1,2,0xfffff);//0xBE初始化命令,AHT20的初始化命令是0xBE,   AHT10的初始化命令是0xE1
		rt_thread_mdelay(5);

}

7、读取温度与数据:


void AHT10_Read_CTdata(uint32_t *ct) //没有CRC校验,直接读取AHT10的温度和湿度数据
{
//	i2c_status_type i2c_status;
	unsigned char	dat1[3]={0xac,0x33,0x00},retuenDAT[6]={0},dat2[3]={0xbe,0x08,0x00};//dat1 AC读取命令,retuenDAT 缓存数组,dat2为校准命令
//	unsigned char status=0;

	//uint16_t cnt = 0;
	rt_thread_mdelay(50);
	i2c_master_transmit(&hi2cx,AHT10_ADDRESS,dat2,3,0xffffff);//向AHT20发送校准命令
	rt_thread_mdelay(50);	
	i2c_master_transmit(&hi2cx,AHT10_ADDRESS,dat1,3,0xffffff);//向AHT20发送AC命令
//	printf("i2c_read_status=%d\n\r",i2c_status);
	rt_thread_mdelay(50);
	i2c_master_receive(&hi2cx,AHT10_ADDRESS,retuenDAT,6,0xffffff);
//	printf("i2c_receive_status=%d\n\r",i2c_status);
	while((retuenDAT[0]&0x80)==0x80)
	{
		i2c_master_receive(&hi2cx,AHT10_ADDRESS,retuenDAT,6,0xffffff);
		rt_thread_mdelay(10);
		printf("busy =0x%x\n\r",retuenDAT[0]);

	}
	ct[0]=(((uint32_t)retuenDAT[1]<<12)+((uint32_t)retuenDAT[2]<<4)+((uint32_t)retuenDAT[3]>>4));
	ct[1]=((((uint32_t)retuenDAT[3]&0xf)<<16)+((uint32_t)retuenDAT[4]<<8)+((uint32_t)retuenDAT[5]));	
}

至此,AHT10的函数已经写好,在main函数中引入AHT10.h,创建一个任务,在LCD屏上显示采集到的数据。

#define THREAD_PRIORITY         25
#define THREAD_STACK_SIZE       1024
#define THREAD_TIMESLICE        5

static rt_thread_t tid_AHT10 = RT_NULL;

static void tid_AHT10_entry(void *parameter)
{
	uint32_t temp[2]={0};
	volatile float t1;
	u8 humidity;
	while(1)
	{
		AHT10_Read_CTdata(temp);
		humidity=(int)(temp[0]*100.0/1024/1024+0.5);
		t1=((int)(temp[1]*2000.0/1024/1024+0.5))/10.0-50;
		
		LCD_ShowIntNum(90, 100, humidity, 2,  BLUE,WHITE, 32);
		LCD_ShowFloatNum1(80, 60, t1, 4, BLUE,WHITE, 32);
		rt_thread_mdelay(500);
	}
}

 

【感受】

        经过一天的学习,AT32F425的学习资源还是很多的,特别是雅特力这次做这个开发板的测评活动,出的贴子非常多,关于i2c驱动OLED屏的文章也很多,只要花点时间,i2c的驱动还是很容易的。我这次花了一些时间来阅读官方提供的源码,收获也挺多。

       但是昨晚本来驱动好了,准备收工时,突然程序卡死,找了好久的原因,直到今天中午才找到,就是USB供电一定要稳定、电流要足够,要不就找不到AHT10,这样就一直等待超时。其实官方出的这个驱动的中间件在处理超时的函数还是阻塞式的,在RT—Thread OS下,会因为阻塞时间处发生跑飞现象。要用到生产环境,还是要加以修改为非阻塞的超时等待。

       这个I2C的程序还有很大的修改空间,比如I2C在等待接收ACK、NACK、STOP等超时返回错误的判断等。用硬的i2C相比软件模拟的就要更多的考虑到极端环境的问题,要不会出现很多意想不到的结果。


 

最新回复

谢谢分享,期待后续   详情 回复 发表于 2022-3-29 17:14
点赞 关注
 
 

回复
举报

7048

帖子

11

TA的资源

版主

沙发
 

将RT_Thread Studio工程上传上来,供需要的网友交流。

AT32F425SP9306—AHT10.7z

1.37 MB, 下载次数: 1

 
 
 

回复

7671

帖子

2

TA的资源

五彩晶圆(高级)

板凳
 

谢谢分享,期待后续

个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表