GY-30光照传感器软件I2C方式驱动代码,基于STM32Cube

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。


这个驱动适用于所有的STM32系列芯片,使用STM32Cube方式开发,HAL库。如果本篇文章的内容对你有帮助的话,就点个赞鼓励一下吧!

        GY-30光照传感器的具体资料网上很多,直接搜索“GY-30光照传感”,或者问淘宝卖家要。所以传感器的这里我就不多介绍了。

用法

        STM32Cube开发方式就是4个字“简单高效”

        接线:VCC连接3到5伏电压,两根信号线连接自己选定的引脚。

        配置:根据“.c”文件(在下面)开头的注释描述在STM32CubeMX中配置好外设。

CubeMX配置

 1.软件I2C

  • 选择两个GPIO引脚作为软件I2C引脚。示例里选择PB8和PB9

  • 用户标签建议命名为softI2C1_SCL,softI2C1_SDA
  • PB8默认输出低电平,PB9默认输出高电平;配置为开漏输出、上拉、速度设置为Hign

  2.毫秒级延时

  • 选择定时器,配置为每毫秒计数一次,无需开中断(示例中为TIM3)

定时器配置如下图所示,这里的主频频率配置的是72*10^6。

需要一微秒(1*10^-6秒)所以这里预分频系数=(主频频率/1*10^6)-1=71。预分频系数为0时表示1分频,所以要减去1。

CubeMX配置好以后,直接将下列的驱动代码添加到工作空间中,调用对应函数即可。

gy30.h

#ifndef __GY30_H__
#define __GY30_H__

/********************************************************************************
 * 作    者:洛宇航(SiriusIoT)
 * 名    称:gy30.h
 * 备    注:GY-30光照传感器软件I2C方式驱动代码头文件
 ********************************************************************************/

#include "main.h"

//main函数里需要使用的就这一个输入亮度变量的地址,返回读取状态
uint8_t getGY30_Lux(uint16_t *nowLum);

void Z_I2C_Start(void);
void Z_I2C_End(void);
void Z_I2C_SendByte(uint8_t byte);
uint8_t Z_I2C_ReveiceByte();
void Z_I2C_SendACK(uint8_t ack);
uint8_t Z_I2C_ReveiceACK();


#endif 

gy30.c 

/********************************************************************************
 * 作    者:洛宇航(SiriusIoT)
 * 名    称:gy30.c 
 * 备    注:GY-30光照传感器软件I2C方式驱动代码
 * CubeMX配置方法:
 * 1.软件I2C
 * 选择两个GPIO引脚作为软件I2C引脚。
 * 建议命名为softI2C1_SCL,softI2C1_SDA
 * 默认输出高电平、开漏输出、上拉、速度设置为Hign
 * 2.毫秒级延时
 * 选择定时器,配置为每毫秒计数一次,无需开中断(默认为TIM6)
 ********************************************************************************/

#include "gy30.h"
#include "tim.h"

//外设配置宏定义start
#define DHT_HTIM    htim3//微秒级延时,这里使用了定时器3,换定时器的话改这里就行

//定义I2C总线连接的GPIO端口, 只需要修改下面5段行代码即可任意改变SCL和SDA的引脚
#define GPIO_PORT_GY30    GPIOE                   //GY30       GPIO端口

//软件I2C外设配置
#define GY30_SCL_PORT	softI2C1_SCL_GPIO_Port
#define GY30_SCL_PIN	softI2C1_SCL_Pin

#define GY30_SDA_PORT	softI2C1_SDA_GPIO_Port
#define GY30_SDA_PIN	softI2C1_SDA_Pin
//外设配置宏定义end

//定义读写SCL和SDA的宏
//SCL = 1
#define GY30_SCL_1		HAL_GPIO_WritePin(GY30_SCL_PORT, GY30_SCL_PIN, GPIO_PIN_SET)
//SCL = 0
#define GY30_SCL_0		HAL_GPIO_WritePin(GY30_SCL_PORT, GY30_SCL_PIN, GPIO_PIN_RESET)
//读SCL口线状态
#define GY30_SCL_READ	HAL_GPIO_ReadPin(GY30_SCL_PORT, GY30_SCL_PIN)

//SDA = 1
#define GY30_SDA_1		HAL_GPIO_WritePin(GY30_SDA_PORT, GY30_SDA_PIN, GPIO_PIN_SET)
//SDA = 0
#define GY30_SDA_0		HAL_GPIO_WritePin(GY30_SDA_PORT, GY30_SDA_PIN, GPIO_PIN_RESET)
//读SDA口线状态
#define GY30_SDA_READ	HAL_GPIO_ReadPin(GY30_SDA_PORT, GY30_SDA_PIN)

#define SCL_Pin GPIO_Pin_0
#define SDA_Pin GPIO_Pin_1
  
//利用定时器微秒级延时
void GY30_Delay_us(uint16_t us)
{
	uint16_t differ = 0xffff-us-5;
	__HAL_TIM_SET_COUNTER(&DHT_HTIM,differ);
	HAL_TIM_Base_Start(&DHT_HTIM);

	while(differ < 0xffff-5)
	{
		differ = __HAL_TIM_GET_COUNTER(&DHT_HTIM);
	}

	HAL_TIM_Base_Stop(&DHT_HTIM);
}

void I2C_SetSCL(uint8_t signal){
    if(signal==1) GY30_SCL_1;
    else GY30_SCL_0;
    GY30_Delay_us(5);                    //防止电平翻转过快,因此加上延时
}
 
void I2C_SetSDA(uint8_t signal){
    if(signal==1) GY30_SDA_1;
    else GY30_SDA_0;
    GY30_Delay_us(5);
}
 
void I2C_Start(void){
    I2C_SetSDA(1);
    I2C_SetSCL(1);
    I2C_SetSDA(0);
    I2C_SetSCL(0);
}
 
void I2C_End(){
    I2C_SetSDA(0);
    I2C_SetSCL(1);
    I2C_SetSDA(1);
}
 
void I2C_SendByte(uint8_t byte){
    I2C_SetSCL(0);
    for(int i=0;i<8;++i){
        if((byte&0x80)==0)
        	I2C_SetSDA(0);
        else
        	I2C_SetSDA(1);
        byte<<=1;
        I2C_SetSCL(1);
        I2C_SetSCL(0);
    }
}
 
uint8_t I2C_ReveiceByte()
{
    uint8_t data=0x00;
    I2C_SetSDA(1);
    for(int i=0;i<8;++i)
    {
        I2C_SetSCL(1);
        if(GY30_SDA_READ==1)
        	data|=(0x80>>i);
        I2C_SetSCL(0);
    }
    return data;
}
 
void I2C_SendACK(uint8_t ack)
{
    if(ack==0)
    	I2C_SetSDA(0);
    else
    	I2C_SetSDA(1);
    I2C_SetSCL(1);
    I2C_SetSCL(0);
}
 
uint8_t I2C_ReveiceACK()
{
    I2C_SetSDA(1);
    I2C_SetSCL(1);
    uint8_t ack=GY30_SDA_READ;
    I2C_SetSCL(0);
    return ack;
}
 
uint8_t getGY30_Lux(uint16_t* nowLum)
{
   
    I2C_Start();
    I2C_SendByte(0x46);
    if(I2C_ReveiceACK()!=0) 
        return 0;

    I2C_SendByte(0x01);
    if(I2C_ReveiceACK()!=0) 
        return 0;

    I2C_End();
    
    I2C_Start();
    I2C_SendByte(0x46);
    if(I2C_ReveiceACK()!=0)
        return 0;

    I2C_SendByte(0x10);
    if(I2C_ReveiceACK()!=0)
        return 0;

    I2C_End();
    HAL_Delay(200);
    
    uint16_t Light=0;
    I2C_Start();
    I2C_SendByte(0x47);
    if(I2C_ReveiceACK()!=0) 
        return 0;

    Light|=I2C_ReveiceByte();
    Light<<=8;
    I2C_SendACK(0);
    Light|=I2C_ReveiceByte();
    I2C_SendACK(1);
    I2C_End();
    
    *nowLum = Light;
    return 1;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值