一.平台

芯片:STM8S103F3P6
环境:IAR + STVP
系统:WIN7


二. 目的

STM8S103F3P6:使用STM8标准库开发
角色------从机
方式----------硬件IIC

STM32H7:
角色------主机
方式----------IO口模拟IIC主机

主机发送命令包,从机接收后进行判断
主机发送读取命令,从机返回上次命令包判断后要返回的数据包

三.STM8硬件IIC

STM8S103时钟

由于该芯片实际应用是放到控制板作为一个附属芯片,不考虑功耗、尽可能采用高的频率,且需要满足硬件I2C对时钟的需求(后续讲到),由STM8S103参考手册时钟章节可看出,接外部高速时钟最高是16M,内部RC最高16M,因此时钟最高是16M。测试时使用的是内部RC振荡器时钟。

由STM8S系列参考手册时钟章节,时钟树上无对时钟进行倍频的单元,因此HSE或者HSI都是16M时钟输入,如果不进行分频,那么同样对CPU时钟而言都是16M。为了方便 (懒。。。),在初步测试时使用的是内部RC振荡器16M。

硬件IIC

从STM8S103数据手册上看I2C有两种支持速率:最高到100K和400K

使用的是PB5复用I2C_SDA,PB4复用I2C_SCL

需要注意的是:选项字节中的OPT2中的AFR4需要是0,如果不是0则PB4和PB5不是复用为I2C引脚

另外,需要注意的是,由下图看:
I2C在100K和400K速率下对时钟要求不同,且。。且。。。且主机用的是IO口模拟IIC,必须符合相应的最短电平持续时间
还有一点:如果使用400K速度,那么主时钟至少是8M

硬件IIC库

从IIC库的相关文件上开放了一些接口,我仅用到了两个,就只说这两个

I2C_Init

void I2C_Init(uint32_t OutputClockFrequencyHz, uint16_t OwnAddress, I2C_DutyCycle_TypeDef I2C_DutyCycle, I2C_Ack_TypeDef Ack, I2C_AddMode_TypeDef AddMode, uint8_t InputClockFrequencyMHz )

功能:I2C硬件初始化
参数:OutputClockFrequencyHz ----- 输出时钟频率
OwnAddress-------本I2C设备地址
I2C_DutyCycle-----占空比,高低电平的时间,和速率有关,详情看手册CCR寄存器
Ack---------应答模式,接收一个字节数据后是否产生应答
AddMode----采用7/10位地址设置
InputClockFrequencyMHz----提供给I2C硬件时钟

I2C_ITConfig

void I2C_ITConfig(I2C_IT_TypeDef I2C_IT, FunctionalState NewState)

功能:I2C的中断配置
参数:I2C_IT ----- 中断类型,如接收到本机地址则产生中断
NewState----中断使能/关闭

四.代码

代码利用测试板和测试过,跑的是100K的速率,能正常运行

  1. CPU时钟:分频配置为不分频,16M

        CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
    
  2. I2C硬件初始化

       u32 CPU_CLK;// CPU时钟// GPIOB4作为上拉无中断输入,GPIOB5高阻态快速输出(10M大小)GPIO_Init(GPIOB,GPIO_PIN_4, GPIO_MODE_IN_PU_NO_IT);GPIO_Init(GPIOB,GPIO_PIN_5, GPIO_MODE_OUT_OD_HIZ_FAST);// 获取当前CPU时钟,M为单位CPU_CLK = CLK_GetClockFreq()/1000000;/* I2C初始化:不需输出时钟,随便写个400000,设备地址0XA0,实际上最后一位是读写控制位每接收一个字节回应答,7位地址模式,输入I2C时钟是上面的CPU_CLK*/I2C_Init(400000, 0XA0 , I2C_DUTYCYCLE_2, I2C_ACK_CURR, I2C_ADDMODE_7BIT, CPU_CLK);//I2C初始化/*I2C中断配置:开启 错误中断、事件中断(如匹配了地址、接收了一字节数据等)、BUF中断(接收和发送相关)*/I2C_ITConfig((I2C_IT_TypeDef)(I2C_IT_ERR | I2C_IT_EVT | I2C_IT_BUF), ENABLE) ;
    
  3. 开总中断

    __enable_interrupt();

  4. I2C中断函数
    在写中断函数之前,先看一下参考手册关于I2C硬件的部分功能描述

I2C接口在接收到地址并且匹配上时,根据ACK可以自动产生一个应答信号,且会将ADDR标志写1,产生一个中断
总结:I2C设备接收到别人发过来的地址,匹配上时,可以自动应答,并且产生中断。
但是,如何对本设备进行读和写的区分呢?因为本次我们配置的是7位地址模式,上面配置本机地址为0XA0,按照最后一位是0还是1,I2C硬件自动识别是读还是写的动作。如果起始信号后,主机发送0XA0,那么主机对从机进行写操作;如果起始信号后,主机发送0XA1,那么主机对从机进行读操作。

从设备接收模式(主机发送、从机接收,因此DR寄存器用来接收数据)
可以得出信息:

 .接收到地址后,要清除ADDR标志.在清除标志后,才会从移位寄存器的数据放到DR寄存器上(因此,接收时要及时清除ADDR标志).每接收一个字节数据可以自动应答.接收一个数据后,RxNE位置1,可产生中断注意:在接收数据后,DR寄存器没被读出时,I2C接口SCL是一直保持为低电平的,这个时候,主机进行发送是没效果的。因此要在中断中及时读取走DR寄存器


EV1是在地址应答阶段后,解释说明指出要清除ADDR,通过读SR1和SR3
EV2是每接收到一个数据,要通过读DR来清除,如果不读则出现上述情况
EV4是接收到停止信号后,通过读SR1,写CR2寄存器清除标志

从设备发送模式(主机接收、从机发送,因此DR寄存器用来发送数据)
可以得出信息:

.在接收地址后并清除了ADDR标志位后,从设备才会将DR寄存器发出
.如果ADDR标志不清除、DR寄存器没及时写入,SCL会一直被拉低,主机操作无效果(特别重要,清除标志,对DR寄存器写操作越快越往前越好)
.如果发送完成,可以产生中断


请注意地址应答后的阶段是 EV1/EV3-1/EV3,这个时候就是需要及时清标志位和写DR寄存器进行发送。如果不呢?
像我当时在中断中还执行了一些语句,并没有把写DR寄存器放到靠前位置,也有一些多余未优化的语句,导致从逻辑分析仪的图形中可以明显看出SCL被一直拉低了,其实我在主机IO模拟中,应答动作后SCL拉低没有那么长的延时的,而是很规律的时钟。

状态寄存器
SR1:
TXE-------发送状态,如果DR寄存器没有发送,那么置1
RXNE----接收到数据,置1
STOPF–接收到停止信号,置1
BTF-----接收到数据/发送数据完成,但还没读取/再次写入
ADDR–匹配到设备地址

SR2:一些错误标志位

SR3:
TRA:处于接收还是发送的状态

代码:由于一些原因,将I2C的数据包格式协议这些用一些变量和数组代替,有需要用的记得根据自己的需求改动

// 测试相关
u8 Test_read[50] = “HELLO ,THANK U,THANK U VERY MUCH”;
u8 Test_r_num = 31; //从机发送个数
u8 Test_r_pos = 0;        // 发送指针
u8 Test_Write[50] = {0};
u8 Test_w_num = 0;   // 主机发送数据个数
u8 Commucation_flag = 0;// 通信完成标志/*** @brief I2C Interrupt routine.* @param  None* @retval None*/
INTERRUPT_HANDLER(I2C_IRQHandler, 19)
//void IIC_Interrupt(void)
{/* In order to detect unexpected events during development,it is recommended to set a breakpoint on the following instruction.*///接收发送   if (I2C->SR1&0x02)//地址已经匹配 ADDR标志{          // 清ADDR标志:读SR1,读SR3// 主机读,从机发出的情况,DR寄存器写数据越快越好// 判断是否是读操作 TRAif ((I2C->SR3)&0x04){        if (Test_r_pos < Test_r_num){I2C->DR = Test_read[Test_r_pos ];Test_r_pos ++;}else I2C->DR = 0XFF;}else{Test_r_pos=0; }Test_w_num= 0;}else if ((I2C->SR3)&0x04)//如果是接收状态:{        // 查看TXE是否DR为空if ((((I2C->SR1)&0x80) == 0X80))        {if (Test_r_pos < Test_r_num){I2C->DR = Test_read[Test_r_pos ];Test_r_pos ++;}else I2C->DR = 0XFF;           }              }else if (((I2C->SR1)&0x40)&&(!((I2C->SR3)&0x04))){// 读DR,清接收标志u8 data = I2C->DR;// 如果主机发送,从机接收到数据if (Test_w_num < 50)Test_Write[Test_w_num ++] = data ;}else if ((I2C->SR1)&0x10){//检测到停止位----清除停止位---通过写CR2I2C->CR2 = I2C->CR2;// 停止标志位置Test_r_pos = 0;Commucation_flag = 1;}// 错误管理if ((I2C->SR2)&0X0F)           {I2C->SR2 &= ~(0X0F); // 清零}}

STM8硬件IIC从机相关推荐

  1. 20131007-STM8L101F3P6关于硬件IIC写时序和勘误部分的翻译

    写时序 ------------------------------------------------------------------------------------------------ ...

  2. STM32使用IIC总线通讯协议在OLED屏幕上显示字符串、汉字、图像(硬件IIC)

    参考:基于STM32-Oled(IIC)的使用 作者:奋斗的小殷 发布时间: 2021-05-07 13:09:26 网址:https://blog.csdn.net/boybs/article/de ...

  3. 使用硬件iic方式实现OLED的字符显示

    IIC和OLED 什么是oled oled的特点 oled的接线 oled的显存 OLED的指令 OLED 取模软件使用 IIC协议的简述 IIC的总线架构 硬件IIC的特点 IIC的总线协议 IIC ...

  4. 【BLE】CC2541之硬件IIC(TMP102温度传感器)

    本篇博文最后修改时间:2017年01月06日,11:06. 一.简介 本文以SimpleBLEPeripheral为例,介绍如何使用硬件IIC读取温度传感器TMP102. 二.实验平台 协议栈版本:B ...

  5. STM32硬件IIC的BUG问题

    问题描述 大概是这样,使用STM32硬件IIC作为主机通讯,只要不发送错误的从机地址, 通讯一直都是没问题的,因为验证程序的关系,所以在程序中修改了一下从机地址, 这时候就出现了问题,下面直接看图把 ...

  6. HC32F460开发之硬件IIC驱动AT24C64

    文章目录 前言 一.AT24C64 二.驱动步骤 1.宏定义 2.代码实现 总结 前言 在嵌入式设计中,E2PROM存储芯片常被应用于需要掉电存储,且容量不大的场合.对比flash存储芯片,E2PRO ...

  7. STM32 驱动 GY-302 光照传感器 BH1750 模块(软件IIC与硬件IIC驱动)

    1.特别说明 ​ 要是不想看原理和过程,直接下拉找代码吧,都是测试过的,很稳定,有硬件I2C驱动的,也有软件模拟I2C驱动的,基于STM32F103系列和STM32F4系列实现,基于标准库实现,条理清 ...

  8. 12. STM32——硬件IIC驱动OLED屏幕显示

    STM32--硬件IIC驱动OLED屏幕显示 OLED屏幕 OLED屏幕特点 OLED屏幕接线说明 OLED屏幕显存 OLED屏幕原理 OLED屏幕常用指令 OLED屏幕字模软件的使用 写命令 写数据 ...

  9. GD32F303调试小记(三)之IIC(硬件IIC+PCF8563实时时钟)

    前言 前面的文章介绍了在单片机中常用的两种通信协议(USART和SPI),并给出了GD32F303对应的配置流程.这次介绍第三种常见的通信协议IIC.这此使用GD32的硬件IIC通信PCF8563实时 ...

最新文章

  1. SharePoint中修改密码的WEB Part之终极版:即可以修改AD,又可以修改本机用户密码的Web Part!!...
  2. ubuntu启动后反复进入initramfs
  3. [js] 使用ajax轮询接口有什么优缺点?
  4. C++ opengl 矩阵的压栈与出栈
  5. 又一腾讯应用将停运!企业QQ将于2022年1月31日关闭
  6. Linux脚本(1)__批量下载
  7. 模板题——快排、归并、二分
  8. 一篇适合小白的Shiro教程
  9. android 读写txt文件,Android:将文本写入txt
  10. MyEclipse10破解教程
  11. 杰理之ANC降噪三种类型【篇】
  12. 用Python模拟QQ界面之QQ登录界面的奥秘
  13. 宇枫资本年轻人投资理财的方法
  14. 大数据和云计算的区别
  15. JAVA面大厂简历怎么写_大厂程序员来谈一谈要如何写简历!!(附简历模板)...
  16. RAW、YUV、RGB、JPEG格式简介
  17. 2020年前端开发工具大全:50款热门的前端工具汇总
  18. 电容屏物体识别_触摸屏物体识别到底是怎么实现的
  19. 冒险岛V79个人用私服搭建回顾
  20. 小米10青春版科学计算机,中端新势力 小米10青春版对华为nova 7 SE

热门文章

  1. mac电脑删除启动台顽固图标方式
  2. C# 字符串写成多行
  3. 书写我的人生回忆录-这应该是给子女和父母最好的礼物
  4. 创业公司如何分配股份与期权?
  5. css为图片添加一层蒙版
  6. echarts3地级市人口密度热力图
  7. 为咱们广州俱乐部做的衣服
  8. Discuz 论坛设置发帖最大字数
  9. I need tests now!
  10. 我为什么不在乎人工智能 / 王垠