1 主机设备(这是一个stm32f4的芯片):正常的iic时序
2 从机设备(一个stm32f1的mcu作从设备)的接收中断函数
3.关于IIC从设备(一个stm32f1的mcu作从设备)
初始化:io初始化,iic设备初始化并使能,iic中断设置并使能
/**************************实现函数********************************************
*函数原型: void IIC_Init(void)
*功 能: 初始化I2C对应的接口引脚。
*******************************************************************************/
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //io口初始化
I2C_InitTypeDef i2cInitStructure; //iic设备初始化并使能
NVIC_InitTypeDef nvicInitStructure; //iic中断
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);
// 设置中断优先级,要求中断优先级最高
nvicInitStructure.NVIC_IRQChannel = I2C2_EV_IRQn;
nvicInitStructure.NVIC_IRQChannelPreemptionPriority = 0;
nvicInitStructure.NVIC_IRQChannelSubPriority = 0;
nvicInitStructure.NVIC_IRQChannelCmd = ENABLE; //开启中断
NVIC_Init(&nvicInitStructure);
//配置PB10 PB11 为开漏输出 刷新频率为50Mhz
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//应用配置到GPIOB
GPIO_Init(GPIOB, &GPIO_InitStructure);
// 配置IIC
I2C_DeInit(I2C2);
i2cInitStructure.I2C_Mode = I2C_Mode_I2C;
i2cInitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
i2cInitStructure.I2C_Ack = I2C_Ack_Enable;
i2cInitStructure.I2C_OwnAddress1 = I2C2_ADDRESS;//0x30
i2cInitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
i2cInitStructure.I2C_ClockSpeed = 100000;/?????????????
I2C_Init(I2C2, &i2cInitStructure);
I2C_ITConfig(I2C2, I2C_IT_EVT|I2C_IT_BUF, ENABLE);
I2C_Cmd(I2C2, ENABLE);
}
中断函数设置:
/**************************实现函数********************************************
*函数原型: void I2C2_EV_IRQHandler(void)
*功 能: I2C中断。
协议类型
发送两个字节
--4位-- --4位-- --4位-- --4位--
灯类型 ON时间ms OFF时间ms 灯次数
红^^^^ 1代表100 1代表100 次
红绿蓝灯特列情况
*,0,1,1 灯ON
*,1,0,1 灯OFF
*******************************************************************************/
volatile uint8_t Recv_Led_Data = 0;
uint8_t iic_Index = 0;
uint32_t test;
void I2C2_EV_IRQHandler(void)
{
int temp;
uint32_t event;
event = I2C_GetLastEvent(I2C2);
//清除总线错误标志
if((event&0x00000100) == 0x00000100)
{
I2C2->SR1 = I2C2->SR1 & 0x1011;
}
else
{
switch(event) //I2C_GetLastEvent(I2C_TypeDef* I2Cx):??????I2C ??
{
//IIC开始信号
case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: //I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED
iic_Index = 0;
temp=I2C2->SR1;
temp=I2C2->SR2;
break;
//IIC接收信号,,协议定义是一次接收两个字节
case I2C_EVENT_SLAVE_BYTE_RECEIVED: //I2C_EVENT_SLAVE_BYTE_TRANSMITTED??????
if(iic_Index == 0)
{
ledStatus[iic_Index] = I2C_ReceiveData(I2C2);
iic_Index++;
}
else if(iic_Index == 1)
{
ledStatus[iic_Index] = I2C_ReceiveData(I2C2);
iic_Index = 0;
Recv_Led_Data = 1;
}
break;
//IIC结束信号
case I2C_EVENT_SLAVE_STOP_DETECTED:
temp=I2C2->SR1;
I2C2->CR1=0x0401;
break;
//IIC主机读信息,然后从机发送
case I2C_EVENT_SLAVE_BYTE_TRANSMITTING:
while((I2C2->SR1 & 0x80) != 0)
I2C2->DR = Battery_Value[2];
//等待发送完成,,如果发送两个字节的话在此句后面继续赋值I2C2->DR
while((I2C2->SR1 & 0x04) == 0)
break;
default:
break;
}
}
}
信息的使用:
4.参考代码: