STM8硬件IIC从机
一.平台
芯片: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的速率,能正常运行
CPU时钟:分频配置为不分频,16M
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
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) ;
开总中断
__enable_interrupt();
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从机相关推荐
- 20131007-STM8L101F3P6关于硬件IIC写时序和勘误部分的翻译
写时序 ------------------------------------------------------------------------------------------------ ...
- STM32使用IIC总线通讯协议在OLED屏幕上显示字符串、汉字、图像(硬件IIC)
参考:基于STM32-Oled(IIC)的使用 作者:奋斗的小殷 发布时间: 2021-05-07 13:09:26 网址:https://blog.csdn.net/boybs/article/de ...
- 使用硬件iic方式实现OLED的字符显示
IIC和OLED 什么是oled oled的特点 oled的接线 oled的显存 OLED的指令 OLED 取模软件使用 IIC协议的简述 IIC的总线架构 硬件IIC的特点 IIC的总线协议 IIC ...
- 【BLE】CC2541之硬件IIC(TMP102温度传感器)
本篇博文最后修改时间:2017年01月06日,11:06. 一.简介 本文以SimpleBLEPeripheral为例,介绍如何使用硬件IIC读取温度传感器TMP102. 二.实验平台 协议栈版本:B ...
- STM32硬件IIC的BUG问题
问题描述 大概是这样,使用STM32硬件IIC作为主机通讯,只要不发送错误的从机地址, 通讯一直都是没问题的,因为验证程序的关系,所以在程序中修改了一下从机地址, 这时候就出现了问题,下面直接看图把 ...
- HC32F460开发之硬件IIC驱动AT24C64
文章目录 前言 一.AT24C64 二.驱动步骤 1.宏定义 2.代码实现 总结 前言 在嵌入式设计中,E2PROM存储芯片常被应用于需要掉电存储,且容量不大的场合.对比flash存储芯片,E2PRO ...
- STM32 驱动 GY-302 光照传感器 BH1750 模块(软件IIC与硬件IIC驱动)
1.特别说明 要是不想看原理和过程,直接下拉找代码吧,都是测试过的,很稳定,有硬件I2C驱动的,也有软件模拟I2C驱动的,基于STM32F103系列和STM32F4系列实现,基于标准库实现,条理清 ...
- 12. STM32——硬件IIC驱动OLED屏幕显示
STM32--硬件IIC驱动OLED屏幕显示 OLED屏幕 OLED屏幕特点 OLED屏幕接线说明 OLED屏幕显存 OLED屏幕原理 OLED屏幕常用指令 OLED屏幕字模软件的使用 写命令 写数据 ...
- GD32F303调试小记(三)之IIC(硬件IIC+PCF8563实时时钟)
前言 前面的文章介绍了在单片机中常用的两种通信协议(USART和SPI),并给出了GD32F303对应的配置流程.这次介绍第三种常见的通信协议IIC.这此使用GD32的硬件IIC通信PCF8563实时 ...
最新文章
- SharePoint中修改密码的WEB Part之终极版:即可以修改AD,又可以修改本机用户密码的Web Part!!...
- ubuntu启动后反复进入initramfs
- [js] 使用ajax轮询接口有什么优缺点?
- C++ opengl 矩阵的压栈与出栈
- 又一腾讯应用将停运!企业QQ将于2022年1月31日关闭
- Linux脚本(1)__批量下载
- 模板题——快排、归并、二分
- 一篇适合小白的Shiro教程
- android 读写txt文件,Android:将文本写入txt
- MyEclipse10破解教程
- 杰理之ANC降噪三种类型【篇】
- 用Python模拟QQ界面之QQ登录界面的奥秘
- 宇枫资本年轻人投资理财的方法
- 大数据和云计算的区别
- JAVA面大厂简历怎么写_大厂程序员来谈一谈要如何写简历!!(附简历模板)...
- RAW、YUV、RGB、JPEG格式简介
- 2020年前端开发工具大全:50款热门的前端工具汇总
- 电容屏物体识别_触摸屏物体识别到底是怎么实现的
- 冒险岛V79个人用私服搭建回顾
- 小米10青春版科学计算机,中端新势力 小米10青春版对华为nova 7 SE