F0的I2C与F103不同,Slave I2C接口协议采用寄存器访问的格式。
(1)I2C初始化
void IIC_Slavemode_Init(u8 debug, u8 addr)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
if(debug == 1) return;
//---------------------------- GPIO pins configuration ------------------
/* I2C Periph clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
/* Configure the I2C clock source. The clock is derived from the HSI */
//RCC_I2CCLKConfig(RCC_I2C1CLK_HSI); //RCC_I2C1CLK_SYSCLK
// Enable I2C1 SCL and SDA Pin Clock
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);
//PA10:SDA PA9:SCL
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;
// Set GPIO frequency to 50MHz
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// Select Alternate function mode
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
//Select output Open Drain type
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
// Disable internal Pull-up
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//GPIO_PuPd_NOPULL;
GPIO_Init((GPIO_TypeDef*)GPIOA, &GPIO_InitStructure);
// Connect PXx to I2C_SCL I2C_SDA PA10:SDA PA9:SCL meilh 201024 GPIO_AF_1->GPIO_AF_4
GPIO_PinAFConfig((GPIO_TypeDef*)GPIOA,GPIO_PinSource9,GPIO_AF_4);
GPIO_PinAFConfig((GPIO_TypeDef*)GPIOA,GPIO_PinSource10,GPIO_AF_4);
//---------------------------- Deinitialize I2C1 clock ------------------
// Reset I2C1 device clock in order to avoid non-cleared error flags
//RCC_APB1PeriphResetCmd((RCC_APB1Periph_I2C1),ENABLE);
//RCC_APB1PeriphResetCmd((RCC_APB1Periph_I2C1),DISABLE);
//I2C1 Configuration
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
I2C_InitStructure.I2C_DigitalFilter = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_OwnAddress1 = addr<<1;
//I2C_InitStructure.I2C_Timing = 0x10805D88;//0x50E30000;//0x20D22E37;//slave: 0x20D20000;
I2C_Cmd(I2C1,ENABLE);
I2C_Init(I2C1, &I2C_InitStructure);
I2C_ITConfig(I2C1, I2C_CR1_ADDRIE | I2C_CR1_STOPIE | I2C_CR1_TXIE | I2C_CR1_RXIE, ENABLE); //meilh 20171025 remove I2C_CR1_ERRIE|I2C_CR1_NACKIE|
//---------------------------- Peripheral and DMA interrupts Initialization ------------------
// Initialize I2C1 interrupts
/* Configure NVIC for I2C1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = I2C1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
要注意的地方是:GPIO_PinAFConfig((GPIO_TypeDef*)GPIOA,GPIO_PinSource9,GPIO_AF_4);
之前看例子是用的 GPIO_AF_1,I2C死活没反应,后来找厂家提供了一个可以跑的例子比较寄存器,发现此地方要用GPIO_AF_4,就正常工作了。
(2)中断处理接口
void I2C1_IRQHandler(void)
{
__IO uint32_t I2CFlagStatus = 0x00000000;
uint8_t data;
I2CFlagStatus = (uint32_t)(I2C1->ISR & (uint16_t)0x0000100FE);
if ((I2CFlagStatus & I2C_ISR_ADDR) != 0)
{
if(I2C1->ISR&I2C_ISR_DIR) //tx mode
{
Tx_count = 0;
I2C1->ISR |= I2C_ISR_TXE;
I2C1->ICR |= I2C_ICR_ADDRCF;
}
if((I2C1->ISR&I2C_ISR_DIR)==0) //rx mode
{
Rx_buffer[0] = 0;
Rx_count= 1;
I2C1->ICR |= I2C_ICR_ADDRCF;
}
}
else if ((I2CFlagStatus & I2C_ISR_RXNE) != 0)
{
data = I2C_ReceiveData(I2C1);
if(Rx_count < Rx_MAX){
Rx_buffer[Rx_count++] = data ;
if(Rx_count == 2){
reg_offset = Rx_buffer[1];
}
}
}
else if ((I2CFlagStatus & I2C_ISR_TXIS) != 0)
{
I2C_SendData(I2C1,Tx_buffer[reg_offset+Tx_count]);
Tx_count++;
if(Tx_count >= Tx_MAX)
{
Tx_count = 0; //tx ok
}
}
else if ((I2CFlagStatus & I2C_ISR_STOPF) != 0)
{
I2C1->ICR |= I2C_ICR_STOPCF;
Rx_buffer[0] = Rx_count;
Rx_count = 0;
Tx_count = 0;
}
}
F0的I2C状态判断比较容易,不过可能也因为使用的频率低暂未发现问题,后来F103也仿照这个形式进行了修改。
其它就没什么好说的,自己根据自己的协议接口进行修改。
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』