xx新编基于以太网的用电监控系统设计案例内容摘要:

Delay_1ms(10)。 WriteToC02(AC_I_OFFSET_ADDR, AC_I_OFFSET, 3)。 //write AC_I_OFFSET TO EEPROM Delay_1ms(10)。 WriteToC02(AC_V_OFFSET_ADDR, AC_V_OFFSET, 3)。 //write AC_V_OFFSET TO EEPROM } void Start_AC_OFFSET_Adj(UINT8 *a, UINT8 *b, UINT8 *p, UINT8 *q) { Clear_DRDY()。 CS5460_WriteCommand(POWER_HALT)。 Clear_DRDY()。 CS5460_WriteCommand(DC_I_ADJ)。 Wait_DRDY_High()。 CS5460_ReadReg(I_DC_OFFSET, a)。 Clear_DRDY()。 CS5460_WriteCommand(DC_V_ADJ)。 Wait_DRDY_High()。 CS5460_ReadReg(V_DC_OFFSET, b)。 Clear_DRDY()。 CS5460_WriteCommand(AC_I_ADJ)。 Wait_DRDY_High()。 CS5460_ReadReg(I_AC_OFFSET, p)。 Clear_DRDY()。 CS5460_WriteCommand(AC_V_ADJ)。 Wait_DRDY_High()。 CS5460_ReadReg(I_AC_OFFSET, q)。 12 } 增益标定过程需要在电压电流通道 加入标准的 电压电流信号,假设为 I 和U ,在进行之前所述的校准之后,开启转换,分别获得转换结果 gI 和 gU ,再通过计算就可以得到电压电流关系系数 xI 和 xU : gxgx UUUIII  , 按上述方法就可以将读取到的数据,转换成实际的电压电流值。 程序如下: FP32 Get_VRMS(void) { UINT8 i,j。 UINT8 p[3]。 FP32 G = , temp =。 FP32 VoltRMS。 Wait_DRDY_High()。 CS5460_ReadReg(LAST_V_RMS, p)。 Clear_DRDY()。 for(i=0。 i=2。 i++) { for(j=1。 j=7。 j++) { if( (p[i]amp。 (1(8j))) != 0 ) temp+=G。 G = G/2。 } } VoltRMS = V * temp。 //黑体 V 为电压关系系数 return VoltRMS。 } FP32 Get_IRMS(void) { UINT8 i,j。 UINT8 p[3]。 FP32 G = , temp =。 FP32 CurrentRMS。 Wait_DRDY_High()。 CS5460_ReadReg(LAST_I_RMS, p)。 Clear_DRDY()。 for(i=0。 i=2。 i++) { for(j=1。 j=7。 j++) { if( (p[i]amp。 (1(8j))) != 0 ) temp+=G。 G = G/2。 } } CurrentRMS = I * temp。 //黑体 I 为 电流 关系系数 return CurrentRMS。 } 网络数据解析 前文指出, ENC28J60 的输出的 是标准的以太网 帧 数据 (以太网的相关协议, 13 请参考其他文献 ), MCU 需要对该数据进行解析。 目前已有比较完善的嵌入式以太网协议栈,将该协议栈移植到自己的系统中,提供一些底层的函数即可,如Lwip。 本 系统中使用了一种很简洁的以太网协议栈。 相应的数据解析函数 如下: extern UINT16 NETPcCheckSum(UINT8 *buf, UINT16 len, UINT8 type)。 //校验和 extern void NETPcInit(UINT8 *mymac, UINT8 *myip, UINT8 port)。 //设置本地的 IP、 MAC、端口 extern UINT8 NETPcEthIsArpAndMyIp(UINT8 *buf, UINT16 len)。 //检查 ARP和本机地址是否正确 extern UINT8 NETPcEthIsIpAndMyIp(UINT8 *buf, UINT16 len)。 //检查以太网类型、 IP 版本、 IP 地址 extern void NETPcMakeEth(UINT8 *buf)。 //建立以太网首部 extern void NETPcMakeIP(UINT8 *buf)。 //建立 IP 首部 extern void NETPcFillIPHdrChkSum(UINT8 *buf)。 //填充 IP 包校验和 extern void NETPcMakeTcpHead(UINT8 *buf, UINT16 rel_ack_num, UINT8 mss, UINT8 cp_seq)。 //建立 TCP首部 extern void NETPcMakeArpAnswer(UINT8 *buf)。 //ARP 应答 extern void NETPcMakeEchoReply(UINT8 *buf, UINT16 len)。 //ECHO应答 extern void NETPcMakeUdpReply(UINT8 *buf, char *data, UINT8 datalen, UINT16 port)。 //填充 UDP 应答数据 extern void NETPcMakeTcpSynAck(UINT8 *buf)。 //TCP 同步应答 extern void NETPcInitLenInfo(UINT8 *buf)。 //初始化响应的数据长度 extern UINT16 NETPcGetTcpDataPointer(void)。 //获取 TCP数据包指针 extern UINT16 Fill_tcp_data(UINT8 *buf, UINT16 pos, const char *s)。 //填充 TCP 数据 extern void NETPcMakeTcpAck(UINT8 *buf)。 //填充 TCP应答信息 extern void NETPcMakeTcpAckWithData(UINT8 *buf, UINT16 dlen)。 //发送 TCP 数据 操作系统任务与软件流程 本系统移植了 嵌入式操作系统 uCOSII,重点介绍系统的任务划分,对于操作系统的移植不作过多阐述。 本系统需要下列任务结合完成功能: static void App_TaskCreate(void)。 //创建任务的函数 static void App_TaskStart(void *p_arg)。 //首个任务,用于创建其他任务, 调用 App_TaskCreate() static void EthRec_Task(void *p_arg)。 //网络数据接受任务 static void EthRecAnalysis_Task(void *p_arg)。 //网络数据标志位分析任务 static void SysInfoDisp_Task(void *p_arg)。 //系统信息显示任务 static void Led1_Task(void *p_arg)。 //运行指示灯任务一 static void Led2_Task(void *p_arg)。 //运行指示灯任务二 static void Key_Task(void *p_arg)。 //键盘任务 static void ADJ_Task(void *p_arg)。 //校准任务 static void ReConfigEth_Task(void *p_arg)。 //网络重配置任务 static void TimeSet_Task(void *p_arg)。 //RTC 时间校对 任务 上述任务之间使用操作系统提供的邮箱进行通信 ,某些任务由其他任务通过这种通信机制来触发。 网络数据标志位分析 任务对接收到数据中的标志位进行解析, 来触发网络重配置任务和 RTC 时间校对任务 , 系统默认一个本地 IP 地址,若用户要重新配置 IP 地址是允许的, 由网络重配置任务 来完成; RTC 时间校对任务,是接受来自网络的时间数据来校对系统的 RTC 时钟。 键盘任务负责触发校准任务。 被触发的任务往往只需要运行一次,所以在这些任务执行一次后就要删除它,来减轻操作系统的调 度。 14 前文 给出的转换函数返回值是一个浮点数,为了方便数据传输,将浮点数转成了一个 8位字符数组,函数如下: //浮点数转换到字符数组 void Float_To_Array(UINT8 *temp, FP32 FloatVariables) { UINT8 i。 UINT8 *pdata = (UINT8 *)amp。 FloatVariables。 for (i=0。 i4。 i++) { temp[i] = *pdata++。 } } 在软件中定义了 两个 与数据接收和发送相关的联合体:union { UINT8 Temp[13]。 struct { UINT8 IP_Set_Flag :1。 //网络设置 UINT8 RTC_Set_Flag :1。 //时间校对 UINT8 other_Flag :6。 //保留位 UINT8 Year[2]。 //年份两字节 UINT8 Mon。 //月份 UINT8 Day。 //日期 UINT8 Dow。 //星期 UINT8 Hour。 //小时 UINT8 Min。 //分鈡 UINT8 Sec。 //秒 UINT8 Rec_IP[4]。 //IP 地址 ,32位 }data。 }Eth_UDP_Rec。 union { UINT8 Temp[17]。 struct { UINT8 Meter_Flag :1。 //正在测量 UINT8 RTC_Set_Flag :1。 //正在校对 UINT8 other_Flag :6。 保留位 UINT8 T_Temp[4]。 温度 值 字符数组 UINT8 V_Temp[4]。 电压值 字符数组 UINT8 I_Temp[4]。 电流值 字符数组 UINT8 P_Temp[4]。 功率值 字符数组 }data。 }Eth_UDP_Sen。 软件流程图: 开 始u C O S I I 初 始 化板 级 的 硬 件 初 始 化创 建 首 个 任 务u C O S I I 运 行键 盘 任 务 系 统 信 息 显 示 任 务 网 络 数 据 接 收 任 务网 络 数 据 标 志 位 分 析运 行 指 示 灯 任 务采 集。 发 送 采 集 数 据 , 返 回 Y N时 间 校 对。 重 配 置。 N N时 间 校 对 任 务执 行 完 删 除 任 务网 络 重 配 置 任 务Y Y校 准。 Y创 建 校 准 任 务 N执 行 完 删 除 任 务执 行 完 删 除 任 务图 19 15 开发环境的使用 生成新的工作区 生成新的项目 设置项目选项 编译链接和调试应用。
阅读剩余 0%
本站所有文章资讯、展示的图片素材等内容均为注册用户上传(部分报媒/平媒内容转载自网络合作媒体),仅供学习参考。 用户通过本站上传、发布的任何内容的知识产权归属用户或原始著作权人所有。如有侵犯您的版权,请联系我们反馈本站将在三个工作日内改正。