查看: 5456|回复: 5

[原创] 【LPC54114双核任务二】双核之从零开始--#mailbox通信4之PC_M4_M0#

[复制链接]
  • TA的每日心情

    2021-1-28 20:09
  • 签到天数: 317 天

    连续签到: 1 天

    [LV.8]以坛为家I

    61

    主题

    1582

    帖子

    6

    金牌会员

    Rank: 6Rank: 6

    积分
    9365
    最后登录
    2022-5-12
    发表于 2017-7-1 08:23:39 | 显示全部楼层 |阅读模式
    本帖最后由 小马哥-1650185 于 2017-7-2 11:33 编辑

    在上回书 【LPC54114双核任务二】双核之从零开始--#mailbox通信3之按键#中主要搭建了按键发送mailbox的平台,测试外部触发模式  M4  TO  M0 的mailbox  中断通信新机制。也提到了是为PC触发做准备的。。。
    PS:小马哥的帖子绝对为原创,亲测,跟着小马哥一系列的帖子足矣让小白们入门上手了,包含了官方demo实例讲解,还有自己加的一些实战例子,后面有时间 还要添加wifii模块测试,亲们如果喜欢,请多多支持,可以跟着小马哥的思路实测,如果抄贴,,请注明出处。。。

    话说这个帖子的功能代码也是调到昨天大半夜(7.1凌晨3点)。上班真的很忙,白天各种项目代码都要搞,只有晚上有那么一丁点时间,为了调出来结果,带领大家也是拼了。。。

    对了,由于串口助手接收只能选单一的ascii或者hex模式,为了避免乱码,小马哥只能委屈下,吧串口接收的数据全部以ascii码显示了,发送的数据还是hex,这里就需要单片机把需要发送的数据 转码成ascii码了,也是为了更直观的说明使用串口的USART_WriteByte(),USART_ReadByte()收发数据的。也就多麻烦一步,懒得用PRINTF()函数发送数据了,这个就用来纯粹打印调试信息了

    声明:代码部分只是为了验证实现功能,并非严禁规范,多多海涵。。。。

    老规矩  先看下结果图吧,,大晚上3点拍的。。。呜呜~~~~(>_<)~~~~

    11111.png
    2.png

    -------------------------------------------------------------------------------------------------------
    好了,下面具体讲解吧。。。


    思路:
    按键部分:和上个帖子基本上差不多,做了一个按键扫描函数void key_scan(void)(详见#mailbox通信3之按键#),通过检测PB2是否按下?
           如果PB2按下,LE7绿灯翻转,打印提示信息,并通过MAILBOX_SetValue函数发送一个数据g_msg给M0核,M0核接收到数据g_msg,触发mailbox中断,在中断中自加一次,原路返回(通过MAILBOX_SetValue发给M4核),触发M4核的mailbox中断,在M4的mailbox ISR中,把接到到的 (g_msg+1)转成ascii码的格式通过串口0发送给PC,这里用到了串口发送函数USART_WriteByte(DEMO_USART, demoRingBuffer[txIndex]);


    按键PB2的效果图:
    3.png

    PC部分:
           这里重新初始化了uart0,开启了串口0的收发中断,从PC接收到的数据在回调函数void DEMO_USART_IRQHandler(void)中处理。PC通过串口助手发送一个数据g_msg给M4核,触发M4的串口接收中断,在串口中断,通过双核邮箱机制MAILBOX_SetValue函数把这个数据传输给M0核,M0核处理和上面一样,返回给M4核的数据 进行了 加一 操作(g_msg),触发M4核的mailbox中断,在M4的mailbox ISR中,把接到到的 (g_msg+1)转成ascii码的格式通过串口0发送给PC,这里用到了串口发送函数USART_WriteByte(DEMO_USART, demoRingBuffer[txIndex]);


    PC发送效果图
    4.png


    以上就是大致流程思路,,,,,,,下面附加代码讲解。。。。。
          先说M0核吧,因为无论是按键还是PC,M0核中mailbox处理的数据是一样的。。。配置和上个帖子一样的,就贴出来邮箱中断处理函数把。
    这里对接收数据限制了一下,一个字节的,所以超过255,强制为0,同样进中断,LED11翻转,提示M0和收到了数据,在处理。。。。
    1. void MAILBOX_IRQHandler()
    2. {
    3.     g_msg = MAILBOX_GetValue(MAILBOX, kMAILBOX_CM0Plus);

    4.     if(g_msg<=255) g_msg++;
    5.         else
    6.         {g_msg = 0;
    7.         }
    8.     led11_flg ^=1;

    9.         if(1 ==led11_flg )
    10.         {
    11.                 LED11_ON();
    12.         }
    13.         else
    14.         {
    15.                 LED11_OFF();
    16.         }
    17.          MAILBOX_SetValue(MAILBOX, kMAILBOX_CM4, g_msg);
    18.    MAILBOX_ClearValueBits(MAILBOX, kMAILBOX_CM0Plus, 0xffffffff);
    19.         

    20. }
    复制代码


    下面是关键部分,M4核的代码分析
    邮箱中断处理部分公用的,收到数据后,通过HexToChar()函数转成字符串ascii码,通过串口0的USART_WriteByte函数发送,发送出去。。。
    1. uint8_t HexToChar(uint8_t hex,uint8_t * xmg)
    复制代码
    HexToChar这个函数内容就不贴出来了,测试的写的比较乱,意思就是把hex值得每一位 转成ascii,相信同学们能系诶的比我好。
    举个例子:
    uint8_t hex = 0x05;
    hex += 0x30;
    那个hex就转成了ascii码了,分别对个位,十位,百位,等转换下就ok了
    1. void MAILBOX_IRQHandler()
    2. {
    3.     g_msg = MAILBOX_GetValue(MAILBOX, kMAILBOX_CM4);
    4.         
    5.         rxIndex = HexToChar(g_msg,demoRingBuffer);

    6.     MAILBOX_ClearValueBits(MAILBOX, kMAILBOX_CM4, 0xffffffff);

    7.         txIndex=0;
    8.                            while (rxIndex != 0)
    9.         {
    10.             USART_WriteByte(DEMO_USART, demoRingBuffer[txIndex]);//串口发送
    11.             txIndex++;
    12.                                         rxIndex--;

    13.         }
    14.                                 PRINTF("\r\n---------------------------------------------------------\r\n\r\n");
    15.                                 
    16. }
    复制代码


    按键部分:和上个帖子类似,简单说明吧,主循环中扫描按键状态,如果按下调用MAILBOX_SetValue函数触发M0和的邮箱中断

    1. while (1)
    2.     {
    3.                         key_scan();
    4.         
    5.                         if(1== key_M)
    6.                         {
    7.                                         key_M=0;
    8.                                         PRINTF("Press Button :PB2(M4)  \n");
    9.                                                         led7_flg ^=1;        
    10.                                 PRINTF("----M4  SEND  DATA  TO M0 BY BUTTON PB2----\r\n\r\n");
    11.                                 if(led7_flg==1 )
    12.                                 {
    13.                                         LED7_OFF();
    14.                                         PRINTF("M4:LED7****ON****\r\n\r\n");
    15.                                 }
    16.                                 else
    17.                                 {
    18.                                         LED7_ON();
    19.                                         PRINTF("M4-:LED7****OFF****\r\n\r\n");
    20.                                 }
    21.                                 PRINTF("-小马哥-USART0 Receive Data(ASCII) from M0 by Button PB2 is: ");
    22.                                 
    23.                                 MAILBOX_SetValue(MAILBOX, kMAILBOX_CM0Plus, g_msg);
    24.                                 MAILBOX_ClearValueBits(MAILBOX, kMAILBOX_CM4, 0xffffffff);
    25.                                 
    26.                         }
    27. }
    复制代码

    下面主要讲下串口接收发送部分。。。。。

    这里我们还使用usart0,需要添加一个配置,初始化操作
    先定义一些与uart0 相关的宏
    1. #define DEMO_USART USART0
    2. #define DEMO_USART_CLK_SRC kCLOCK_Flexcomm0
    3. #define DEMO_USART_CLK_FREQ CLOCK_GetFreq(kCLOCK_Flexcomm0)
    4. #define DEMO_USART_IRQHandler FLEXCOMM0_IRQHandler
    5. #define DEMO_USART_IRQn FLEXCOMM0_IRQn

    6. #define DEMO_RING_BUFFER_SIZE 16

    7. uint8_t demoRingBuffer[DEMO_RING_BUFFER_SIZE];
    8. volatile uint16_t txIndex; /* Index of the data to send out. */
    9. volatile uint16_t rxIndex; /* Index of the memory to save new arrived data. */
    复制代码
    然后在main函数初始化串口,开启接收中断,等待PC发送数据。
    1.   USART_GetDefaultConfig(&config);
    2.     config.baudRate_Bps = BOARD_DEBUG_UART_BAUDRATE;
    3.     config.enableTx = true;
    4.     config.enableRx = true;

    5.     USART_Init(DEMO_USART, &config, DEMO_USART_CLK_FREQ);

    6.     /* Send g_tipString out. */
    7. //    USART_WriteBlocking(DEMO_USART, g_tipString, sizeof(g_tipString) / sizeof(g_tipString[0]));

    8.     /* Enable RX interrupt. */
    9.     USART_EnableInterrupts(DEMO_USART, kUSART_RxLevelInterruptEnable | kUSART_RxErrorInterruptEnable);
    10.     EnableIRQ(DEMO_USART_IRQn);
    复制代码
    接收到pc的数据后,进入串口中断函数,并把数据通过MAILBOX_SetValue,发送给M0处理。
    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.                                         g_msg = USART_ReadByte(DEMO_USART);//data;
    8.                                         rxIndex = HexToChar(g_msg,demoRingBuffer);
    9.                         txIndex=0;
    10.                         MAILBOX_SetValue(MAILBOX, kMAILBOX_CM0Plus, g_msg);
    11.                         MAILBOX_ClearValueBits(MAILBOX, kMAILBOX_CM4, 0xffffffff);
    12.                         PRINTF("****M4  SEND  DATA  TO M0 BY PC****\r\n\r\n");
    13.                         PRINTF("-小马哥-USART0 Receive Data(ASCII) from M0 by PC is: ");
    14.     }
    15. }
    复制代码
    到此为止,就完事了,大家多多支持哦。。。
    小马哥出品,绝对原创。






    -----------------------小马哥系列【LPC54114双核任务二】传送门--------------------
    【LPC54114双核任务二】双核之从零开始--#KEIL工程建立配置#
    【LPC54114双核任务二】双核之从零开始--#HelloWorld双核调试#

    【LPC54114双核任务二】双核之从零开始--#MDK生成BIN#

    【LPC54114双核任务二】双核之从零开始--#mailbox通信1之中断#


    【LPC54114双核任务二】双核之从零开始--#mailbox通信2之mutex#

    【LPC54114双核任务二】双核之从零开始--#mailbox通信3之按键#

    【LPC54114双核任务二】双核之从零开始--#mailbox通信4之PC_M4_M0#

    【LPC54114双核任务二】双核之从零开始--#mailbox通信5之PC_M0_M4#



    【LPC54114双核任务二】双核之从零开始--#mailbox通信6之WIFI_M4_M0#


    【LPC54114双核任务二】已完结,小马哥出品,谢谢大家支持。。。。
    -----------------------小马哥系列【LPC54114双核任务二】传送门--------------------


    好好
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2018-7-12 20:45
  • 签到天数: 75 天

    连续签到: 1 天

    [LV.6]常住居民II

    7

    主题

    213

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    441
    最后登录
    2018-10-25
    发表于 2017-7-1 09:45:13 | 显示全部楼层
    大神厉害了
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2018-7-3 23:08
  • 签到天数: 57 天

    连续签到: 1 天

    [LV.5]常住居民I

    0

    主题

    106

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    351
    最后登录
    2018-7-3
    发表于 2017-7-1 09:47:52 | 显示全部楼层
    我的串口收不到数据
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2021-1-28 20:09
  • 签到天数: 317 天

    连续签到: 1 天

    [LV.8]以坛为家I

    61

    主题

    1582

    帖子

    6

    金牌会员

    Rank: 6Rank: 6

    积分
    9365
    最后登录
    2022-5-12
     楼主| 发表于 2017-7-1 09:57:06 | 显示全部楼层
    FSCLK64 发表于 2017-7-1 09:47
    我的串口收不到数据

    配置问题吧,参考下 官方串口demo
    好好
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2018-7-3 22:55
  • 签到天数: 35 天

    连续签到: 1 天

    [LV.5]常住居民I

    0

    主题

    56

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    200
    最后登录
    2018-7-28
    发表于 2017-7-1 10:08:04 | 显示全部楼层
    学习研究中
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2018-2-28 16:09
  • 签到天数: 65 天

    连续签到: 1 天

    [LV.6]常住居民II

    8

    主题

    238

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    488
    最后登录
    2019-9-18
    发表于 2017-7-26 18:18:18 | 显示全部楼层
    原来是代替PRINTF()使用
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

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

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

    GMT+8, 2025-8-22 06:03 , Processed in 0.094020 second(s), 25 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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