数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 3683|回复: 24

[ARM] 分享STM32F0x/STM32G0x单片机的硬件IIC寄存器级代码

[复制链接]
发表于 2022-8-23 18:11:37 | 显示全部楼层 |阅读模式
最近玩了下STM32G030 感觉这波更新很多,好多外设都有焕然一新的感觉,时钟系统也大改了,玩起来还蛮有意思的。
关键是还挺便宜的,今天研究了下硬件IIC驱动,HAL库实在是又长又臭 不爱看,再加上DMA更乱了,就干脆直接寄存器硬怼吧。
研究了以后发现好像和STM32F030的硬件IIC是同一个核 那就一起都测试下吧。
网上关于STM32G系列的资料太少了 找啥都没有 吧自己研究结果共享下大家一起玩


相关阅读:
stm8的硬件IIC代码-寄存器版|http://bbs.mydigit.cn/read.php?tid=2540435


测试效果
检查外设是否响应-ACK

检查外设是否响应-NAK  已加入简单的错误处理防止nak以后卡死


读和写



以下是代码-G030下的

  1. #define FLAG_TIMEOUT         ((uint32_t)0x1000)
  2. #define LONG_TIMEOUT         ((uint32_t)(10 * FLAG_TIMEOUT))
  3. #define CR1_CLEAR_MASK          ((uint32_t)0x00CFE0FF)
  4. //PA11 I2C_SCL
  5. //PA12 I2C_SDA
  6. void I2C_Init(void)
  7. {
  8.         RCC->IOPENR |= RCC_IOPENR_GPIOAEN;
  9.         RCC->APBENR1 |= RCC_APBENR1_I2C2EN;
  10.         //SYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_RMP|SYSCFG_CFGR1_PA12_RMP;
  11.        
  12.         GPIOA->MODER &=~ (GPIO_MODER_MODE9|GPIO_MODER_MODE10|GPIO_MODER_MODE11|GPIO_MODER_MODE12);
  13.         GPIOA->MODER |=  GPIO_MODER_MODE11_1|GPIO_MODER_MODE12_1;
  14.         GPIOA->OTYPER |= (GPIO_OTYPER_OT11|GPIO_OTYPER_OT12);
  15.         GPIOA->OSPEEDR |= GPIO_OSPEEDR_OSPEED11|GPIO_OSPEEDR_OSPEED12;
  16.         GPIOA->PUPDR&=~(GPIO_PUPDR_PUPD11|GPIO_PUPDR_PUPD12);
  17.         GPIOA->PUPDR|= GPIO_PUPDR_PUPD11_0|GPIO_PUPDR_PUPD12_0;//pull-up
  18.         GPIOA->AFR[1]&=~(GPIO_AFRH_AFSEL11|GPIO_AFRH_AFSEL12);
  19.         GPIOA->AFR[1]|=(6<<3*4)|(6<<4*4);//PA11/12 AF6 IIC2
  20.        
  21.         I2C2->CR1 &= ((uint32_t)~((uint32_t)I2C_CR1_PE))&CR1_CLEAR_MASK;
  22.         I2C2->CR1 &=~ I2C_CR1_ANFOFF;
  23.         //400KHz<span id="kM0.15701809540889855">@64MHz</span>
  24.         I2C2->TIMINGR = (0x17UL << I2C_TIMINGR_SCLL_Pos)|(0x9UL << I2C_TIMINGR_SCLH_Pos)|(0x2UL << I2C_TIMINGR_SDADEL_Pos)|(0x3UL << I2C_TIMINGR_SCLDEL_Pos)|(0x3UL << I2C_TIMINGR_PRESC_Pos);
  25.         I2C2->CR1 = (0x1UL << I2C_CR1_DNF_Pos);
  26.         I2C2->CR1 |= I2C_CR1_PE;
  27. }

  28. //返回1为失败 0为正常
  29. uint8_t IIC_Wait(uint32_t I2C_FLAG)
  30. {
  31.         uint32_t Timeout;
  32.         Timeout = LONG_TIMEOUT;  
  33.   //while(I2C_GetFlagStatus(I2C2, I2C_ISR_TXIS) == RESET)
  34.         while((I2C2->ISR&I2C_FLAG)==0)
  35.   {
  36.     if((Timeout--) == 0)
  37.                         return 1;
  38.   }
  39.         if(I2C2->ISR&I2C_ISR_NACKF)
  40.         {
  41.                 I2C2->ICR = I2C_ICR_NACKCF;
  42.                 return 1;//收到nak
  43.         }               
  44.         return 0;
  45. }

  46. //0-ok
  47. //other error
  48. uint32_t I2C_Check_Device(uint8_t I2C_Addr)
  49. {
  50.         uint32_t tmpreg;
  51.         //if(IIC_Wait(I2C_ISR_BUSY))return 1;//总线忙
  52.         tmpreg=I2C2->CR2;
  53.         tmpreg&= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP));
  54.         tmpreg|=I2C_Addr|I2C_CR2_START|I2C_CR2_STOP;
  55.         I2C2->CR2 = tmpreg;  
  56.         tmpreg = IIC_Wait(I2C_ISR_STOPF);
  57.         I2C2->ICR = I2C_ICR_STOPCF;
  58.         return tmpreg;
  59. }

  60. //返回实际读取数量
  61. uint8_t IIC_Read(uint8_t Addr,uint8_t Reg,uint8_t Num,uint8_t* Data_Buff)
  62. {
  63.         uint32_t tmpreg,Pointer=0;
  64.         if(Num==0)return 0;
  65.         tmpreg=I2C2->CR2;
  66.         tmpreg&= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP));
  67.         tmpreg|=Addr|I2C_CR2_START|(1<<16);//数量       
  68.         I2C2->CR2 = tmpreg;  
  69.         if(IIC_Wait(I2C_ISR_TXIS))return 0;
  70.         //Send memory address
  71.         I2C2->TXDR=Reg;
  72.         if(IIC_Wait(I2C_ISR_TC))return 0;
  73.        
  74.         tmpreg=I2C2->CR2;
  75.         tmpreg&= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP));
  76.         tmpreg|=Addr|I2C_CR2_START | I2C_CR2_RD_WRN|I2C_CR2_AUTOEND|(Num<<16);
  77.         I2C2->CR2 = tmpreg;
  78.         while(Num)
  79.         {
  80.                 if(IIC_Wait(I2C_ISR_RXNE))return Pointer;
  81.                 Data_Buff[Pointer]=I2C2->RXDR;
  82.                 Pointer++;
  83.                 Num--;
  84.         }
  85.         return Pointer;
  86. }


  87. void IIC_Write(uint8_t Addr,uint8_t Reg,uint8_t Num,uint8_t* Data_Buff)
  88. {
  89.         uint32_t tmpreg,Pointer=0;
  90.         if(Num==0)return;
  91.         tmpreg=I2C2->CR2;
  92.         tmpreg&= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP));
  93.         tmpreg|=Addr|I2C_CR2_START|I2C_CR2_AUTOEND|((Num+1)<<16);//数量       
  94.         I2C2->CR2 = tmpreg;  
  95.         if(IIC_Wait(I2C_ISR_TXE))return;
  96.         //Send memory address
  97.         I2C2->TXDR=Reg;       
  98.         while(Num)
  99.         {
  100.                 if(IIC_Wait(I2C_ISR_TXE))return;
  101.                 I2C2->TXDR=Data_Buff[Pointer];
  102.                 Pointer++;
  103.                 Num--;
  104.         }
  105.         IIC_Wait(I2C_ISR_TXE);
  106.         return;
  107. }

  108. void IIC_Write_REG(uint8_t Addr,uint8_t Reg)
  109. {
  110.         uint32_t tmpreg;
  111.         tmpreg=I2C2->CR2;
  112.         tmpreg&= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP));
  113.         tmpreg|=Addr|I2C_CR2_START|I2C_CR2_AUTOEND|(1<<16);//数量       
  114.         I2C2->CR2 = tmpreg;  
  115.         if(IIC_Wait(I2C_ISR_TXE))return;
  116.         //Send memory address
  117.         I2C2->TXDR=Reg;       
  118.         IIC_Wait(I2C_ISR_TXE);
  119.         return;
  120. }

  121. //返回实际读取数量
  122. uint8_t IIC_Read_Without_Reg_Addr(uint8_t Addr,uint8_t Num,uint8_t* Data_Buff)
  123. {
  124.         uint32_t tmpreg,Pointer=0;
  125.        
  126.         tmpreg=I2C2->CR2;
  127.         tmpreg&= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP));
  128.         tmpreg|=Addr|I2C_CR2_START | I2C_CR2_RD_WRN|I2C_CR2_AUTOEND|(Num<<16);
  129.         I2C2->CR2 = tmpreg;
  130.         while(Num)
  131.         {
  132.                 if(IIC_Wait(I2C_ISR_RXNE))return Pointer;
  133.                 Data_Buff[Pointer]=I2C2->RXDR;
  134.                 Pointer++;
  135.                 Num--;
  136.         }
  137.         return Pointer;
  138. }

  139. void IIC_Write_Without_Reg_Addr(uint8_t Addr,uint8_t Num,uint8_t* Data_Buff)
  140. {
  141.         uint32_t tmpreg,Pointer=0;
  142.         if(Num==0)return;
  143.         tmpreg=I2C2->CR2;
  144.         tmpreg&= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP));
  145.         tmpreg|=Addr|I2C_CR2_START|I2C_CR2_AUTOEND|((Num)<<16);//数量       
  146.         I2C2->CR2 = tmpreg;  
  147.         while(Num)
  148.         {
  149.                 if(IIC_Wait(I2C_ISR_TXE))return;
  150.                 I2C2->TXDR=Data_Buff[Pointer];
  151.                 Pointer++;
  152.                 Num--;
  153.         }
  154.         IIC_Wait(I2C_ISR_TXE);
  155.         return;
  156. }
复制代码
STM32F0上的初始化
如果是TSSOP20的丐版 自己改下引脚到PA脚,然后全局Ctrl+H替换I2C2----->I2C1


  1. void IIC2_Init(void)
  2. {       
  3.         RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
  4.         RCC->APB1ENR |= RCC_APB1ENR_I2C2EN;       
  5.        
  6.        
  7.         GPIOB->OTYPER|=GPIO_OTYPER_OT_11|GPIO_OTYPER_OT_10;//OD
  8.         GPIOB->OSPEEDR|=GPIO_OSPEEDR_OSPEEDR11|GPIO_OSPEEDR_OSPEEDR10;//50M
  9.         GPIOB->MODER&=~(GPIO_MODER_MODER11|GPIO_MODER_MODER10);
  10.         GPIOB->PUPDR&=~(GPIO_PUPDR_PUPDR11|GPIO_PUPDR_PUPDR10);
  11.         GPIOB->MODER|=GPIO_MODER_MODER11_1|GPIO_MODER_MODER10_1;//复用
  12.         GPIOB->PUPDR|=GPIO_PUPDR_PUPDR11_0|GPIO_PUPDR_PUPDR10_0;//pull-up
  13.         GPIOB->AFR[1]&=~(GPIO_AFRH_AFR11|GPIO_AFRH_AFR10);
  14.         GPIOB->AFR[1]|=(1<<3*4)|(1<<2*4);//PB10/11 AF1 IIC
  15.        
  16.         //Disable I2Cx Peripheral
  17.   I2C2->CR1 &= ((uint32_t)~((uint32_t)I2C_CR1_PE))&CR1_CLEAR_MASK;
  18.         //EN AnalogFilter
  19.         I2C2->CR1 &=~ I2C_CR1_ANFOFF;
  20.         //Configure I2Cx: Timing
  21.   I2C2->TIMINGR = 0x00210507;//381K<span id="kM0.5335161359873961">@48MHz</span>
  22.   //Enable I2Cx Peripheral
  23.   I2C2->CR1 |= I2C_CR1_PE;               
  24. }
复制代码


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x

打赏

参与人数 6家元 +105 收起 理由
kkdkj + 20 謝謝分享
玛德陛下 + 20 謝謝分享
mousebat04 + 5 大佬V5
rush + 20 優秀文章
cushion + 20 謝謝分享

查看全部打赏

发表于 2022-8-23 18:55:44 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 2022-8-23 19:03:01 来自手机浏览器 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 2022-8-23 19:31:57 来自手机浏览器 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 2022-8-23 21:58:12 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-8-23 23:05:43 来自手机浏览器 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-8-23 23:08:45 来自手机浏览器 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 2022-8-23 23:22:30 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 2022-8-23 23:47:39 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-8-24 04:35:24 来自手机浏览器 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 2022-8-24 08:37:59 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 2022-8-24 10:02:30 来自手机浏览器 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 2022-8-24 10:04:24 来自手机浏览器 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-8-24 10:39:41 来自手机浏览器 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 1 反对 0

使用道具 举报

发表于 2022-8-24 12:54:57 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 2022-8-24 13:26:20 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 2022-8-24 13:50:51 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 2022-8-28 13:30:47 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 2022-8-28 13:45:35 来自手机浏览器 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 微信登录

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-12-12 07:57 , Processed in 0.452401 second(s), 14 queries , Gzip On, Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

快速回复 返回顶部 返回列表