完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1 VEML6040颜色传感器
1.1 芯片简介 关于VEML6040颜色传感器的详细介绍可以到这个网址去看 简单点来说,VEML6040是一款颜色传感器,可以获取当前颜色的RGBW值(W值有什么用我也不知道),然后通过计算得到色坐标,最终得到采集的颜色。 VEML6040适用于3.3V的单片机系统,采用I2C总线传输数据,使用OPLG封装(这种封装手焊很难的,因为引脚在芯片正下面) 芯片长这样的,手册里面也给出了推荐的焊盘尺寸: 手册里面得到4个焊盘的大小是不一样的,在立创商城里面也给出了推荐的尺寸: 这里面给出的是4个一样的,我实际用的这种封装焊接过,大小正好,但是还是差点,我推荐用手册中给出的,但是可以画成一样的4个焊盘。 1.2 芯片外围电路 手册中给出了芯片的推荐电路: 外围电路非常简单, 1.GND接地就可以 2.VDD接电源,但是要接0.1UF的电容滤波,所以在给芯片供电的时候,电源线要先经过电容再接入芯片 3.I2C的2根数据线分别接入单片机的I2C总线的引脚。当然你也可以使用I/O口软件模拟I2C的时序,这样的话就直接接2个普通的I/O口就可以了。 4.2跟数据线要通过2个上啦电阻拉高至3.3V(电源电压) 2 I2C总线 至于什么是I2C总线,百度比我解释的更加清楚,大家可以自己去查,VEML6040采用的是I2C总线进行数据传输,我们得首先知道I2C中的几个命令: 还有VEML6040在进行数据传输的时候的方式,手册里面给出了在进行获取颜色数据时候的时序: 3 基于STM32的程序 3.1 I2C驱动 首先我们应该写出I2C的驱动程序,就是上面说的那几个信号,开始、结束、应答信号。我这里采用的是是使用软件模拟的方式来驱动。 3.1.1 I/O口设置 使用软件模拟的话,就随便使用2个I/O就可以了,I/O口设置为输出模式就可以 __HAL_RCC_GPIOB_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 3.1.2 开始信号 这里的SDA1和SCL1是我之前久宏定义好的,就是对应相应的I/O口 void IIC1_Start(void) { SDA1_OUT(); //sda线输出 SDA1=1; SCL1=1; delay_us(4); SDA1=0;//START:when CLK is high,DATA change form high to low delay_us(4); SCL1=0;//钳住I2C总线,准备发送或接收数据 } 3.1.3 停止信号 void IIC1_Stop(void) { SDA1_OUT();//sda线输出 SCL1=0; SDA1=0;//STOP:when CLK is high DATA change form low to high delay_us(4); SCL1=1; SDA1=1;//发送I2C总线结束信号 delay_us(4); } 3.1.4 等待应答信号 这里的SDA1_IN()是把这个I/O口设置为输入模式 我这里使操作寄存器实现的,就是把相应的寄存器置位就可以。 //等待应答信号到来 //返回值:1,接收应答失败 // 0,接收应答成功 #define SDA7_IN() {GPIOB->CRH&=0XF0FFFFFF;GPIOB->CRH|=(u32)8<<24;} u8 IIC1_Wait_Ack(void) { u8 ucErrTime=0; SDA1_IN(); //SDA设置为输入 SDA1=1;delay_us(1); SCL1=1;delay_us(1); while(Read_SDA1) { ucErrTime++; if(ucErrTime>250) { IIC1_Stop(); return 1; } } SCL1=0;//时钟输出0 return 0; } 3.1.5 应答信号 这里的SDA1_OUT()是把这个I/O口设置为输出模式 我这里使操作寄存器实现的,就是把相应的寄存器置位就可以。 //不产生ACK应答 void IIC1_NAck(void) { SCL1=0; SDA1_OUT(); SDA1=1; delay_us(2); SCL1=1; delay_us(2); SCL1=0; } 3.1.7 给指定地址发送信号 void IIC1_Send_Byte(u8 txd) { u8 t; SDA1_OUT(); SCL1=0;//拉低时钟开始数据传输 for(t=0;t<8;t++) { SDA1=(txd&0x80)>>7; if(txd==1) SDA1=1; if(txd==0) SDA1=0; txd<<=1; delay_us(2); SCL1=1; delay_us(2); SCL1=0; delay_us(2); } } 经过以上几个步骤,I2C的驱动代码基本上就完成了。 3.2 VEML6040驱动 3.2.1 读取数据 这个函数可以在制定的地址读取数据 #define VEML6040_ADDR 0x20 u16 VEML6040_1_ReadByte(u16 ReadAddr) //指定地址读取一个字节 { u16 data=0; u8 m***=0; u8 l***=1; IIC1_Start(); IIC1_Send_Byte(VEML6040_ADDR); //发送写命令 if(IIC1_Wait_Ack()==1) return 1; IIC1_Send_Byte(ReadAddr); if(IIC1_Wait_Ack()==1) return 1; IIC1_Start(); IIC1_Send_Byte((VEML6040_ADDR)+1); // if(IIC1_Wait_Ack()==1) return 1; l***=IIC1_Read_Byte(0); m***=IIC1_Read_Byte(0); IIC1_Stop(); data=((uint16_t)m*** << 8)|l***; return data; } 3.2.2 写入数据 这个函数可以在制定的地址写入制定的数据或者命令,用来设置颜色传感器里面的一些参数 uint8_t VEML6040_1_Write_Bytes(uint8_t res,uint8_t cmd) { uint8_t m***,l***; m***=0x00; l***=cmd; IIC1_Start(); IIC1_Send_Byte(VEML6040_ADDR); if(IIC1_Wait_Ack()==1) return 1; IIC1_Send_Byte(res); if(IIC1_Wait_Ack()==1) return 1; IIC1_Send_Byte(l***); if(IIC1_Wait_Ack()==1) return 1; IIC1_Send_Byte(m***); if(IIC1_Wait_Ack()==1) return 1; IIC1_Stop(); return 0; } 3.3 设置参数 这里的意思是向0X10这个地址里面写入了0X00这个命令,是用来设置传感器的相应参数, veml_1_Ack = VEML6040_1_Write_Bytes(0x10,0x00); 如果你想设置别的参数,只需要按照手册里面的表格设置相应的参数就可以了 3.4 读取数据 分别从不同的地址读取不同的颜色数据 if(veml_1_Ack==0) { VEML6040_No_Read(1,0x08); VEML6040_1_R = VEML6040_1_ReadByte(0x08);//红 VEML6040_1_G = VEML6040_1_ReadByte(0x09);//绿 VEML6040_1_B = VEML6040_1_ReadByte(0x0A);//蓝 VEML6040_1_W = VEML6040_1_ReadByte(0x0B);//白 } |
|
|
|
只有小组成员才能发言,加入小组>>
3310 浏览 9 评论
2991 浏览 16 评论
3492 浏览 1 评论
9057 浏览 16 评论
4086 浏览 18 评论
1175浏览 3评论
603浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
596浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2333浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1894浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 09:42 , Processed in 0.971679 second(s), Total 48, Slave 39 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号