查看: 12515|回复: 22

[LPC双核挑战赛] 基于双核ARM-LPC54114-Lite的真有效值交流电压表

[复制链接]
  • TA的每日心情
    开心
    2023-12-29 09:54
  • 签到天数: 10 天

    [LV.3]偶尔看看II

    7

    主题

    267

    帖子

    10

    金牌会员

    Rank: 6Rank: 6

    积分
    4368
    最后登录
    2024-4-19
    发表于 2018-5-25 10:26:16 | 显示全部楼层 |阅读模式
    本帖最后由 wenyangzeng 于 2018-7-6 11:36 编辑

    一、  项目名称
    基于双核ARM-LPC54114-Lite的真有效值交流电压表

    图片1.JPG


    二、项目概述

       一般的交流电压测量采用的是分压整流后测量其有效值的方法,由于整流二极管非线性特性,测量并不能得到真实的有效值测量结果,且对于非正弦波的测量,误差更大。基于双核ARM-LPC54114-Lite的真有效值交流电压表测量方法是对一个交流电的周期连续采样,按下式进行计算,得到真实的真有效值电压值。对于非正弦波波形的测量,也能得到正确的测量结果。

    SIN.jpg
          本项目使用LPC54114-Lite开发板的4个ADC通道对三相交流电压进行ADC转换,并按照上式进行数学运算,得出三相交流电压R、S、T的线对线(L-L)、线对零(L-N)共6组的真有效值电压数据,然后在OLED屏上显示。充分利用LPC54114-Lite双核的优势,M4负责数学运算和显示,M0+负责ADC转换和数据传送,轻松实现本项目的功能。本项目具有成本低、测量交流电压真实度高的特点,具有一定的推广使用价值。


    三、功能的实现
    1、双核任务分配
         如果使用LPC54114-Lite仍按照单核ARM的模式来写代码,就失去了LPC54114双核的优势。本项目利用NXP官方现成的Remote Processor Messaging_Lite库(RPMsg-Lite)工程框架,很方便的实现双核通讯机制来调度M4与M0+对共享RAM的访问权限,很好地解决了双核访问共享RAM的互斥的问题。任务分配:M0+负责4个通道ADC转换和数据传输任务,M4内核负责对数据进行复杂数学运算和显示。双核RPMsg-Lite通讯框图参见图1:

    多核通讯机制.jpg
                                 图1

    2、硬件
       开发板资源
        需要使用LPC54114-Lite 4个通道ADC,在不改变开发板硬件连接前提下,阅读原理图查阅LPC54114-Lite剩余可利用资源,可知ADC功能可分配GPIO引脚为P1.3、P1.4、P1.8和P1.0(ADC3、6、7、11),驱动OLED显示屏可用的GPIO引脚为P0.11、P0.12、P0.14、P1.10、P1.11。


        外扩资源:
           需要外扩ADC采样前置电路(见图2):3只1:1电压互感器T1-T3用于初级交流电高压端和次级输入信号低压端的安全隔离,初级串接的高阻值电阻R1-R3保证电压互感器线圈绕组工作在线性区并且不过流。T1-T3次级经过R7-R9、C1-C3的RC滤波后进入LPC54114-Lite的ADC输入端。并联在次级线圈上的电阻R4-R6阻尼了次级绕组的反峰压,保护LPC54114输入端不因脉冲过压损坏。图2中T1-T3次级线圈公共点连接到ADC3,ADC3连接到开发板上的可调电阻调节在1/2VCC。这样的连接把交流电波形的负电压巧妙的“垫高”到GND电平,使得ADC能够完整采样整个交流电波形。

    原理图.jpg
                                   图2

    3、 软件

    开发环境:

        MDK5.23

    工程模板:
        直接利用SDK_2.3.0_LPCXproesso5441\boards\lpcxpresso54114\multicore_examples\rpmsg_lite_pingpong这个官方演示包进行修改使用。

    双核通讯:
           演示包rpmsg_lite_pingpong这个工程预先为我们建立了一个双核乒乓通讯触发事件机制,稍加修改用来运行本工程非常方便。M4与M0+的通讯调度过程如下:
    ①         首先在0x20022000建立一个共享内存:二维数组results[40][4]用于双核共享存取ADC数据;
    ②         修改rpmsg_lite_send()函数为我所用;
    ③         在M0+工程添加nxp官方ADC库函数,ADC转换速率设置刚好满足一个交流电周期采样4个通道每通道40次,M0+不停的进行ADC转换;
    ④         在M4工程添加OLED和真有效值数学计算函数;
    ⑤         M4发送msg数据请求通知给M0+,M0+将最近转换完成的ADC数据传送到共享内存数组results中;
    ⑥         M0+发送数据准备好msg给M4;
    ⑦         M4处理数据、刷新OLED后与M0+进行下一次通讯。

    修改后的工程结构见图3

    项目.png

                         图3

    双核调试:

          在社区看到帖子介绍双核的调试,有的说要打开2个MDK,有的说要IAR8才能调双核等等。菜鸟初次接触双核LPC,一开始确实有点信心不足。参阅NXP官网资料和NXP社区大侠详细介绍调试经验,经过一段时间动手练习,逐步掌握正确的调试方法。调试过程中发现:LPC54114-Lite开发板附带的CMSIS DAP仿真工具给双核调试带来极大方便。先编译M0+核,生成.BIN文件。(NXP官方已经在rpmsg_lite_pingpong工程里把生成BIN的参数配置都预设好),然后编译M4核、下载代码,M0+的.BIN也自动下载了。当需要修改M0+时,激活m0+的工程(社区大侠有许多帖子详细介绍,不再贴图了),修改编译后回到M4工程,重新编译下载后即可运行。

        其实:用MDK调试双核是很简单的

        下载完成,点击运行,运行结果达到原设计要求,参见附件的图片和视频链接。初次接触LPC54114-Lite,亲身体验到双核ARM相对单核ARM的性能的差异,感受到双核ARM的更强大,对将来产品设计优先选择双核ARM有了深刻的认识。

    图片2.JPG

    图片3.jpg

    图片4.jpg


    True RMS.part01.rar (9.02 MB, 下载次数: 0)

    评分

    参与人数 1 +5 收起 理由
    doatello + 5

    查看全部评分

    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 18:45
  • 签到天数: 2149 天

    [LV.Master]伴坛终老

    17

    主题

    4601

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    9744
    最后登录
    2024-4-19
    发表于 2018-5-25 11:52:52 | 显示全部楼层
    这个厉害了
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2023-12-29 09:54
  • 签到天数: 10 天

    [LV.3]偶尔看看II

    7

    主题

    267

    帖子

    10

    金牌会员

    Rank: 6Rank: 6

    积分
    4368
    最后登录
    2024-4-19
     楼主| 发表于 2018-5-25 12:32:13 | 显示全部楼层

    谢谢支持!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-26 15:16
  • 签到天数: 266 天

    [LV.8]以坛为家I

    3298

    主题

    6545

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32003
    最后登录
    2024-4-9
    发表于 2018-5-25 13:30:59 | 显示全部楼层
    赞赞!
    签到签到
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2020-6-16 09:38
  • 签到天数: 589 天

    [LV.9]以坛为家II

    3

    主题

    1039

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    2387
    最后登录
    2020-6-16
    发表于 2018-5-25 23:58:04 | 显示全部楼层
    完成速度很快,支持一下!
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2023-12-29 09:54
  • 签到天数: 10 天

    [LV.3]偶尔看看II

    7

    主题

    267

    帖子

    10

    金牌会员

    Rank: 6Rank: 6

    积分
    4368
    最后登录
    2024-4-19
     楼主| 发表于 2018-5-26 07:20:00 | 显示全部楼层
    eric_bestmyself 发表于 2018-5-25 23:58
    完成速度很快,支持一下!

    谢谢支持
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    昨天 09:54
  • 签到天数: 1731 天

    [LV.Master]伴坛终老

    4

    主题

    7025

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    11340
    最后登录
    2024-4-19
    发表于 2018-5-28 09:11:58 | 显示全部楼层
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2021-7-15 11:21
  • 签到天数: 61 天

    [LV.6]常住居民II

    4

    主题

    173

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    429
    最后登录
    2023-2-27
    发表于 2018-6-5 17:50:01 | 显示全部楼层
    就冲楼主这么认真上传的东西,我就得投一票。
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2023-12-29 09:54
  • 签到天数: 10 天

    [LV.3]偶尔看看II

    7

    主题

    267

    帖子

    10

    金牌会员

    Rank: 6Rank: 6

    积分
    4368
    最后登录
    2024-4-19
     楼主| 发表于 2018-6-5 18:59:59 | 显示全部楼层
    碎了心 发表于 2018-6-5 17:50
    就冲楼主这么认真上传的东西,我就得投一票。

    谢谢楼上的支持。认真做好每一件工作才对得起LPC54114。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2021-7-15 11:21
  • 签到天数: 61 天

    [LV.6]常住居民II

    4

    主题

    173

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    429
    最后登录
    2023-2-27
    发表于 2018-6-6 22:31:30 | 显示全部楼层
    wenyangzeng 发表于 2018-6-5 18:59
    谢谢楼上的支持。认真做好每一件工作才对得起LPC54114。
    不用客气,作为小白的我,想问大佬一个问题。就是想用上位机调电机PID。这个好像是被人写的上位机,但我不知道怎么整合到我的程序里,是只要改UART吗,具体应该怎么改?望大佬不吝赐教。

    /*
    * wave.h
    *
    *  Created on: Nov 29, 2014
    *      Author: ass
    */
    #ifndef WAVE_H_
    #define WAVE_H_

    #include "uart.h"

    void Uart1_Send_AF(signed int aa,signed int bb,signed int cc,signed int dd,signed int ee,signed int ff,signed int gg,signed int hh);
    unsigned char UART_Putc(unsigned char data);
    void send_wave(void);

    void printhh(void);
    void print5n(unsigned int x);
    void print4n(unsigned int x);
    void print3n(unsigned int x);
    void print2n(unsigned int x);

    #endif /* WAVE_H_ */


    #include "wave.h"
    #include "uart.h"

    #define tx_num        32

    unsigned char TxBuffer[tx_num];
    unsigned char count=0;

    #define BYTE0(dwTemp)       (*(char *)(&dwTemp))
    #define BYTE1(dwTemp)       (*((char *)(&dwTemp) + 1))
    #define BYTE2(dwTemp)       (*((char *)(&dwTemp) + 2))
    #define BYTE3(dwTemp)       (*((char *)(&dwTemp) + 3))

    /**************************向物理串口发一个字节***************************************
    *******************************************************************************/
    __inline unsigned char UART_Putc(unsigned char data)                        //
    {
            uart_send1(UART_1,data);
            return data;
    }

    unsigned char Uart1_Put_Char(unsigned char DataToSend)
    {
            TxBuffer[count++] = DataToSend;  
            return DataToSend;
    }

    unsigned char Uart1_Put_Int16(uint16_t DataToSend)
    {
            unsigned char sum = 0;
            TxBuffer[count++] = BYTE1(DataToSend);
            TxBuffer[count++] = BYTE0(DataToSend);
            sum += BYTE1(DataToSend);
            sum += BYTE0(DataToSend);
            return sum;
    }


    void Uart1_Send_AF(signed int aa,signed int bb,signed int cc,signed int dd,signed int ee,signed int ff,signed int gg,signed int hh)
    {
            unsigned char sum = 0;
            count=0;
            sum += Uart1_Put_Char(0x88);
            sum += Uart1_Put_Char(0xAF);
            sum += Uart1_Put_Char(0x1C);
            sum += Uart1_Put_Char(BYTE1(aa));//1
            sum += Uart1_Put_Char(BYTE0(aa));
            sum += Uart1_Put_Char(BYTE1(bb));//2
            sum += Uart1_Put_Char(BYTE0(bb));
            sum += Uart1_Put_Char(BYTE1(cc));//3
            sum += Uart1_Put_Char(BYTE0(cc));
            sum += Uart1_Put_Char(BYTE1(dd));//4
            sum += Uart1_Put_Char(BYTE0(dd));
            sum += Uart1_Put_Char(BYTE1(ee));//5
            sum += Uart1_Put_Char(BYTE0(ee));
            sum += Uart1_Put_Char(BYTE1(ff));//6
            sum += Uart1_Put_Char(BYTE0(ff));
            Uart1_Put_Char(0);
            Uart1_Put_Char(0);
            Uart1_Put_Char(0);
            Uart1_Put_Char(0);
            Uart1_Put_Char(0);
            Uart1_Put_Char(0);
            sum += Uart1_Put_Char(BYTE1(gg));//7,4500->45'//这是姿态!!!
            sum += Uart1_Put_Char(BYTE0(gg));
            sum += Uart1_Put_Char(BYTE1(hh));//8
            sum += Uart1_Put_Char(BYTE0(hh));
            Uart1_Put_Char(0);
            Uart1_Put_Char(0);
            Uart1_Put_Char(0);
            Uart1_Put_Char(0);
            Uart1_Put_Char(0);
            Uart1_Put_Char(0);
            Uart1_Put_Char(sum);
    }

    void send_wave(void)
    {
            char count_1=0;
            while(count_1<tx_num)
          UART_Putc(TxBuffer[count_1++]);
    }
    ///////////////////////////////////////////////////////////////////////

    void printhh(void)
      {
            UART_Putc(0x0d);                                //output'CR'
            UART_Putc(0x0A);                                //output'CR'
      }

    void print5n(unsigned int x)
      {          
               UART_Putc((x/10000)+0x30);           //计算万位数字
               UART_Putc(((x%10000)/1000)+0x30);    //计算千位数字
               UART_Putc(((x%1000)/100)+0x30);      //计算百位数字
               UART_Putc(((x%100)/10)+0x30);        //计算十位数字
               UART_Putc((x%10)+0x30);              //计算个位数字
      }

    void print4n(unsigned int x)
      {          
              UART_Putc((x/1000)+0x30);    //计算千位数字
              UART_Putc(((x%1000)/100)+0x30);      //计算百位数字
              UART_Putc(((x%100)/10)+0x30);        //计算十位数字
              UART_Putc((x%10)+0x30);              //计算个位数字
      }
    void print3n(unsigned int x)
    {
            UART_Putc((x/100)+0x30);      //计算百位数字
            UART_Putc(((x%100)/10)+0x30);        //计算十位数字
            UART_Putc((x%10)+0x30);   
    }
    void print2n(unsigned int x)
    {

            UART_Putc((x/10)+0x30);        //计算十位数字
            UART_Putc((x%10)+0x30);   
    }


    这个好像是被人写的上位机,但我不知道怎么整合到我的程序里,是只要改UART吗,具体应该怎么改?





    波形显示总结.zip

    1.95 MB, 下载次数: 18, 下载积分: 威望 1

    网上找的上位机和程序

    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-20 06:47 , Processed in 0.161696 second(s), 33 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表