63、ARM/STM32中IIC相关学习20240417

完成温湿度传感器数据采集实验。

【思路:1.通过IIC通信原理,理解其通信过程,通过调用封装的IIC函数达成主机和从机之间:起始信号、终止信号、读、写数据的操作;    2.了解温湿度传感器控制芯片SI7006的工作原理,通过对其寄存器的相应操作,完成SI7006的初始化、启动温度测量并读取数值、启动湿度测量并读取数值】

【本次实验效果:当读取到的测量温度大于等于28°时,启动电风扇,小于则关闭风扇;当读取到的测量湿度大于等于60时,启动震动马达,小于则关闭】

代码如下<不含icc.c/.h>:

头文件si7006.h:

// 先写防止头文件的重复包含的机制 

#ifndef __SI7006_H__
#define __SI7006_H__

#include"iic.h"
void delay_ms(int ms);
void si7006_init();
unsigned short si7006_read_hum();
short si7006_read_tem();
extern void printf(const char *fmt, ...);
void Motor_init();
void FAN1_init();
#endif 

封装函数:si7006.c:

#include "si7006.h"

//封装延时函数
void delay_ms(int ms)
{
	int i,j;
	for(i=0;i<ms;i++)
	{
		for(j=0;j<2000;j++)
		{

		}
	}
}

//温湿度传感器初始化
void si7006_init()
{
    //1.发起起始信号
    i2c_start();
    //2.发送7bit从机地址和写标志位   0X80
    i2c_write_byte(0x80);
    //3.等待从机应答
    if(i2c_wait_ack())
    {
        printf("no ack\n");
    }
    //4.发送寄存器地址 0XE6
    i2c_write_byte(0xe6);
    //5.等待从机应答
    if(i2c_wait_ack())
    {
        printf("no ack\n");
    }
    //6.向从机发送数据  0X3A
    i2c_write_byte(0x3a);
    //7.等待从机应答
     if(i2c_wait_ack())
    {
        printf("no ack\n");
    }
    //8.发送终止信号
    i2c_stop();
}


unsigned short si7006_read_hum()
{
    unsigned char hum_l,hum_h;
    unsigned short hum;

    // 1.主机发起起始信号
    i2c_start();
    // 2.主机发送7bit从机地址+1bit写标志
    i2c_write_byte(0x80);
    // 3.等待从机应答
    if(i2c_wait_ack())
    {
        printf("no ack\n");
    }
    // 4.主机发送8bit寄存器地址
    i2c_write_byte(0xe5);  
    // 5.等待从机应答
    if(i2c_wait_ack())
    {
        printf("no ack\n");
    }    
    // 6.主机发起重复起始信号
    i2c_start();
    // 7.主机发送7bit从机地址+1bit 读  0X81
    i2c_write_byte(0x81);      
    // 8.等待从机应答
    if(i2c_wait_ack())
    {
        printf("no ack\n");
    }    
    // 9.延时等待从机测量数据
    delay_ms(100);
    // 10.读取湿度的高8bit数据  hum_h
    hum_h = i2c_read_byte(0);
    hum_l =  i2c_read_byte(1);
    // 11.发送应答信号
    // 12.读取湿度的低8位数据  hum_l
    // 13.发送非应答信号
    // 14.发起终止信号
    i2c_stop();
    // 15.将读取到的数据的低8位和高8bit合成一个完整的数据
    hum=hum_h<<8|hum_l ;
    return hum;

}


short si7006_read_tem()
{
    char tem_l,tem_h;
    short tem;

    // 1.主机发起起始信号
    i2c_start();
    // 2.主机发送7bit从机地址+1bit写标志
    i2c_write_byte(0x80);
    // 3.等待从机应答
    if(i2c_wait_ack())
    {
        printf("no ack\n");
    }
    // 4.主机发送8bit寄存器地址
    i2c_write_byte(0xe3);  
    // 5.等待从机应答
    if(i2c_wait_ack())
    {
        printf("no ack\n");
    } 
    // 6.主机发起重复起始信号
    i2c_start();
    // 7.主机发送7bit从机地址+1bit 读  0X81
    i2c_write_byte(0x81);    
    // 8.等待从机应答
    if(i2c_wait_ack())
    {
        printf("no ack\n");
    } 
    // 9.延时等待从机测量数据
    delay_ms(100);
    // 10.读取温度的高8bit数据 tem_h
    tem_h = i2c_read_byte(0);
    tem_l =  i2c_read_byte(1);
    // 11.发送应答信号
    // 12.读取温度的低8位数据 tem_l
    // 13.发送非应答信号
    // 14.发起终止信号
    i2c_stop();
    // 15.将读取到的数据的低8位和高8bit合成一个完整的数据
    tem=tem_h<<8|tem_l;
    return tem;
}

//马达初始化 TIM16 /GPIOF6 
void Motor_init()
{
    //iic.c中已经使能GPIOF时钟
    //使能TIM16 时钟
    RCC->MP_APB2ENSETR |= (0X1<<3);
    // 设置PF6引脚为通用的输出功能
    GPIOF->MODER &= (~(0x3 << 12));
    GPIOF->MODER |= (0x1 << 12);
    //初始化设置为低电平(关闭状态)
    GPIOF->ODR &= (~(0X1<<6));
}

//风扇初始化 TIM1 / GPIOE9
void FAN1_init()
{
    //使能TIM1时钟
    RCC->MP_APB2ENSETR |= (0X1);
    //使能GPIOE时钟
    RCC->MP_AHB4ENSETR  |= (0x1 << 4);
    // 设置PE9引脚为通用的输出功能
    GPIOE->MODER &= (~(0x3 << 18));
    GPIOE->MODER |= (0x1 << 18);
    //默认关闭状态
    GPIOE->ODR &= (~(0X1<<9));
}

主程序main.c:

#include "si7006.h"

int main()

{

	//si7006初始化

	si7006_init();

	i2c_init();

	Motor_init();

	FAN1_init();

	unsigned short hum;

	short tem;

	while (1)

	{

		hum = si7006_read_hum();

		tem = si7006_read_tem();

		hum = hum*125/65536 -6;

		tem=tem*175.72/65536-46.85;

        printf("hum:%d\n",hum);

        printf("tem:%d\n",tem);

		if(tem >= 28)

		{

			//如果温度超出30 打开风扇

		    GPIOE->ODR |= (0X1<<9);

		}else

		{

			//关闭风扇

    		GPIOE->ODR &= (~(0X1<<9));

		}

		if(hum>=60 )

		{

			//如果湿度大于60打开震动马达

		    GPIOF->ODR |= (0X1<<6);

		}else

		{

			//关闭震动马达

			GPIOF->ODR &= (~(0X1<<6));

		}	

        delay_ms(1000);

	}

	return 0;

}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值