如题,lm3s9b96做一个I2C从机,为什么一连上8051(主机)时,SCL,SDA的信号都没了,SCL被拉高,SDA被拉低了。然后从机就时钟不能进入中断函数了。
而反过来lm3s9b96做主机,8051做主机,一切都正常的,这是为什么呢?哪儿设置有问题吗?请教前辈们!谢谢!程序如下:
#include "inc/hw_i2c.h"
#include "inc/hw_ints.h"
#include "inc/hw_gpio.h"
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/i2c.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "driverlib/interrupt.h"
#include "inc/lm3s9b96.h"
#include "driverlib/uart.h"
//#include "uartstdio.c"
#define SLAVE_ADDRESS 0x00
#define LED_ON 0x00
#define LED_OFF GPIO_PIN_3
#define LED_FLASH 0x02
volatile unsigned char g_ucDataRx = LED_ON;
volatile unsigned long ulStatus = 0;
unsigned long c;
void delay(void){
for(c= 0xFFFFF ; c > 0; c--);
}
void Uart_Init(void);
void I2C1_Init(void);
void Port_Init(void);
void I2C1SlaveIntHandler(void);
int main(void){
// 运行在外部晶振16MHz
SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_16MHZ);
Port_Init();
Uart_Init();
I2C1_Init();
IntEnable(INT_I2C1);// 开启I2C1的中断
IntMasterEnable(); // 开启总中断
}
///////////////////////////////////////////////////////////////////////////////////////////
void I2C1SlaveIntHandler(void){
//
// 清除中断
//
I2CSlaveIntClear(I2C1_SLAVE_BASE);
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, LED_ON);
//
// 读取中断状态
//
ulStatus = I2CSlaveStatus(I2C1_SLAVE_BASE);
//
// 屏蔽不需要的位
//
ulStatus = ulStatus & (I2C_SLAVE_CSR_RREQ | I2C_SLAVE_CSR_TREQ | I2C_SLAVE_CSR_FBR);
//
// 判断状态
//
switch(ulStatus){
//
// 有发送请求,从发送
// 无论什么请求都发送0xAA
//
case I2C_SLAVE_CSR_TREQ:
I2CSlaveDataPut(I2C1_SLAVE_BASE , 0xaa);
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, LED_ON);
break;
//
// 有读取请求,从接收
//
case I2C_SLAVE_CSR_RREQ:
g_ucDataRx = I2CSlaveDataGet(I2C1_SLAVE_BASE);
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, LED_ON);
break;
//
// 接受到第一个字节
// 第一个字节是地址
//
case (I2C_SLAVE_CSR_RREQ | I2C_SLAVE_CSR_FBR):
g_ucDataRx = I2CSlaveDataGet(I2C1_SLAVE_BASE);
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, LED_ON);
break;
default:
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, LED_ON);
;
}
}
void Port_Init(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); // 使能PORTF的时钟
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_3); // 配置并熄灭LED1
GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3, GPIO_PIN_3); // 关闭Test_Led
}
void Uart_Init(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
// Configure the GPIO pin muxing for the UART function.
// This is only necessary if your part supports GPIO pin function muxing.
// Study the data sheet to see which functions are allocated per pin.
// TODO: change this to select the port/pin you are using
GPIOPinConfigure(GPIO_PD2_U1RX);
GPIOPinConfigure(GPIO_PD3_U1TX);
// Since GPIO A0 and A1 are used for the UART function, they must be
// configured for use as a peripheral function (instead of GPIO).
// TODO: change this to match the port/pin you are using
GPIOPinTypeUART(GPIO_PORTD_BASE, GPIO_PIN_2 | GPIO_PIN_3);
//
// Configure the UART for 115,200, 8-N-1 operation.
// This function uses SysCtlClockGet() to get the system clock
// frequency. This could be also be a variable or hard coded value
// instead of a function call.
//
UARTConfigSetExpClk(UART1_BASE, SysCtlClockGet(), 115200,
(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE));
//
// Put a character to show start of example. This will display on the
// terminal.
//
UARTCharPut(UART1_BASE, '!');
}
void I2C1_Init(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1); // 使能I2C1的时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // 使能I2C1相应的引脚时钟
GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7); // 配置PA6和PA7引脚的类型
GPIOPinConfigure(GPIO_PA6_I2C1SCL);//bule // 配置PA0和PA1为SCL和SDA
GPIOPinConfigure(GPIO_PA7_I2C1SDA);//yellow
I2CSlaveInit(I2C1_SLAVE_BASE, SLAVE_ADDRESS); // 设置本身地址
I2CSlaveEnable(I2C1_SLAVE_BASE); // 使能I2C模块
I2CSlaveIntEnableEx(I2C1_SLAVE_BASE,I2C_SLAVE_INT_DATA|I2C_SLAVE_INT_START|I2C_SLAVE_INT_STOP);//中断条件选择
I2CSlaveIntEnable(I2C1_SLAVE_BASE); // 使能从机中断源
// I2CIntRegister(I2C1_SLAVE_BASE,I2C1SlaveIntHandler);//注册中断
//GPIO_PORTA_ODR_R &= GPIO_PIN_6;//开漏
// GPIO_PORTA_ODR_R &= GPIO_PIN_7;
// GPIO_PORTA_PUR_R |= GPIO_PIN_6;//上拉
//GPIO_PORTA_PUR_R |= GPIO_PIN_7;
// GPIO_PORTA_DR2R_R |= GPIO_PIN_6; //驱动电流2ma
// GPIO_PORTA_DR2R_R |= GPIO_PIN_7;
// Set GPIO Pins for Open-Drain operation
// GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_6, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_OD);
// GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_7, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_OD);
// Give control to the I2C Module
// GPIODirModeSet(GPIO_PORTA_BASE, GPIO_PIN_6, GPIO_DIR_MODE_HW);
// GPIODirModeSet(GPIO_PORTA_BASE, GPIO_PIN_7, GPIO_DIR_MODE_HW);
}
#if 0
while(1){
switch(g_ucDataRx){
case LED_ON:
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, LED_ON);
break;
case LED_OFF:
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, LED_OFF);
break;
case LED_FLASH:
default:
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3,
GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_3) ^ GPIO_PIN_3);
delay();
}
}
#endif