找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2620|回复: 4
收起左侧

最近小弟在用iar调试msp430g2553单片机读取bm43tnd的温度,一直读不出来 求帮助

[复制链接]
ID:575378 发表于 2019-7-25 09:56 | 显示全部楼层 |阅读模式
25黑币
单片机用的是msp430g2553,传感器是i2c协议 sda线和scl线接到单片机p1.1和p1.2口,一直读不出温度,相关的程序和工程在下边和附件中,大家有时间的帮忙看下,是哪方面的问题。
主程序:
#include "msp430.h"
#include "main.h"
////#include "uart.h"
#include "pin.h"
#include "i2c.h"
#include "bm43tnd.h"
/////////////////////////////////////////////////////////////////////////////////
void Hex_to_BCD(unsigned long hex_input,unsigned char *BCD_output)
{
  BCD_output[0] = hex_input / (long)100000;
  hex_input = hex_input - (BCD_output[0]* (long)100000);
  BCD_output[1] = hex_input / (long)10000;
  hex_input = hex_input - (BCD_output[1]* (long)10000);
  BCD_output[2] = hex_input / (long)1000;
  hex_input = hex_input -(BCD_output[2] *(long) 1000);
  BCD_output[3] = hex_input / 100;
  hex_input = hex_input - (BCD_output[3] * 100);
  BCD_output[4] = hex_input / 10;
  hex_input = hex_input - (BCD_output[4] * 10);
  BCD_output[5] = hex_input / 1;
  return;
}
void MSP_MCU_Init(void)
{
  unsigned int i;
  WDTCTL = WDTPW + WDTHOLD;       // Stop WDT
// BCSCTL1 &=~ XT2OFF;      //打开XT2振荡器
//    do
//    {
//    IFG1 &= ~OFIFG; //清除振荡器失效标志
//    for (i = 0xFFFF; i > 0; i--);  //延时,等待XT2起振
//    }
// while ((IFG1 & OFIFG) != 0);    //判断XT2是否起振
// BCSCTL2 = SELM_2+SELS;    //选择MCLK、SMCLK为XT2
}
void main(void)
{
   unsigned long temperature;
   unsigned char temp[6],symbol;
   MSP_MCU_Init();
   I2C_Init();
  //Uart_Init();
  //Uart_Send_Msg("BM43TND_MSP430_DEMO\r\n");
  //write_mem_register(0x02,0x01,0x80);
   read_mem_register(0x39);
   while(1)
   {
       delay_ms(200);   
        command_only(Start_CM);//start Command mode
        get_data(SM_TM_AZTM_DEFAULT, 0x00, 0x00);//1 Full Measurement cycle
        command_only(Start_NOM);//start normal mode  
calculate(&symbol,&temperature);
        Hex_to_BCD(temperature,temp);
   }
}      
void Delay_100us(unsigned int t)
{
t*=1324;
do (t--);
while (t != 0);
}
i2c.c
#include "msp430.h"
#include "pin.h"
#include "i2c.h"
#include "main.h"
//#include "uart.h"
//P1.2 SCL
#define SCL_1       P1OUT |=  BIT2              //SCL = 1
#define SCL_0       P1OUT &=~ BIT2              //SCL = 0
//P1.1 SDA
#define SDA_1       P1OUT |=  BIT1             //SDA = 1
#define SDA_0       P1OUT &=~ BIT1             //SDA = 0
#define DIR_IN      P1DIR &=~ BIT1        //I/O口为输入
#define DIR_OUT     P1DIR |=  BIT1             //I/0口为输出
#define SDA_IN      ((P1IN >> 1) & 0x01)       //Read SDA
void Delay(void)
{
        _NOP();
        _NOP();
        _NOP();
        _NOP();
}
unsigned char I2C_Init(void)
{
P1SEL &=~BIT2;
P1SEL &=~BIT1;
        P1DIR |= BIT2;//P1.2=SCL
P1DIR |= BIT1;//P1.1=SDA
SCL_1;   //SCL = 1
        DIR_IN; // I/O为输入
return OK;
}
/********************************/
/*函数名:      iic_cack()         */
/*功能:   iic检测ack信号 */
/*输入参数: 无   */
/*输出参数: 无   */
/*返回值:     无   */
/********************************/
unsigned char I2C_Cack(void)
{
unsigned char ack;
   
        DIR_IN;
SCL_1;         
        ack = SDA_IN;
//#if I2C_Debug
// if(ack == 0)
//    {
//     Uart_Send_Msg("->ACK = 0\r\n");
//    }
//    else
//    {
//        Uart_Send_Msg("->ACK = 1\r\n");
//     //while(1);
//    }
//#endif  
        if(ack == 0)
        {
        P2DIR=BIT2;
        P2OUT&=~BIT2;
        delay_ms(200);
        P2OUT^=BIT2;
        }
SCL_0;
return ack;
}
/********************************/
/*函数名:     iic_start()  */
/*功能:  iic发送start信号*/
/*输入参数: 无    */
/*返回值:     无    */
/*******************************/
void I2C_Start(void)
{
#if I2C_Debug      
Uart_Send_Msg("I2C START\r\n");
#endif
DIR_IN;
  
SCL_1;//SCL拉高
  Delay();
  
SDA_0;
        DIR_OUT;//SDA为输出
Delay();
SCL_0;
Delay();
        
return;
}
/********************************/
/*函数名:     iic_stop()  */
/*功能:  iic发送stop */
/*输入参数: 无   */
/*返回值:     无   */
/*******************************/
//停止条件定义为:在SDA置于低电平时,将SCL拉高并保持高电平,然后将SDA拉高。
void I2C_Stop(void)
{
Delay();
      
        SDA_0;
        DIR_OUT;//SDA输出
Delay();

SCL_1;
Delay();

DIR_IN;//SDA外部拉高
Delay();
#if I2C_Debug
Uart_Send_Msg("I2C STOP\r\n");
#endif
    return;
}
/********************************/
/*函数名:     iic_wrack()  */
/*功能:  iic发送ack  */
/*输入参数: 无    */
/*返回值:     无    */
/*******************************/
void I2C_Wrack(void)
{
    SDA_0;//SDA输出低电平
    DIR_OUT;//SDA输出

    SCL_0;
SCL_1;
//Delay();
SCL_0;
        
#if I2C_Debug
Uart_Send_Msg("SEND ACK\r\n");
#endif
return;
}

/********************************/
/*函数名:     iic_wrnack() */
/*功能:  iic发送nack  */
/*输入参数: 无    */
/*返回值:     无    */
/*******************************/
//如果它不拉低SDA线,就表示不响应(NACK)。
void I2C_Wrnack(void)
{
    SCL_0;
      
    DIR_IN;//SDA外部拉高
   
    SCL_1;
   
SCL_0;
#if I2C_Debug
    Uart_Send_Msg("SEND NAK\r\n");
#endif
   return;
}
/********************************/
/*函数名:     iic_wrbyte() */
/*功能:  iic发送8 bit */
/*输入参数: data_out  */
/*返回值:     无   */
/********************************/
void I2C_Wrbyte(unsigned char data_out)
{
unsigned char write_data;
#if I2C_Debug
    Uart_Send_Msg("->I2C SEND BYTE ");
    Uart_Send_Hex(&data_out,1);
    Uart_Send_Msg("\r\n");
#endif
write_data = data_out;      
        
    DIR_OUT;        
SCL_0;
   
    if(write_data & 0x80)//BIT7
     SDA_1;
    else
     SDA_0;
    SCL_1;
    SCL_0;
      
    if(write_data & 0x40)//BIT6
     SDA_1;
    else
        SDA_0;
    SCL_1;
    SCL_0;
      
    if(write_data & 0x20)//BIT5
     SDA_1;
    else
        SDA_0;
    SCL_1;
    SCL_0;
      
    if(write_data & 0x10)//BIT4
        SDA_1;
    else
        SDA_0;
    SCL_1;
    SCL_0;
      
    if(write_data & 0x08)//BIT3
     SDA_1;
    else
        SDA_0;
    SCL_1;
    SCL_0;
      
    if(write_data & 0x04)//BIT2
     SDA_1;
    else
        SDA_0;
    SCL_1;
    SCL_0;
      
    if(write_data & 0x02)//BIT1
     SDA_1;
    else
        SDA_0;
    SCL_1;
    SCL_0;
      
    if(write_data & 0x01)//BIT0
        SDA_1;
    else
        SDA_0;
    SCL_1;
    SCL_0;
    DIR_IN;
  
}
/********************************/
/*函数名:     iic_rdbyte() */
/*功能:  iic接收8bit  */
/*输入参数: 无    */
/*返回值:     iic_data_in  */
/********************************/
unsigned char I2C_Rdbyte(void)
{
unsigned char read_data,i;
read_data=0;
    DIR_IN;//SDA输入
SCL_0;
   
for(i=0;i<8;i++)
{
     read_data = read_data<<1;
        SCL_1;
  read_data |= SDA_IN; //按位或之后赋值
  SCL_0;               
}
        
#if I2C_Debug
Uart_Send_Msg("<-I2C RECE BYTE");
Uart_Send_Hex(&read_data,1);
        Uart_Send_Msg("\r\n");
#endif
    return read_data;
}
bm43tnd.c
#include "i2c.h"
#include "bm43tnd.h"
#include "uart.h"
#include "math.h"
unsigned char SlaveAddr = 0x00; //Change after changing slaveaddress 0x02 register[6:0]
unsigned char mcu_register[] =
{
0x00, // STATUS 0
0x01, // SENSOR_HIGH 1
0x02, // SENSOR_MiDDLE 2
0x03, // SENSOR_LOW 3
0x04, // TEMP_HIGH 4
0x05, // TEMP_MIDDLE 5
0x06, // TEMP_LOW 6
0x00, // COMMAND 7
0x00, // COMMAND_DAT1 8
0x00, // COMMAND_DAT2 9
0x00, // READ_REGISTER 10
0x00, // READ_MEMDAT1 11
0x00, // READ_MEMDAT2 12
0x00  // I2C_Error 13
};
void delay_ms(unsigned int t)
{
  unsigned int i,j;
for(i = 0;i < t; i++)
for(j = 0;j < 1141; j++);  
return;
}

void command_only(unsigned char cmd) //See command list listed above
{
I2C_Start();
I2C_Wrbyte((SlaveAddr<<1)&0x3F);//Write data Bit0 = 0
I2C_Cack();
I2C_Wrbyte(cmd);
I2C_Cack();
I2C_Stop();
check_busy();
return;
}
void command_data(unsigned char cmd, unsigned char cmddat1, unsigned char cmddat2)
{
I2C_Start();
I2C_Wrbyte((SlaveAddr<<1)&0x3F);//Write data Bit0 = 0
I2C_Cack();
I2C_Wrbyte(cmd);
I2C_Cack();
I2C_Wrbyte(cmddat1);
I2C_Cack();
I2C_Wrbyte(cmddat2);
I2C_Cack();
I2C_Stop();
check_busy();
return;
}
void write_mem_register(unsigned char address, unsigned char dat1, unsigned char dat2) //register write
{
//Uart_Send_Msg("write_mem_register");
//Uart_Send_Hex(&address,1);
//Uart_Send_Msg("\r\n");
I2C_Start();
I2C_Wrbyte((SlaveAddr<<1)&0x3F);//Write data Bit0 = 0
I2C_Cack();
I2C_Wrbyte(address + 0x40);//0x40 is Read_Mem_Reg_Offset
I2C_Cack();
I2C_Wrbyte(dat1);
I2C_Cack();
I2C_Wrbyte(dat2);
I2C_Cack();
I2C_Stop();
check_busy();
mcu_register[COMMAND] = address;
mcu_register[COMMAND_DAT1] = dat1;
mcu_register[COMMAND_DAT2] = dat2;

//Uart_Send_Msg("->STATUS = ");
//Uart_Send_Hex(&mcu_register[STATUS],1);
//Uart_Send_Msg("\r\n");

//Uart_Send_Msg("->WRITE_MEMDAT = ");
//Uart_Send_Hex(&mcu_register[COMMAND_DAT1],2);
//Uart_Send_Msg("\r\n");
return;
}
void read_mem_register(unsigned char address) //read register
{
//Uart_Send_Msg("read_mem_register ");
//Uart_Send_Hex(&address,1);
//Uart_Send_Msg("\r\n");
//mcu_register[READ_MEMDAT1] = 0;
//mcu_register[READ_MEMDAT2] = 0;
command_data(address, 0x80, 0xa9);//需要验证作用是什么???
check_busy();
I2C_Start();
I2C_Wrbyte((SlaveAddr <<1)|0x01);//Read data Bit0 = 1
I2C_Cack();

// I2C_Wrbyte(address);
// I2C_Cack();

mcu_register[STATUS] = I2C_Rdbyte();
I2C_Wrack();

mcu_register[READ_REGISTER] = address;
mcu_register[READ_MEMDAT1] = I2C_Rdbyte();
I2C_Wrack();
mcu_register[READ_MEMDAT2] = I2C_Rdbyte();
I2C_Wrnack();
I2C_Stop();
check_busy();
//Uart_Send_Msg("->STATUS = ");
//Uart_Send_Hex(&mcu_register[STATUS],1);
//Uart_Send_Msg("\r\n");
        
//Uart_Send_Msg("->READ_MEMDAT = ");
//Uart_Send_Hex(&mcu_register[READ_MEMDAT1],2);
//Uart_Send_Msg("\r\n");
return;
}

void read_status(void)//read status
{
I2C_Start();
I2C_Wrbyte(SlaveAddr<<1|0x01);//Read data Bit0 = 1
I2C_Cack();
mcu_register[STATUS] = I2C_Rdbyte();
I2C_Wrnack();  
I2C_Stop();
return;
}
void check_busy(void) //check if flash writing is finished or not
{
int i = 0;
while(1)
{
  read_status();
  //if (bit_test(mcu_register[STATUS], 5)==0)
  if(mcu_register[STATUS]&0x10)
   break;
  i++;
  if (i > 10)
   break;
  else
   delay_ms(10);
}
return;
}
void get_data(unsigned char command, unsigned char dat1, unsigned char dat2) //read internal temp and sensor values
{
switch(command)
{
case SM_DEFAULT:
    break;
case SM_AZSM_DEFAULT:
  break;
case SM_TM_AZTM_DEFAULT:
  //Uart_Send_Msg("SM_TM_AZTM_DEFAULT\r\n");
  command_only(command);
  I2C_Start();
  I2C_Wrbyte((SlaveAddr<<1)|0x01);//Read data Bit0 = 1
  I2C_Cack();
  mcu_register[STATUS] = I2C_Rdbyte();
  I2C_Wrack();
  mcu_register[SENSOR_HIGH] = I2C_Rdbyte();
  I2C_Wrack();
  mcu_register[SENSOR_MIDDLE] = I2C_Rdbyte();
  I2C_Wrack();
  mcu_register[SENSOR_LOW] = I2C_Rdbyte();
  I2C_Wrack();
  mcu_register[TEMP_HIGH] = I2C_Rdbyte();
  I2C_Wrack();
  mcu_register[TEMP_MIDDLE] = I2C_Rdbyte();
  I2C_Wrack();
  mcu_register[TEMP_LOW] = I2C_Rdbyte();
  I2C_Wrnack();
  I2C_Stop();
  break;  
case SM_USERSET:
    break;
case SM_AZSM_USERSET:
  break;
case TM_DEFAULT:
    break;
case TM_AZTM_DEFAULT:
  break;
case TM_USERSET:
    break;
case TM_AZTM_USERSET:
  break;
case MeasureCyclic:
  break;
case Over2Measure:
    break;
case Over4Measure:
    break;
case Over8Measure:
    break;
case Over16Measure: //use Measure Cyclic for general purpose
    //Uart_Send_Msg("Over16Measure\r\n");
  command_only(command);
  I2C_Start();
  I2C_Wrbyte((SlaveAddr<<1)|0x01);//Read data Bit0 = 1
  I2C_Cack();
  mcu_register[STATUS] = I2C_Rdbyte();
  I2C_Wrack();
  mcu_register[SENSOR_HIGH] = I2C_Rdbyte();
  I2C_Wrack();
  mcu_register[SENSOR_MIDDLE] = I2C_Rdbyte();
  I2C_Wrack();
  mcu_register[SENSOR_LOW] = I2C_Rdbyte();
  I2C_Wrack();
  mcu_register[TEMP_HIGH] = I2C_Rdbyte();
  I2C_Wrack();
  mcu_register[TEMP_MIDDLE] = I2C_Rdbyte();
  I2C_Wrack();
  mcu_register[TEMP_LOW] = I2C_Rdbyte();
  I2C_Wrnack();
  I2C_Stop();
  break;
}

//Uart_Send_Msg("->STATUS = ");
//Uart_Send_Hex(&mcu_register[STATUS],1);
//Uart_Send_Msg("\r\n");

//Uart_Send_Msg("->SENSOR_HIGH = ");
//Uart_Send_Hex(&mcu_register[SENSOR_HIGH],1);
//Uart_Send_Msg("\r\n");

//Uart_Send_Msg("->SENSOR_MIDDLE = ");
//Uart_Send_Hex(&mcu_register[SENSOR_MIDDLE],1);
//Uart_Send_Msg("\r\n");

//Uart_Send_Msg("->SENSOR_LOW = ");
//Uart_Send_Hex(&mcu_register[SENSOR_LOW],1);
//Uart_Send_Msg("\r\n");

//Uart_Send_Msg("->TEMP_HIGH = ");
//Uart_Send_Hex(&mcu_register[TEMP_HIGH],1);
//Uart_Send_Msg("\r\n");

//Uart_Send_Msg("->TEMP_MIDDLE = ");
//Uart_Send_Hex(&mcu_register[TEMP_MIDDLE],1);
//Uart_Send_Msg("\r\n");

//Uart_Send_Msg("->TEMP_LOW = ");
//Uart_Send_Hex(&mcu_register[TEMP_LOW],1);
//Uart_Send_Msg("\r\n");
return;
}

void calculate (unsigned char *symbol,unsigned long *temperature)   
{      
float TemperatureValue = 0.0;
float SensorValue = 0.0;
float Ambient = 0.0;
float Delta_T = 0.0;
float Object;


//mcu_register[TEMP_HIGH] = 0x86;
//mcu_register[TEMP_MIDDLE] = 0x46;
//mcu_register[TEMP_LOW] = 0x80;
//mcu_register[SENSOR_HIGH] = 0x80;
//mcu_register[SENSOR_MIDDLE] = 0x68;
//mcu_register[SENSOR_LOW] = 0x40;
   
   

//TemperatureValue = make32(mcu_register[TEMP_HIGH], mcu_register[TEMP_MIDDLE], mcu_register[TEMP_LOW]);

TemperatureValue = (float)(mcu_register[TEMP_HIGH]*65536)+(float)(mcu_register[TEMP_MIDDLE]*256)+(float)mcu_register[TEMP_LOW];
  
//SensorValue = make32(mcu_register[SENSOR_HIGH], mcu_register[SENSOR_MIDDLE], mcu_register[SENSOR_LOW]);

SensorValue = (float)((float)mcu_register[SENSOR_HIGH]*(float)65536)+(float)((float)mcu_register[SENSOR_MIDDLE]*(float)256)+(float)mcu_register[SENSOR_LOW];
  
//if (TemperatureValue > 8388607)//Change from 2’s complement
   //TemperatureValue = 16777216 - TemperatureValue;
//if (SensorValue > 8388607) //Change from 2’s complement
   //SensorValue = 16777216 - SensorValue;

Ambient = (TemperatureValue / (float)pow(2, 24))*(float)125.0 - (float)40.0;
Delta_T = (float)1000*(SensorValue / (float)pow(2, 24) -(float) 0.5);
Object = Ambient + Delta_T;  
if(Object < 0)
   *symbol = 0;
else
   *symbol = 1;
*temperature = (unsigned long)(Object*(float)1000);
return;      
}
X7%O4Z%K3C%{9PTA4@(_H[G.png BM43TND_MSP430_I2C.zip (388.62 KB, 下载次数: 39)

回复

使用道具 举报

ID:351097 发表于 2019-7-25 14:36 | 显示全部楼层
建议用逻辑分析仪监控也行IIC通信过程,看看是否通信成功,这个才是最重要的。
回复

使用道具 举报

ID:575378 发表于 2019-7-25 15:01 | 显示全部楼层
没有你 发表于 2019-7-25 14:36
建议用逻辑分析仪监控也行IIC通信过程,看看是否通信成功,这个才是最重要的。

我用示波器抓了下sda和scl线,发现是能往sda写的,但是后续读不出写进去的数据,想问下有可能是什么原因(另外抓的时候发现sda空闲时没有拉高 这个会影响吗)
回复

使用道具 举报

ID:147266 发表于 2019-7-25 22:05 | 显示全部楼层
花几十块买个saleae逻辑分析仪,调这些低速通信借口无往不利
回复

使用道具 举报

ID:247732 发表于 2019-12-4 09:36 | 显示全部楼层
请问你读出来没。赐教一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表