你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32G031K LL库的使用 - IIC

[复制链接]
STMCU小助手 发布时间:2021-11-10 22:53
说明:驱动基于STm32G031K6,其他型号需自行做改动。

注:因为之前项目暂未用到LL库的IIC,所以此驱动未经过实机验证。欢迎反馈使用中的问题。

IIC的初始化: CubeMX生成

  1. void STM32LLI2C1_Init(void)
  2. {
  3.   LL_I2C_InitTypeDef I2C_InitStruct = {0};

  4.   LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

  5.   LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
  6.   /**I2C1 GPIO Configuration  
  7.   PA9   ------> I2C1_SCL
  8.   PA10   ------> I2C1_SDA
  9.   */
  10.   GPIO_InitStruct.Pin = LL_GPIO_PIN_9|LL_GPIO_PIN_10;
  11.   GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  12.   GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
  13.   GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
  14.   GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
  15.   GPIO_InitStruct.Alternate = LL_GPIO_AF_6;
  16.   LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  17.   /* Peripheral clock enable */
  18.   LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);

  19.   /** I2C Initialization
  20.   */
  21.   I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C;
  22.   I2C_InitStruct.Timing = 0x00303D5B;
  23.   I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE;
  24.   I2C_InitStruct.DigitalFilter = 0;
  25.   I2C_InitStruct.OwnAddress1 = 0;
  26.   I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK;
  27.   I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT;
  28.   LL_I2C_Init(I2C1, &I2C_InitStruct);
  29.   LL_I2C_EnableAutoEndMode(I2C1);
  30.   LL_I2C_SetOwnAddress2(I2C1, 0, LL_I2C_OWNADDRESS2_NOMASK);
  31.   LL_I2C_DisableOwnAddress2(I2C1);
  32.   LL_I2C_DisableGeneralCall(I2C1);
  33.   LL_I2C_EnableClockStretching(I2C1);
  34.   LL_I2C_Enable(I2C1);
  35. }
复制代码

由于LL库未提供与HAL类似的I2C多数据读取的函数接口,所以需要自行编写函数,我这里是参照HAL库内的HAL_I2C_Mem_Write和HAL_I2C_Mem_Read写的LL库可使用的相对应函数。

I2C读多个数据:

  1. void STM32I2C1_MasterRead(uint8_t device_7BitAddr, uint16_t mem_address,uint16_t mem_size,uint8_t *pdata,uint8_t length)
  2. {
  3.     //等待iic空闲
  4.     while(LL_I2C_IsActiveFlag_BUSY(I2C1));
  5.     //确认iic是否使能
  6.     if(!LL_I2C_IsEnabled(I2C1))
  7.     {
  8.         LL_I2C_Enable(I2C1);
  9.     }
  10.     //配置
  11.     LL_I2C_HandleTransfer(I2C1,device_7BitAddr,LL_I2C_ADDRSLAVE_7BIT,mem_size,I2C_SOFTEND_MODE,I2C_GENERATE_START_WRITE);
  12.     while(!LL_I2C_IsActiveFlag_TXIS(I2C1));

  13.     //写入从设备寄存器地址
  14.     ucBSP_I2C1_WriteMemAddr(mem_address,mem_size);
  15.     while(!LL_I2C_IsActiveFlag_TC(I2C1));

  16.     //配置
  17.     LL_I2C_HandleTransfer(I2C1,device_7BitAddr,LL_I2C_ADDRSLAVE_7BIT,length,I2C_AUTOEND_MODE,I2C_GENERATE_START_READ);

  18.     //读取数据
  19.     ucBSP_I2C1_ReadMultipleData(pdata,length);

  20.     //等待停止完成
  21.     while(!LL_I2C_IsActiveFlag_STOP(I2C1));
  22.     LL_I2C_ClearFlag_STOP(I2C1);
  23. }
复制代码

I2C写多个数据:

  1. void STM32I2C1_MasterWrite(uint8_t device_7BitAddr, uint16_t mem_address,uint16_t mem_size,uint8_t *pdata,uint8_t length)
  2. {
  3.     //等待iic空闲
  4.     while(LL_I2C_IsActiveFlag_BUSY(I2C1));
  5.     //确认iic是否使能
  6.     if(!LL_I2C_IsEnabled(I2C1))
  7.     {
  8.         LL_I2C_Enable(I2C1);
  9.     }
  10.     //配置为写
  11.     LL_I2C_HandleTransfer(I2C1,device_7BitAddr,LL_I2C_ADDRSLAVE_7BIT,mem_size,I2C_RELOAD_MODE,I2C_GENERATE_START_WRITE);
  12.     while(!LL_I2C_IsActiveFlag_TXIS(I2C1));

  13.     //写入从设备寄存器地址
  14.     ucBSP_I2C1_WriteMemAddr(mem_address,mem_size);
  15.     while(!LL_I2C_IsActiveFlag_TCR(I2C1));

  16.     //重新配置为自动停止模式
  17.     LL_I2C_HandleTransfer(I2C1,device_7BitAddr,LL_I2C_ADDRSLAVE_7BIT,length,I2C_AUTOEND_MODE,I2C_NO_STARTSTOP);

  18.     //写数据
  19.     ucBSP_I2C1_WriteMultipleData(pdata,length);

  20.     //等待停止完成
  21.     while(!LL_I2C_IsActiveFlag_STOP(I2C1));
  22.     LL_I2C_ClearFlag_STOP(I2C1);
  23. }
复制代码

为了减少代码重复和增加可读性,对读写的一些过程另作了函数;

写寄存器地址:

  1. void STM32I2C1_WriteMemAddr(uint16_t mem_address,uint16_t mem_size)
  2. {
  3.     uint8_t MemAddrLSB = I2C_MEM_ADD_LSB(mem_address);;
  4.     uint8_t MemAddrMSB = I2C_MEM_ADD_MSB(mem_address);;

  5.     //发送器件寄存器地址
  6.     if(mem_size == I2C_MEMADD_SIZE_8BIT)
  7.     {
  8.         LL_I2C_TransmitData8(I2C1, MemAddrLSB);
  9.     }else{
  10.         LL_I2C_TransmitData8(I2C1, MemAddrMSB);
  11.         //等待发送完成
  12.         while(!LL_I2C_IsActiveFlag_TXIS(I2C1));
  13.         LL_I2C_TransmitData8(I2C1, MemAddrLSB);
  14.     }
  15. }
复制代码

连续写入小于255个数据:

  1. void STM32I2C1_WriteMultipleData(uint8_t *pdata,uint8_t length)
  2. {
  3.     uint8_t count;
  4.     for(count=0;count<length; count++)
  5.     {
  6.         //等待发送完成
  7.         while(!LL_I2C_IsActiveFlag_TXIS(I2C1));
  8.         LL_I2C_TransmitData8(I2C1, *(pdata+count));
  9.     }
  10. }
复制代码

连续读取小于255个数据:

  1. void STM32I2C1_ReadMultipleData(uint8_t *pdata,uint8_t length)
  2. {
  3.     uint8_t count;
  4.     for(count=0;count<length; count++)
  5.     {
  6.         //等待接收非空
  7.         while(!LL_I2C_IsActiveFlag_RXNE(I2C1));
  8.         *(pdata+count) = LL_I2C_ReceiveData8(I2C1);
  9.     }
  10. }
复制代码


收藏 评论2 发布时间:2021-11-10 22:53

举报

2个回答
Spring_ly 回答时间:2023-1-12 13:32:15
你好,我想问一下,HAL库自带的函数可以连续写入256个字节,为什么改写的LL库的这个不能连续写入256个字节?
submer 回答时间:2023-4-27 15:53:32

有收获,感谢分享。

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版