历史上的今天
今天是:2025年04月02日(星期三)
2019年04月02日 | STM32 I2C Slave(SMBUS)模式软件参考设计
2019-04-02 来源:eefocus
I2C大家都很熟悉,总共2根线,CLK和DATA,stm32的I2C相信大家就更熟悉了,采用写控制器的方式,直接由控制器去完成I2C时序操作,用户无需关心具体产生的逻辑。然而,大部分情况下,使用的都是I2C Master模式,即主设备模式,很少当成slave模式即从设备模式来用,这篇文章讲的是如何把stm32 I2C当成slave模式来使用,更严格来说,本篇讲的是smbus模式。
从官网stm32手册上我们发现了smbus和I2C区别,大家自行理解:

真正使用时,可以把smbus等同于I2C来设置和使用,从代码上看,除了I2C Clock设置为20K之外,其它暂无明显区别。以下为I2C smbus模式的设置:
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
// RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOB , ENABLE);
/* Configure I2C1 pins: SCL and SDA */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //6:SCL 7:SDA
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;//Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// RCC_APB1PeriphClockCmd (RCC_APB1Periph_I2C1, ENABLE);
// Initialize I2C1 clock
// Reset I2C1 device clock in order to avoid non-cleared error flags
//__I2C_RCC_RESET(CPAL_I2C_CLK [Device]);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1,ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1,DISABLE);
// Enable I2C1 device clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
I2C_DeInit(I2C1);
I2C_InitStructure.I2C_Mode = I2C_Mode_SMBusDevice;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x76;//slave addr
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 20000;//20K
I2C_Init(I2C1, &I2C_InitStructure);
I2C_ITConfig(I2C1, I2C_IT_EVT|I2C_IT_BUF, ENABLE);
I2C_ITConfig(I2C1, I2C_IT_ERR, ENABLE);
I2C_Cmd(I2C1,ENABLE);
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure and enable I2Cx event interrupt -------------------------------*/
NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
从以上代码可以看出,I2C初始化的是I2C的IO映射、工作模式I2C_Mode_SMBusDevice、slave地址0x76(可以自定义)、I2C Clock、I2C中断向量等参数。设置完成之后,每当I2C有数据产生时,就会产生IRQ中断,同时进入中断处理函数I2C1_EV_IRQn,如下所示:
void I2C1_EV_IRQHandler(void)
{
uint32_t I2CFlagStatus;
static uint8_t IIC_Data=0;
I2CFlagStatus = I2C_GetLastEvent(I2C1); // => (SR2<<16|SR1)
// print_info("I2CFlagStatus=0x%x rn",I2CFlagStatus);
IIC1_EV_INT_Flag=1;
IIC_Get_Data_Flag=1;
if ((I2CFlagStatus & I2C_SR1_ADDR) != 0)//bit1:addr matched
{
//print_info("4rn");
if(I2CFlagStatus & I2C_SR1_TXE) //bit7 Data register empty (transmitters)
{//read
Rx_Idx=0;
Tx_Idx = 0;
I2C_SendData(I2C1, I2C_Buffer_Tx[Tx_Idx]);
}
else
{
}
}
else if((I2CFlagStatus & I2C_SR1_RXNE) != 0)//bit6 RxNE -Data register not empty (receivers))
{
IIC_Data=I2C_ReceiveData(I2C1);
I2C_Buffer_Rx[Frame_Idx][Rx_Idx] = IIC_Data;
Rx_Idx++;
}
else if((I2CFlagStatus & I2C_SR1_STOPF) != 0)//bit4 STOPF -Stop detection (slave mode)
{
//I2C_Buffer_Rx[0] = num-1;
I2C1->CR1 |= 0x1000;//CR1_PEC_Set;
Rx_Idx_t=Rx_Idx;
Rx_Idx=0;
Frame_Idx++;
I2C1->SR1=0;
I2C1->SR2=0;
}
else
{
}
}
中断处理函数中,产生中断后,把标志位IIC_Get_Data_Flag置1,根据读到的I2CFlagStatus状态位,来获取当前I2C的状态,获取数据,然后在main函数中根据该标志位来处理I2C产生的数据,处理完成后,再把IIC_Get_Data_Flag标志位置0,这是一种很好的处理数据方法。(PS:中断处理函数不能处理太复杂及费时的事务,以免影响中断响应的实时性,所以把处理数据的过程放到main函数中)
史海拾趣
|
各位高手有没有测试过加速计和陀螺仪这两颗的功能阿,三轴加速计有X,Y,Z三个电压输出,都是经过其内部的AD转换后输出的,不知道这三个方向上的电压是怎么变化的,是有加速度的时候变化呢,还是位置改变了变化啊? 陀螺仪有X,Y两个电压输出,也是 ...… 查看全部问答> |
|
很多MTD驱动都有调用simple_map_init()函数来初始化read,write等函数,不知道这个函数的用法,请大虾帮忙讲一讲啊,如果我需要改变这些read,write函数,该怎么办啦?… 查看全部问答> |
|
求职: 请问有没有人需要高级WINCE工程师--限深圳地区! 求职: 请问有没有人需要高级WINCE驱动工程师--限深圳地区! 如有,请如下EMAIL联系 lumit_hu@126.com… 查看全部问答> |
|
上周在研讨会上买了英蓓特的开发板,试了下,感觉有几个地方不爽,所以就自己动手DIY了:1)USB供电问题,必须插2条USB线,可怜我的本本一共才3个,鼠标用了一个,被他全占了,其它USB-232就没法用了;2)板子附带的1602没有接背光,而实际这 ...… 查看全部问答> |
|
各位高手大家好,小妹我用此板子的UART出了一點問題,大家可以幫幫我嗎? 感激不盡 問題是這樣的,我開啟了八個UART,為了使輸入資料可以做辨識,個別在UART4跟UART5的地方 加了三個#字號跟一個通道編號 例如:UART4是 ###Edata 這樣 ...… 查看全部问答> |
|
SimpliciTI简介: SimpliciTI是TI开发的专门针对其CCxxxx系列无线通信芯片的网络协议。 它支持两种网络拓扑结构:严格的点对点通信和基于星型的网络拓扑结构,在星型连接中Hub点在SimplciTI被称为Access Point,简称AP.(AP就是常说的网关,数据中 ...… 查看全部问答> |
|
老师给了一块tm4c 1294的launchpad,说让我们自己玩,但之前没接触过arm这些东西,接触过单片机;所以完全不知道怎么开始??这块板子能干嘛我都不知道,该怎么学习??完全处于迷茫状态??望大神相助,指点一二,让我有个方向!!非常感谢! … 查看全部问答> |




