STM32使用模拟IIC控制BH1750实验程序,printf输出

2019-07-21 07:50发布

本帖最后由 spl928 于 2018-3-4 15:12 编辑

一个小小的IIC程序整了好几天,从网上查了资料,终于调试好了,不过其中仍然有不懂得地方,以后再慢慢琢磨。
主要有两个地方:(有知道的帮忙释疑下啊)
(1)比如IIC.c文件中,IIC_Send_Byte()函数中有四句话(我自己加的,原子哥的IIC.c中没有),有或者没有会对程序造成很大的影响。
(2)读书只能读到54612.5lux,读不到65535,这是因为读完数据后除以1.2导致的。

先放上我已经调试ok的程序,IIC.c大部分跟原子哥的是一致的,但有些地方改了。
方法1和方法2,转换的数据一个用数组表示,一个用字符表示,差不多。
方法3,把转换数据的函数放到了外面。
这是main.c函数
[mw_shl_code=applescript,true]int main(void)
{
  //float data;
        delay_init();                     //延时函数初始化         
        uart_init(9600);
        BH1750_Init();
        
                /****方法一:使用此while循环****/
while(1)
{

          //Single_Write_BH1750(0x07);    //Power On
          BH1750_ReadContinuous1();
                 delay_ms(200);


                printf("light:");
                printf("%5.1f ",lux);   
                printf("lux ");    //注意此处的lux仅仅代表单位
                delay_ms(500);
                delay_ms(500);
        
}
        
        /****方法二:使用此while循环****/
// while(1)
// {

//           //Single_Write_BH1750(0x07);    //Power On
//           BH1750_ReadContinuous2();
//                  delay_ms(200);
//                  Conversion();         

//                 printf("light:");
//                 printf("%5.1f ",lux);   
//                 printf("lux ");    //注意此处的lux仅仅代表单位
//                 delay_ms(500);
//                 delay_ms(500);
//         
// }

        
        //方法三时使用此while循环
//         while(1)
//         {
//                 Single_Write_BH1750(0x01);    //Power On
//                 Single_Write_BH1750(0x10);    //连续H-Mode
//                 
//                 BH1750_Multiple_Read();
//                 delay_ms(200);
//                 Conversion();
//                 printf("light:");
//                 printf("%5.1f ",lux);   
//                 printf("lux ");    //注意此处的lux仅仅代表单位
//                 delay_ms(500);
//                 delay_ms(500);
//         }
//         
        
}

[/mw_shl_code]


下面是BH1750.c中的主要函数。
[mw_shl_code=applescript,true]/****向BH1750单次写命令****/
void Single_Write_BH1750(unsigned char Reg_Address)
{
        IIC_Start();
        IIC_Send_Byte(0x46);  //发送器件地址0100 0110   最后一位0,表示写
        //IIC_Wait_Ack();
        IIC_Send_Byte(Reg_Address);  
        //IIC_Wait_Ack();
        IIC_Stop();
}


/****BH1750初始化****/
void BH1750_Init(void)
{
        IIC_Config();
  Single_Write_BH1750(0x01);
        
}


/****从BH1750单次读Lux****/
/****
模式选择:H-Resolution Mode,分辨率1lux
单次读Opecode:0010 0000 ,即0x20
器件地址:0100011,ADDR接GND
****/
void BH1750_ReadOneTime(void)
{
        

        IIC_Start();
        IIC_Send_Byte(0x46);  //发送器件地址0100 0110   最后一位0,表示写
        IIC_Wait_Ack();
        IIC_Send_Byte(0x20);   //发送One time H-Resolution Mode的Opecode 0010 0000,分辨率为1lux
        IIC_Wait_Ack();
        IIC_Stop();
        delay_ms(200);
        IIC_Start();
        IIC_Send_Byte(0x47);  //
        IIC_Wait_Ack();
        BUF[0]=IIC_Read_Byte(1);
        //IIC_Ack();        //主机应答
        //temp1=temp<<8;
        BUF[1]=IIC_Read_Byte(0);
        //IIC_NAck();        //主机不应答        
        IIC_Stop();
        
        
//         temp2=BUF[0];
//         temp2=(temp2<<8)+BUF[1];
//         lux=(float)temp2/1.2;    //lux是float型
        
        //return lux;
        //delay_ms(200);
}

/****方法一:****/
/****从BH1750连续读Lux****/
/****
模式选择:H-Resolution Mode,分辨率1lux
连续读Opecode:0001 0000
器件地址:0100011,ADDR接GND
****/
void  BH1750_ReadContinuous1(void)
{
        u16 temp=0,temp1=0;


        IIC_Start();
  IIC_Send_Byte(0x46);  //发送器件地址0100 0110   最后一位0,表示写
        IIC_Wait_Ack();
        IIC_Send_Byte(0x10);  //发送Continuous H-Resolution Mode的Opecode 0001 0000,分辨率为1lux
        IIC_Wait_Ack();
        IIC_Stop();
        delay_ms(200);
        IIC_Start();
  IIC_Send_Byte(0x47);  //此处严重失误,写成了IIC_Read_Byte,想当然的认为最后一位是1,就应该用IIC_Read_Byte,特别注意!!!
        IIC_Wait_Ack();
        
        
//         BUF[0]=IIC_Read_Byte(1);
//         BUF[1]=IIC_Read_Byte(0);        
        
        
        temp=IIC_Read_Byte(1);
        temp1=IIC_Read_Byte(0);


        IIC_Stop();
        
        temp2=temp1+(temp<<8);
        lux=(float)temp2/1.2;    //lux是float型


}


/****方法二:****/


void  BH1750_ReadContinuous2(void)
{
        //u16 temp=0,temp1=0;


        IIC_Start();
  IIC_Send_Byte(0x46);  //发送器件地址0100 0110   最后一位0,表示写
        IIC_Wait_Ack();
        IIC_Send_Byte(0x10);  //发送Continuous H-Resolution Mode的Opecode 0001 0000,分辨率为1lux
        IIC_Wait_Ack();
        IIC_Stop();
        delay_ms(200);
        IIC_Start();
  IIC_Send_Byte(0x47);  //此处严重失误,写成了IIC_Read_Byte,想当然的认为最后一位是1,就应该用IIC_Read_Byte,特别注意!!!
        IIC_Wait_Ack();
        
        
        BUF[0]=IIC_Read_Byte(1);
        BUF[1]=IIC_Read_Byte(0);        
        
        
//         temp=IIC_Read_Byte(1);
//         temp1=IIC_Read_Byte(0);

        IIC_Stop();
        
//         temp2=temp1+(temp<<8);
//         lux=(float)temp2/1.2;    //lux是float型


}



/****方法三****/
/****
利用函数BH1750_Multiple_Read()进行读
利用Conversion(void)函数进行转换
****/
void BH1750_Multiple_Read(void)
{
        IIC_Start();
  IIC_Send_Byte(0x47);  //此处严重失误,写成了IIC_Read_Byte,想当然的认为最后一位是1,就应该用IIC_Read_Byte,特别注意!!!

        BUF[0]=IIC_Read_Byte(1);
        BUF[1]=IIC_Read_Byte(0);         
        IIC_Stop();                          //停止信号  
        delay_us(5);
        delay_ms(200);
}

void Conversion(void)
{
        temp2=BUF[0];
        temp2=(temp2<<8)+BUF[1];
        lux=(float)temp2/1.2;    //lux是float型
        
}
[/mw_shl_code]



友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
5条回答
spl928
2019-07-21 08:51
本帖最后由 spl928 于 2018-3-4 15:29 编辑

调试的过程中发现,
若是你输出的结果一直是255,有可能是你参数设置成u8了
若一直出现65535或者54612,或者某一个固定的值,大概率是IIC.c程序有问题。比如IIC_Send_Byte()函数,
反正一句话,多看几遍,跟别的比较,一定能调试出来,我自己这个程序整了三天,O(∩_∩)O~
下面是输出的结果:

一周热门 更多>