各位大神,求助啊,我没玩过I2C,这是我东拼西凑些的I2C从机代码,主要是完成和主机的通讯用的。但是先在问题出来了,代码运行时,主机向0xA0发送一个数据,
从机能进中断( I2C2_EV_IRQHandler)函数,在switch (I2C_Event)这一句时,I2C各个寄存器函数如下:
图片看不到.............算了,手打
I2C2_CR1 0x00000401
I2C2_CR2 0x00000624
I2C2_OAR1 0x000040A0
I2C2_OAR2 0
I2C2_DR 0
I2C2_SR1 0x00000110
I2C2_SR2 0
I2C2_CCR 0x0000801E
I2C2_TRISE 0x0000000B
[ 本帖最后由 lifeissweet66 于 2012-9-13 14:47 编辑 ]
谢谢,我还是手工吧,下面的是mian.c文件
[ 本帖最后由 lifeissweet66 于 2012-9-13 15:01 编辑 ]
回复 4楼 lifeissweet66 的帖子
图片不能复制,先下载再上传试试!
#include "includes.h"
/* Private typedef -----------------------------------------------------------*/
typedef enum
{
FAILED = 0,
PASSED = !FAILED
}TestStatus;
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
extern void RCC_Configuration(void);
extern void GPIO_Configuration(void);
extern void delay_ms(u16 nms);
extern void delay_init(u8 SYSCLK);
extern void NVIC_Configuration(void);
extern void LED_On(LED_STATE led_status);
void I2C_Comm_Init(u32 I2C_Speed, u16 I2C_Addr);
/* Private functions ---------------------------------------------------------*/
/**
* @brief Main program
* @param None
* @retval : None
*/
int main(void)
{
/********************初始化函数*********************************/
RCC_Configuration();
GPIO_Configuration();
I2C_Comm_Init(400000,0xa0);
delay_init(72);
while(1)
{
LED_On(LED1);
delay_ms(500);
LED_On(LED2);
delay_ms(500);
LED_On(LED3);
delay_ms(500);
LED_On(LED4);
delay_ms(500);
}
}
void I2C_Comm_Init(u32 I2C_Speed, u16 I2C_Addr)
{
/******* GPIO configuration and clock enable *********/
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10| GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/*********** I2C periphral configuration **********/
I2C_DeInit(I2C2);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; // fixed
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; // fixed
I2C_InitStructure.I2C_OwnAddress1 = I2C_Addr; // user parameter
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; // fixed
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = I2C_Speed; // user parameter
I2C_Cmd(I2C2, ENABLE);
I2C_Init(I2C2, &I2C_InitStructure);
I2C_ITConfig(I2C2, I2C_IT_EVT | I2C_IT_BUF, ENABLE);
/************** I2C NVIC configuration *************************/
/* 1 bit for pre-emption priority, 3 bits for subpriority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = I2C2_EV_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = I2C2_ER_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void I2C2_EV_IRQHandler(void)
{
uint32_t I2C_Event;
int i=0;
i++;
if(i==2)
{
i=0;
}
I2C_Event = I2C_GetLastEvent(I2C2);
switch (I2C_Event)
{
//case 0x20002:
//while(1);
case 0x20401:
while(1);
case 0x20624:
while(1);
case 0x20000:
while(1);
case 0x20328:
while(1);
case 0x20025:
while(1);
case 0x240A0:
while(1);
case 0x20110:
while(1);
case 0x00110:
while(1);
/***********************slave receiver**************************************/
case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: /* EV1 */
I2C_ITConfig(I2C2, I2C_IT_BUF , ENABLE); // also allow RxNE
break;
case I2C_EVENT_SLAVE_BYTE_RECEIVED: /* EV2 */
/* Store I2C1 received data */
*pRxBuffer++ = I2C_ReceiveData(I2C2);
RxLength--;
if (RxLength == 0)
{
//SlaveReceptionComplete = 1;
I2C_ITConfig(I2C2, I2C_IT_BUF , DISABLE); // only EVT(STOPF) int
I2C_ITConfig(I2C2, I2C_IT_EVT , ENABLE);
}
break;
case I2C_EVENT_SLAVE_STOP_DETECTED: /* EV4 */
/* Clear I2C1 STOPF flag: read of I2C_SR1 followed by a write on I2C_CR1 */
(void)(I2C_GetITStatus(I2C2, I2C_IT_STOPF));
I2C_Cmd(I2C2, ENABLE);
// i2c_comm_state = COMM_DONE;
I2C_ITConfig(I2C2, I2C_IT_EVT, DISABLE);
break;
case 0x20050:
// used when Rx and Tx handley by one mcu at the same time
// receive last data and clear stopf
// BUSY+RxNE+STOP
*pRxBuffer++ = I2C_ReceiveData(I2C2);
RxLength--;
//SlaveReceptionComplete = 1;
(void)(I2C_GetITStatus(I2C2, I2C_IT_STOPF));
I2C_Cmd(I2C2, ENABLE);
I2C_ITConfig(I2C2, I2C_IT_EVT | I2C_IT_BUF, DISABLE);
I2C_ITConfig(I2C2, I2C_IT_BUF , DISABLE);
break;
case 0x20010:
// busy+stopf
// when last data read isr exist, there would be stopf flag
//which is set during read ISR. and as sender's check begin
// busy also set
// i2c_comm_state = CHECK_IN_PROCESS;
(void)(I2C_GetITStatus(I2C2, I2C_IT_STOPF));
I2C_Cmd(I2C2, ENABLE);
break;
default:
break;
/***********************slave t**************************************/
case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED: // EV1
// i2c_comm_state = COMM_IN_PROCESS;
I2C_SendData(I2C2, *pTxBuffer++);
TxLength--;
I2C_ITConfig(I2C2, I2C_IT_BUF , ENABLE); // also allow RxNE
break;
case I2C_EVENT_SLAVE_BYTE_TRANSMITTED: // EV3
//TRA, BUSY, TXE and BTF 0x60084
if (TxLength>0)
{
I2C_SendData(I2C2, *pTxBuffer++);
TxLength--;
}
break;
case 0x60080:
// TRA, BUSY,TXE, no BTF
// if this case added, above case would never be reached
if (TxLength>0)
{
I2C_SendData(I2C2, *pTxBuffer++);
TxLength--;
if (TxLength ==0)
{
//SlaveTransitionComplete =1;
// i2c_comm_state = COMM_DONE;
I2C_ITConfig(I2C2, I2C_IT_BUF , DISABLE);//close TxE int
I2C_ITConfig(I2C2, I2C_IT_ERR , ENABLE);//to handle AF from master receiver
//PV_flag_2 = 0;
}
}
break;
}
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval : None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
while (1)
{}
}
#endif
/**
* @}
*/
/**
* @}
*/
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
关于主函数我说明下,在 I2C2_EV_IRQHandler中最前面几个case是我测试最后进入哪儿用的,经测试,每次都是死在case 0x20110上,然后我返回去进入I2C_GetLastEvent(I2C2)中计算了下:
他有三个标志位:flag1,flag2,lastevent
flag1 = I2C->SR1
flag2 = I2C ->SR2
flag2 = flag2 << 16
lastevent = (flag1 | flag2 ) & 0x1F
return lastevent;
把最上面的寄存器值代入我计算了下lastevent = 0x20110
这是我的文件目录,关于I2C的都写在main.c中