ARM第四次

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值