GD32 + 光照传感器 BH1750的使用
1、GPIO模拟i2c配置
使用管脚为SCL PB10 SDA PB11,移植代码时可换自己的管脚。软件模拟i2c在十九章中讲过,与其不同的地方是,这里的us延时函数,换成了定时器3做us级的延时。
tim3的配置:
void timer3_config(void)
{
/* -----------------------------------------------------------------------
系统主频108MHZ,timer_initpara.prescaler为107,timer_initpara.period为65535,
一us加一个数,65535重新计数,最大延时us为65535-1
----------------------------------------------------------------------- */
timer_parameter_struct timer_initpara;
rcu_periph_clock_enable(RCU_TIMER3);
timer_deinit(TIMER3);
/* TIMER1 configuration */
timer_initpara.prescaler = 108-1;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 65535-1;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER3,&timer_initpara);
/* auto-reload preload enable */
timer_auto_reload_shadow_enable(TIMER3);
/* auto-reload preload enable */
timer_disable(TIMER3);
}
void tim3_delay_us(__IO uint32_t us)
{
timer_counter_value_config(TIMER3,0);
timer_enable(TIMER3);
while(timer_counter_read(TIMER3)< us);
timer_disable(TIMER3);
}
2、光照传感器BH1750配置
1、接线图。
GD32 BH1750
PB10 ------------- SCL
PB11 ------------- SDA
3.3 ------------- VCC
GND ------------- GND
GND ------------- ADDR
如果ADDR接地,器件八位地址为01000110,即0x46
如果ADDR接VCC,器件八位地址为10111000,即0xB8
2、初始化的流程
3、command命令
4、读写时序图
以ex2为例:
写命令格式为
start信号+ 器件地址 + command + stop信号。
所以swi2c封装写函数如下:
void swi2c_write_data(uint8_t device_addr,uint8_t *buf,uint8_t len)
{
swi2c_start();
swi2c_write_byte(device_addr);//写地址,7位地址左移,低位补0
swi2c_wait_ack();//等待应答
while(len)
{
swi2c_write_byte(*buf++);//写位置
swi2c_wait_ack();
len--;
}
swi2c_stop();
}
读数据格式:
start信号+ 器件地址(写) + command + 器件地址(读)+ 高低位数据 +stop信号。
封装读数据函数为:
void swi2c_read_data(uint8_t device_addr,uint8_t *buf,uint8_t len)
{
swi2c_start();
swi2c_write_byte((device_addr) | 0x01);//读写位改为读
swi2c_wait_ack();
while(len > 1)
{
*buf++ = swi2c_read_byte();
swi2c_ack();
len--;
}
*buf = swi2c_read_byte();//循环体结束指针已经指向最后一个字节存放位置
swi2c_no_ack();//读一个字节结束
swi2c_stop();
}
5、根据初始化流程图,我们初始化bh1750的代码如下:
int init_bh1750()
{
uint8_t power_on = BH_POWER_ON;
uint8_t reset = BH_RESET;
swi2c_write_data(0x46,&power_on,1);
delay_1ms(10);
swi2c_write_data(0x46,&reset,1);
return 0;
}
6、读取光照值的代码如下:
int get_light_value(uint16_t *light_value)
{
uint8_t r_light_data[2] = {0};
uint8_t high_mode = BH_HMODE_RESOLUTION;
swi2c_write_data(0x46,&high_mode,1);
delay_1ms(180);
swi2c_read_data(0x46,r_light_data,2);
*light_value = ((r_light_data[0] << 8) | r_light_data[1]);
return 0;
}
我们采用高分辨率连续读模式,根据上图提示,最大延时180ms。
7、main函数调用。
3、现象与结果
4、代码路径
代码路径:https://gitee.com/xiaoguo-tec_0/gd32-iap-code.git