温湿度模块"/>
GD32F303移植ATH10温湿度模块
目录
前期准备
移植准备
开始移植
ATH10.c
ATH10.h
main.c
效果图
总结
前期准备
开发硬件:GD32F303RCT6开发板
开发平台:Keil5
网盘资料:见文章底部
移植准备
ATH10模块I2C驱动使用到us延时,因此需要调整时钟频率,调整方法详细请看GD32F303移植4针0.96寸OLED显示屏(I2C)中时钟频率调整部分,这里就不过多讲解了。
开始移植
ATH10.c
#include "gd32f30x.h"
#include "systick.h"
#include <stdio.h>
#include "ath10.h"/*初始化ATH10 GPIO引脚
*/
void ath10_iic_gpio_init(void)
{// 使能GPIOB时钟rcu_periph_clock_enable(ATH10_ENABLE_GPIO);// 配置ATH10_SDA_PIN为输出gpio_init(ATH10_SDA_GPIO, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, ATH10_SDA_PIN); // 配置ATH10_SCL_PIN为输出gpio_init(ATH10_SCL_GPIO, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, ATH10_SCL_PIN); ATH10_SDA_H;ATH10_SCL_H;
}/*SDA模式切换mode: 1:输出 0:输入
*/
void ath10_iic_sda_mode(uint8_t mode)
{// 使能GPIOB时钟rcu_periph_clock_enable(ATH10_ENABLE_GPIO);if (mode){// 配置ATH10_SDA_PIN为输出gpio_init(ATH10_SDA_GPIO, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,ATH10_SDA_PIN); }else{// 配置ATH10_SDA_PIN为上拉输入gpio_init(ATH10_SDA_GPIO, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ,ATH10_SDA_PIN); }
}/*读取SDA 输入模式下的引脚状态
*/
uint8_t read_sda_in_mode_data(void)
{return gpio_input_bit_get(ATH10_SDA_GPIO, ATH10_SDA_PIN);
}/*主机发送开始信号
*/
void ath10_start(void)
{ATH10_SDA_OUT; // SDA为输出模式ATH10_SCL_H; // 拉高SCLATH10_SDA_H; // 拉高SDAdelay_us(5);ATH10_SDA_L; // 先拉低SDA,持续5usdelay_us(5);ATH10_SCL_L; // 再拉低SCL
}/*主机发送停止信号
*/
void ath10_stop(void)
{ATH10_SDA_OUT; // SDA为输出模式ATH10_SCL_L; // 拉低SCLATH10_SDA_L; // 拉低SDAdelay_us(5);ATH10_SCL_H; // 先拉高SCL,持续5usdelay_us(5);ATH10_SDA_H; // 再拉高SDA
}/*等待从机应答返回: 0:收到应答 1:未收到应答
*/
uint8_t ath10_wait_ack(void)
{uint8_t ErrTime = 0;ATH10_SDA_IN;ATH10_SDA_H;delay_us(1);ATH10_SCL_H;delay_us(1);// 循环读取SDA引脚状态while (read_sda_in_mode_data()){ErrTime++;if (ErrTime > 250){ath10_stop();return 1;}}ATH10_SCL_L;delay_us(1);return 0;
}/*主机是否发送应答 ack: 1:发送 0:不发送
*/
void ath10_send_ack(uint8_t ack)
{ATH10_SCL_L;ATH10_SDA_OUT;if (ack) ATH10_SDA_L;else ATH10_SDA_H;delay_us(2);ATH10_SCL_H;delay_us(2);ATH10_SCL_L;
}/*主机发送一个字节
*/
void ath10_send_Byte(uint8_t data)
{uint8_t i;ATH10_SDA_OUT;ATH10_SCL_L;delay_us(2);for (i=0; i<8; i++){if ((data<<i) & 0x80) ATH10_SDA_H;else ATH10_SDA_L;ATH10_SCL_H;delay_us(2);ATH10_SCL_L;delay_us(2);}
}/*主机读取一个字节
*/
uint8_t ath10_read_Byte(void)
{uint8_t i, receive = 0;ATH10_SCL_L;ATH10_SDA_IN;delay_us(2);for (i=0; i<8; i++){ATH10_SCL_H;delay_us(1);receive<<=1;if (read_sda_in_mode_data()) receive ++;ATH10_SCL_L;delay_us(1);}return receive;
}/*检测ATH10是否响应 返回: 1:未响应 0:响应
*/
uint8_t ath10_check(void)
{uint8_t ack = 0;ath10_start();ath10_send_Byte(ATH10_ADDRESS);ack = ath10_wait_ack();ath10_stop();return ack;
}/*初始化ATH10
*/
uint8_t ath10_init(void)
{ath10_iic_gpio_init();ath10_start();ath10_send_Byte(ATH10_ADDRESS); ath10_wait_ack();ath10_send_Byte(0xe1); ath10_wait_ack();ath10_send_Byte(0x08); ath10_wait_ack();ath10_send_Byte(0x00); ath10_wait_ack();ath10_stop();delay_1ms(40); // 延时40ms,使传感器稳定return 1;
}/*ATH10 软件复位
*/
void ath10_reset(void)
{ath10_start();ath10_send_Byte(ATH10_WRITE);ath10_wait_ack();ath10_send_Byte(0xba);ath10_wait_ack();ath10_stop();
}/*读取ATH10 温湿度数据 返回: 0:获取成功 1:获取失败
*/
uint8_t ath10_read_data(uint16_t *temp, uint16_t *humi)
{// 状态(第1数据)uint8_t state = 0;// 数据2-6uint8_t databuf[5];// for循环次数uint8_t i;// 温度、湿度缓冲区uint32_t temp_buf = 0, humi_buf = 0;/*----------------- 触发测量 -----------------------*/ath10_start();ath10_send_Byte(ATH10_WRITE); ath10_wait_ack();ath10_send_Byte(0xac); ath10_wait_ack();ath10_send_Byte(0x33); ath10_wait_ack();ath10_send_Byte(0x00); ath10_wait_ack();ath10_stop();delay_1ms(80); // 手册中要求主机发出测量指令(0xAC)后,需延时75ms以上/*---------------------------------------------------*/ath10_start();ath10_send_Byte(ATH10_READ); ath10_wait_ack();state = ath10_read_Byte();ath10_send_ack(1);// 首次读取为状态数据,判断Bit7位,0表示可正常读取,1表示传感器正忙if ((state&0x80) == 0){for (i=0; i<5; i++){databuf[i] = ath10_read_Byte();if (i == 4) ath10_send_ack(0);else ath10_send_ack(1);}ath10_stop();// 第2、3数据,第4数据高4位为湿度数据humi_buf = (databuf[0]<<12) + (databuf[1]<<4) + (databuf[2]>>4);// 第4数据低4位,第5、6数据为湿度数据temp_buf = ((databuf[2]&0x0f)<<16) + (databuf[3]<<8) + (databuf[4]);*humi = humi_buf*1000/1024/1024;*temp = temp_buf*2000/1024/1024-500; printf("获取温湿度成功!\r\n");return 0;}printf("获取温湿度失败!\r\n");ath10_stop();return 1;
}
ATH10.h
#ifndef ATH10_H
#define ATH10_H/*-------------------------------- GPIO ------------------------------------------*/#define ATH10_ENABLE_GPIO RCU_GPIOB#define ATH10_SDA_GPIO GPIOB
#define ATH10_SCL_GPIO GPIOB#define ATH10_SDA_PIN GPIO_PIN_1
#define ATH10_SCL_PIN GPIO_PIN_2#define ATH10_SDA_H gpio_bit_write(ATH10_SDA_GPIO, ATH10_SDA_PIN, SET)
#define ATH10_SDA_L gpio_bit_write(ATH10_SDA_GPIO, ATH10_SDA_PIN, RESET)#define ATH10_SCL_H gpio_bit_write(ATH10_SCL_GPIO, ATH10_SCL_PIN, SET)
#define ATH10_SCL_L gpio_bit_write(ATH10_SCL_GPIO, ATH10_SCL_PIN, RESET)#define OUT_MODE 1
#define IN_MODE 0#define ATH10_SDA_OUT ath10_iic_sda_mode(OUT_MODE)
#define ATH10_SDA_IN ath10_iic_sda_mode(IN_MODE)/*-------------------------------- ADDRESS ------------------------------------------*/#define ATH10_ADDRESS 0x70
#define ATH10_WRITE 0x70
#define ATH10_READ 0x71/*-------------------------------- Func Dec ------------------------------------------*/void ath10_iic_gpio_init(void);
void ath10_iic_sda_mode(uint8_t mode);
uint8_t read_sda_in_mode_data(void);void ath10_start(void);
void ath10_stop(void);
uint8_t ath10_wait_ack(void);
void ath10_send_ack(uint8_t ack);
void ath10_send_Byte(uint8_t data);
uint8_t ath10_read_Byte(void);
uint8_t ath10_check(void);uint8_t ath10_init(void);
void ath10_reset(void);
uint8_t ath10_read_data(uint16_t *temp, uint16_t *humi);
/*-------------------------------- End ------------------------------------------*/#endif
main.c
#include "gd32f30x.h"
#include "systick.h"
#include <stdio.h>
#include <string.h>
#include "ath10.h"uint16_t temp = 0;
uint16_t humi = 0;char temp_string[32];
char humi_string[32];int main(void)
{uint8_t flag = 0;// 设置主频120MHZ -- 分频器选择rcu_ahb_clock_config(RCU_AHB_CKSYS_DIV1);// 配置系统时钟 -- 1ussystick_config();// 使能AF时钟 -- 开启GPIO复用功能rcu_periph_clock_enable(RCU_AF); // 延时1sdelay_1ms(1000);// 将SWJ和NRST引脚重新映射到其他可用的引脚上,以确保它们不会与其他外设引脚功能发生冲突。// 即可当作普通IO引脚使用gpio_pin_remap_config(GPIO_SWJ_NONJTRST_REMAP, ENABLE);flag = ath10_init();if (flag == 0){printf("Init Error!\r\n");return 0;}while (1){if ( ath10_read_data(&temp, &humi) == 0){sprintf(temp_string,"Temp:%d%d.%d C", temp/100, (temp/10)%10, temp%10);sprintf(humi_string,"Humi:%d%d.%d RH", humi/100, (humi/10)%10, humi%10);printf("%s -- %s\r\n", temp_string, humi_string);}delay_1ms(100);}
}
串口打印部分的代码根据自身的情况进行添加,这里作者就不加上了。
效果图
总结
写的比较简洁,如有遗漏之处还请各位大佬指正,我是陈师傅,我们下章再见!
ATH10=3p8b
更多推荐
GD32F303移植ATH10温湿度模块
发布评论