查看: 4390|回复: 3

[原创] 【LPC54114双核任务二】②双核通讯+串口控制

[复制链接]
  • TA的每日心情
    擦汗
    2017-12-29 14:09
  • 签到天数: 144 天

    连续签到: 1 天

    [LV.7]常住居民III

    9

    主题

    534

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1857
    最后登录
    2025-7-22
    发表于 2017-7-1 21:03:41 | 显示全部楼层 |阅读模式
    本帖最后由 liao122 于 2017-7-2 21:02 编辑

    上个帖子 (【LPC54114双核任务二】① 双核通讯 mailbox) 中说到双核之间可以通过mailbox来进行通讯;

    本帖主要讲的是 用M0+来进行串口数据的收发,M4进行数据处理控制

    我们知道通过mailbox 的中断方式 双核间能传递一个的32bit的值,由于串口不可能总是一个值,为了能够一次中断传递多个值,我们可以借助指针,首先创建一个结构体和一个指向该结构体的指针、一个存字符串的数组
    1. struct mail_message
    2. {
    3.     uint8_t *string;        //传递字符串指针
    4.     uint8_t num;            //传递的字符数
    5. }s_message;

    6. struct mail_message p_message;
    7. uint8_t bufferString[50] = {0};
    复制代码
    然后
    1. p_message = &s_message;                         //把s_mssage的地址给指针p_message
    2. g_msg = (uint32_t)p_message;                    //把p_message 强制转换为32bit的值给g_msg
    3. MAILBOX_SetValue(MAILBOX, kMAILBOX_CM4, g_msg);
    复制代码

    这样我们就能在一次mailbox中断传递多个数值了

    程序主体流程如下:
    M0+ 这边  
                      1、接收PC端串口发来的数据,当接收完成后通过mailbox传给M4核;
                      2、接收M4核通过mailbox发来数据,并进行串口打印输出到PC端;

    M4 这边   
                      1、接收M0+通过mailbox发来的数据,并通过mailbox回传给M0+
                      2、根据接收的数据进行处理(打开LED1、关闭LED1、向M0+发送字符串)

    下面进行代码讲解:
    M0+ 这边
      mailbox的中断函数
    1. void MAILBOX_IRQHandler()
    2. {
    3.     g_msg = MAILBOX_GetValue(MAILBOX, kMAILBOX_CM0Plus);        // 读取从M0+发来的值
    4.   
    5.     p_message =(struct mail_message *)g_msg;                    // 将g_msg 转换为指针
    6.     receive_flag = 1;                                            //收到M0+数据标志位
    7.    
    8.     MAILBOX_ClearValueBits(MAILBOX, kMAILBOX_CM0Plus, 0xffffffff);      
    9. }
    复制代码

    串口接收中断函数
         约定PC端发来的数据以‘#’号结束符
    1. void DEMO_USART_IRQHandler(void)
    2. {
    3.     uint8_t data;
    4.     /* If new data arrived. */
    5.     if ((kUSART_RxFifoNotEmptyFlag | kUSART_RxError) & USART_GetStatusFlags(DEMO_USART))
    6.     {
    7.         data = USART_ReadByte(DEMO_USART);
    8.         bufferString[pc_receive_index] = data;
    9.         if (bufferString[pc_receive_index] == '#')                     
    10.         {
    11.             pc_receive_flag = 1;                                    //接收完成PC端数据标志位
    12.         }
    13.         pc_receive_index++;                                           //记录接收的字符数
    14.     }
    15. }
    复制代码


    主函数主体
    1. while (1)
    2. {
    3.     if (receive_flag == 1)  // receive data from cm4
    4.     {
    5.         receive_flag = 0;
    6.         USART_WriteBlocking(DEMO_USART, p_message->string, p_message->num);
    7.     }

    8.     if (pc_receive_flag == 1) //receive data from pc uart
    9.     {
    10.         pc_receive_flag = 0;

    11.         s_message.num = pc_receive_index;
    12.         pc_receive_index = 0;
    13.         s_message.string = bufferString;
    14.         p_message = &s_message;
    15.         g_msg = (uint32_t)p_message;
    16.         MAILBOX_SetValue(MAILBOX, kMAILBOX_CM4, g_msg);
    17.     }                    
    18. }
    复制代码

    M4 这边

    mailbox的中断函数
    1. void MAILBOX_IRQHandler()
    2. {
    3.     g_msg = MAILBOX_GetValue(MAILBOX, kMAILBOX_CM4);
    4.     p_message =(struct de *)g_msg;
    5.     receive_flag = 1;
    6.     MAILBOX_ClearValueBits(MAILBOX, kMAILBOX_CM4, 0xffffffff);
    7. }
    复制代码

    主函数主体
    1. while (1)
    2. {
    3.     if (receive_flag == 1)  // receive data from cm0+
    4.     {
    5.         receive_flag = 0;
    6.         s_message.num = p_message->num;
    7.         buffer_num = p_message->num;
    8.         s_message.string = p_message->string;
    9.         for (i=0; i<(s_message.num); i++)
    10.         {
    11.             bufferString[i] = *(p_message->string);
    12.             (p_message->string)++;
    13.         }

    14.         if (   (bufferString[0] == 'L')             //当收到“LED1 ON”时
    15.             && (bufferString[1] == 'E')
    16.             && (bufferString[2] == 'D')
    17.             && (bufferString[3] == '1')
    18.             && (bufferString[4] == ' ')
    19.             && (bufferString[5] == 'O')
    20.             && (bufferString[6] == 'N'))
    21.         {
    22.             Led(0,15,1);                             //点亮LED1
    23. /*********向M0+ 发送“The CM4 receive is: ” 字符串******************/
    24.             s_message.string = string_order_re;
    25.             s_message.num = sizeof(string_order_re)/sizeof(string_order_re[0]);
    26.             p_message = &s_message;
    27.             g_msg = (uint32_t)p_message;
    28.             /* Wr ite g_msg to CM0+ mailbox register - it causes interrupt on CM0+ core */
    29.             MAILBOX_SetValue(MAILBOX, kMAILBOX_CM0Plus, g_msg);

    30. /*********向M0+回传接收的字符串******************/
    31.             delay();             // 等待M0+ 接收数据
    32.             s_message.string = bufferString;
    33.             p_message = &s_message;
    34.             g_msg = (uint32_t)p_message;
    35.             /* Wr ite g_msg to CM0+ mailbox register - it causes interrupt on CM0+ core */
    36.             MAILBOX_SetValue(MAILBOX, kMAILBOX_CM0Plus, g_msg);
    37.                                        
    38. /*********向M0+ 发送“LED1 has been open. ” 字符串******************/
    39.             delay();
    40.             s_message.string = string_order_ledopen;
    41.             s_message.num = sizeof(string_order_ledopen)/sizeof(string_order_ledopen[0]);
    42.             p_message = &s_message;
    43.             g_msg = (uint32_t)p_message;
    44.             /* Wr ite g_msg to CM0+ mailbox register - it causes interrupt on CM0+ core */
    45.             MAILBOX_SetValue(MAILBOX, kMAILBOX_CM0Plus, g_msg);
    46.             delay();
    47.             for (i=0; i<buffer_num; i++)                 //清除接收数组bufferString中数据
    48.             {
    49.                 bufferString[i] = 0;
    50.             }

    51.         }
    52.         else if (  (bufferString[0] == 'L')       //当接收到“LED1 OFF”字符串
    53.                 && (bufferString[1] == 'E')
    54.                 && (bufferString[2] == 'D')
    55.                 && (bufferString[3] == '1')
    56.                 && (bufferString[4] == ' ')
    57.                 && (bufferString[5] == 'O')
    58.                 && (bufferString[6] == 'F')
    59.                 && (bufferString[7] == 'F'))
    60.         {
    61.             Led(0,15,0);                       //灭掉LED1

    62. /*********向M0+ 发送“The CM4 receive is: ” 字符串******************/
    63.             s_message.string = string_order_re;
    64.             s_message.num = sizeof(string_order_re)/sizeof(string_order_re[0]);
    65.             p_message = &s_message;
    66.             g_msg = (uint32_t)p_message;
    67.             /* Wr ite g_msg to CM0+ mailbox register - it causes interrupt on CM0+ core */
    68.             MAILBOX_SetValue(MAILBOX, kMAILBOX_CM0Plus, g_msg);
    69.                                        
    70. /*********向M0+回传接收的字符串******************/
    71.             delay();
    72.             s_message.string = bufferString;
    73.             p_message = &s_message;
    74.             g_msg = (uint32_t)p_message;
    75.             /* Wr ite g_msg to CM0+ mailbox register - it causes interrupt on CM0+ core */
    76.             MAILBOX_SetValue(MAILBOX, kMAILBOX_CM0Plus, g_msg);
    77.                                        
    78. /*********向M0+ 发送“LED1 has been close. ” 字符串******************/
    79.             delay();
    80.             s_message.string = string_order_ledclose;
    81.             s_message.num = sizeof(string_order_ledclose)/sizeof(string_order_ledclose[0]);
    82.             p_message = &s_message;
    83.             g_msg = (uint32_t)p_message;
    84.             /* Wr ite g_msg to CM0+ mailbox register - it causes interrupt on CM0+ core */
    85.             MAILBOX_SetValue(MAILBOX, kMAILBOX_CM0Plus, g_msg);

    86.             delay();
    87.             for (i=0; i<buffer_num; i++)
    88.             {
    89.                 bufferString[i] = 0;
    90.             }
    91.         }
    92. /*****************其他字符串回传M0+********************/
    93.         else                  
    94.         {
    95.             s_message.string = string_order_re;
    96.             s_message.num = sizeof(string_order_re)/sizeof(string_order_re[0]);
    97.             p_message = &s_message;
    98.             g_msg = (uint32_t)p_message;
    99.             /* Wr ite g_msg to CM0+ mailbox register - it causes interrupt on CM0+ core */
    100.             MAILBOX_SetValue(MAILBOX, kMAILBOX_CM0Plus, g_msg);

    101.             delay();
    102.             s_message.string = bufferString;
    103.             p_message = &s_message;
    104.             g_msg = (uint32_t)p_message;
    105.             /* Wr ite g_msg to CM0+ mailbox register - it causes interrupt on CM0+ core */
    106.             MAILBOX_SetValue(MAILBOX, kMAILBOX_CM0Plus, g_msg);

    107.             delay();                        // wait for M0+ taken data finish
    108.             for (i=0; i<buffer_num; i++)      // clear receive data
    109.             {
    110.                 bufferString[i] = 0;
    111.             }
    112.         }
    113.     }
    114. }
    复制代码

    程序运行结果
    注意: 把发送新行的√去掉(勾上运行就不一样了,还没找到原因)

    mailbox 串口.png

    任务2板子.jpg
    程序是在SDK_2.2.1_LPCXpresso54114\boards\lpcxpresso54114\driver_examples\mailbox\interrupt   例程上修改的,只需替换相应的主函数即可(主函数见附件)





    项目的主函数.zip

    6.23 KB, 下载次数: 15, 下载积分: 威望 1

    项目主函数

    签到!!!
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2018-3-27 15:23
  • 签到天数: 49 天

    连续签到: 1 天

    [LV.5]常住居民I

    0

    主题

    109

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    333
    最后登录
    2018-6-28
    发表于 2017-7-2 13:25:41 | 显示全部楼层
    学习了   
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2018-3-27 15:23
  • 签到天数: 49 天

    连续签到: 1 天

    [LV.5]常住居民I

    0

    主题

    109

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    333
    最后登录
    2018-6-28
    发表于 2017-7-2 13:26:13 | 显示全部楼层

    学习了   
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2017-11-20 11:31
  • 签到天数: 123 天

    连续签到: 1 天

    [LV.7]常住居民III

    1

    主题

    313

    帖子

    0

    高级会员

    Rank: 4

    积分
    893
    最后登录
    2018-7-13
    发表于 2017-7-2 15:41:58 | 显示全部楼层
    见识了
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

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

    本版积分规则

    关闭

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

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

    GMT+8, 2025-8-31 06:39 , Processed in 0.080622 second(s), 23 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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