|
MSP430 硬件I2C 中断法始终调不通,求助!!!
[复制链接]
MSP430F5x单片机硬件I2C通过中断的方式对AT24C02进行读写
代码如下:
- #include "msp430.h"
- typedef unsigned char uint8;
- uint8 test_buf1[10] = {'H','E','L','L','O','Y','O','U',0,0};
- uint8 test_buf2[10] = {0,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));
- }
- if(I2C_State==0)
- {
- UCB0TXBUF = *I2C_Tx_Buffer; // Load TX buffer
- while(!(UCB0IFG & UCTXIFG)); // wait UCTXIFG=1
- UCB0IE &= ~UCTXIE;
- UCB0CTL1 |= UCTXSTP; // I2C stop condition
- __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
- }
- // Clear USCI_B0 TX int flag
- __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
- break;
- default:
- break;
- }
- }
- void main()
- {
- uint8 I2C_SUCCESS_FLAG=0;
- WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
- GPIO_Init();
- LED_ON();
- CLK_Init();
- UCB0_I2C_Init();
- delay_ms(20);
- I2C_Write_Byte(0x00,test_byte1);
- I2C_Read_Byte(0x00,&test_byte2);
- if((test_buf1[0]==test_buf2[0])&&(test_buf1[1]==test_buf2[1]))
- I2C_SUCCESS_FLAG=1;
- }
复制代码
等待法已经调试成功了,说明AT24C02没有问题,求助各位帮忙看看这个程序有什么问题,谢谢!
|
|