工具与软件:
我是嵌入式编程新手、并且在 通过 I2C 连接两个 EK-TM4C123GXL 板来使 LED 闪烁时遇到问题。 I2C0引脚上连接了两个电路板、并且初始化已完成。 为了确认主板发送横截面、代码正在检查 BUSY 位的状态(而环路代码行) 98 )。 在调试时、我发现繁忙位永远不会变为0、因此代码停留在无限 while 循环中。 有人能帮忙吗?
主代码-
#include "TM4C123.h" // Device header
#include <stdio.h>
void I2C_Init(void);
void I2C0_Send(uint8_t slave_addr, char data);
void PORTF_Init(void);
void delay(void);
char I2C0_Recieve(uint8_t slave_addr);
#define RCGCI2C (((volatile unsigned long)(0x400FE000+0x620)))
#define RCGCGPIO (((volatile unsigned long)(0x400FE000+0x608)))
//PB2->SCL AND PB3->SDA
#define PORTB_BASE 0x40005000
#define PORTB_AFSEL_R (((volatile unsigned long) (PORTB_BASE + 0x420)))
#define PORTB_PCTL_R (((volatile unsigned long) (PORTB_BASE + 0x52C)))
#define PORTB_DIR_R (((volatile unsigned long) (PORTB_BASE + 0x400)))
#define PORTB_DEN_R (((volatile unsigned long) (PORTB_BASE + 0x51C)))
#define PORTB_DATA_R (((volatile unsigned long) (PORTB_BASE + 0x3FC)))
#define PORTB_AMSEL_R (((volatile unsigned long) (PORTB_BASE + 0x528)))
#define PORTB_ODR_R (((volatile unsigned long) (PORTB_BASE + 0x50C)))
#define I2C0_BASE (0x40020000)
#define I2C_MSA_R (((volatile unsigned long) (I2C0_BASE + 0x00)))
#define I2C_MCS_R_R (((volatile unsigned long) (I2C0_BASE + 0x004)))
#define I2C_MCS_W_R (((volatile unsigned long) (I2C0_BASE + 0x004)))
#define I2C_MDR_R (((volatile unsigned long) (I2C0_BASE + 0x008)))
#define I2C_MTPR_R (((volatile unsigned long) (I2C0_BASE + 0x00C)))
#define I2C_MCR_R (((volatile unsigned long) (I2C0_BASE + 0x020)))
#define I2C_MBMON_R (((volatile unsigned long) (I2C0_BASE + 0x02C)))
//#define I2C_SOAR_R (((volatile unsigned long) (I2C0_BASE + 0x00C)))
#define PORTF_BASE 0x40025000
#define PORTF_DIR_R (((volatile unsigned long) (PORTF_BASE + 0x400)))
#define PORTF_DEN_R (((volatile unsigned long) (PORTF_BASE + 0x51C)))
#define PORTF_DATA_R (((volatile unsigned long) (PORTF_BASE + 0x3FC)))
#define PORTF_AFSEL_R (((volatile unsigned long) (PORTF_BASE + 0x420)))
#define PORTF_PCTL_R (((volatile unsigned long) (PORTF_BASE + 0x52C)))
#define PORTF_AMSEL_R (((volatile unsigned long) (PORTF_BASE + 0x528)))
int main(){
char arr[3]={'G','B','G'};
I2C_Init();
PORTF_Init();
uint8_t ad=0x2C;
int i=0;
while(1){
I2C0_Send(ad,arr[i]);
char data=I2C0_Recieve(ad);
if (data == 'R') {
PORTF_DATA_R = 0x02; // Red LED on PF1
} else if (data == 'G') {
PORTF_DATA_R = 0x08; // Green LED on PF3
} else if (data == 'B') {
PORTF_DATA_R = 0x04; // Blue LED on PF2
}
i =i+1;
if(i==3)
i=0;
delay();
}
}
void I2C_Init(void){
RCGCI2C|=0x01;
RCGCGPIO|=0x02;
PORTB_AFSEL_R|=0x0C;
PORTB_ODR_R|=0x08;//open drain for data line
PORTB_DEN_R|=0x0C;
PORTB_PCTL_R|=0x3300;
PORTB_AMSEL_R&=~0x0C;
I2C_MCR_R=0x10;
I2C_MTPR_R=7;//SET CLOCK 100KBPS
}
void PORTF_Init(void) {
RCGCGPIO |= 0x20; // enable GPIO Port F clock
PORTF_DIR_R = 0x0E; // PF1, PF2, and PF3 as output (LEDs)
PORTF_DEN_R |= 0x0E; // digital enable PF1, PF2, and PF3
PORTF_AFSEL_R &=~0x0E; // disable alternate function
PORTF_PCTL_R &=~0xFFF0; // configure as GPIO
PORTF_AMSEL_R &= ~0x0E; // disable analog function
}
void I2C0_Send(uint8_t slave_addr, char data) {
while(I2C_MCS_R_R&0x01){};//wait unitt i2c0 is busy
I2C_MSA_R = (slave_addr<<1)&0xFE; // Set slave address
I2C_MSA_R&=~0x01;//specify a write operation
I2C_MDR_R = data&0xFF;
I2C_MCS_W_R = 0x07; // Start, Run, and Stop conditions
while (I2C_MCS_R_R& 0x01==1) {}; // Wait for the transmission to complete
// I2C_MCS_R_R&(0x0D);
}
char I2C0_Recieve(uint8_t slave_addr){
while(I2C_MCS_R_R&0x01){};//wait unitt i2c0 is busy
I2C_MSA_R = (slave_addr<<1)&0xFE; // Set slave address
I2C_MSA_R|=0x01;//specify a read operation
I2C_MCS_W_R = 0x07; // Start, Run, and Stop conditions
while (I2C_MCS_R_R& 0x01) {};//busy bit
return (char)I2C_MDR_R & (0xFF);
}
void delay(void) {
unsigned long i = 8000000;
while (i > 0) {
i--;
}
}
从机代码-
#include "TM4C123.h" // Device header
#include <stdio.h>
void I2C_Init(void);
void slave_Send(char data);
void PORTF_Init(void);
void delay(void);
char slave_Recieve(void);
#define RCGCI2C (((volatile unsigned long)(0x400FE000+0x620)))
#define RCGCGPIO (((volatile unsigned long)(0x400FE000+0x608)))
//PB2->SCL AND PB3->SDA
#define PORTB_BASE 0x40005000
#define PORTB_AFSEL_R (((volatile unsigned long) (PORTB_BASE + 0x420)))
#define PORTB_PCTL_R (((volatile unsigned long) (PORTB_BASE + 0x52C)))
#define PORTB_DIR_R (((volatile unsigned long) (PORTB_BASE + 0x400)))
#define PORTB_DEN_R (((volatile unsigned long) (PORTB_BASE + 0x51C)))
#define PORTB_DATA_R (((volatile unsigned long) (PORTB_BASE + 0x3FC)))
#define PORTB_AMSEL_R (((volatile unsigned long) (PORTB_BASE + 0x528)))
#define PORTB_ODR_R (((volatile unsigned long) (PORTB_BASE + 0x50C)))
#define I2C0_BASE (0x40020000)
#define I2C_SOAR_R (((volatile unsigned long) (I2C0_BASE + 0x800)))
#define I2C_SCS_R_R (((volatile unsigned long) (I2C0_BASE + 0x804)))
#define I2C_SCS_W_R (((volatile unsigned long) (I2C0_BASE + 0x804)))
#define I2C_SDR_R (((volatile unsigned long) (I2C0_BASE + 0x808)))
#define I2C_MCR_R (((volatile unsigned long) (I2C0_BASE + 0x020)))
#define PORTF_BASE 0x40025000
#define PORTF_DIR_R (((volatile unsigned long) (PORTF_BASE + 0x400)))
#define PORTF_DEN_R (((volatile unsigned long) (PORTF_BASE + 0x51C)))
#define PORTF_DATA_R (((volatile unsigned long) (PORTF_BASE + 0x3FC)))
#define PORTF_AFSEL_R (((volatile unsigned long) (PORTF_BASE + 0x420)))
#define PORTF_PCTL_R (((volatile unsigned long) (PORTF_BASE + 0x52C)))
#define PORTF_AMSEL_R (((volatile unsigned long) (PORTF_BASE + 0x528)))
int main(){
char arr[3]={'G','B','R'};
I2C_Init();
PORTF_Init();
int i=0;
PORTF_DATA_R=0;
while(1){
char data=slave_Recieve();
if (data == 'R') {
PORTF_DATA_R = 0x02; // Red LED on PF1
} else if (data == 'G') {
PORTF_DATA_R = 0x08; // Green LED on PF3
} else if (data == 'B') {
PORTF_DATA_R = 0x04; // Blue LED on PF2
}
slave_Send(arr[i]);
i =i+1;
if(i==3)
i=0;
}
}
void I2C_Init(void){
RCGCI2C|=0x01;
RCGCGPIO|=0x02;
PORTB_AFSEL_R|=0x0C;
PORTB_ODR_R|=0x08;
PORTB_DEN_R|=0x0C;
PORTB_PCTL_R|=0x3300;
I2C_MCR_R=0x20;//slave mode is on
I2C_SOAR_R=0x2C;//setting its address
I2C_SCS_W_R=0x01;//enable slave
}
void PORTF_Init(void) {
RCGCGPIO |= 0x20; // enable GPIO Port F clock
PORTF_DIR_R = 0x0E; // PF1, PF2, and PF3 as output (LEDs)
PORTF_DEN_R |= 0x0E; // digital enable PF1, PF2, and PF3
PORTF_AFSEL_R &=~0x0E; // disable alternate function
PORTF_PCTL_R &=~0xFFF0; // configure as GPIO
PORTF_AMSEL_R &= ~0x0E; // disable analog function
}
void slave_Send( char data) {
while(I2C_SCS_R_R&0x02==0){}//wait unittl MASTER IS NOT READY
I2C_SDR_R=data;
}
char slave_Recieve(void){
while(I2C_SCS_R_R&0x01==0){}//wait while data is not sned
return (char) I2C_SDR_R&0xFF;
}
void delay(void) {
unsigned long i = 8000000;
while (i > 0) {
i--;
}
}