资讯专栏INFORMATION COLUMN

【RISC-V MCU 创新应用】一种网络型单相智能电表

rockswang / 3757人阅读

摘要:负责对电能检测模块下发收集指令,以及对电能检测模块响应的数据进行处理,一方面对接收的单相数据进行转换后驱动屏幕对相关数据进行显示,另一方面对单相数据进行重新打包并通过串口对以太网模块进行数据传输。

一、预想功能

基于32 位通用增强型 RISC-V MCU CH32V103开发板作为核心控制主板,通过接收和处理单相电能检测模块实时获取的单相数据,包括对电压、电流、有功功率、无功功率、电能、功率因数、二氧化碳含量、频率、芯片温度等相关数据进行计算和整理,同时驱动OLED 屏幕实时刷新显示单相电能数据,并将数据进行打包后通过串口向以太网模块发送数据包,以太网模块将数据包上传至云端,实现远距离在有人云平台对数据进行监控及上下发指令功能。

二、系统框架

三、硬件介绍


该智能电表硬件部分主要由RISC-V MCU CH32V103开发板、电能计模块、以太网模块、驱动模块、OLED 屏幕以及排插等器件组成。

RISC-V MCU CH32V103开发板:作为核心主板。负责对电能检测模块下发收集指令,以及对电能检测模块响应的数据进行处理,一方 面对接收的单相数据进行转换后驱动OLED 屏幕对相关数据进行显示,另一方面对单相数据进行重新打包并通过串口对以太网模块进行数据传输。

电能计模块:通过排插连接电器,并实时检测外接电器的单相数据。若接收主板发来的接收指令,则将检测到的数据上发到主板。

以太网模块:作为开发板与云端进行数据传输的媒介。当模块接收主板下发的数据包时,会将数据包通过路由器上传到云端,有人云平台通过对数据进行接收并显示到监控界面上,用户也可通过在有人云的监控界面对主板下发数据和指令。

驱动模块:按照主板指令驱动散热器开关以及转动的速度等。

OLED屏幕:显示相关数据。

排插:可外接电器,支持220V交流供电,接入排插的电器运行时的单相数据不断被电能检测模块进行收集。

四、软件介绍

1.主函数

int main(void){	uint8_t OLED_Show_Change = 0;	uint8_t OLED_Show_First_In = 0;	DisableGlobalIRQ();	board_init();           //务必保留,本函数用于初始化MPU 时钟 调试串口	gpio_init(B2, GPO, 0, GPIO_PIN_CONFIG);           //GPIO初始化  PB2//外接LED2	gpio_init(C0, GPO, 1, GPIO_PIN_CONFIG);           //GPIO初始化  PC0//外接KEY	gpio_init(C1, GPO, 1, GPIO_PIN_CONFIG);           //GPIO初始化  PC1//外接LED1	gpio_init(C3, GPO, 0, GPIO_PIN_CONFIG);	gpio_init(C4, GPO, 0, GPIO_PIN_CONFIG);	uart_init(UART_1, 4800, UART1_TX_A9, UART1_RX_A10);	uart_init(UART_2, 115200, UART2_TX_A2, UART2_RX_A3);	uart_rx_irq(UART_1, ENABLE);//	uart_tx_irq(UART_1, ENABLE);	uart_rx_irq(UART_2, ENABLE);//  uart_tx_irq(UART_2, ENABLE);	U_OLED_Init();  //用户初始化OLED函数	U_OLED_Clear(); //清屏函数	timer_pit_interrupt_ms(TIMER_1, 10);	//初始化定时TIM1  10毫秒中断一次	EnableGlobalIRQ(0);	while (1)	{		if (U_Tim_Count > 250)//计时		{			U_Tim_Count = 0;			OLED_Show_Change++;			if (OLED_Show_Change > 2)			{				OLED_Show_Change = 0;				OLED_Show_First_In = 0;			}		}		switch (OLED_Show_Change)//OLED切屏		{		case 0:			U_Show_IM1253B_Data1(OLED_Show_First_In, U_IM1253B_Data);			OLED_Show_First_In = 1;			break;		case 1:			U_Show_IM1253B_Data2(OLED_Show_First_In, U_IM1253B_Data);			OLED_Show_First_In = 0;			break;		case 2:			U_Show_IM1253B_Data3(OLED_Show_First_In, U_IM1253B_Data);			OLED_Show_First_In = 1;			break;		default:			break;		}		if (MCU_Interrupt0_Timer_1S_End) //定时1S向IM1253B模块发送读取相关寄存器数据的命令		{			U_Send_RendCommand_IM1253B(); //向IM1253B模块发送读取相关寄存器数据函数			MCU_Interrupt0_Timer_1S_End = 0;			U_Send_Ethernet_Data();//向以太网模块发送电能数据			systick_delay_ms(100);//延时100ms,分段发送数组			U_Send_Ethernet_Data2();//向以太网模块发送开关数据		}		U_Calculation_IM1253B_Data(); //计算IM1253B相关电能数据函数	    receive_key();//接收以太网下发数据	}}

2.电能计量模块相关驱动函数

串口1中断函数

void USART1_IRQHandler(void){	static uint8_t U_GetData;	uart_query(UART_1, &U_GetData);	USART_ClearITPendingBit(USART1, USART_IT_RXNE);	U_MCU_UART1_GetData_End = U_Get_IM1253B_Data(U_GetData); //接收IM1253B电能计量模块驱动函数}

读取电能计上发的数据,进行判断后存入特定数组中

uint8_t U_Get_IM1253B_Data(uint8_t Get_Data){	static uint8_t i = 0;	static uint8_t Get_Data_Buf[37] =	{ 0 }; //存储获取数据数组	Get_Data_Buf[i++] = Get_Data; //将获取到的数据存入数组	if (Get_Data_Buf[0] != 0x01)  //判断帧头	{		i = 0;	}	if ((i == 2) && (Get_Data_Buf[1] != 0x03)) //判断帧头	{		i = 0;	}	if ((i == 3) && (Get_Data_Buf[2] != 0x20)) //判断帧头	{		i = 0;	}	if (i > 2)	{		if (i != (Get_Data_Buf[2] + 5))		{			return 0;		}		if (Get_Data_Buf[2] == 0X20)		{			memcpy(IM1253B_Data_Buf, Get_Data_Buf, 37); //将数据拷贝到IM1253B_Data_Buf数组中			return 1;		}	}	return 0;}

向电能计发送读取相关寄存器命令函数

void U_Send_RendCommand_IM1253B(void){	static uint8_t ReadCommad[8] =	{ 0x01, 0x03, 0x00, 0x48, 0x00, 0x08, 0xc4, 0x1a }; //读取IM1253B相关寄存器命令	uint8_t i = 0;	for (i = 0; i < 8; i++)	{		uart_putchar(UART_1, ReadCommad[i]);		systick_delay_ms(1);	}}

3.以太网模块相关驱动函数

对电能相关数据进行打包并发送给以太网模块函数

void U_Send_Ethernet_Data(void)//用户向以太网模块发送电能相关数据{	uint8_t U_Send_Ethernet_Data[45] =	{ 0x01, 0x46, 0x00, 0x00, 0x00, 0x10, 0x20 };		//电能和温度数据存储数组	Float_Data_Arry_Change_uchar(U_Send_Ethernet_Data, U_IM1253B_Data_Float,10);//浮点型16进制数据转化成字符型数据并存入电能和温度数据存储数组	U_GetCrcData(U_Send_Ethernet_Data, 39);		//计算Modbus RTU协议的CRC校验码	//systick_delay_ms(500);	uart_putbuff(UART_2, U_Send_Ethernet_Data, 41);}

向以太网发送设备开关指令函数

void U_Send_Ethernet_Data2(void)//发送开关指令{	uint8_t U_Send_Ethernet_Data2[12] =	{ 0x01, 0x45, 0x00, 0x00, 0x00, 0x10, 0x02 };		//开关	U_Send_Ethernet_Data2[7] = U_Ethernet_Data_Float[0];//将开关信号存入相关数组内	U_Send_Ethernet_Data2[8] = U_Ethernet_Data_Float[1];	U_GetCrcData(U_Send_Ethernet_Data2, 9);//计算校验位	uart_putbuff(UART_2, U_Send_Ethernet_Data2, 11);//输出开关指令}

对以太网模块返回到主板的数据进行判断后把特定数据存入数组中

uint8_t U_MCU_UART2_GetData_End = 0;  //串行口2接收数据结束标志位uint8_t Ethernet_Data_Buf[8] =	{ 0 };uint8_t U_Get_Ethernet_Data(uint8_t Get_Data)//接收以太网下发的数据并进行判断,存入数组中{	static uint8_t i = 0;	static uint8_t E_Data_Buf[8] =	{ 0 }; //存储获取数据数组	E_Data_Buf[i++] = Get_Data; //将获取到的数据存入数组	if (E_Data_Buf[0] != 0x01)  //判断帧头	{		i = 0;	}	if ((i == 2) && (E_Data_Buf[1] != 0x05)) //判断帧头	{		i = 0;	}	if ((i == 3) && (E_Data_Buf[2] != 0x00)) //判断帧头	{		i = 0;	}	if ((i == 4) && (E_Data_Buf[3] != 0x00)) //判断帧头	{		i = 0;	}	if(i == 8)//接收完一套完整的数据	{		memcpy(Ethernet_Data_Buf, E_Data_Buf, 9);将数据拷贝到Ethernet_Data_Buf数组中(比数组个数多一位,否则未知bug)	}}

计算校验位函数

static void U_GetCrcData(uint8_t *U_Data_Buffer, uint8_t len)//计算Modbus RTU协议的CRC校验码{	uint16_t wcrc = 0XFFFF;					//16位crc寄存器预置	uint8_t temp;	uint8_t CRC_L, CRC_H;	uint8_t i = 0, j = 0;			//计数	for (i = 0; i < len; i++)				//循环计算每个数据	{		temp = *U_Data_Buffer & 0X00FF;			//将八位数据与crc寄存器亦或		U_Data_Buffer++;							//指针地址增加,指向下个数据		wcrc ^= temp;						//将数据存入crc寄存器		for (j = 0; j < 8; j++)				//循环计算数据的		{			if (wcrc & 0X0001)				//判断右移出的是不是1,如果是1则与多项式进行异或。			{				wcrc >>= 1;					//先将数据右移一位				wcrc ^= 0XA001;				//与上面的多项式进行异或			}			else							//如果不是1,则直接移出			{				wcrc >>= 1;					//直接移出			}		}	}	CRC_L = wcrc & 0xff;							//crc的低八位	*U_Data_Buffer = CRC_L;	CRC_H = wcrc >> 8;							//crc的高八位	*(U_Data_Buffer + 1) = CRC_H;}

五、有人云平台控制面板


在有人云平台对控制界面进行编辑排版,定义相关变量及协议。

六、功能验证

1.完整成品展示

2.OLED 屏幕显示测试

将设备接入负载,打开电源。

如上所示,OLED 屏幕显示正常,且数据无错误。

3.有人云平台测试

接通电源和电器后在电脑端打开有人云平台
如上所示,数据能够正常显示且实时更新。

打开手机有人云平台小程序

如上所示,数据能正常显示且实时更新。

正常状态下散热器未打开

打开下发指令开关


如上所示,可见散热器开始转动,云平台下发指令成功,开发板执行指令成功。

综合上面几项测试,以RISC-V MCU CH32V103芯片为核心的开发板实现了对电能数据的收发和处理以及通过OLED正常显示,对云平台实现数据交换以及远程无线指令上发下发和执行功能,达到预想功能,测试成功。

七.演示视频

演示视频

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/121238.html

相关文章

  • 【沁恒CH32学习】——RISC-V架构学习笔记

    摘要:我首先百度简单了解了架构和架构的区别,以我个人的理解是架构代表之前的复杂指令集,而架构代表着精简指令集。而我这次的学习的重点并不是围绕着指令集,而是基于架构的开发板的应用上。以上就是我本次学习架构的笔记和心路历程。 作为新手第一次接触RISC-V架构时。我首先百度简单了解了ARM架构和RIS...

    nihao 评论0 收藏0
  • 不用 WASM,我们从头造轮子!采用 RISC-V 设计的区块链虚拟机 CKB-VM 诞生记

    摘要:在区块链上,虚拟机就是智能合约的运行环境,是一个可以完全对外隔离的完整计算机体系。区块链通过虚拟机来调用和执行智能合约,并要求所有节点都达成一致。 秘猿科技使命是用技术创造信任,为价值网络提供基础设施和服务。为了实现这个使命,我们三年来坚持初心,步步为营打造加密经济网络。我们想要让互联网回归到本源,用区块链技术,去构造更美好的社会,因此我们设计了 CKB 底层公链。我们自己造轮子,开创...

    joywek 评论0 收藏0
  • 当区块链遇见 RISC-V

    摘要:在区块链上,虚拟机就是智能合约的运行环境,是一个可以完全对外隔离的完整计算机体系。区块链通过虚拟机来调用和执行智能合约,并要求所有节点都达成一致。当区块链遇见在很多科技领域都得到了运用,目前,也开始在区块链领域逐渐的得以发展。 showImg(https://segmentfault.com/img/bVbsfi2?w=2779&h=1179); 区块链的出现使得智能合约得到了更好的实...

    Tychio 评论0 收藏0
  • 常见物联网操作系统介绍

    摘要:相比之下,物联网操作系统领域的碎片化问题则非常严重,并没有哪几个操作系统占据绝对优势,正处于百花齐放百家争鸣的阶段。在年被公司正式收购,将自己的服务内嵌到系统中,并于年推出了集成无线连接安全等功能的物联网操作系统。 物联网操作系统是运行在物联网设备上的提供物物相连能力的操作系统,其核心在于...

    AdolphLWQ 评论0 收藏0
  • 区块链正在重塑法律(上)

    摘要:秘猿科技法务总监钱靖受邀参加北京大学数字金融研究中心举办的数字金融第十讲,作为主讲嘉宾就区块链正在重塑法律做了主题演讲。而区块链在很大程度上可以帮助解决这些问题。第三个方面涉及到区块链对每个部门法的影响。 showImg(https://segmentfault.com/img/bVboMSK?w=1280&h=543); 秘猿科技法务总监钱靖受邀参加北京大学数字金融研究中心举办的数字...

    wendux 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<