当前位置: 首页 > news >正文

基于I2C的stm32f103c8t6的硬件配置(寄存器实现)

        前面已经学过了通过两个IO口模拟I2C的通信,这种方法可以在硬件资源少的时候很方便的进行各个外设之间的通信,但在模拟时序的精度上还是不如硬件I2C的,因为硬件I2C是通过硬件自动生成的,精度高,同时在传输速率上硬件I2C也比软件I2C的传输速率要快,因此我们可以得出硬件I2C在刚需高性能,高稳定的场景下使用。

I2C的初始化

在前面我们已经介绍了I2C的寄存器,在初始化中我们需要打开具有硬件I2C的引脚的时钟,然后进行GPIO的配置,配置成复用开漏模式,配置完成这些后我们还需要对 SMBUS和FS进行配置,SMBUS是配置I2C的CR1寄存器中的一位,主要是用来选择是否选择I2C模式,而FS是CCR寄存器中的一位,用来选择I2C的模式,一般我们统一都是配置成标准模式,接下来就是配置时钟CR2外设时钟频率,也就是36MHZ,也就是挂载到APB1总线上的,然后就是通信速率CCR,它的值是根据CR2来的。

SCL频率 = 36,000,000 Hz / (2 * 180) = 36,000,000 / 360 = 100,000 Hz = 100kHz

接着就是最大上升时间TRISE,具体的计算方法为

TRISE值 = (最大允许上升时间 / APB1时钟周期) + 1

具体的代码实现:

void I2C_INIT()
{RCC->APB2ENR|=RCC_APB2ENR_IOPBEN;GPIOB->CRL &=~GPIO_CRL_CNF7|GPIO_CRL_MODE7|GPIO_CRL_CNF6|GPIO_CRL_MODE6;GPIOB->CRL |=GPIO_CRL_MODE6|GPIO_CRL_MODE7;GPIOB->CRL |=GPIO_CRL_CNF7|GPIO_CRL_CNF6;I2C1->CR1 &=~I2C_CR1_SMBUS;I2C1->CCR &=~I2C_CCR_FS;I2C1->CR2 =36;I2C1->CCR=180;I2C1->TRISE=37;I2C1->CR1 |=I2C_CR1_PE;}

I2C的开始信号和停止信号

I2C硬件发送开始信号然后等待应答在应答期间我们需要有一个变量来进行检测超时,不然程序就会一直卡死。

uint8_t I2C_START()
{I2C1->CR1 |=I2C_CR1_START;uint16_t  timeout=0xffff;while(I2C1->CR1&I2C_CR1_ACK&&timeout){timeout--;}return timeout?OK:NOOK;}

停止信号直接用硬件停止即可

void I2C_ACK()
{I2C1->CR1 |=I2C_CR1_ACK;}

I2C的应答信号和非应答信号

应答信号ACK存于CR1中的一位

void I2C_STOP()
{I2C1->CR1 |=I2C_CR1_STOP;}

非应答信号直接置0即可

void I2C_NACK()
{I2C1->CR1 &=~I2C_CR1_ACK;}

发送地址

在开始传输数据之前我们要选择是哪个从机设备想要和主机进行通信,因此我们就写入一个想要进行通信的从机的地址然后写入寄存器DR最后判断是否写入成功,主要就是进行地址的写入,用来告诉主机是哪个从机想要进行通信,写入完成后我们要进行清除,清除的做法就是读取寄存器SR2。

uint8_t I2C_SendAddr(uint8_t addr)
{uint16_t timeout=0xfff;I2C1->DR=addr;while(I2C1->SR1&I2C_SR1_ADDR&timeout){timeout--;}if(timeout>0){I2C1->SR2;}return timeout?OK:NOOK;}

发送数据

发送数据前先检测发送寄存器是否为空,为空后写入数据寄存器DR,然后接着判断BTF位。BTF是位于SR1寄存器中的关于数据是否发完成的位。

uint8_t I2C_Sendbyte(uint8_t byte)
{uint16_t  timeout=0xffff;while(I2C1->SR1&I2C_SR1_TXE&&timeout){timeout--;}I2C1->DR=byte;timeout=0xffff;while(I2C1->SR1&I2C_SR1_BTF&timeout){timeout--;}return timeout?OK:NOOK;}

读取数据

读取数据就是判断RXNE是否是满的,是满的就直接返回数据寄存器DR。

uint8_t I2C_Readbyte()
{uint16_t  timeout=0xffff;while(I2C1->SR1&I2C_SR1_RXNE&timeout){timeout--;}return  timeout?I2C1->DR:NOOK;}

以上就是关于I2C中硬件寄存器的配置,如果有错误的地方还请广大网友多多指正。

        

http://www.dtcms.com/a/508325.html

相关文章:

  • Android 系统中进程间通信方式
  • YOLOv4:集大成的目标检测王者
  • 微服务架构
  • 软件制作工程师企业网站seo运营
  • 云服务器小网站制作wordpress企业显示不了
  • AIGC降重软件开发
  • 网站开发的预算用dw制作视频网站
  • 【项目】基于多设计模式下的同步异步日志系统 - 项目实现
  • 优秀个人网页成都白帽优化
  • 有没有个人做的网站赚流量费中山网站建设公司哪个好
  • 专业手机网站建设价格wordpress 图片响应式
  • 河南 网站建设wordpress电商插件下载
  • JVM 垃圾收集器相关知识总结
  • Spring Boot 3零基础教程,WEB 开发 Thymeleaf 遍历 笔记40
  • 网站优化的策略品牌型网站的设计
  • qq刷赞网站推广软件网红营销活动
  • PHP MySQL 插入数据详解
  • 互联网建网站做网站 上海
  • UiPath2025笔记第九节:Orchestrator设置邮件连接,以QQ邮箱为例
  • 详细讲解一下机器人的NVR控制
  • 3网站建设公司怎样建设责任文化
  • 网站开发实战框架网站建设
  • w3c网站模板可视化app开发工具
  • Orleans 可观测性实战:基于源码的指标与分布式追踪(含 Prometheus 集成)
  • 成都 企业网站设计天眼查询企业信息电话
  • 肥料网站建设 中企动力网站企业备案和个人备案的区别吗
  • 用coze工作流生成软著申请材料
  • 【SAP FI】3.资产会计_3.固定资产模块的基本业务操作-资产价值浏览器折旧
  • 力扣(LeetCode) ——118.杨辉三角(C++)
  • 媒体发布的技术革命:Infoseek如何用AI重构企业传播全链路