同学们好,最近做cc430f5137和mlx90614非接触式测温,软件模拟IIc和硬件IIc模块都尝试了,都收不到ack信号,做了近两个月了,附上模拟IIc的代码,跪求大神解答,希望可以有点实质性的建议,先谢谢了
#include "msp430_kyg.h"
void Init_CLK(unsigned char nDco) //DCO_CLK 1,8,12,16MHZ------------------
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
switch(nDco)
{
case 1:
UCSCTL3 |= SELREF_2+FLLREFDIV_4; // Set DCO FLL reference = REFO,
UCSCTL2 = FLLD_0 + 374; // Set DCO 1MHz
break;
case 8:
UCSCTL3 |= SELREF_2+FLLREFDIV_4; // Set DCO FLL reference = REFO,
UCSCTL2 = FLLD_2 + 374; // Set DCO 8MHz
break;
case 12:
UCSCTL3 |= SELREF_2+FLLREFDIV_0; // Set DCO FLL reference = REFO,
UCSCTL2 = FLLD_0 + 374; // Set DCO Multiplier for 12MHz
case 16:
UCSCTL3 |= SELREF_2+FLLREFDIV_4; // Set DCO FLL reference = REFO,
UCSCTL2 = FLLD_3 + 374; // Set DCO 16MHz
break;
default:
break;
}
}
#include "mlx90615.h"
//--------------------------------------------------------------------------
//Description: mlx90615操作函数
//write by Meredith
//2010.4.21
//email:cyberkyg@163.com
//此代码仅供学习交流使用,未经作者允许,不可用于其他用途!
//--------------------------------------------------------------------------
void MLX90615_init(void)
{
mSDA_OUT; // Set SDA as Output
mSDA_LOW();
mSCL_OUT; // Set SCL as Output
mSCL_HIGH();
mSDA_HIGH();
SendRequest();
}
void START_bit(void)
{
mSDA_OUT;
mSDA_HIGH(); // Set SDA line
delay_Tbuf; // Wait a few microseconds
mSCL_HIGH(); // Set SCL line
delay_Tbuf; // Generate bus free time between Stop
// and Start condition (Tbuf=4.7us min)
mSDA_LOW(); // Clear SDA line
delay_Tbuf; // Hold time after (Repeated) Start
// Condition. After this period, the first clock is generated.
//(Thd:sta=4.0us min)
mSCL_LOW(); // Clear SCL line
delay_Tbuf; // Wait a few microseconds
}
void STOP_bit(void)
{
mSDA_OUT;
mSCL_LOW(); // Clear SCL line
delay_Tbuf; // Wait a few microseconds
mSDA_LOW(); // Clear SDA line
delay_Tbuf; // Wait a few microseconds
mSCL_HIGH(); // Set SCL line
delay_Tbuf; // Stop condition setup time(Tsu:sto=4.0us min)
mSDA_HIGH(); // Set SDA line
}
unsigned char TX_byte(unsigned char Tx_buffer)
{
unsigned char Bit_counter;
unsigned char Ack_bit;
unsigned char bit_out;
for(Bit_counter=8; Bit_counter>0; Bit_counter--)
{
if(Tx_buffer&0x80)
bit_out=1; // If the current bit of Tx_buffer is 1 set bit_out
else
bit_out=0; // else clear bit_out
send_bit(bit_out); // Send the current bit on SDA
Tx_buffer<<=1; // Get next bit for checking
}
Ack_bit=Receive_bit(); // Get acknowledgment bit
return Ack_bit;
}// End of TX_bite()
//---------------------------------------------------------------------------------------------
void send_bit(unsigned char bit_out)
{
mSDA_OUT;
if(bit_out)
mSDA_HIGH();
else
mSDA_LOW();
delay_Thd; // Tsu:dat = 250ns minimum
mSCL_HIGH(); // Set SCL line
delay_Tbuf; // High Level of Clock Pulse------------------
mSCL_LOW(); // Clear SCL line
delay_Tbuf; // Low Level of Clock Pulse----------------------
// mSDA_HIGH(); // Master release SDA line ,
return;
}
//---------------------------------------------------------------------------------------------
unsigned char Receive_bit(void)
{
unsigned char Ack_bit;
mSDA_IN; // SDA-input
_NOP();_NOP();_NOP();
mSCL_HIGH(); // Set SCL line
delay_Tbuf; // High Level of Clock Pulse
if(P1Input(BIT3))
Ack_bit=1; //Read acknowledgment bit, save it in Ack_bit
else
Ack_bit=0;
mSCL_LOW(); // Clear SCL line
delay_Tbuf; // Low Level of Clock Pulse
return Ack_bit;
}//End of Receive_bit
unsigned char RX_byte(unsigned char ack_nack)
{
unsigned char RX_buffer;
unsigned char Bit_Counter;
for(Bit_Counter=8; Bit_Counter>0; Bit_Counter--)
{
if(Receive_bit()) // Get a bit from the SDA line
{
RX_buffer <<= 1; // If the bit is HIGH save 1 in RX_buffer
RX_buffer |=0x01;
}
else
{
RX_buffer <<= 1; // If the bit is LOW save 0 in RX_buffer
RX_buffer &=0xfe;
}
}
send_bit(ack_nack); // Sends acknowledgment bit
return RX_buffer;
}
//----------------------------------------------------------------------------------------------
unsigned int MemRead(unsigned char SlaveAddress,unsigned char command)
{
unsigned int data; // Data storage (DataH:DataL)
unsigned char Pec; // PEC byte storage
unsigned char DataL; // Low data byte storage
unsigned char DataH; // High data byte storage
unsigned char arr[6]; // Buffer for the sent bytes
unsigned char PecReg; // Calculated PEC byte storage
unsigned char ErrorCounter; // Defines the number of the attempts for communication with MLX90614
ErrorCounter=0x00; // Initialising of ErrorCounter
do{
repeat:
STOP_bit(); //If slave send NACK stop comunication
--ErrorCounter; //Pre-decrement ErrorCounter
if(!ErrorCounter){ //ErrorCounter=0?
break; //Yes,go out from do-while{}
}
START_bit(); //Start conditio
if(TX_byte(SlaveAddress))
{ //Send SlaveAddress
goto repeat; //Repeat comunication again
}
if(TX_byte(command)){ //Send command
goto repeat; //Repeat comunication again
}
START_bit(); //Repeated Start condition
if(TX_byte(SlaveAddress)){ //Send SlaveAddress-------------------???
goto repeat; //Repeat comunication again
}
DataL=RX_byte(ACK); //Read low data,master must send ACK
DataH=RX_byte(ACK); //Read high data,master must send ACK
Pec=RX_byte(NACK); //Read PEC byte, master must send NACK
STOP_bit(); //Stop condition
arr[5]=SlaveAddress; //
arr[4]=command; //
arr[3]=SlaveAddress; //Load array arr
arr[2]=DataL; //
arr[1]=DataH; //
arr[0]=0; //
PecReg=PEC_calculation(arr);//Calculate CRC
}while(PecReg != Pec); //If received and calculated CRC are equal go out from do-while{}
*((unsigned char *)(&data))=DataL; //
*((unsigned char *)(&data)+1)=DataH ; //data=DataH:DataL
return data;
}
//---------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------
void SendRequest(void)
{
mSCL_LOW(); //SCL 1 ____________|<-----80ms------->|______________
_delay_ms(80); // 0 |__________________|
mSCL_HIGH();
}
//---------------------------------------------------------------------------------------------
void DummyCommand(unsigned char byte)
{
START_bit(); //Start condition
TX_byte(byte); //Send Slave Address or whatever,no need ACK checking
STOP_bit(); //Stop condition
}
//---------------------------------------------------------------------------------------------
float CalcTemp(unsigned int value)
{
float temp;
temp=(value*0.02)-273.15;
_NOP();
return temp;
}
unsigned char PEC_calculation(unsigned char pec[])
{
unsigned char crc[6];
unsigned char BitPosition=47;
unsigned char shift;
unsigned char i;
unsigned char j;
unsigned char temp;
do{
crc[5]=0; /* Load CRC value 0x000000000107 */
crc[4]=0;
crc[3]=0;
crc[2]=0;
crc[1]=0x01;
crc[0]=0x07;
BitPosition=47; /* Set maximum bit position at 47 */
shift=0;
//Find first 1 in the transmited message
i=5; /* Set highest index */
j=0;
while((pec[i]&(0x80>>j))==0 && i>0){
BitPosition--;
if(j<7){
j++;
}
else{
j=0x00;
i--;
}
}/*End of while */
shift=BitPosition-8; /*Get shift value for crc value*/
//Shift crc value
while(shift){
for(i=5; i<0xFF; i--){
if((crc[i-1]&0x80) && (i>0)){
temp=1;
}
else{
temp=0;
}
crc[i]<<=1;
crc[i]+=temp;
}/*End of for*/
shift--;
}/*End of while*/
//Exclusive OR between pec and crc
for(i=0; i<=5; i++){
pec[i] ^=crc[i];
}/*End of for*/
}while(BitPosition>8);/*End of do-while*/
return pec[0];
}/*End of PEC_calculation*/
void Init_IIC(void)
{
P1DIR |= BIT6;
P1OUT |= BIT6;
/**** 输出9个时钟以恢复I2C总线状态 ****/
for( uint i= 0; i <9 ; i++)
{
P1OUT |= BIT6;
__delay_cycles(8000);
P1OUT &= ~BIT6;
__delay_cycles(8000);
}
mSCL_LOW();
_delay_ms(2.5);
mSCL_HIGH();
mSDA_HIGH(); // bus free
}
//----------------------------------------------------
//Description: msp430f2274+mlx90615+ht1621
//write by Meredith
//2010.4.21
//email:cyberkyg@163.com
//
//此代码仅供学习交流使用,未经作者允许,不可用于其他用途!
//
//其中ht1621.c是白沙兄的函数库,版权归白沙所有
//-----------------------------------------------------
//******************************************************************************
//
//
// MSP430F2274
// -----------------
// /|| XIN|-
// | | |
// --|RST XOUT|-
// | P1.0|-->LED RED
// | P1.1|-->LED GREEEN
// | P1.2|-->key
// | P2.1|-->LCD DATA
// | P4.5|-->LCD /WR
// | P4.3|-->LCD /RD
// | P2.3|-->LCD /CS
// | P2.4|-->LCD /BL
// | P2.0|-->96015 SCL
// | P2.2|-->96015 SDA
// -----------------
//
//
//
//
// Built with IAR Embedded Workbench Version: 4.21.2
//******************************************************************************
#include "cc430f5137.h"
#include "mlx90615.h"
//#include "ht1621.h"
//**********************************************************************************
//void displayTemp(unsigned int temp);
void main(void)
{
unsigned char SlaveAddress; //Contains device address
unsigned char command; //Contains the access command
unsigned int data; //Contains data value
float date;
SlaveAddress=SA<<1; //Set device address
command=RAM_Access|RAM_To; //Form RAM access command + RAM address
Init_CLK(DCO_F);
//lcd_init();
//lcd_clr();
//lcd_char(_lcd_DEGREE,1); //显示℃标志
//lcd_char(_lcd_DOT2,1); //显示小数点
// Init_IIC();
MLX90615_init();
while(1)
{
//data=MemRead(SlaveAddress,command); //Read memory
//MLX90615_init();
data=MemRead(SlaveAddress,command);//Read memory
date=CalcTemp(data);
_delay_ms(10);
}
#include "cc430f5137.h"
//----------------------------------------------------
//Description: msp430系列单片机常用端口位操作
//write by Meredith
//2007.5.1
//email:cyberkyg@163.com
//
//modify at 2010.4.21
//-----------------------------------------------------
#ifndef _MSP430_KYG_H_
#define _MSP430_KYG_H_
#define U8 unsigned char
#define U16 unsigned int
#define uint unsigned int
#define uchar unsigned char
//----------------IO bits Set/Clr---------------------
#define ClrP1(n) P1OUT&=(~n)
#define SetP1(n) P1OUT|=n
/*#define ClrP2(n) P2OUT&=(~n)
#define SetP2(n) P2OUT|=n
#define ClrP3(n) P3OUT&=(~n)
#define SetP3(n) P3OUT|=n
#define ClrP4(n) P4OUT&=(~n)
#define SetP4(n) P4OUT|=n
#define ClrP5(n) P5OUT&=(~n)
#define SetP5(n) P5OUT|=n
#define ClrP6(n) P6OUT&=(~n)
#define SetP6(n) P6OUT|=n*/
//--------------------IO bits Input/Output--------------------------
#define SetInP1(n) P1DIR&=(~n)
#define SetOutP1(n) P1DIR|=n
/*#define SetInP2(n) P2DIR&=(~n)
#define SetOutP2(n) P2DIR|=n
#define SetInP3(n) P3DIR&=(~n)
#define SetOutP3(n) P3DIR|=n
#define SetInP4(n) P4DIR&=(~n)
#define SetOutP4(n) P4DIR|=n
#define SetInP5(n) P5DIR&=(~n)
#define SetOutP5(n) P5DIR|=n
#define SetInP6(n) P6DIR&=(~n)
#define SetOutP6(n) P6DIR|=n*/
//---------------------IO bits PULL Enabled/Disabled----------------
#define PullEnabledP1(n) P1REN|=n
#define PullDisabledP1(n) P1REN&=(~n)
#define PullEnabledP2(n) P2REN|=n
#define PullDisabledP2(n) P2REN&=(~n)
#define PullEnabledP3(n) P3REN|=n
#define PullDisabledP3(n) P3REN&=(~n)
#define PullEnabledP4(n) P4REN|=n
#define PullDisabledP4(n) P4REN&=(~n)
#define PullEnabledP5(n) P5REN|=n
#define PullDisabledP5(n) P5REN&=(~n)
#define PullEnabledP6(n) P6REN|=n
#define PullDisabledP6(n) P6REN&=(~n)
//---------------------IO bits PullUp/PullDown----------------------
#define PullDownP1(n) P1OUT&=(n)
#define PullUpP1(n) P1OUT|=n
#define PullDownP2(n) P2OUT&=(~n)
#define PullUpP2(n) P2OUT|=n
#define PullDownP3(n) P3OUT&=(~n)
#define PullUpP3(n) P3OUT|=n
#define PullDownP4(n) P4OUT&=(~n)
#define PullUpP4(n) P4OUT|=n
#define PullDownP5(n) P5OUT&=(~n)
#define PullUpP5(n) P5OUT|=n
#define PullDownP6(n) P6OUT&=(~n)
#define PullUpP6(n) P6OUT|=n
//------------------------IO bits Input-----------
#define P1Input(n) P1IN&n?1:0
#define P2Input(n) P2IN&n?1:0
#define P3Input(n) P3IN&n?1:0
#define P4Input(n) P4IN&n?1:0
#define P5Input(n) P5IN&n?1:0
#define P6Input(n) P6IN&n?1:0
//------------------------------------------------------------------------
#define DCO_F 12 //定义主时钟频率,1,8,12,16(MHZ)
#define _delay_us(n) __delay_cycles((float)(n)*DCO_F) //20us以下误差较大
#define _delay_ms(n) __delay_cycles(n*(1000.0f)*DCO_F)
//------------------------------------------------------------------------
#define delay_Tbuf __delay_cycles(76)//16MHZ,62.5ns*76=4.75us
#define delay_Thd __delay_cycles(5)//16MHZ,62.5ns*5=312.5ns
//----------------------------------------------------------------------------
void Init_CLK(unsigned char nDco);
#endif
#include "msp430_kyg.h"
#ifndef _MLX90615_H_
#define _MLX90615_H_
//-----------------------------------
#define mSDA_LOW() ClrP1(BIT3)
#define mSDA_HIGH() SetP1(BIT3)
#define mSCL_LOW() ClrP1(BIT6)
#define mSCL_HIGH() SetP1(BIT6)
#define mSDA_IN SetInP1(BIT3)
#define mSDA_OUT SetOutP1(BIT3)
#define mSCL_IN SetInP1(BIT6)
#define mSCL_OUT SetOutP1(BIT6)
#define ACK 0
#define NACK 1
//MLX90614 constants
#define SA 0x00 // Slave address
#define DEFAULT_SA 0x5a // Default Slave address
#define RAM_Access 0x00 //0x20 // RAM access command
#define EEPROM_Access 0x10 // EEPROM access command
#define RAM_To 0x07 // To address in the ram
//*PROTOTYPES**********************************************************************************
void START_bit(void);
void STOP_bit(void);
unsigned char TX_byte(unsigned char Tx_buffer);
unsigned char RX_byte(unsigned char ack_nack);
void send_bit(unsigned char bit_out);
unsigned char Receive_bit(void);
void MLX90615_init(void);
unsigned int MemRead(unsigned char SlaveAddress,unsigned char command);
void SendRequest(void);
void DummyCommand(unsigned char byte);
float CalcTemp(unsigned int value);
unsigned char PEC_calculation(unsigned char pec[]);
void Init_IIC(void);
#endif
此帖出自
小平头技术问答
一周热门 更多>