小熊派GD32开发(7)—使用软件模拟I2C读取SHT30温湿度传感器

⼩熊派GD32开发(7)—使⽤软件模拟I2C读取SHT30温湿度传感器
⼩熊派GD32开发(7)— 使⽤软件模拟I2C读取SHT30温湿度传感器
⼀、编写软件模拟I2C驱动程序
在【Devices】下新建soft_i2c.c和soft_i2c.h⽂件,⾸先,查看硬件原理图,可以看到,IIC_SCL使⽤PB6引脚,IIC_SDA使⽤PB7引脚,将这两个引脚初始化即可:
/* 软件模拟IIC引脚初始化
* IIC_SCL --> PB6
* IIC_SDA --> PB7 */
void IIC_Init(void)
{
rcu_periph_clock_enable(RCU_GPIOB);/* 使能GPIOB时钟 */
/* 配置IIC_SCL引脚为推挽输出 */
gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
/* 配置IIC_SDA引脚为推挽输出 */
gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
gpio_bit_set(GPIOB, GPIO_PIN_6);
gpio_bit_set(GPIOB, GPIO_PIN_7);
}
因为模拟IIC通信⾥需要⽤到us延时,所以,编写⼀个us延时函数
/* 描述:us级延时函数
* 参数nus:需要延时的us数
* 返回值:⽆*/
void delay_us(uint32_t nus)
{
uint32_t ticks;
uint32_t told, tnow, tcnt =0;
uint32_t reload = SysTick->LOAD;/* 滴答定时器的重装载值 */
微电影 青春期ticks = nus *120;/* 需要的节拍数 */
told = SysTick->VAL;/* 刚进⼊时的计数器值 */
while(1)
{
tnow = SysTick->VAL;
if(tnow != told)
{
if(tnow < told)tcnt += told - tnow;
else tcnt += reload - tnow + told;
if(tcnt >= ticks)break;/* 时间超过/等于要延迟的时间,则退出. */
told = tnow;
}
}
}
模拟IIC通信的函数如下
/* 描述:启动I2C总线,即发送I2C起始条件.
* 参数:⽆
* 返回值:⽆      */
void IIC_Start(void)
{
SDA_OUT();
IIC_SDA(1);
IIC_SCL(1);
delay_us(4);
IIC_SDA(0);
delay_us(4);
IIC_SCL(0);
}
/* 描述:结束I2C总线,即发送I2C结束条件.
* 参数:⽆
* 返回值:⽆      */
void IIC_Stop(void)
{
SDA_OUT();
IIC_SCL(0);
IIC_SDA(0);
delay_us(4);
IIC_SCL(1);
delay_us(4);
IIC_SDA(1);
delay_us(4);
}
/* 描述:发送应答 ACK
* 参数:⽆
* 返回值:⽆  */
void IIC_ACK(void)
{
SDA_OUT();
IIC_SCL(0);
delay_us(2);
IIC_SDA(0);
delay_us(2);
IIC_SCL(1);
delay_us(2);
计算机的分类IIC_SCL(0);
delay_us(1);
}
/* 描述:发送⾮应答 NACK
* 参数:⽆
* 返回值:⽆  */
void IIC_NACK(void)
{
SDA_OUT();
IIC_SCL(0);
delay_us(2);
IIC_SDA(1);
对地观测中心delay_us(2);
IIC_SCL(1);
delay_us(2);
IIC_SCL(0);
delay_us(1);
}
/* 描述:等待ACK
* 参数:⽆
* 返回值:等待应答返回0,没有等待到应答返回1 */
uint8_t IIC_wait_ACK(void)
{
uint8_t t =200;
SDA_OUT();
IIC_SDA(1);
delay_us(1);
IIC_SCL(0);
软件仿真delay_us(1);
SDA_IN();/* 数据发送完后释放数据线,准备接收应答位 */ delay_us(1);
while(READ_SDA)/* 等待IIC应答*/
{
t--;
delay_us(1);
delay_us(1);
if(t==0)
{
IIC_SCL(0);
return1;
}
delay_us(1);
}
delay_us(1);
IIC_SCL(1);
delay_us(1);
IIC_SCL(0);
delay_us(1);
return0;
}
/* 描述:⼀个字节数据发送函数
* 参数:⽆
* 返回值:⽆  */
void IIC_SendByte(uint8_t byte)
郁可欣{
uint8_t BitCnt;
SDA_OUT();
IIC_SCL(0);
for(BitCnt=0;BitCnt<8;BitCnt++)/* 要传送的数据长度为8位 */ {
if(byte&0x80)IIC_SDA(1);/* 判断发送位 */
else IIC_SDA(0);
byte<<=1;
delay_us(2);
IIC_SCL(1);
delay_us(2);
IIC_SCL(0);
delay_us(2);
}
小分子团水}
/* 描述:⼀个字节数据接收函数
* 参数:⽆
* 返回值:接收到的字节数据  */
uint8_t IIC_RcvByte(void)
{
uint8_t retc;
uint8_t BitCnt;
retc=0;
SDA_IN();/* 设置数据线为输⼊⽅式 */
delay_us(1);
for(BitCnt=0;BitCnt<8;BitCnt++)
{
IIC_SCL(0);/* 设置时钟线为低,准备接收数据位 */
delay_us(2);
IIC_SCL(1);/* 设置时钟线为⾼使数据线上数据有效  */
retc=retc<<1;
if(READ_SDA) retc |=1;/* 读数据位,接收的数据位放⼊retc中 */ delay_us(1);
}
IIC_SCL(0);
return(retc);
}
soft_i2c.h⽂件如下,
/* 设置IIC_SDA的⽅向,输⼊还是输出 */
#define SDA_IN()  {GPIO_CTL0(GPIOB)&=~GPIO_MODE_MASK(7);GPIO_CTL0(GPIOB)|=GPIO_MODE_SET(7,0x8);}//PB9输⼊模式#define SDA_OUT() {GPIO_CTL0(GPIOB)&=~GPIO_MODE_MASK(7);GPIO_CTL0(GPIOB)|=GPIO_MODE_SET(7,0x3);}//PB9输出模式/* 设置SCL和SDA输出电平,以及读取SDA电平 */
#define IIC_SCL(n) (n?gpio_bit_set(GPIOB, GPIO_PIN_6):gpio_bit_reset(GPIOB, GPIO_PIN_6))
#define IIC_SDA(n) (n?gpio_bit_set(GPIOB, GPIO_PIN_7):gpio_bit_reset(GPIOB, GPIO_PIN_7))
#define READ_SDA gpio_input_bit_get(GPIOB,GPIO_PIN_7)
void IIC_Init(void);/* 软件模拟IIC引脚初始化 */
void IIC_Start(void);/* 启动I2C总线,即发送I2C起始条件 */
void IIC_Stop(void);/* 结束I2C总线,即发送I2C结束条件 */
void IIC_ACK(void);/* 发送应答 ACK */
void IIC_NACK(void);/* 发送⾮应答 NACK */
uint8_t IIC_wait_ACK(void);/* 等待ACK */
void IIC_SendByte(uint8_t byte);/* ⼀个字节数据发送函数 */
uint8_t IIC_RcvByte(void);/* ⼀个字节数据接收函数 */
#endif
⼆、编写SHT30应⽤程序
在【Devices】下新建sht3x.c和sht3x.h⽂件,头⽂件如下
#include"systick.h"
uint8_t SHT3x_Init(void);/* 描述:SHT3x初始化函数  */
uint8_t SHT3x_ReadSerialNumber(uint32_t* serialNumber);
uint8_t SHT3x_Get_Humiture_single(double*Tem_val,double*Hum_val);/* 单次获取 */ uint8_t SHT3x_Get_Humiture_periodic(double*Tem_val,double*Hum_val);/* 周期获取 */ /* 枚举SHT3x命令列表 */
typedef enum
{
/* 软件复位命令 */
SOFT_RESET_CMD =0x30A2,
/* 单次测量模式
命名格式:Repeatability_CS_CMD
CS: Clock stretching */
HIGH_ENABLED_CMD    =0x2C06,
MEDIUM_ENABLED_CMD  =0x2C0D,
LOW_ENABLED_CMD    =0x2C10,
HIGH_DISABLED_CMD  =0x2400,
MEDIUM_DISABLED_CMD =0x240B,
LOW_DISABLED_CMD    =0x2416,
/* 周期测量模式
命名格式:Repeatability_MPS_CMD
MPS:measurement per second */
HIGH_0_5_CMD  =0x2032,
MEDIUM_0_5_CMD =0x2024,
LOW_0_5_CMD    =0x202F,
HIGH_1_CMD    =0x2130,
MEDIUM_1_CMD  =0x2126,
LOW_1_CMD      =0x212D,
HIGH_2_CMD    =0x2236,
MEDIUM_2_CMD  =0x2220,
LOW_2_CMD      =0x222B,
HIGH_4_CMD    =0x2334,
MEDIUM_4_CMD  =0x2322,
LOW_4_CMD      =0x2329,
HIGH_10_CMD    =0x2737,
MEDIUM_10_CMD  =0x2721,
LOW_10_CMD    =0x272A,
/* 周期测量模式读取数据命令 */
READOUT_FOR_PERIODIC_MODE =0xE000,
/* 读取传感器编号命令 */
READ_SERIAL_NUMBER =0x3780,
} SHT3X_CMD;
#endif
在sht3x.c⽂件中,先将读写标志以及SHT30的地址设置好:
#define write 0
#define read  1
uint8_t addr =0x44;//设置传感器地址
然后就是发送命令和接收数据函数

本文发布于:2024-09-22 23:26:11,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/398935.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:发送   模拟   数据
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议