stm32硬件实现IIC

这篇具有很好参考价值的文章主要介绍了stm32硬件实现IIC。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

#include "Driver_IIC.h"
#include "Delay.h"

/**
 * IIC默认地工作于从模式。
 *  生成起始条件后自动地从从模式切换到主模式,
 *  当仲裁丢失或产生停止信号时,从主模式切换到从模式。
 * 
 * 
 * 从模式用于接收数据;主模式用于发送数据。
*/


/**
 * 初始化
*/
void Driver_IIC_Init(void)
{
    /* 1.时钟控制使能IIC 和 GPIOB */
    RCC->APB1ENR |= RCC_APB1ENR_I2C2EN;
    RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;

    /* 2.配置PB10、PB11为复用开漏 */
        // PB10 和 PB11 引脚为 I2C2
    GPIOB->CRH |= ( GPIO_CRH_MODE10 | GPIO_CRH_CNF10 | GPIO_CRH_MODE11 | GPIO_CRH_CNF11 );

    /* 3.配置IIC, */
    // 3.0 配置SMBUS模式,0为IIC模式;1为SMBUS模式。
    I2C2->CR1 &= ~I2C_CR1_SMBUS;

    // 3.1 配置IIC时钟频率 FREQ
        // 这里就不先将0-5位清零了,直接 或 操作了。
    I2C2->CR2 |= 0x24;

    // 3.2 配置模式(标准模式/快速模式)
    I2C2->CCR &= ~I2C_CCR_FS;

    // 3.3 配置通讯速率(标准模式100KHz,快速模式400KHz), 
            // 计算为: CCR = Thigh / T  
            //  --->  100KHz/s 即 10us/1Hz, Thigh+Tlow=10us,Thigh=5us (即5us产生一个高电平)
            //  --->  T为周期(产生一个方波需要的时间) = 1s/f     f为频率,   即 1s/36MHz,即 1us/36Hz, 即 1/36us产生一个方波
            //  --->  CRR = 5 / (1/36) = 180
    I2C2->CCR |= 180;

    // 3.4 允许的SCL最大上升时间  TRISE = (最大上升沿时间/时钟周期)+1   (100KHz要求最大上升沿时间不超过1us)
    I2C2->TRISE |= 37;

    // 3.5 IIC使能PE
    I2C2->CR1 |= I2C_CR1_PE;

}

/**
 * 产生开始条件
 * 1成功;0失败
*/
uint8_t Driver_IIC_Start(void)
{
    /* 1.起始条件产生,无所谓主从,1就行 */
        // 起始条件产生后,就从从模式变成主模式了
    I2C2->CR1 |= I2C_CR1_START;

    /* 2.用SR1的SB位判断主模式起始条件,加个检测超时的变量判断*/
    uint16_t timeout = 0xffff;
    while(!(I2C2->SR1&I2C_SR1_SB) && timeout) {
        timeout--;
    }

    /* 3.返回开始条件是否返回成功 */
    return timeout ? 1: 0;
}

/**
 * 产生终止条件
*/
void Driver_IIC_Stop(void)
{
    /* 产生终止条件 */
        // 终止产生后,自动变为从模式
    I2C2->CR1 |= I2C_CR1_STOP;
}

/**
 * 产生应答
*/
void Driver_IIC_ACK(void)
{
    /* 产生应答信号 */
    I2C2->CR1 |= I2C_CR1_ACK;
}

/**
 * 产生无应答
*/
void Driver_IIC_NACK(void)
{
    /* 产生无应答信号 */
    I2C2->CR1 &= ~I2C_CR1_ACK;
}

/**
 * 发送地址
 * 发送成功返回1;失败返回0
*/
uint8_t Driver_IIC_SendAddr(uint8_t addr) {

    uint16_t timeout = 0xffff;
    while (((I2C2->SR1 & I2C_SR1_TXE) == 0) && timeout)
    {
        timeout--;
    }

    /* 把数据写入到数据寄存器中 */
    I2C2->DR = addr;

    /* 等待地址发送完成。*/
    timeout = 0xffff;
    while(!(I2C2->SR1 & I2C_SR1_ADDR) /* 地址还没有发送结束 */ && timeout) {
        timeout--;
    }
    // 走出循环后,如果timeout为0,则是超时了;如果timeout非0,则是发送结束了。
    if(timeout) {
        // 通过  读取SR1寄存器 再 读取SR2寄存器 对 ADDR寄存器进行清零
        // I2C2->SR1;
        I2C2->SR2;
        return 1;
    }
    return 0;
}

/**
 * 发送一个字节
 * 1成功;0失败
*/
uint8_t Driver_IIC_Transmit(uint8_t byte)
{
    /* 1.等待数据寄存器空 */
    uint16_t timeout = 0xffff;
    while(!(I2C2->SR1&I2C_SR1_TXE) && timeout) {
        timeout--;
    }
    if(!timeout) return 0;

    /* 2.往数据寄存器中写数据 */
    I2C2->DR = byte;

    /* 3. 通过SR1_BTF位判断数据是否发送结束,并返回 */
    timeout = 0xffff;
    while(!(I2C2->SR1&I2C_SR1_BTF) && timeout) {
        timeout--;
    }
    return timeout ? 1:0;
}

/**
 * 读取一个字节
*/
uint8_t Driver_IIC_ReadByte(void)
{
    /* 1.通过SR1_RxNE位判断数据寄存器是否非空 */
    uint16_t timeout = 0xffff;
    while(!(I2C2->SR1&I2C_SR1_RXNE) && timeout) {
        timeout--;
    }

    /* 2.根据判断结果返回数据寄存器中的值 */
    return timeout ? I2C2->DR : 0;
}



文章来源地址https://www.toymoban.com/news/detail-798568.html

到了这里,关于stm32硬件实现IIC的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【STM32+HAL库】---- 硬件IIC驱动0.96OLED

    代码借鉴学习于以下文章: STM32 使用硬件IIC驱动0.96寸4针IOLED显示器(HAL库) 略... 点击查看代码 首先在 main.c 中引入头文件 随即根据要求在 main函数 中添加对应功能函数即可 【 注意 】使用时应将编译器编码选项选择为 GBK系列 ,否则编译报错,尤其注意通过keil修改后,再

    2024年02月19日
    浏览(17)
  • STM32硬件IIC卡死问题和DMA发送数据异常问题

    问题1描述: 一直听说STM32的硬件IIC有问题,我平时做项目一直没有遇到过,这次做项目发现硬件IIC居然会自己卡死,现象就是IIC发不出数据,用逻辑分析仪捕捉不到任何电平,必须要重启单片机才能正常,接下来说一下我的硬件环境:STM32作为主机,IIC总线上挂载这AT24C02和一

    2024年02月03日
    浏览(16)
  • STM32 硬件IIC 控制OLED I2C卡死问题

    #更新通知:2023-09-06 STM32L151 固件库 使用I2C 太难了,又宕机了,建议不要在固件库版本上尝试硬件IIC 了,一般人真用不了,直接使用软件模拟的,或者不要使用固件库了,用HAL 库吧,据说HAL 库没这么多问题,不死心的我还是死心了,等有空再研究吧 3.1 I2C模式,我这里选的

    2024年02月09日
    浏览(22)
  • STM32Cubemxhal库硬件IIC驱动SHT40温湿度传感器

    STM32cubemx配置硬件IIC如图所示  SHT40的驱动代码 注意:在读sht40的寄存器之后一定要加10几个ms的延时

    2024年02月12日
    浏览(12)
  • 【STM32】 硬件IIC 驱动SSD1306(0.96 OLED模块) -- 1/4 库函数 学习

    经过了对于STM32的学习,但是大多数时候都还是以移植别人的历程然后修修改改为主。为了更好的巩固自己的学习能力。 所以此篇文章将会以记录我个人学习 硬件IIC 为案例,学习驱动IIC总线设备的能力。 1.《STM32F10x-中文参考手册》 2.《SSD1306芯片手册》 《STM32F10x-中文参考手

    2024年02月01日
    浏览(22)
  • STM32F103硬件IIC控制4针0.96寸OLED显示屏

    OLED使用的0.96寸四针屏幕,以下直接看实际操作。 使用PCtoLCD2002软件提取OLED字模。 注意红色方框的选项内容,不要选错了,选错会导致烧录程序后无法显示。 此为硬件IIC,如果使用过我的模拟IIC控制程序可直接看 void OLED_Write_Command(unsigned char IIC_Command); void OLED_Write_Data(unsig

    2024年02月02日
    浏览(24)
  • 一个简单的HAL库STM32使用DMA+硬件IIC驱动0.96寸OLED的方法

    自己在刚入坑嵌入式的时候,加入学校科协的一道免试题是开发一个简易的示波器,当时萌新不会做,中间又在准备比赛没时间,最近帮女朋友做课设需要做一个简易的交流电压表,而且终于有空做一下自己感兴趣的项目了,就想到了之前想做有没得做的一个简易示波器。

    2024年02月19日
    浏览(21)
  • STM32软件模拟IIC时序实现与EEPROM的通信

                       IIC简介  IIC物理层 用软件模拟IIC时序         一、空闲状态(初始化):SCL 和SDA都保持高电平         二、开始信号 :SCL为高电平期间,SDA由高电平变为低电平。         三、停止信号:SCL为高电平期间,SDA由低电平变为高电平   

    2024年02月09日
    浏览(49)
  • STM32软件模拟实现IIC写入和读取AT24C02(STM32CubeMx配置)

    IIC:Inter Integrated Circuit,集成电路总线,是一种 同步 串行 半双工 通信总线。 在使用IIC时分为硬件IIC以及软件IIC,下图为两者的区别: 在使用IIC前先来了解一下IIC总线结构图,即下图: 从图中可以看出IIC有两个双向信号线,一根是数据线SDA,一根是时钟线SCL,并且都接上拉

    2024年02月04日
    浏览(20)
  • STM32模拟IIC与IIC四种实现数字光强采集模块GY30(标准库与HAL库)

    目录 代码实现是的IIC通信,数据采集后在串口显示,方便大家实现二次开发 原件选择 GY-30 数字光强度介绍 BH1750芯片参数 引脚说明  BH1750指令集 接线表设计 通过四种方式实现GY-30数据采集 1.标准库模拟IIC实现GY-30采集并串口1显示  2.标准库IIC实现GY-30采集并串口1显示 3.HAL库

    2023年04月26日
    浏览(21)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包