AM2322温湿度传感器STM8S208驱动(更新)

更新时间:2024-04-15 13:25:02 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

AM2322温湿度传感器STM8S208驱动

AM2322温湿度传感器STM8S208驱动该程序测试能用,AM2322产品都是共用一个器件地址0xB8,所以只能挂 一个AM2322器件,如果挂两个就有两个相同的器件地址 ,这样IIC没有办法寻址,但这并不代表不能与其它器件共存,比喻AT24C02,它的器件地址是0xA0,它们可以在同一条IIC部上面工作的。

AM2322温度采集成功后,得到高8位和低8位的数据。将其组合成一个16位的值,再换算成十进制的温湿值,该值是实际值的10倍,除以10后就是正确温湿度值了。

例如:采集到的湿度值为:高8位是0x03 低8位是0x39,组合成16位的值就是0x0339,换算成十进制是825,再除以10就是82.5,表示相对湿度82.5%,温度值也是这样计算。 该程序采用模拟IIC通讯,总共有四个文件:

IIC.c、IIC.h、AM2322.c、AM2322.h, 在工程新建这四个文件依次添加以下代码: 在IIC.c文件中添加以下代码(通用的IIC底层驱动): void I2C_Configuration()//初始化IIC端口 {

GPIO_Init(I2C_PORT, I2C_SCL_PIN, GPIO_MODE_OUT_PP_HIGH_SLOW); GPIO_Init(I2C_PORT, I2C_SDA_PIN, GPIO_MODE_OUT_PP_HIGH_SLOW); }

//产生IIC起始信号 void IIC_Start(void) { }

I2C_SDA_OUT; //sda线输出 I2C_SDA_H; I2C_SCL_H; delay_us(14);

I2C_SDA_L;//开始:当SCL为高时,数据从高到低变化 delay_us(14);

I2C_SCL_L;//钳住I2C总线,准备发送或接收数据

//产生IIC停止信号 void IIC_Stop(void) { I2C_SDA_OUT;//sda线输出 I2C_SCL_L;

I2C_SDA_L;//停止:当SCL为高时,数据从低到高变化 delay_us(14); I2C_SCL_H; delay_us(14); I2C_SDA_H;//发送I2C总线结束信号 }

//等待应答信号到来

//返回值:1,接收应答失败

// 0,接收应答成功 u8 IIC_Wait_Ack(void) { u8 ucErrTime=0; I2C_SCL_L; I2C_SDA_H; I2C_SDA_IN; //SDA设置为输入 delay_us(14); I2C_SCL_H; delay_us(14);

while(GPIO_ReadInputPin(I2C_PORT, I2C_SDA_PIN))//等到SDA变低 { ucErrTime++; if(ucErrTime>250) { IIC_Stop(); return 1; } delay_us(1); }

I2C_SCL_L;//时钟输出0 delay_us(10); return 0; }

//产生ACK应答 void IIC_Ack(void)

{ I2C_SDA_OUT; I2C_SCL_L; I2C_SDA_L; delay_us(50); I2C_SCL_H; delay_us(50); I2C_SCL_L;

//I2C_SDA_H; }

//产生非ACK应答 void IIC_NAck(void) { I2C_SDA_OUT; I2C_SCL_L; I2C_SDA_H; delay_us(50); I2C_SCL_H; delay_us(50); I2C_SCL_L;

// I2C_SDA_H; } //IIC发送一个字节 //返回从机有无应答 //1,有应答 //0,无应答 void IIC_Send_Byte(u8 txd) { u8 t; I2C_SDA_OUT;

I2C_SCL_L;//拉低时钟开始数据传输 for(t=0;t<8;t++) { I2C_SCL_L; if((txd&0x80))

{I2C_SDA_H;} else

{I2C_SDA_L;} txd<<=1; delay_us(15); //延时 I2C_SCL_H; delay_us(15); } I2C_SCL_L; }

//读1个字节,ack=1时,发送ACK,ack=0,发送nACK u8 IIC_Read_Byte(unsigned char ack) { unsigned char i,receive=0; I2C_SDA_IN;//SDA设置为输入 for(i=0;i<8;i++ ) {

I2C_SCL_L; delay_us(50); I2C_SCL_H; delay_us(50); receive<<=1;

if(GPIO_ReadInputPin(I2C_PORT, I2C_SDA_PIN))receive++; }

I2C_SCL_L; if (!ack)

IIC_NAck();//发送nACK else

IIC_Ack(); //发送ACK

return receive; }

在IIC.h中添加以下代码 :

#ifndef H_I2C_H //宏定义,定义文件名称 #define H_I2C_H

/*---------------------------头文件引用--------------------------------------*/ #include \引用STM8头文件

#define I2C_SCL_PIN GPIO_PIN_1 //如果将IIC端口换到它引脚 只修改这里,其它的不用动 #define I2C_SDA_PIN GPIO_PIN_2 //如果将IIC端口换到它引脚 只修改这里,其它的不用动#define I2C_PORT GPIOE //如果将IIC端口换到它引脚 只修改这里,其它的不用动

#define I2C_SCL_L GPIO_WriteLow(I2C_PORT,I2C_SCL_PIN); #define I2C_SCL_H GPIO_WriteHigh(I2C_PORT,I2C_SCL_PIN);

#define I2C_SDA_L GPIO_WriteLow(I2C_PORT,I2C_SDA_PIN); #define I2C_SDA_H GPIO_WriteHigh(I2C_PORT,I2C_SDA_PIN);

#define I2C_SDA_OUT GPIO_Init(I2C_PORT, I2C_SDA_PIN, GPIO_MODE_OUT_OD_HIZ_FAST); #define I2C_SDA_IN GPIO_Init(I2C_PORT, I2C_SDA_PIN, GPIO_MODE_IN_PU_NO_IT); //以下是函数声明: void I2C_Configuration(); void IIC_Start(void); void IIC_Stop(void); u8 IIC_Wait_Ack(void); void IIC_Ack(void); void IIC_NAck(void);

void IIC_Send_Byte(u8 txd);

u8 IIC_Read_Byte(unsigned char ack);

#endif

在AM2322.c中添加以下代码:

u8 WR_Flag;

u8 WriteNByte(unsigned char sla,unsigned char *s)//写数据 {

IIC_Start();//起始条件

IIC_Send_Byte(sla);//发送器件地址 IIC_Wait_Ack();//等待ACK响应 IIC_Send_Byte(s[0]);//发送字节地址 IIC_Wait_Ack();//等待ACK响应 IIC_Send_Byte(s[1]);//发送字节地址

IIC_Wait_Ack();//等待ACK响应 IIC_Send_Byte(s[2]);//发送字节地址 IIC_Wait_Ack();//等待ACK响应 IIC_Stop(); //执行停止条件 return(0); }

u8 ReadNByte(unsigned char Sal, unsigned char *p)//接收或叫读数据 {

IIC_Start();//发送起始条件

IIC_Send_Byte(Sal|0x01);//发送器件地址 IIC_Wait_Ack();//等待ACK响应 delay_us(50);

p[0]=IIC_Read_Byte(1);//功能码 p[1]=IIC_Read_Byte(1);//数据长度 p[2]=IIC_Read_Byte(1);//湿度高8位 p[3]=IIC_Read_Byte(1);//湿度低8位 p[4]=IIC_Read_Byte(1);//温度高8位 p[5]=IIC_Read_Byte(1);//温度低8位 p[6]=IIC_Read_Byte(1);//CRC高8位 p[7]=IIC_Read_Byte(0);//CRC低8位 IIC_Stop();//发送停止条件

return 0;//读取的数据返回给函数 }

void Waken(void) //唤醒器件 {

IIC_Start(); // 启动I2C

IIC_Send_Byte(0xB8); // 发送器件地址 IIC_Wait_Ack(); // 唤醒指令时 传感器不会回ACK 但是第一定要发检测ACK的时钟 否则会出错

delay_ms(1); // 至少延时1个ms说明书里,有个最大值 ,实际当中 你只要大于1MS IIC_Stop(); }

在AM2322.h中添加以下代码:

#ifndef H_AM2322_H //宏定义,定义文件名称 #define H_AM2322_H

/*---------------------------头文件引用--------------------------------------*/ #include \引用STM8头文件

u8 WriteNByte(unsigned char sla,unsigned char *s); u8 ReadNByte(unsigned char Sal, unsigned char *p); void Waken(void);

#endif

最后注意要在main.c中引用IIC.h和AM2322.h两个头文件。

以下MAIN.C内容

#include \这个头文件引用了所有的其它头文件 void BSP_Configuration(void);//初始化函数引用 u16 stp;

unsigned char IIC_TX_Buffer[]={0x03,0x00,0x04}; //读温湿度命令(无CRC校验) unsigned char IIC_RX_Buffer[IIC_RX_Length] = {0x00};//读回的温湿度 unsigned char Uart_RX_Buffer[30] = {0x00};//接收数据存储数组 void main() {

BSP_Configuration();//端口初始化 while(1) {

Waken(); //唤醒

WriteNByte(IIC_Add, IIC_TX_Buffer);//发送指命令函数 /*IIC_Add为器件地址0xB8,IIC_TX_Buffer是一个数组, 值为0x03,0x00,0x08:

0x03是功能码(手册第9页)读一个或多个寄存器

0x00是读寄存器的第一个地址,总共0x00-0x07(手册第9页) 0x08是要读寄存器的个数 */

delay_ms(2);//唤醒后等2ms

ReadNByte(IIC_Add,IIC_RX_Buffer);

//IIC_Add是器件地址0xB8,IIC_RX_Buffer是接收数据的数组

/*以下是一个示例:数据成功全部读取后,

数组第一个字节是功能码,第二个字节是数据长度,

第三四个字节是温度,第五六个字节是湿度,第七八个字节是CRC值, 需要读的就个四个寄存器,其它的是传感自动返回的(手册第10页)*/ stp=IIC_RX_Buffer[4]; //温度的高8位 stp=(stp<<8)|IIC_RX_Buffer[5]; //与上温度的低8位

printf(\ //从串口输出,显示整数位 printf(\ //从串口输出,显示整数位

I2C_SCL_H;I2C_SDA_H; //确认释放总线*/

delay_ms(2000); //重复读传感器间隔时间必须 大于2秒 }

}

void BSP_Configuration(void) {

//CLK_ClockSwitchCmd(ENABLE);//使能时钟切换功能 //CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSE, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE);

//CLK_HSECmd(ENABLE);//使能HSE时钟源

CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1); //配置内部时钟为1分频 _UART1_Init();

I2C_Configuration(); }

//断言函数,编程过程中提供错误检查。 #ifdef USE_FULL_ASSERT

void assert_failed(u8 *file, u32 line) {

while(1) { ; } }

#endif

本文来源:https://www.bwwdw.com/article/8kep.html

Top