main.c
#include "delay.h"
#include "led.h"
#include "beep.h"
#include "motor.h"
#include "fan.h"
#include "key.h"
#include "si7006.h"
#include "iic.h"
extern void printf(const char *fmt, ...);
int main()
{
LED1_Init();
LED2_Init();
LED3_Init();
BEEP_Init();
Motor_Init();
Fan_Init();
key1_Init();
key2_Init();
key3_Init();
IIC_Init();
Si7006_Init();
short temp,threshold1=28;
unsigned short hum,threshold2=75;
while (1)
{
temp=read_tem();
hum=read_hum();
temp=175.72*temp/65536-46.85;
hum=125*hum/65536-6;
printf("tem=%d hum=%d\n",temp,hum);
if (temp>threshold1)
{
Fan_Open();
}
if (hum>threshold2)
{
BEEP_Open();
}
delay_ms(1000);
}
return 0;
}
iic.c
#include "iic.h"
void IIC_Init(void)
{
//使能GPIOF时钟
RCC->MP_AHB4ENSETR |= (0X1<<5);
//PF14和PF15设置成输出模式
GPIOF->MODER &= (~(0XF<<28));
GPIOF->MODER |= (0X5<<28);
//PF14和PF15设置成推挽输出
GPIOF->OTYPER &= (~(0X3<<14));
//PF14和PF15设置成超高速输出
GPIOF->OSPEEDR &= (~(0XF<<28));
GPIOF->OSPEEDR |= (0XF<<28);
//PF14和PF15设置成无上拉下电阻
GPIOF->PUPDR &= (~(0XF<<28));
//让IIC处于空闲状态
IIC_SCL_H;
IIC_SDA_H;
}
//IIC的开始信号:在SCL的高电平期间,SDA由高电平变为低电平
void IIC_Start(void)
{
SDA_OUT;
IIC_SCL_H;
IIC_SDA_H;
delay_us();
IIC_SDA_L;
delay_us();
IIC_SCL_L;//钳住IIC总线,使其准备接收和发送数据
}
//IIC的结束信号:在SCL的高电平期间,SDA由低电平变为高电平
void IIC_Stop(void)
{
SDA_OUT;
IIC_SCL_L;//钳住IIC总线,使其准备接收和发送数据
delay_us();
IIC_SDA_L;
delay_us();
IIC_SCL_H;
delay_us();
IIC_SDA_H;
}
//只有SDA处于空闲状态下,从机才能向主机发送应信号
//等待接收从机反馈的应答信号:在第九脉冲期间,将SDA拉高,释放总线,让从机发送应答信号,拉高SCL,读取从机发送应答信号
unsigned char IIC_Wait_ACK(void)
{
unsigned char waittime=0;
IIC_SCL_L;//钳住IIC总线,使其准备接收和发送数据
IIC_SDA_H;
SDA_IN;
delay_us();
IIC_SCL_H;
delay_us();
while (SDA_READ)
{
waittime++;
if (waittime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL_L;//钳住IIC总线,使其准备接收和发送数据
return 0;
}
//IIC的有效应答信号:在SCL第九个脉冲前的低电平期间,将SDA拉低,在第九个脉冲高电平期间,SDA保持低电平
void IIC_ACK(void)
{
IIC_SCL_L;
SDA_OUT;
IIC_SDA_L;
delay_us();
IIC_SCL_H;
delay_us();
IIC_SCL_L;//钳住IIC总线,使其准备接收和发送数据
}
//IIC的无效应答信号:在SCL第九个脉冲前的低电平期间,将SDA拉高,在第九个脉冲高电平期间,SDA保持高电平
void IIC_NACK(void)
{
IIC_SCL_L;
SDA_OUT;
IIC_SDA_H;
delay_us();
IIC_SCL_H;
delay_us();
IIC_SCL_L;//钳住IIC总线,使其准备接收和发送数据
}
//主机向从机写一字节数据:SCL低电平期间才能写入数据
void IIC_Write_Byte(unsigned char txd)
{
unsigned int i;
SDA_OUT;
IIC_SCL_L;//钳住IIC总线,使其准备接收和发送数据
delay_us();
for ( i = 0; i < 8; i++)
{
if ((txd&0X80)>>7)//获取最高位的值
{
IIC_SDA_H;
}
else
{
IIC_SDA_L;
}
txd<<=1;//准备一字节数据中的下一位
IIC_SCL_H;
delay_us();
IIC_SCL_L;//钳住IIC总线,使其准备接收和发送数据
delay_us();
}
}
//主机从从机读取一字节数据:SCL高电平期间才能读取数据
unsigned char IIC_Read_Byte(unsigned char ack)
{
unsigned int i;
unsigned char receive=0;
SDA_IN;
for ( i = 0; i < 8; i++)
{
IIC_SCL_L;//钳住IIC总线,使其准备接收和发送数据
delay_us();
IIC_SCL_H;
delay_us();
receive<<=1;
if (SDA_READ)
{
receive++;
// receive |= 1;
}
// else
// {
// receive |= 0;
// }
delay_us();
}
if (!ack)
{
IIC_ACK();
}
else
{
IIC_NACK();
}
return receive;
}
iic.h
#ifndef __IIC_H__
#define __IIC_H__
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"
#include "delay.h"
#define IIC_SCL_L do{GPIOF->BRR |= (0X1<<14);} while (0)
#define IIC_SCL_H do{GPIOF->BSRR |= (0X1<<14);} while (0)
#define IIC_SDA_L do{GPIOF->BRR |= (0X1<<15);} while (0)
#define IIC_SDA_H do{GPIOF->BSRR |= (0X1<<15);} while (0)
#define SDA_OUT do{GPIOF->MODER &= (~(0X3<<30));\
GPIOF->MODER |= (0X1<<30);} while (0)
#define SDA_IN do{GPIOF->MODER &= (~(0X3<<30));} while (0)
#define SDA_READ GPIOF->IDR & (0X1<<15)
void IIC_Init(void);
void IIC_Start(void);
void IIC_Stop(void);
unsigned char IIC_Wait_ACK(void);
void IIC_ACK(void);
void IIC_NACK(void);
void IIC_Write_Byte(unsigned char txd);
unsigned char IIC_Read_Byte(unsigned char ack);
#endif
si7006.h
#ifndef __SI7006_H__
#define __SI7006_H__
#include "iic.h"
#include "delay.h"
void Si7006_Init(void);//初始化si7006
short read_tem(void);//读取温度
unsigned short read_hum(void);//读取湿度
#endif
si7006.c
#include "si7006.h"
void Si7006_Init(void)//初始化si7006
{
//开始信号
IIC_Start();
//发送从机地址和写操作
IIC_Write_Byte(0X80);//7位从机地址0x40与一位写操作0合在一起是0x80
//等待应答信号
IIC_Wait_ACK();
//发送从机存储数据寄存器地址
IIC_Write_Byte(0XE6);//si7006用户写寄存器地址
//等待应答信号
IIC_Wait_ACK();
//发送数据给从机
IIC_Write_Byte(0X3A);//发送si7006的配置信息
//等待应答信号
IIC_Wait_ACK();
//停止信号
IIC_Stop();
}
short read_tem(void)//读取温度
{
char teml,temh;
short temp;
IIC_Start();
IIC_Write_Byte(0X80);
IIC_Wait_ACK();
IIC_Write_Byte(0XE3);
IIC_Wait_ACK();
IIC_Start();
IIC_Write_Byte(0X81);
IIC_Wait_ACK();
delay_ms(10);
temh=IIC_Read_Byte(0);
teml=IIC_Read_Byte(1);
IIC_Stop();
temp=(temh<<8) | teml;
return temp;
}
unsigned short read_hum(void)//读取湿度
{
unsigned char humh,huml;
unsigned short hum;
IIC_Start();
IIC_Write_Byte(0X80);
IIC_Wait_ACK();
IIC_Write_Byte(0XE5);
IIC_Wait_ACK();
IIC_Start();
IIC_Write_Byte(0X81);
IIC_Wait_ACK();
delay_ms(10);
humh=IIC_Read_Byte(0);
huml=IIC_Read_Byte(1);
IIC_Stop();
hum=(humh<<8) | huml;
return hum;
}