当前位置: 代码迷 >> 综合 >> STM32之BH1750光照强度模块(GY-302)C语言代码(代码稳定详细,简洁明了)
  详细解决方案

STM32之BH1750光照强度模块(GY-302)C语言代码(代码稳定详细,简洁明了)

热度:95   发布时间:2023-10-18 03:35:21.0
STM32之BH1750光照强度模块(GY-302)C语言代码(代码稳定详细,简洁明了)
BH1750光强模块图片

STM32之BH1750光照强度模块(GY-302)C语言代码(代码稳定详细,简洁明了)
BH1750光强模块数据显示

请别乱用printf!!!!!以下是printf函数重定向方法!!!!!!!!搞不懂的话,就别用,就只用光照模块部分代码

今日头条

第一部分:BH1750光强模块代码头文件(BH1750.h)

#ifndef BH1750_H
#define BH1750_H
#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"//IIC总线地址接口定义
#define IIC_SCL PBout(3)
#define IIC_SDA_OUT PAout(15)
#define IIC_SDA_IN PAin(15)#define IIC_INPUT_MODE_SET()  {GPIOA->CRH&=0x0FFFFFFF;GPIOA->CRH|=0x80000000;}
#define IIC_OUTPUT_MODE_SET() {GPIOA->CRH&=0x0FFFFFFF;GPIOA->CRH|=0x30000000;}#define  IIC_WRITE      0     // 写
#define  IIC_READ       1     // 读
#define	 SlaveAddress   0x46  //BH1750地址
extern u8  BUF[3];
//函数声明
void IIC_Init(void);
void BH1750_Start();
void BH1750_Stop();
void BH1750_SendACK(char ack);
char BH1750_RecvACK();
void BH1750_SendByte(u8 data);
void Single_Write_BH1750(u8 REG_Address);
void Multiple_Read_BH1750();
void Get_Sunlight_Value();
u8 BH1750_RecvByte();#endif

第二部分:BH1750光强模块代码文件(BH1750.c)

#include "BH1750.h"
/*
函数功能: IIC总线初始化
硬件连接:SCL-PB3SDA-PA15
*/
u8  BUF[3];void IIC_Init(void)
{/*1. 开时钟*/RCC->APB2ENR|=1<<2; //PARCC->APB2ENR|=1<<3; //PBRCC->APB2ENR|=1<<0; //开启AFIO时钟/*2. 配置模式*/AFIO->MAPR |= 0x2<<24;//关闭JTAG-DP,启用SW-DPGPIOA->CRH&=0x0FFFFFFF;GPIOA->CRH|=0x30000000;GPIOB->CRL&=0xFFFF0FFF;GPIOB->CRL|=0x00003000;/*3. 上拉*/GPIOA->ODR|=0x1<<15;GPIOB->ODR|=0x1<<3;//printf("BH1750 IIC_Init OK! \n");
}/**************************************
起始信号
**************************************/
void BH1750_Start()
{IIC_OUTPUT_MODE_SET(); //配置输出模式IIC_SDA_OUT = 1;       //拉高数据线IIC_SCL = 1;           //拉高时钟线DelayUs(5);            //延时IIC_SDA_OUT = 0;       //产生下降沿DelayUs(5);            //延时IIC_SCL = 0;           //拉低时钟线
}/*
函数功能: 停止信号
*/
void BH1750_Stop()
{IIC_OUTPUT_MODE_SET(); 	//配置输出模式IIC_SDA_OUT = 0;        //拉低数据线IIC_SCL = 1;            //拉高时钟线DelayUs(5);             //延时IIC_SDA_OUT = 1;        //产生上升沿DelayUs(5);             //延时
}/**************************************
发送应答信号
入口参数:ack (0:ACK 1:NAK)
**************************************/
void BH1750_SendACK(char ack)
{IIC_OUTPUT_MODE_SET(); 	  //配置输出模式IIC_SCL = 0;              //拉低时钟线if(ack) IIC_SDA_OUT = 1; else IIC_SDA_OUT = 0;     //写应答信号DelayUs(2);               //延时IIC_SCL = 1;              //拉高时钟线DelayUs(5);               //延时IIC_SCL = 0;              //拉低时钟线
}/**************************************
接收应答信号
**************************************/
char BH1750_RecvACK()
{u8 cnt=0;IIC_INPUT_MODE_SET();//输入模式IIC_SDA_OUT=1; DelayUs(1);IIC_SCL=1;DelayUs(1);while(IIC_SDA_IN)//等待应答{cnt++;DelayUs(1);if(cnt>=250)//等待时间过长,产生停止信号,返回1,表示接收应答失败{BH1750_Stop();//printf("N0 ACK\n");return 1;}}IIC_SCL=0;//应答成功,则SCL变低return 0;
}/**************************************
向IIC总线发送一个字节数据
**************************************/
void BH1750_SendByte(u8 data)
{u8 i;IIC_OUTPUT_MODE_SET();IIC_SCL = 0;//拉低时钟线, 数据准备发送DelayUs(2);//延时for (i=0;i<8;i++)//从高位开始一位一位地传送{if(data&0x80) IIC_SDA_OUT=1;//送数据口else IIC_SDA_OUT=0;data <<= 1;//移出数据的最高位IIC_SCL = 1; //拉高时钟线,发送数据DelayUs(2);//延时IIC_SCL = 0;//拉低时钟线,数据发送完毕DelayUs(2);//延时}
}
/**************************************
从IIC总线接收一个字节数据
**************************************/
u8 BH1750_RecvByte()
{u8 i;u8 data = 0;IIC_INPUT_MODE_SET();//使能内部上拉,准备读取数据,for (i=0;i<8;i++)//8位计数器{IIC_SCL=0;//置时钟线为低,准备接收数据位DelayUs(2);//时钟低电平周期大于4.7μsIIC_SCL=1;//置时钟线为高使数据线上数据有效,主机开始读数据,从机不能再改变数据了,即改变SDA的电平data <<= 1;IIC_SCL = 1;//拉高时钟线if(IIC_SDA_IN) data|=0x01;//读数据               DelayUs(1);//延时}IIC_SCL=0;return data;
}void Single_Write_BH1750(u8 REG_Address)
{BH1750_Start();//起始信号BH1750_SendByte(SlaveAddress);//发送设备地址+写信号BH1750_RecvACK();BH1750_SendByte(REG_Address);//内部寄存器地址,请参考中文pdf22页 BH1750_RecvACK();BH1750_Stop();//发送停止信号
}
/*********************************************************
连续读出BH1750内部数据
*********************************************************/
void Multiple_Read_BH1750()
{   BH1750_Start();//起始信号BH1750_SendByte(SlaveAddress+1);//发送设备地址+读信号BH1750_RecvACK();BUF[0] = BH1750_RecvByte();//BUF[0]存储0x32地址中的数据BH1750_SendACK(0);BUF[1] = BH1750_RecvByte();//BUF[0]存储0x32地址中的数据BH1750_SendACK(1);BH1750_Stop();//停止信号DelayMs(5);
}/*********************************************************
读出数据并合成实际光强值
*********************************************************/
void Get_Sunlight_Value()
{int dis_data=0;float temp;u8 i=0;Single_Write_BH1750(0x01);// power onSingle_Write_BH1750(0x10);// H- resolution modeDelayMs(180);//延时180msMultiple_Read_BH1750();//连续读出数据,存储在BUF中  for(i=0;i<3;i++)//printf("0X%X ",BUF[i]);dis_data=BUF[0];dis_data=(dis_data<<8)+BUF[1];//合成数据 temp=(float)dis_data/1.2;//printf("Sunlight=%0.2f lx\n",temp);
}

第三部分:主函数(main.c)

#include "stm32f10x.h"
#include "config.h"
#include "usart.h"
#include "delay.h"
#include "string.h"
#include "stdio.h"
#include "BH1750.h"int main(void)
{u8 i=0;USARTx_Init(USART1,72,115200); TIMERx_Init(TIM1,72,20000);   //辅助串口1接收。20ms为一帧数据。	IIC_Init();//BH1750初始化while(1){	Get_Sunlight_Value();//获取光照强度值DelayMs(2000);	}	
}

第四部分:USARTx_Init(USART1,72,115200);//printf串口打印


void USARTx_Init(USART_TypeDef *USARTx,int clock,int baud)
{if(USARTx==USART1){/*1.开总线GPIOA的时钟*/RCC->APB2ENR |= 1<<2;/*2.设置GPIOA口模式 PA9--TX(1011)  PA10--RX(1000)*/GPIOA->CRH &= 0xFFFFF00F;GPIOA->CRH |= 0x000008B0;/*3.开USART1时钟*/	RCC->APB2ENR |= 1<<14;//使能USART1RCC->APB1RSTR |= 1<<14;//开启复位USART1RCC->APB1RSTR &= ~(1<<14);//关闭复位USART1 /*4.设置USARTx中断 */
#ifdef USART1_IRQ_RX	USART1->CR1|=1<<5;  //开启串口接收中断STM32_NVIC_SetPriority(USART1_IRQn,0,0); //优先级设置
#endif}else if(USARTx==USART2){/*1.开总线GPIOA的时钟*/RCC->APB2ENR |= 1<<2;/*2.设置GPIOA口模式 PA2--TX(1011)  PA3--RX(1000)*/GPIOA->CRL &= 0xFFFF00FF;GPIOA->CRL |= 0x00008B00;/*3.开USART2时钟*/	RCC->APB1ENR |= 1<<17;//使能USART2RCC->APB1RSTR |= 1<<17;//开启复位USART2RCC->APB1RSTR &= ~(1<<17);//关闭复位USART2 /*4.设置USARTx中断 */
#ifdef USART2_IRQ_RX	USART2->CR1|=1<<5;  //开启串口接收中断STM32_NVIC_SetPriority(USART2_IRQn,1,0); //优先级设置
#endif		}else if(USARTx==USART3){/*1.开总线GPIOB的时钟*/RCC->APB2ENR |= 1<<3;/*2.设置GPIOB口模式 PB10--TX(1011)  PB11--RX(1000)*/GPIOB->CRH &= 0xFFFF00FF;GPIOB->CRH |= 0x00008B00;/*3.开USART3时钟*/	RCC->APB1ENR |= 1<<18;//使能USART3RCC->APB1RSTR |= 1<<18;//开启复位USART3RCC->APB1RSTR &= ~(1<<18);//关闭复位USART3/*4.设置USARTx中断 */
#ifdef USART3_IRQ_RX	USART3->CR1|=1<<5;  //开启串口接收中断STM32_NVIC_SetPriority(USART3_IRQn,2,0); //优先级设置
#endif}else {printf("%s串口参数错误!!!\n","USARTx");return ;}/*5.设置USARTx波特率*/USARTx->BRR = clock*1000000/baud; //brr=clock/baud/*6.设置USARTx控制寄存器 */USARTx->CR1 |= 1<<2;//使能接收USARTx->CR1 |= 1<<3;//使能发送USARTx->CR1 |= 1<<13;//USARTx模块使能
}

第五部分:printf重定向函数


/********************************
将标准输入输出重定向到USART1
********************************/int fputc(int c ,FILE *stream)
{USART1->DR = c;while(!(USART1->SR&1<<7));//等待数据发送完成return c;
}int fgetc(FILE *stream)
{while(!(USART1->SR&1<<5));//等待数据	return USART1->DR;
}

第六部分:初始化定时器 TIMERx_Init(TIM1,720,10000); 


/*函数功能: 初始化定时器
函数形参:u32 psc :预分频系数u32 arr :重装载计数器*/void TIMERx_Init(TIM_TypeDef *TIMx,u32 psc,u32 arr)
{if(TIMx==TIM1){RCC->APB2ENR|=1<<11;RCC->APB2RSTR|=1<<11;RCC->APB2RSTR&=~(1<<11);
#ifdef	 TIME1_UP_IRQTIMx->DIER|=1<<0;//配置更新中断STM32_NVIC_SetPriority(TIM1_UP_IRQn,1,0); //设置中断优先级printf("TIM1_Init OK!\n");
#endif	}else if(TIMx==TIM2){RCC->APB1ENR|=1<<0;RCC->APB1RSTR|=1<<0;RCC->APB1RSTR&=~(1<<0);
#ifdef	 TIME2_UP_IRQTIMx->DIER|=1<<0;//配置更新中断STM32_NVIC_SetPriority(TIM2_IRQn,1,0); //设置中断优先级printf("TIM2_Init OK!\n");
#endif	}else if(TIMx==TIM3){RCC->APB1ENR|=1<<1;RCC->APB1RSTR|=1<<1;RCC->APB1RSTR&=~(1<<1);
#ifdef	 TIME3_UP_IRQTIMx->DIER|=1<<0;//配置更新中断STM32_NVIC_SetPriority(TIM3_IRQn,1,0); //设置中断优先级printf("TIM3_Init OK!\n");
#endif	}else if(TIMx==TIM4){RCC->APB1ENR|=1<<2;RCC->APB1RSTR|=1<<2;RCC->APB1RSTR&=~(1<<2);
#ifdef	 TIME4_UP_IRQTIMx->DIER|=1<<0;//配置更新中断STM32_NVIC_SetPriority(TIM4_IRQn,1,0); //设置中断优先级printf("TIM4_Init OK!\n");
#endif}else {printf("TIMx_Init ERROR!\n");return;}/*配置定时器核心寄存器*/TIMx->PSC=psc-1; //预分频器TIMx->ARR=arr;   //重装载寄存器TIMx->CR1|=1<<7; //开启缓存功能//TIMx->CR1|=1<<0; //开启定时器TIMx->CR1&=~(1<<0); //关闭定时器
}

实物工程源码下载:

农业大棚环境监测(温湿度+二氧化碳浓度+光照强度+时间+OLED显示+ESP8266连网+EEPROM)-C文档类资源-CSDN下载