技术标签: STM32驱RN8209 RN8209C单相计量芯片使用心得 计量芯片驱动程序
由于项目需求,最近使用了一下RN8209C单相电量计量芯片,用STM32读取外接用电器的有效功率。第一次接触肯定是看技术手册。
RN8209C技术手册V1.5
单相计量芯片应用笔记
手册中有电路设计方案,寄存器使用介绍。
下面直接上干货,由于我负责编写驱动程序,所以电路设计就不说了,按官方给的方案就行。
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//GPIOA时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);//使能USART2
//USART2_TX GPIOA.2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.2
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //频率50M
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA.2
//USART2_RX GPIOA.3
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.3
//USART2初始化配置
USART_InitStructure.USART_BaudRate = 4800;//波特率4800
USART_InitStructure.USART_WordLength = USART_WordLength_9b;//数据9位,偶校验算一位
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一位停止位
USART_InitStructure.USART_Parity = USART_Parity_Even;//偶校验
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART2, &USART_InitStructure); //初始化UART2
//USART2 NVIC初始化
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能
NVIC_Init(&NVIC_InitStructure);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启接收中断,RXNE读寄存器非空
USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);//使能接收一帧数据中断
USART_ITConfig(USART2, USART_IT_TC, ENABLE);//开启发送中断,TC发送完成
USART_Cmd(USART2, ENABLE);//使能串口2
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能GPIOA时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;//GPIOA.2
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //频率50M
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.2
GPIO_ResetBits(GPIOA, GPIO_Pin_2);//RN8209C复位引脚拉低
g_IRn8209C.Delay_ms(25);//延时25mm
GPIO_SetBits(GPIOA, GPIO_Pin_2);//RN8209C复位引脚拉高,复位结束
g_IRn8209C.Delay_ms(20);
RN8209C写操作
写操作就是给它相应的寄存器里发送值,用串口发送一帧数据包括 寄存器地址,数据,校验码。校验码如何算手册中有,这里就不啰嗦了。
注意:
(1)发送时高字节在前,低字节再后,写操作最高字节最高位为1,即寄存器地址|0x80;
(2)写操作前必须先发送写使能命令 EA E5 30,EA是地址,E5是命令,30是校验码
(3)使用前可以先测试一下芯片和MCU是否通信正常,发送 0X7F,如果收到
“82 09 00 F5” 说明通信正常。
写校表参数
校表参数的计算我就不说了,手册和笔记中有,如果你和我一样没有标准校表平台,需要的数据又不需要特别精确,可以用一块电子计量插座读出此时外部用电器的功率Pa,然后读出此时芯片功率寄存器中的值Pb,计算出Kp=Pa/Pb;(Kp可多次测量求平均值),下次直接用寄存器的值乘Kp就是功率有效值。
校表参数写之前先写使能,等待使能命令发送完成后逐一发送要写的命令,而且必须等待前一个发送完成才能发送后一个,此处我用的是发送中断,发送完成后置标志位,while等待,如果标志位置位则继续发送下一个(备注:我用延时不行,可能延时不准确,两帧数据间的间隔有要求)
u8 Temp_wreg[1] = {
0xE5}; //写使能 0xEA
g_IRn8209C.RN_Write(0xEA, Temp_wreg, 1);
//g_IRn8209C.RN_Read(0x7F, NULL, 0);//通讯测试命令,RN8209回复 82 09 00 F5
u8 Temp_syscon[2] = {
0x55, 0x16};//SYSCON 电流通道B开启,电流A,B,电压增益为2倍 0x00
g_IRn8209C.RN_Write(0x00, Temp_syscon, 2);
u8 Temp_emucon[2] = {
0x03, 0x28};//正反累加,无负
g_IRn8209C.RN_Write(0x01, Temp_emucon, 2);
u8 Temp_emucon2[2] = {
0xC0, 0x00};//更新速度13.982hz
g_IRn8209C.RN_Write(0x17, Temp_emucon2, 2);
u8 Temp_hfconst[2] = {
0xC1, 0xA7};//HFConst
g_IRn8209C.RN_Write(0x02, Temp_hfconst, 2);
u8 Temp_gpqa[2] = {
0x7B, 0xFE};
g_IRn8209C.RN_Write(0x05, Temp_gpqa, 2);
u8 Temp_gpqb[2] = {
0x7B, 0xFE};
g_IRn8209C.RN_Write(0x06, Temp_gpqb, 2);
u8 Temp_phsa[1] = {
0x06};//0x06
g_IRn8209C.RN_Write(0x07, Temp_phsa, 1);
u8 Temp_phsb[1] = {
0x06};//0x06
g_IRn8209C.RN_Write(0x08, Temp_phsb, 1);
u8 Temp_aposa[2] = {
0xF1, 0x0A};//APOSA有功offset
g_IRn8209C.RN_Write(0x0A, Temp_aposa, 2);
u8 Temp_aposb[2] = {
0xF1, 0x0A};//APOSB有功offset
g_IRn8209C.RN_Write(0x0B, Temp_aposb, 2);
u8 Temp_iarmsos[2] = {
0xA4, 0xEB};//IARMSOS有效offset
g_IRn8209C.RN_Write(0x0E, Temp_iarmsos, 2);
u8 Temp_disw[1] = {
0xDC};//写保护
g_IRn8209C.RN_Write(0xEA, Temp_disw, 1);
//发送完成while检测
g_IRn8209C.RN_Send();
while(!g_IRn8209C.SendFinsh);
我驱这个芯片的时候遇到了很多坑,而且网上关于这芯片的资料太少了,基本上都出自一处。如果你们遇到和我一样的问题那你就很幸运了,这些问题我都解决了。
一、读出的功率值为负数,即最高位为1,手册上说如果读到为负需要舍去…,如果你的电路已经确定了,你也不想再改电路的话那就和我一样用程序解决。
经过我的“大数据“分析,我发现即便是负数它也是线性变化的,只是因为采样电流的方向反了,我们只需要按照补码转原码的方式求出原码即可,然后按照我第4点中的方法求出Kp和功率即可。
二、能读出数据但是就是写不进去,连写使能命令都写不进去,如果你也遇到这个问题,请按如下步骤检查。
1、最高位是否置1
2、请先检查你的写命令的函数,因为读操作只需要发送一字节数据,而写操作至少需要发送三字节,检查串口发送的时候是否出现漏字节,重复发送或多发的问题,串口发送一定要及时清空标志位。
3、发送的每一帧数据之间是否等待了发送完成,建议不要用延时,用while堵塞检测是否发送完成。
4、校验码计算是否正确
5、串口配置是否正确,波特率,偶校验,停止位,9位数据
6、如果你检测到还是不能写操作那建议你换芯片喽。
三、如果你需要连续读取有效值,但是发现读出的值不正确,抖动很大,那么请你这样操作。
1、连续读取的周期必须大于有效值的更新周期,13.982hz下周期为71.5ms,3.495hz下周期为286ms,所以必须等更新完成再读。
2、每次读操作前都进行一次校表参数配置,并且读0X2D寄存器的值看校表是否完成,有效值是否能用。
我的心得总结完了,希望能给你们带来一丝的帮助,如果里面说的没有你遇到的 问题,手册中也没有介绍到,你可以留言我们共同探讨,如果我这篇文章对你有帮助请支持我一下,谢谢,祝你早日解决BUG
文章浏览阅读1.5w次,点赞10次,收藏129次。文章目录目录模型评估评价指标1.分类评价指标acc、recall、F1、混淆矩阵、分类综合报告1.准确率方式一:accuracy_score方式二:metrics2.召回率3.F1分数4.混淆矩阵5.分类报告6.kappa scoreROC1.ROC计算2.ROC曲线3.具体实例2.回归评价指标3.聚类评价指标1.Adjusted Rand index 调整兰德系数2.Mutual Informa..._model.score
文章浏览阅读344次。因工作需要,在Apache上使用,重新学习配置mod_jk1. 分别安装Apache和Tomcat:2. 编辑httpd-vhosts.conf: LoadModule jk_module modules/mod_jk.so #加载mod_jk模块 JkWorkersFile conf/workers.properties #添加worker信息 JkLogFil_apache mod_jk 虚拟
文章浏览阅读335次。待老夫kotlin大成,扩展:MotionLayout 与 CoordinatorLayout,DrawerLayout,ViewPager 的 交互众所周知,MotionLayout 的 动画是有完成度的 即Progress ,他在0-1之间变化,一.CoordinatorLayout 与AppBarLayout 交互时,其实就是监听 offsetliner 这个 偏移量的变化 同样..._android onoffsetchanged
文章浏览阅读8.3k次,点赞3次,收藏19次。【转】多核处理器的工作原理及优缺点《处理器关于多核概念与区别 多核处理器工作原理及优缺点》原文传送门 摘要:目前关于处理器的单核、双核和多核已经得到了普遍的运用,今天我们主要说说关于多核处理器的一些相关概念,它的工作与那里以及优缺点而展开的分析。1、多核处理器 多核处理器是指在一枚处理器中集成两个或多个完整的计算引擎(内核),此时处理器能支持系统总线上的多个处理器,由总..._多核处理器怎么工作
文章浏览阅读306次。1. eclipse配置lombok 拷贝lombok.jar到eclipse.ini同级文件夹下,编辑eclipse.ini文件,添加: -javaagent:lombok.jar2. myeclipse配置lombok myeclipse像eclipse配置后,定义对象后,直接访问方法,可能会出现飘红的报错。 如果出现报错,可按照以下方式解决。 ..._eclispe每次运行个新项目都需要重新配置lombok吗
文章浏览阅读1.2w次,点赞31次,收藏126次。#注意:笔者在2021/11/11当天调试过这个代码是可用的,由于pdfminer版本的更新,网络上大多数的语法没有更新,我也是找了好久的文章才修正了我的代码,仅供学习参考。1、把pdf文件移动到本代码文件的同一个目录下,笔者是在pycharm里面运行的项目,下图中的x1文件夹存储了我需要转换成文本文件的所有pdf文件。然后要在此目录下创建一个存放转换后的txt文件的文件夹,如图中的txt文件夹。2、编写代码 (1)导入所需库# coding:utf-8import ..._python批量读取文字并批量保存
文章浏览阅读1.4k次。http://blog.csdn.net/pipisorry/article/details/52902234Scala 访问修饰符Scala 访问修饰符基本和Java的一样,分别有:private,protected,public。如果没有指定访问修饰符符,默认情况下,Scala对象的访问级别都是 public。Scala 中的 private 限定符,比 Java 更严格,在嵌套类情况下,外层_scala ===运算符
文章浏览阅读2.6k次,点赞7次,收藏19次。ER图导出为PDF或图片格式_数据库怎么导出er图
文章浏览阅读655次。CREATE OR REPLACE TRIGGER Trg_ReimFactBEFORE UPDATEON BP_OrderFOR EACH ROWDECLAREPRAGMA AUTONOMOUS_TRANSACTION;--自制事务fc varchar2(255);BEGINIF ( :NEW.orderstate = 2AND :NEW.TransState = 1 ) THENBEG..._oracle触发器更新同一张表
文章浏览阅读513次。目录概念debouncethrottle实现debouncethrottle应用场景debouncethrottle场景举例debouncethrottle概念debounce字面理解是“防抖”,何谓“防抖”,就是连续操作结束后再执行,以网页滚动为例,debounce要等到用户停止滚动后才执行,将连续多次执行合并为一次执行。throttle字面理解是“节流”,何谓“节流”,就是确保一段时..._throttle和debounce应用在哪些场景
文章浏览阅读526次。regex() $regex 正则表达式用于模式匹配,基本上是用于文档中的发现字符串 (下面有例子)注意:若未加 @Field("名称") ,则识别mongdb集合中的key名为实体类属性名。也可以对数组进行索引,如果被索引的列是数组时,MongoDB会索引这个数组中的每一个元素。也可以对整个Document进行索引,排序是预定义的按插入BSON数据的先后升序排列。save: 若新增数据的主键已经存在,则会对当前已经存在的数据进行修改操作。_java 操作mongodb
文章浏览阅读1k次。今天push代码到github仓库时出现这个报错TACKCHEN-MB0:tc-image tackchen$ git pushremote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.remote: Please see https://github.blog/2020-12-15-token-authentication_git push remote: support for password authentication was removed on august 1