單片機用的是msp430g2553,傳感器是i2c協(xié)議 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;
}
/********************************/
/*函數(shù)名: iic_cack() */
/*功能: iic檢測ack信號 */
/*輸入?yún)?shù): 無 */
/*輸出參數(shù): 無 */
/*返回值: 無 */
/********************************/
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;
}
/********************************/
/*函數(shù)名: iic_start() */
/*功能: iic發(fā)送start信號*/
/*輸入?yún)?shù): 無 */
/*返回值: 無 */
/*******************************/
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;
}
/********************************/
/*函數(shù)名: iic_stop() */
/*功能: iic發(fā)送stop */
/*輸入?yún)?shù): 無 */
/*返回值: 無 */
/*******************************/
//停止條件定義為:在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;
}
/********************************/
/*函數(shù)名: iic_wrack() */
/*功能: iic發(fā)送ack */
/*輸入?yún)?shù): 無 */
/*返回值: 無 */
/*******************************/
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;
}
/********************************/
/*函數(shù)名: iic_wrnack() */
/*功能: iic發(fā)送nack */
/*輸入?yún)?shù): 無 */
/*返回值: 無 */
/*******************************/
//如果它不拉低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;
}
/********************************/
/*函數(shù)名: iic_wrbyte() */
/*功能: iic發(fā)送8 bit */
/*輸入?yún)?shù): 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;
}
/********************************/
/*函數(shù)名: iic_rdbyte() */
/*功能: iic接收8bit */
/*輸入?yún)?shù): 無 */
/*返回值: 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 (67.14 KB, 下載次數(shù): 47)
下載附件
2019-7-25 09:54 上傳
BM43TND_MSP430_I2C.zip
(388.62 KB, 下載次數(shù): 39)
2019-7-25 09:56 上傳
點擊文件名下載附件
|