本人现在正在做两片STM32的IIC通讯主机选用的是IO模拟IIC而从机是通过硬件IIC中断来做的,直接上从机程序:
static void I2C_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//scl
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitStructure.GPIO_Pin = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;//sda
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitStructure.GPIO_Pin = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
static void I2C_Mode_Config(void)
{
I2C_InitTypeDef I2C_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
I2C_DeInit(I2C1);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0X30;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_ClockSpeed = 100000;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C1,&I2C_InitStructure);
I2C_ITConfig(I2C1,(I2C_IT_ERR |I2C_IT_EVT |I2C_IT_BUF),ENABLE);
I2C_Cmd(I2C1,ENABLE);
}
void I2C_clear_ADDR(I2C_TypeDef* I2Cx)
{
I2C_GetFlagStatus(I2Cx, I2C_FLAG_ADDR);
((void)(I2Cx->SR2));
}
void I2C_clear_STOPF(I2C_TypeDef* I2Cx) {
I2C_GetFlagStatus(I2Cx, I2C_FLAG_STOPF);
I2C_Cmd(I2Cx, ENABLE);
}
void I2C_SLAVE_Init(void)
{
I2C_GPIO_Config();
I2C_Mode_Config();
}
/**
* @brief This function handles I2C1_EV_IRQHandler
* @param None
* @retval None
*/
void I2C1_EV_IRQHandler()
{
/*
if(I2C_GetITStatus(I2C1,I2C_IT_AF))
{
I2C_ClearITPendingBit(I2C1,I2C_IT_AF);
}
switch(I2C_GetLastEvent(I2C1))
{
case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
I2C_clear_ADDR(I2C1);
break;
case I2C_EVENT_SLAVE_BYTE_RECEIVED:
iic_flag.Buffer_Rx_IIC1[iic_flag.Rx_Idx_IIC1++] = I2C_ReceiveData(I2C1);
if(iic_flag.Rx_Idx_IIC1 >= 2) iic_flag.Rx_Idx_IIC1 =0;
switch(iic_flag.Buffer_Rx_IIC1[0])
{
case 0x10:
iic_flag.Buffer_Tx_IIC1[0] = 0x21;
break;
case 0x12:
iic_flag.Buffer_Tx_IIC1[0] = 0x44;
break;
case 0x23:
iic_flag.Buffer_Tx_IIC1[0] = 0x76;
break;
case 0x34:
iic_flag.Buffer_Tx_IIC1[0] = 0x67;
break;
default: break;
}
if(I2C_GetFlagStatus(I2C1,I2C_FLAG_DUALF))
{}
else if(I2C_GetFlagStatus(I2C1,I2C_FLAG_GENCALL))
{}
else
{}
break;
case I2C_EVENT_SLAVE_STOP_DETECTED:
I2C_clear_STOPF(I2C1);
break;
case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:
I2C_clear_ADDR(I2C1);
I2C_SendData(I2C1,0X00);
break;
case I2C_EVENT_SLAVE_BYTE_TRANSMITTED:
if(I2C_GetFlagStatus(I2C1,I2C_FLAG_DUALF))
{
}
else if(I2C_GetFlagStatus(I2C1,I2C_FLAG_GENCALL))
{
}
else
{
}
I2C_GetFlagStatus(I2C1,I2C_FLAG_BTF);
I2C_SendData(I2C1,iic_flag.Buffer_Tx_IIC1[iic_flag.Tx_Idx_IIC1++]);
if(iic_flag.Tx_Idx_IIC1>2) iic_flag.Tx_Idx_IIC1=0;
break;
case I2C_EVENT_SLAVE_ACK_FAILURE:
I2C_ClearITPendingBit(I2C1,I2C_IT_AF);
break;
case I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED:
break;
case I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED:
break;
default:
break;
}
//I2C1->CR1 |= 0X0001;
*/
__IO u16 SR1Register =0;
__IO u16 SR2Register =0;
SR1Register = I2C1->SR1;
SR2Register = I2C1->SR2;
//判断I2C是从机模式-最低位(MSL=0)
if((SR2Register&0x0001)!=0x0001)
{
//ADDR:根据状态判断获取从机IIC地址成功
if((SR1Register&0X0002) == 0X0002)
{
SR1Register =0;
SR2Register =0;
I2C_clear_ADDR(I2C1);
iic_flag.Rx_Idx_IIC1 =0;
iic_flag.Tx_Idx_IIC1 =0;
}
//接收数据(RXNE=1:EV2)
if((SR1Register& 0X0040) == 0X0040)
{
iic_flag.Buffer_Rx_IIC1[iic_flag.Rx_Idx_IIC1++] = I2C1->DR;
SR1Register = 0;
SR2Register = 0;
switch(iic_flag.Buffer_Rx_IIC1[0])
{
case 0x10:
iic_flag.Buffer_Tx_IIC1[0] = 0x21;
break;
case 0x12:
iic_flag.Buffer_Tx_IIC1[0] = 0x44;
break;
case 0x23:
iic_flag.Buffer_Tx_IIC1[0] = 0x76;
break;
case 0x34:
iic_flag.Buffer_Tx_IIC1[0] = 0x67;
break;
default: break;
}
}
//检测到停止条件(STOP=1:EV4)
if((SR1Register&0X0010) == 0X0010)
{
I2C1->CR1 |= 0x0001;
SR1Register =0;
SR2Register =0;
iic_flag.Flag_RcvOK_IIC1 =1;
}
//发送数据(TxE = 1:EV3,EV3-1)
if((SR1Register&0X0080) == 0X0080)
{
SR1Register = 0;
SR2Register = 0;
I2C1->DR = 0X21;//iic_flag.Buffer_Tx_IIC1[iic_flag.Tx_Idx_IIC1++];
}
//检测到非应答
if((SR1Register&0X0400) == 0X0400)
{
I2C1->SR1 &= 0XFDFF;
SR1Register =0;
SR2Register =0;
}
}
}
void NVIC_Config_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =1 ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/*
NVIC_InitStructure.NVIC_IRQChannel = I2C1_ER_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =2 ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
*/
}
void Handware_Init(void)
{
//SysTick_Init();
I2C_SLAVE_Init();
NVIC_Config_Init();
//USB_USART_Config();
}
/**
* @brief 主函数
* @param 无
* @retval 无
*/
int main(void)
{
Handware_Init();
while(1)
{
/*
if(timflag.Timing500msFlag==1)
{
timflag.Timing500msFlag=0;
//printf("rxdata[0]=%d\r\n",iic_flag.Buffer_Rx_IIC1[0]);
//printf("rxdata[1]=%d\r\n",iic_flag.Buffer_Rx_IIC1[1]);
}
if(iic_flag.Flag_RcvOK_IIC1 ==1)
{
switch(iic_flag.Buffer_Rx_IIC1[0])
{
case 0x10:
printf("电压值volt:%d\r\n",iic_flag.Buffer_Rx_IIC1[1]);
break;
case 0x12:
printf("电流值cur:%d\r\n",iic_flag.Buffer_Rx_IIC1[1]);
break;
case 0x23:
printf("额定功率:%d\r\n",iic_flag.Buffer_Rx_IIC1[1]);
break;
case 0x34:
printf("时间time:%d\r\n",iic_flag.Buffer_Rx_IIC1[1]);
break;
default: break;
}
//memset(iic_flag.Buffer_Rx_IIC1,0,20);
//memset(iic_flag.Buffer_Tx_IIC1,0,20);
iic_flag.Flag_RcvOK_IIC1=0;
}
*/
}
}
总体程序大致如此,主循环里面都屏蔽了,主要就是IIC配置和中断函数了
但是我通过示波器并没有发现有应答,而且SR1寄存器总是出现0X0110,代表总线错误和检测到停止信号,有时候会进入地址匹配SR1 = 0x0112;现在真的是黔驴技穷了
希望大佬帮忙 |