STM32驱动TSL2561

2014 4.17

最近一直在研究这个东西,查了查资料,感觉挺简单的,但是实际应用的时候也碰到一些问题。

比方说I2C配置不正确,导致数据错误,TSL设备地址不正确,根本读取不到数据。

关于TSL设备地址,这个刚刚开始根本没注意,可以看技术手册可以发现,共有三个地址,这三个地址根据你硬件连接可变。

接地的时候是0x52;

浮空的时候是0x72;

还有一个忘了。

解决这个以后,基本数据就能上来了,然后根据技术手册上的计算公式可以计算出需要的数据。

关于代码,其实东西也没多少,就是一个I2C驱动程序,根据它读取传感器数据。代码明天贴上。

2014 1.18

好吧我又来了,写的东西居然有人看,那我就积极一点了。

废话不多说,贴上我的代码。

下面是我的I2C驱动代码:

myiic.c 文件

#include "myiic.h"#include "delay.h"//初始化IICvoid IIC_Init(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE );GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7); //PB10,PB11 输出高}//产生IIC起始信号void IIC_Start(void){SDA_OUT();//sda线输出IIC_SDA=1;IIC_SCL=1;delay_us(4); IIC_SDA=0;//START:when CLK is high,DATA change form high to low delay_us(4);IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 }//产生IIC停止信号void IIC_Stop(void){SDA_OUT();//sda线输出IIC_SCL=0;IIC_SDA=0;//STOP:when CLK is high DATA change form low to high delay_us(4);IIC_SCL=1; IIC_SDA=1;//发送I2C总线结束信号delay_us(4);}//等待应答信号到来//返回值:1,接收应答失败//0,接收应答成功u8 IIC_Wait_Ack(void){u8 ucErrTime=0;SDA_IN();//SDA设置为输入IIC_SDA=1;delay_us(1);IIC_SCL=1;delay_us(1);while(READ_SDA){ucErrTime++;if(ucErrTime>250){IIC_Stop();return 1;}}IIC_SCL=0;//时钟输出0return 0; } //产生ACK应答void IIC_Ack(void){IIC_SCL=0;SDA_OUT();IIC_SDA=0;delay_us(2);IIC_SCL=1;delay_us(2);IIC_SCL=0;}//不产生ACK应答void IIC_NAck(void){IIC_SCL=0;SDA_OUT();IIC_SDA=1;delay_us(2);IIC_SCL=1;delay_us(2);IIC_SCL=0;}//IIC发送一个字节//返回从机有无应答//1,,有应答//0,无应答void IIC_Send_Byte(u8 txd){u8 t;SDA_OUT();IIC_SCL=0;//拉低时钟开始数据传输for(t=0;t<8;t++){//IIC_SDA=(txd&0x80)>>7;if((txd&0x80)>>7)IIC_SDA=1;elseIIC_SDA=0;txd<<=1;delay_us(2); //对TEA5767这三个延时都是必须的IIC_SCL=1;delay_us(2);IIC_SCL=0;delay_us(2);} }//读1个字节,ack=1时,发送ACK,ack=0,发送nACKu8 IIC_Read_Byte(unsigned char ack){unsigned char i,receive=0;SDA_IN();//SDA设置为输入for(i=0;i<8;i++ ){IIC_SCL=0;delay_us(2);IIC_SCL=1;receive<<=1;if(READ_SDA)receive++;delay_us(2);}if (!ack)IIC_NAck();//发送nACKelseIIC_Ack(); //发送ACKreturn receive;}/**************************实现函数*********************************************函数原型:unsigned char I2C_ReadOneByte(unsigned char I2C_Addr,unsigned char addr)*功  能:读取指定设备 指定寄存器的一个值输入I2C_Addr 目标设备地址addr 寄存器地址返回 读出来的值*******************************************************************************/ unsigned char I2C_ReadOneByte(unsigned char I2C_Addr,unsigned char addr){unsigned char res=0;IIC_Start();IIC_Send_Byte(I2C_Addr); //发送写命令res++;IIC_Wait_Ack();IIC_Send_Byte(addr); res++; //发送地址IIC_Wait_Ack();//IIC_Stop();//产生一个停止条件IIC_Start();IIC_Send_Byte(I2C_Addr+1); res++;//进入接收模式IIC_Wait_Ack();res=IIC_Read_Byte(0);IIC_Stop();//产生一个停止条件return res;}/**************************实现函数*********************************************函数原型:u8 IICreadBytes(u8 dev, u8 reg, u8 length, u8 *data)*功  能:读取指定设备 指定寄存器的 length个值输入dev 目标设备地址reg 寄存器地址length 要读的字节数*data 读出的数据将要存放的指针返回 读出来的字节数量*******************************************************************************/ u8 IICreadBytes(u8 dev, u8 reg, u8 length, u8 *data){u8 count = 0;IIC_Start();IIC_Send_Byte(dev); //发送写命令IIC_Wait_Ack();IIC_Send_Byte(reg); //发送地址IIC_Wait_Ack();IIC_Start();IIC_Send_Byte(dev+1); //进入接收模式IIC_Wait_Ack();for(count=0;count<length;count++){if(count!=length-1)data[count]=IIC_Read_Byte(1); //带ACK的读数据else data[count]=IIC_Read_Byte(0); //最后一个字节NACK}IIC_Stop();//产生一个停止条件return count;}/**************************实现函数*********************************************函数原型:u8 IICwriteBytes(u8 dev, u8 reg, u8 length, u8* data)*功  能:将多个字节写入指定设备 指定寄存器输入dev 目标设备地址reg 寄存器地址length 要写的字节数*data 将要写的数据的首地址返回 返回是否成功*******************************************************************************/ u8 IICwriteBytes(u8 dev, u8 reg, u8 length, u8* data){u8 count = 0;IIC_Start();IIC_Send_Byte(dev); //发送写命令IIC_Wait_Ack();IIC_Send_Byte(reg); //发送地址IIC_Wait_Ack();for(count=0;count<length;count++){IIC_Send_Byte(data[count]);IIC_Wait_Ack();}IIC_Stop();//产生一个停止条件return 1; //status == 0;}/**************************实现函数*********************************************函数原型:u8 IICreadByte(u8 dev, u8 reg, u8 *data)*功  能:读取指定设备 指定寄存器的一个值输入dev 目标设备地址reg 寄存器地址*data 读出的数据将要存放的地址返回 1*******************************************************************************/ u8 IICreadByte(u8 dev, u8 reg, u8 *data){*data=I2C_ReadOneByte(dev, reg);return 1;}/**************************实现函数*********************************************函数原型:unsigned char IICwriteByte(unsigned char dev, unsigned char reg, unsigned char data)*功  能:写入指定设备 指定寄存器一个字节输入dev 目标设备地址reg 寄存器地址data 将要写入的字节返回 1*******************************************************************************/ unsigned char IICwriteByte(unsigned char dev, unsigned char reg, unsigned char data){return IICwriteBytes(dev, reg, 1, &data);}/**************************实现函数*********************************************函数原型:u8 IICwriteBits(u8 dev,u8 reg,u8 bitStart,u8 length,u8 data)*功  能:读 修改 写 指定设备 指定寄存器一个字节 中的多个位输入dev 目标设备地址reg 寄存器地址bitStart 目标字节的起始位length 位长度data 存放改变目标字节位的值返回 成功 为1失败为0*******************************************************************************/ u8 IICwriteBits(u8 dev,u8 reg,u8 bitStart,u8 length,u8 data){u8 b;if (IICreadByte(dev, reg, &b) != 0) {u8 mask = (0xFF << (bitStart + 1)) | 0xFF >> ((8 – bitStart) + length – 1);data <<= (8 – length);data >>= (7 – bitStart);b &= mask;b |= data;return IICwriteByte(dev, reg, b);} else {return 0;}}/**************************实现函数*********************************************函数原型:u8 IICwriteBit(u8 dev, u8 reg, u8 bitNum, u8 data)*功  能:读 修改 写 指定设备 指定寄存器一个字节 中的1个位输入dev 目标设备地址reg 寄存器地址bitNum 要修改目标字节的bitNum位data 为0 时,目标位将被清0 否则将被置位返回 成功 为1失败为0*******************************************************************************/ u8 IICwriteBit(u8 dev, u8 reg, u8 bitNum, u8 data){u8 b;IICreadByte(dev, reg, &b);b = (data != 0) ? (b | (1 << bitNum)) : (b & ~(1 << bitNum));return IICwriteByte(dev, reg, b);}//——————End of File—————————-摘抄美文4、承诺是一件美好的事情,但美好的东西往往不会变为现实。

STM32驱动TSL2561

相关文章:

你感兴趣的文章:

标签云: