void main(void) { /* Infinite loop */ CLK_LSICmd(ENABLE);//使能LSI CLK_SYSCLKSourceConfig(CLK_SYSCLKSource_LSI);//RTC时钟源LSI,1分频=38K while (CLK_GetFlagStatus(CLK_FLAG_LSIRDY) == RESET);//等待LSI就绪 CLK_PeripheralClockConfig(CLK_Peripheral_I2C1, ENABLE); I2C_DeInit(I2C1); I2C_Init(I2C1, 4000, 0x51,I2C_Mode_I2C, I2C_DutyCycle_2,I2C_Ack_Enable, I2C_AcknowledgedAddress_7bit); /* Enable Error Interrupt*/ I2C_ITConfig(I2C1, (I2C_IT_TypeDef)(I2C_IT_ERR | I2C_IT_EVT | I2C_IT_BUF), ENABLE); USART_DeInit(USART1); CLK_PeripheralClockConfig (CLK_Peripheral_USART1,ENABLE);//开启USART时钟 USART_Init(USART1,9600,USART_WordLength_8b,USART_StopBits_1,USART_Parity_No,(USART_Mode_TypeDef)USART_Mode_Tx|USART_Mode_Rx);//设置USART参数9600,8N1,接收/发送 USART_Cmd (USART1,ENABLE); enableInterrupts();//使能中断 while (1) { } } INTERRUPT_HANDLER(I2C1_SPI2_IRQHandler,29) { /* In order to detect unexpected events during development, it is recommended to set a breakpoint on the following instruction. */ u8 temp = 0; if (I2C1->SR1&0x02)//地址已经匹配(读SR1,SR3清除该位) { I2C_GetITStatus(I2C1,I2C_IT_ADDR); temp = I2C1->SR3&0x07; USART1_SendStr("匹配地址\n"); } else if ((I2C1->SR1&0x84)&&(I2C1->SR3&0x04))//数据字节传送完 { I2C_GetITStatus(I2C1,I2C_IT_BTF); temp = 0xA0; //假设这里发送0xA5 I2C1->DR = temp; I2C_GenerateSTOP(I2C1,ENABLE); USART1_SendStr("数据发完 等待发送\n"); } else if ((I2C1->SR1&0x40)&&(0 == (I2C1->SR3&0x04)))//接收时数据寄存器 { temp = I2C1->DR; //读取数据寄存器 USART_SendData8(USART1,temp); USART1_SendStr("数据发完 等待读取\n"); } else if (I2C1->SR1&0x10)//检测到停止位 { I2C1->CR2 = I2C1->CR2;//清除停止位 I2C_GenerateSTOP(I2C1,ENABLE); USART1_SendStr("检测到停止位\n"); } //错误处理 if (I2C1->SR2&0x01)//总线错误 { I2C1->SR2 &= ~0x01;//清零 USART1_SendStr("总线错误\n"); } else if(I2C1->SR2&0x02)//仲裁失败 { I2C1->SR2 &= ~0x02;//清零 USART1_SendStr("仲裁失败\n"); } else if(I2C1->SR2&0x04)//应答失败 { I2C1->SR2 &= ~0x04;//清零 USART1_SendStr("应答失败\n"); } else if(I2C1->SR2&0x08)//上溢、下溢 { I2C1->SR2 &= ~0x08;//清零 USART1_SendStr("上溢下溢\n"); } USART1_SendStr("中断结束\n"); return; } |
时序问题居多。IIC不建议用自带的。协议兼容性差。看半天规格书,不如重写个IO模拟的。