CC430F5x单片机硬件I2C通过中断的方式对AT24C02进行读写,始终调不通,程序如下,请各位帮忙看看
#include "msp430.h"
typedef unsigned char uint8;
uint8 test_buf1[8] = {'H','E','L','L','O','Y','O','U'};
uint8 test_buf2[8] = {0,0,0,0,0,0,0,0};
uint8 test_byte1 = 0x0c;
uint8 test_byte2 = 0x00;
//UCB0---I2C
uint8 I2C_Tx_Size = 0; //left data to be sent
uint8 I2C_Rx_Size = 0; //left data to be received
uint8 *I2C_Tx_Buffer; //pointer of data to be sent
uint8 *I2C_Rx_Buffer; //pointer of data to be received
uint8 I2C_State = 0; //flag of I2C tranmit or receive state
uint8 I2C_Read_Data_Address = 0;
uint8 I2C_Write_Data_Address = 0;
uint8 UCB0_Rx_Or_Tx = 0; // 0--Receive only; 1--Transmit only; 2--Receive and transmit
uint8 Flag_ACK=1;
uint8 Flag_I2C_Address_Transmitted=0;
#define EEPROM_SCL BIT2 //P1.2
#define EEPROM_SDA BIT3 //P1.3
#define ADG841_IN1 BIT7 //P3.7
#define LED BIT1 //P3.1
#define I2C_SLAVE_ADDR 0x50
//Delay
#define CPU_F ((double)26000000) //XT2CLK--26MHz
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
void UCB0_Interrupt_Sel(uint8);
void CLK_Init()
{
UCSCTL6 &= ~(XT2OFF+XT1OFF); // Enable XT2--26MHz XT1--32.768kHz
UCSCTL4 = SELA_0 + SELS_5 + SELM_5;
UCSCTL5 = DIVM_0 | DIVS_0 | DIVA_0;
/*
do
{
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
// Clear XT2,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
}while (SFRIFG1&OFIFG); // Test oscillator fault flag
*/
UCSCTL4 = SELA_0 + SELS_5 + SELM_5;
}
void GPIO_Init()
{
P3DIR |= LED + ADG841_IN1;
P5SEL |= BIT0 + BIT1; //Port select XT1
}
void LED_ON()
{
P3OUT |= LED;
}
void LED_OFF()
{
P3OUT &= ~LED;
}
void UCB0_I2C_Init()
{
P1SEL |= EEPROM_SCL + EEPROM_SDA;
/* Disable USCI */
UCB0CTL1 |= UCSWRST;
//UCB0CTL0 &= ~UCSLA10;////
UCB0CTL0 = UCMST | UCMODE_3 | UCSYNC; //I2C, Mater mode, Synchronous mode
UCB0CTL1 = UCSSEL_2 | UCSWRST;
/* I2C Slave Address Register */
UCB0I2CSA = I2C_SLAVE_ADDR;
/* Bit Rate Control Register 0 */
UCB0BR0 = 4; // 26MHz/260=100KHz
UCB0BR1 = 1;
/* Enable USCI */
UCB0CTL1 &= ~UCSWRST;
P3OUT |= ADG841_IN1;
}
uint8 I2C_Write_Page(uint8 Data_Address, uint8 *pBuffer, uint8 size)
{
if(size==0)
return 0;
if(UCB0STAT & UCBUSY) //If I2C is busy
return 0;
Flag_I2C_Address_Transmitted=0;
I2C_Write_Data_Address=Data_Address;
I2C_Tx_Buffer=pBuffer;
//I2C_Tx_Size=size-1;
I2C_Tx_Size=size;
//_EINT();
UCB0IFG &= ~UCTXIFG;
UCB0_Rx_Or_Tx = 1; //transmit interrupt only
UCB0_Interrupt_Sel(UCB0_Rx_Or_Tx);
_EINT();
while( UCB0CTL1& UCTXSTP );
UCB0CTL1 |= UCTR+UCTXSTT; //write mode, send start bit
__bis_SR_register(LPM0_bits); // Enter LPM0
return 1;
}
uint8 I2C_Read_Page(uint8 Read_Data_Address, uint8 *pbuffer, uint8 size)
{
_DINT();
if(size==0)
return 0;
if(UCB0STAT & UCBUSY) //If I2C is busy
return 0;
I2C_Read_Data_Address=Read_Data_Address; // set address
Flag_I2C_Address_Transmitted=0;
I2C_Tx_Size=0;
/*
UCB0_Rx_Or_Tx = 1; //enable transmit interrupt bit only
_EINT();
UCB0_Interrupt_Sel(UCB0_Rx_Or_Tx);
*/
while( UCB0CTL1& UCTXSTP );
UCB0CTL1 |= UCTR; //write mode
UCB0CTL1 |= UCTXSTT; //send start bit
//UCB0TXBUF = E2PROM_WRITE_CMD;
if(Flag_I2C_Address_Transmitted==0)
{
Flag_I2C_Address_Transmitted=1;
UCB0TXBUF = I2C_Read_Data_Address; //write data address
}
I2C_Rx_Buffer = pbuffer;
//I2C_Rx_Size = size-1; //Number of data to be received
I2C_Rx_Size = size;
UCB0IFG &= ~UCRXIFG;
UCB0_Rx_Or_Tx=0;
UCB0_Interrupt_Sel(UCB0_Rx_Or_Tx);
_EINT();
while( UCB0CTL1& UCTXSTP );
//delay_ms(5);
UCB0CTL1 &= ~UCTR; //read mode
//UCB0IFG &= ~UCRXIFG; // clear interrupt flag
UCB0CTL1 |= UCTXSTT; //send start bit
__bis_SR_register(LPM0_bits); // Enter LPM0, enable interrupts
return 0;
}
void UCB0_Interrupt_Sel(uint8 onOff)
{
if(onOff == 0) //Only receive interrupt enabled
{
UCB0IE &=~UCTXIE; // Disable USCI_B0 TX interrupt
UCB0IE |= UCRXIE; // Enable USCI_B0 RX interrupt
}
else if(onOff==1) //Only transmit interrupt enabled
{
UCB0IE &=~UCRXIE; // Disable USCI_B0 RX interrupt
UCB0IE |= UCTXIE; // Enable USCI_B0 TX interrupt
}
else //Both receive and transmit interrupt enabled
{
UCB0IE |= UCTXIE; // Enable USCI_B0 TX interrupt
UCB0IE |= UCRXIE; // Enable USCI_B0 RX interrupt
}
}
void I2C_Write_Byte(uint8 data_addr, uint8 data_value)
{
while(UCB0STAT & UCBUSY); //If I2C is busy
Flag_I2C_Address_Transmitted=0;
I2C_Write_Data_Address=data_addr;
I2C_Tx_Buffer=&data_value;
//UCB0IFG &= ~UCTXIFG;
UCB0_Rx_Or_Tx = 1; //transmit interrupt only
while( UCB0CTL1& UCTXSTP );
UCB0CTL1 |= UCTR+UCTXSTT; //write mode, send start bit
UCB0_Interrupt_Sel(UCB0_Rx_Or_Tx);
_EINT();
__bis_SR_register(LPM0_bits); // Enter LPM0
}
void I2C_Read_Byte(uint8 data_addr, uint8 * data_value)
{
//_DINT();
I2C_State=1;
while(UCB0STAT & UCBUSY); //If I2C is busy
I2C_Read_Data_Address=data_addr; // set address
Flag_I2C_Address_Transmitted=0;
I2C_Rx_Buffer = data_value;
while( UCB0CTL1& UCTXSTP );
UCB0CTL1 |= UCTR; //write mode
UCB0CTL1 |= UCTXSTT; //send start bit
UCB0IE |= UCTXIE;
UCB0_Rx_Or_Tx=0;
UCB0_Interrupt_Sel(UCB0_Rx_Or_Tx);
/*
if(Flag_I2C_Address_Transmitted==0)
{
Flag_I2C_Address_Transmitted=1;
UCB0TXBUF = I2C_Read_Data_Address; //write data address
}
*/
UCB0IFG &= ~UCTXIFG;
_EINT();
while( UCB0CTL1& UCTXSTP );
UCB0CTL1 &= ~UCTR; //read mode
UCB0CTL1 |= UCTXSTT; //send start bit
__bis_SR_register(LPM0_bits); // Enter LPM0, enable interrupts
}
#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
{
//_DINT();
switch(__even_in_range(UCB0IV,12))
{
case 0: // no interrupt
break;
case 2: // ALIFG
break;
case 4: // NACKIFG
break;
case 6: // STTIFG
break;
case 8: // STPIFG
break;
case 10: // RXIFG
UCB0CTL1 |= UCTXSTP; // Generate I2C stop condition
*I2C_Rx_Buffer = UCB0RXBUF; // Move final RX data to PRxData
__bic_SR_register_on_exit(LPM0_bits); // Exit active CPU
break;
case 12: // TXIFG
if(Flag_I2C_Address_Transmitted==0)
{
UCB0TXBUF = I2C_Write_Data_Address; //write data address
Flag_I2C_Address_Transmitted=1;
/*
while(!(UCB0IFG & UCTXIFG))
{
UCB0IE &= ~UCTXIE;
UCB0IFG &= ~UCTXIFG;
}
*/
}
if(I2C_State==0)
{
UCB0TXBUF = *I2C_Tx_Buffer; // Load TX buffer
/*
while(!(UCB0IFG & UCTXIFG)) // wait UCTXIFG=1
{
UCB0IE &= ~UCTXIE;
UCB0IFG &= ~UCTXIFG;
}
*/
UCB0IE &= ~UCTXIE;
UCB0CTL1 |= UCTXSTP; // I2C stop condition
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
}
// Clear USCI_B0 TX int flag
break;
default:
break;
}
}
void main()
{
uint8 I2C_SUCCESS_FLAG=0;
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
CLK_Init();
GPIO_Init();
LED_ON();
UCB0_I2C_Init();
delay_ms(20);
I2C_Write_Byte(0x00,test_byte1);
I2C_Read_Byte(0x00,&test_byte2);
if(test_byte1==test_byte2)
I2C_SUCCESS_FLAG=1;
}
等待法已经调试成功了,说明AT24C02没有问题,求助各位帮忙看看这个程序有什么问题,谢谢!