wordpress编辑器自动标签,百度seo排名教程,腾讯云wordpress镜像ip访问不了,网站建设方案范本温湿度数据采集应用#xff1a; 由上图可知#xff1a;
控制温湿度采集模块的引脚是PF14#xff08;串行时钟线#xff09;和PF15#xff08;串行数据线#xff09;#xff1a;控制温湿度采集模块的总线是AHB4#xff0c;通过GPIOF串口和RCC使能完成初始化操作。
控制…温湿度数据采集应用 由上图可知
控制温湿度采集模块的引脚是PF14串行时钟线和PF15串行数据线控制温湿度采集模块的总线是AHB4通过GPIOF串口和RCC使能完成初始化操作。
控制风扇的引脚是PE6GPIOE控制马达的引脚是PF6GPIOF两个模块的总线都是APB2同意需要进行串口和时钟初始化操作。 I2C1需要进行初始化 1、发起起始信号 2、发送从机地址写标志 3、等待从机应答 4、发送寄存器地址 0XE6 5、等待从机应答 6、传输要写入的数据0X3A 7、等待从机应答 8、发送终止信号
温湿度模块与内核进行数据的收发 1、发起起始信号 2、发送从机地址写标志 3、等待从机应答 4、发送寄存器地址 5、等待从机应答 6、重复起始信号 7、发送从机地址读标志 8、等待从机应答 9、等待从机测量数据 10、接收数据高八位发送应答信号 11、接收数据低八位 发送非应答信号 12、将高八位和低八位合成一个数据 高八位8|低8位
通过采集到的温湿度数据对风扇和马达进行不同的处理操作
代码如下
头文件1icc.h
#ifndef __IIC_H__
#define __IIC_H__
#include stm32mp1xx_gpio.h
#include stm32mp1xx_rcc.h/* 通过程序模拟实现I2C总线的时序和协议* GPIOF --- AHB4* I2C1_SCL --- PF14* I2C1_SDA --- PF15** */#define SET_SDA_OUT do{GPIOF-MODER (~(0x3 30)); \GPIOF-MODER | (0x1 30);}while(0)#define SET_SDA_IN do{GPIOF-MODER (~(0x3 30));}while(0)#define I2C_SCL_H do{GPIOF-BSRR | (0x1 14);}while(0)
#define I2C_SCL_L do{GPIOF-BRR | (0x1 14);}while(0)#define I2C_SDA_H do{GPIOF-BSRR | (0x1 15);}while(0)
#define I2C_SDA_L do{GPIOF-BRR | (0x1 15);}while(0)#define I2C_SDA_READ (GPIOF-IDR (0x1 15))void delay_us(void);//微秒延时
void delay(int ms);
void i2c_init(void);//初始化
void i2c_start(void);//起始信号
void i2c_stop(void);//终止信号
void i2c_write_byte(unsigned char dat);//写一个字节数据
unsigned char i2c_read_byte(unsigned char ack);//读取一个字节数据
unsigned char i2c_wait_ack(void); //等待应答信号
void i2c_ack(void);//发送应答信号
void i2c_nack(void);//发送非应答信号#endif
头文件2si7006.h
#ifndef __SI7006_H__
#define __SI7006_H__
#includeiic.h
void delay(int ms);
void si7006_init();
short si7006_read_tem();
unsigned short si7006_read_hum();
#endif
主函数
#include si7006.hint main(){//si7006初始化si7006_init();//i2c初始化i2c_init();unsigned short hum;short tem;while(1){//读取温度和湿度humsi7006_read_hum();temsi7006_read_tem();//计算温湿度数据humhum*125/65536-6;temtem*175.72/65536-46.85;//湿度大于65开启马达if(hum65){GPIOF-ODR | (0x16);}else if(hum60) //湿度小于60关闭马达{GPIOF-ODR (~(0x16)); }//温度大于29开启风扇if(tem30){GPIOE-ODR | (0x19);}else if(tem28) //湿度小于27关闭风扇{GPIOE-ODR (~(0x19)); }printf(hum:%d\n,hum);printf(tem:%d\n,tem);delay(1000);}return 0;}
si7006.c
#includesi7006.h
//封装延时函数
void delay(int ms)
{int i,j;for(i0;ims;i){for(j0;j2000;j){}}
}
void si7006_init()
{//发起起始信号i2c_start();//发送从机地址写标志i2c_write_byte(0x80);//等待从机应答i2c_wait_ack();//发送寄存器地址 0XE6i2c_write_byte(0XE6);//等待从机应答i2c_wait_ack();//传输要写入的数据0X3A、i2c_write_byte(0X3A);//等待从机应答i2c_wait_ack();//发送终止信号i2c_stop();
}short si7006_read_tem()
{short tem;char tem_h,tem_l;//发起起始信号i2c_start();//发送从机地址写标志i2c_write_byte(0x80);//等待从机应答i2c_wait_ack();//发送寄存器地址 0XE3i2c_write_byte(0xE3);//等待从机应答i2c_wait_ack();//重复起始信号i2c_start();//发送从机地址读标志i2c_write_byte(0x81);//等待从机应答i2c_wait_ack();//等待从机测量数据delay(100);//接收数据高八位//发送应答信号tem_hi2c_read_byte(0);//接收数据低八位//发送非应答信号tem_li2c_read_byte(1);//将高八位和低八位合成一个数据 高八位8|低8位temtem_h8|tem_l;return tem;
}unsigned short si7006_read_hum()
{unsigned short hum;unsigned char hum_h,hum_l;//发起起始信号i2c_start();//发送从机地址写标志i2c_write_byte(0x80);//等待从机应答i2c_wait_ack();//发送寄存器地址 0XE5i2c_write_byte(0xe5);//等待从机应答i2c_wait_ack();//重复起始信号i2c_start();//发送从机地址读标志i2c_write_byte(0x81);//等待从机应答i2c_wait_ack();//等待从机测量数据delay(100);//接收数据高八位//发送应答信号hum_hi2c_read_byte(0);//接收数据低八位//发送非应答信号hum_li2c_read_byte(1);//将高八位和低八位合成一个数据 高八位8|低8位humhum_h8|hum_l;return hum;
} icc.c
#include iic.hextern void printf(const char* fmt, ...);
/** 函数名 delay_us* 函数功能延时函数* 函数参数无* 函数返回值无* */
void delay_us(void) //微秒级延时
{unsigned int i 2000;while(i--);
}
/** 函数名 i2c_init* 函数功能 i2C总线引脚的初始化 通用输出推挽输出输出速度* 函数参数无* 函数返回值无* */
void i2c_init(void)
{// 使能GPIOF端口的时钟RCC-MP_AHB4ENSETR | (0x1 5); //使能风扇的时钟RCC-MP_APB2ENSETR | 0x1;//使能马达的时钟RCC-MP_APB2ENSETR | (0x13);// 设置PF14PF15引脚为通用的输出功能GPIOF-MODER (~(0xF 28));GPIOF-MODER | (0x5 28);//设置PE9为输出GPIOE-MODER (~(0x318));GPIOE-MODER | (0x118);//设置PF6为输出GPIOF-MODER (~(0x312));GPIOF-MODER | (0x112);// 设置PF14, PF15引脚为推挽输出GPIOF-OTYPER (~(0x3 14));//设置PE9为推挽输出GPIOE-OTYPER (~(0x19));//设置PF6为推挽输出GPIOF-OTYPER (~(0x16));// 设置PF14, PF15引脚为高速输出GPIOF-OSPEEDR | (0xF 28);//设置PE9为低速输出GPIOE-OSPEEDR (~(0x318));//设置PF6为低速输出GPIOF-OSPEEDR (~(0x312));// 设置PF14, PF15引脚的禁止上拉和下拉GPIOF-PUPDR (~(0xF 28));//设置PE9没有上拉下拉电阻GPIOE-PUPDR (~(0x318));//设置PF6没有上拉下拉电阻GPIOF-PUPDR (~(0x312));// 空闲状态SDA和SCL拉高 I2C_SCL_H;I2C_SDA_H;
}/** 函数名i2c_start* 函数功能模拟i2c开始信号的时序* 函数参数无* 函数返回值无* */
void i2c_start(void)
{/** 开始信号时钟在高电平期间数据线从高到低的变化* --------* SCL \* --------* ----* SDA \* --------* */ //确保SDA是输出状态 PF15输出SET_SDA_OUT;// 空闲状态SDA和SCL拉高 I2C_SCL_H;I2C_SDA_H;delay_us();//延时等待一段时间I2C_SDA_L;//数据线拉低delay_us();//延时等待一段时间I2C_SCL_L;//时钟线拉低让总线处于占用状态
}/** 函数名i2c_stop* 函数功能模拟i2c停止信号的时序* 函数参数无* 函数返回值无* */void i2c_stop(void)
{/** 停止信号 时钟在高电平期间数据线从低到高的变化 * ----------* SCL /* --------* --- -------* SDA X /* --- -------* *///确保SDA是输出状态 PF15输出SET_SDA_OUT;//时钟线拉低I2C_SCL_L;//为了修改数据线的电平delay_us();//延时等待一段时间I2C_SDA_L;//数据线拉低delay_us();//延时等待一段时间//时钟线拉高I2C_SCL_H;delay_us();//延时等待一段时间I2C_SDA_H;//数据线拉高}/** 函数名 i2c_write_byte* 函数功能主机向i2c总线上的从设备写8bits数据* 函数参数dat : 等待发送的字节数据* 函数返回值 无* */void i2c_write_byte(unsigned char dat)
{ /** 数据信号时钟在低电平期间发送器向数据线上写入数据* 时钟在高电平期间接收器从数据线上读取数据 * ---- --------* SCL \ / \* -------- --------* -------- ------------------ ---* SDA X X* -------- ------------------ ---** 先发送高位在发送低位 * *///确保SDA是输出状态 PF15输出SET_SDA_OUT;unsigned int i;for(i0;i8;i){//时钟线拉低I2C_SCL_L;delay_us();//延时//0X3A-0011 1010 0X80-10000000if(dat0X80)//最高位为1{//发送1I2C_SDA_H;}else //最高位为0{I2C_SDA_L;//发送0}delay_us();//延时//时钟线拉高接收器接收I2C_SCL_H;delay_us();//延时,用于等待接收器接收数据delay_us();//延时//将数据左移一位让原来第6位变为第7位dat dat1;}}/** 函数名i2c_read_byte* 函数功能 主机从i2c总线上的从设备读8bits数据, * 主机发送一个应答或者非应答信号* 函数参数 0 应答信号 1 非应答信号* 函数返回值读到的有效数据** */
unsigned char i2c_read_byte(unsigned char ack)
{/** 数据信号时钟在低电平期间发送器向数据线上写入数据* 时钟在高电平期间接收器从数据线上读取数据 * ---- --------* SCL \ / \* -------- --------* -------- ------------------ ---* SDA X X* -------- ------------------ ---** 先接收高位 在接收低位 * */unsigned int i;unsigned char dat;//保存接受的数据//将数据线设置为输入SET_SDA_IN;for(i0;i8;i){//先把时钟线拉低等一段时间保证发送器发送完毕数据I2C_SCL_L;delay_us();delay_us();//保证发送器发送完数据//时钟线拉高读取数据I2C_SCL_H;delay_us();datdat1;//数值左移 一定要先左移在赋值不然数据会溢出if(I2C_SDA_READ)//pf15管脚得到了一个高电平输入{dat |1; //0000 0110}else{dat (~0X1);}delay_us();}if(ack){i2c_nack();//发送非应答信号不再接收下一次数据}else{i2c_ack();//发送应答信号 }return dat;//将读取到的数据返回
}
/** 函数名 i2c_wait_ack* 函数功能 主机作为发送器时等待接收器返回的应答信号* 函数参数无* 函数返回值* 0接收到的应答信号* 1接收到的非应答信号* */
unsigned char i2c_wait_ack(void)
{/** 主机发送一个字节之后从机给主机返回一个应答信号** -----------* SCL / M:读 \* ------------- --------* --- ---- --------------------* SDA X X* --- --------------------* 主 释 从机 主机* 机 放 向数据 读数据线* 总 线写 上的数据* 线 数据* */ //时钟线拉低接收器可以发送信号I2C_SCL_L;I2C_SDA_H;//先把数据线拉高当接收器回应应答信号时数据线会拉低delay_us();SET_SDA_IN;//设置数据线为输入delay_us();//等待从机响应delay_us();I2C_SCL_H;//用于读取数据线数据if(I2C_SDA_READ)//PF15得到一个高电平输入收到非应答信号return 1;I2C_SCL_L;//时钟线拉低让数据线处于占用状态return 0;}
/** 函数名 iic_ack* 函数功能 主机作为接收器时给发送器发送应答信号* 函数参数无* 函数返回值无* */
void i2c_ack(void)
{/* --------* SCL / \* ------- ------* ---* SDA X * --- -------------* *///保证数据线是输出SET_SDA_OUT;I2C_SCL_L;//拉低时钟线delay_us();I2C_SDA_L;//数据线拉低表示应答信号delay_us();I2C_SCL_H;//时钟线拉高等待发送器读取应答信号delay_us();//让从机读取我们当前的回应delay_us();I2C_SCL_L;//数据线处于占用状态发送器发送下一次数据}
/** 函数名 iic_nack* 函数功能 主机作为接收器时给发送器发送非应答信号* 函数参数无* 函数返回值无* */
void i2c_nack(void)
{/* --------* SCL / \* ------- ------* --- ---------------* SDA X * --- * */ //保证数据线是输出SET_SDA_OUT;I2C_SCL_L;//拉低时钟线delay_us();I2C_SDA_H;//数据线拉高表示非应答信号delay_us();I2C_SCL_H;//时钟线拉高等待发送器读取应答信号delay_us();delay_us();I2C_SCL_L;//数据线处于占用状态发送器发送下一次数据
}