最近一段时间在做I2C通信协议,需要在两块STM32之间做I2C通信,定的是主机用IO口模拟,从机用的是STM32的硬件I2C,我的项目要求是需要主从机之间能够进行一串数据收发而不出错,实验时在主机方面,利用IO口模拟主机,只需要理解时序就够了,同时将速度能够控制在100K(标准)左右,基本的时序理解网上大把的资料,所以主机这一块几个小时就搞定了,而在做从机时,遇到了困难,本来从机也想用IO口模拟的,但是速度达不到那么快,因此只能选择硬件做从机,现就从机用中断方式开说,总结过程中遇到的几点问题:
1、由于STM32的硬件问题,建议在使用I2C时,将其优先级设为最高。
2、针对程序中除了I2C数据收发,还有别的中断程序或者指令要执行而导致I2C数据传输堵塞时,可以在执行完该段程序后重新初始化I2C。
主机程序如下:
1 #include "Hal_IIC/I2C.h" 2 #include "Hal_delay/delay.h" 3 #include "common.h" 4 #include "gizwits_product.h" 5 6 extern void delayUs(uint32_t nus); 7 uint8_t b[5]; 8 extern uint8_t Cookr[5]; 9 extern uint8_t WR_flag; 10 uint8_t Wifi_SET; //WIFI状态脚 11 extern uint8_t Power_flag; //电磁炉开启关闭标志位 12 uint8_t Give_Up; 13 /*-------------------------------------------------------------------------------- 14 调用方式:void IIC_Init(void) 15 函数说明:私有函数,I2C专用,函数初始化 16 ---------------------------------------------------------------------------------*/ 17 void IIC_Init(void) 18 { 19 GPIO_InitTypeDef GPIO_InitStructure; 20 RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE ); //使能GPIOA时钟 21 22 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12; 23 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出 24 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 25 GPIO_Init(GPIOA, &GPIO_InitStructure); 26 GPIO_SetBits(GPIOA,GPIO_Pin_11|GPIO_Pin_12); //PA11,PA12 输出高 27 } 28 /*-------------------------------------------------------------------------------- 29 调用方式:void I2CStart(void) 30 函数说明:私有函数,I2C专用,开始信号 31 ---------------------------------------------------------------------------------*/ 32 void IIC_Start(void) 33 { 34 SDA_OUT(); //sda线输出 35 IIC_SDA=1; 36 IIC_SCL=1; 37 delayUs(4); 38 IIC_SDA=0;//START:when CLK is high,DATA change form high to low 39 delayUs(4); 40 IIC_SCL=0; //钳住I2C总线,准备发送或接收数据 41 } 42 /*-------------------------------------------------------------------------------- 43 调用方式:void I2CStop(void) 44 函数说明:私有函数,I2C专用,停止信号 45 ---------------------------------------------------------------------------------*/ 46 void IIC_Stop(void) 47 { 48 SDA_OUT();//sda线输出 49 IIC_SCL=0; 50 IIC_SDA=0;//STOP:when CLK is high DATA change form low to high 51 delayUs(4); 52 IIC_SCL=1; 53 IIC_SDA=1;//发送I2C总线结束信号 54 delayUs(4); 55 } 56 /*-------------------------------------------------------------------------------- 57 调用方式:I2CAck(void) 58 函数说明:私有函数,I2C专用,等待从器件接收方的应答&#x