历史上的今天
返回首页

历史上的今天

今天是:2025年08月07日(星期四)

正在发生

2019年08月07日 | stm32的HAL库i2c从机实现

2019-08-07 来源:eefocus

stm32的i2c默认就是slave模式,本文基于HAL库实现中断方式的接收和发送,首先是初始化gpio和i2c,代码如下:


I2C_HandleTypeDef I2cHandle;

void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)

{

    GPIO_InitTypeDef GPIO_InitStruct; 

     __HAL_RCC_GPIOA_CLK_ENABLE() ;

     __HAL_RCC_GPIOC_CLK_ENABLE() ;

    /**I2C3 GPIO Configuration    

    PA8     ------> I2C3_SCL

    PC9     ------> I2C3_SDA 

    */

    GPIO_InitStruct.Pin = GPIO_PIN_8;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;            //开漏输出(i2c需要这种模式)

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

    GPIO_InitStruct.Alternate = GPIO_AF4_I2C3;

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

      

    GPIO_InitStruct.Pin = GPIO_PIN_9;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

    GPIO_InitStruct.Alternate = GPIO_AF4_I2C3;

    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

 

    /* Peripheral clock enable */

    __HAL_RCC_I2C3_CLK_ENABLE();

 

    /* Peripheral interrupt init */

    HAL_NVIC_SetPriority(I2C3_EV_IRQn, 0, 0);

    HAL_NVIC_EnableIRQ(I2C3_EV_IRQn);

    HAL_NVIC_SetPriority(I2C3_ER_IRQn, 0, 0);

    HAL_NVIC_EnableIRQ(I2C3_ER_IRQn);

}

void I2c_config()

{

  I2cHandle.Instance             = I2C3;                           //此处使用i2c3

 

  I2cHandle.Init.AddressingMode  = I2C_ADDRESSINGMODE_7BIT;        //7位地址模式

  I2cHandle.Init.ClockSpeed      = 1000000;                        //时钟支持最高1M

  I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;        //关闭双地址模式

  I2cHandle.Init.DutyCycle       = I2C_DUTYCYCLE_16_9;             

  I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;        

  I2cHandle.Init.NoStretchMode   = I2C_NOSTRETCH_DISABLE;          

  I2cHandle.Init.OwnAddress1     = 0X34;                           //器件地址

  I2cHandle.Init.OwnAddress2     = 0;        

  

  if(HAL_I2C_Init(&I2cHandle) != HAL_OK)                            //调用初始化函数

  {

    /* Initialization Error */

    Error_Handler();    

  }

  HAL_I2C_Slave_Receive_IT(&I2cHandle,i2c_slave_recv,I2C_REC_BYTES);  //开启从机中断接收

}

i2c3中断回调函数:


void I2C3_ER_IRQHandler()                 //异常回调

{

    HAL_I2C_ER_IRQHandler(&I2cHandle);

}

void I2C3_EV_IRQHandler()                //事件回调(接收或发送)

{

    HAL_I2C_EV_IRQHandler(&I2cHandle);

}

  两个中断对应的中断事件如下图所示:


发送完成、接收完成和错误回调函数:


void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *I2cHandle)

{

       //发送完成回调函数 

       {

            //一些其他操作

        }

       HAL_I2C_Slave_Receive_IT(&I2cHandle,i2c_slave_recv,I2C_REC_BYTES);

        {

            //一些其他操作

        }

}

 

void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *I2cHandle)

{

       //接收完成回调函数

        {

            //一些其他操作

        }

        HAL_I2C_Slave_Transmit_IT(&I2cHandle,send_buffer,send_cnt);

        {

            //一些其他操作

        }

}

 

void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *I2cHandle)

{

       //错误异常回调函数

}

实际操作时可以在接收完成中断中处理数据然后开启从机发送中断,在发送完成中断中开启从机接收中断,可以实现收发。


目前用HAL库发送必须将send_cnt的字节全部发送完成才行,不然通信会出问题。这个问题需要进一步解决。

推荐阅读

史海拾趣

Displaytech公司的发展小趣事

Displaytech一直致力于技术创新和产品升级。在多年的发展过程中,公司不断推出新的LCD产品,包括触摸屏TFT、单色图形LCD和字符显示模块等。同时,公司还加强了表面贴装能力、PCB组装服务、工具和注塑成型等业务的拓展,进一步提升了整体竞争力。

ABCO公司的发展小趣事

ABCO公司初创时,电子市场竞争激烈,众多企业争夺市场份额。面对这样的环境,ABCO公司创始人凭借对电子技术的深刻理解,以及敏锐的市场洞察力,选择了专注于某一细分领域——高精度传感器的研发与生产。通过不断优化产品设计,提升产品性能,ABCO公司的传感器逐渐在市场上获得认可,为公司的起步奠定了坚实基础。

ABB公司的发展小趣事

在技术创新的基础上,ABCO公司开始积极拓展市场。公司通过与大型电子设备制造商建立合作关系,将产品应用于汽车、医疗、工业等多个领域。同时,ABCO公司还加强了品牌建设,通过参加国际电子展会、举办技术研讨会等方式,提升了品牌知名度和影响力。

General Dynamics SATCOM Technologies公司的发展小趣事

随着技术的不断进步,ABCO公司意识到只有不断创新才能在竞争中保持领先地位。因此,公司加大了对研发的投入,建立了一支高效的技术团队。这支团队不仅成功研发出了多款具有自主知识产权的新型传感器,还积极探索传感器与其他电子设备的融合应用,为公司开辟了新的增长点。

Amphenol RF公司的发展小趣事

随着技术的不断进步,ABCO公司意识到只有不断创新才能在竞争中保持领先地位。因此,公司加大了对研发的投入,建立了一支高效的技术团队。这支团队不仅成功研发出了多款具有自主知识产权的新型传感器,还积极探索传感器与其他电子设备的融合应用,为公司开辟了新的增长点。

Dailywell Electronics Co Ltd公司的发展小趣事

随着业务的不断扩展和市场需求的增加,德利威电子在1998年实现了全系列防水开关的生产,并取得了RS33A开关专利。同年,公司还扩大了经营规模,搬入了自购的厂办大楼,并增加了资本额至一千五百万元。这些举措不仅提升了公司的生产能力和产品品质,也为公司未来的发展奠定了坚实的基础。

问答坊 | AI 解惑

vs2005上如何开发wince 5.0 应用程序(用的是Windows CE 5.0: Standard Software Development Kit (

如题目: 我想把开发环境搭建好,已经安装的环境如下: 1.vs2005+sp1 2.Windows CE 5.0: Standard Software Development Kit (SDK)已经安装好了。 现在的问题是创建一个《智能设备应用程序》-》Platform SDK(STANDARDSDK_500)-》创建完成。 ...…

查看全部问答>

重开一贴,SQLite问题

最近听说使用SQLite数据库比较方便,想试试这种方法,大家有没有什么好的建议,指导一下。。。或者讨论下!非常感谢…

查看全部问答>

USB过滤驱动中,怎样实现禁用U盘???????????????、

怎样实现在u盘插上后,用户无法打开,用户身份在经过验证后,才能打开。 现在用户验证已经没问题,就是不知道怎样先禁止u盘,然后再放行。…

查看全部问答>

请教USB,CAN等专用SRAM问题

                                 STM32F107的手册上说CAN具有512个字节的专用RAM,USB具有1.25K的专用RAM。我想请问下这个专用RAM是各个外设自带的 ...…

查看全部问答>

刚教的单片机要考试了 大侠们帮个忙做几个题目啊!!!!!!!

用简单的汇编语言编程 1.编程计算从1+2+……+50 2.在RAM中有100个字节,起始地址为100H 找出中间的最小值放在700H中 试编写程序 3.是编写程序实现R4 R5指向的RAM单元中的高四位合并起来 放在地址为500H的单元中,期中R5指向的RAM单元的高四位放 ...…

查看全部问答>

网络中如有多个协调器

刚学ZIGBBE,有点疑惑,当网络中有多个网络(两个协调器),路由器怎么选择进放哪个网络??…

查看全部问答>

我用中断写了个程序输出1KHZ方波,貌似有问题,请高手帮我这个菜鸟看看啊……

#include<iom16v.h>#include<macros.h>#define interrupt_handler pwm:9void pwm(){ PORTB^=BIT(PB0); TCNT1H=0XFF; TCNT1L=0XEF;}void main(){TCCR1B=0X04; TCNT1H=0XFF;TCNT1L=0XEF;TIMSK|=BIT(2);SREG|=BIT(7); DDRB=0 ...…

查看全部问答>

lm3s 引脚死锁原理及解决办法!

lm3s 引脚死锁原理及解决办法! GPIOAFSEL 寄存器是模式控制选择寄存器。向该寄存器中的任意位写“1”表示选择该GPIO线路为备用硬件控制(功能)所用。由于所有的位都在复位时都会清零,因此在默认的情况下,这些GPIO线路设置GPIO模式。对JTAG/S ...…

查看全部问答>

VISHAY 推出的看视频抽礼品活动正在进行,欢迎参加!

VISHAY 推出的看视频抽礼品活动正在进行,欢迎参加! https://www.eeworld.com.cn/huodong/201405_Vishay/…

查看全部问答>