在线时间543 小时
UID1650185
注册时间2017-4-19
NXP金币674
TA的每日心情 | 怒 2021-1-28 20:09 |
---|
签到天数: 317 天 连续签到: 1 天 [LV.8]以坛为家I
金牌会员
 
- 积分
- 9365
- 最后登录
- 2022-5-12
|
本帖最后由 小马哥-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点拍的。。。呜呜~~~~(>_<)~~~~
-------------------------------------------------------------------------------------------------------
好了,下面具体讲解吧。。。
思路:
按键部分:和上个帖子基本上差不多,做了一个按键扫描函数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的效果图:
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发送效果图
以上就是大致流程思路,,,,,,,下面附加代码讲解。。。。。
先说M0核吧,因为无论是按键还是PC,M0核中mailbox处理的数据是一样的。。。配置和上个帖子一样的,就贴出来邮箱中断处理函数把。
这里对接收数据限制了一下,一个字节的,所以超过255,强制为0,同样进中断,LED11翻转,提示M0和收到了数据,在处理。。。。
- void MAILBOX_IRQHandler()
- {
- g_msg = MAILBOX_GetValue(MAILBOX, kMAILBOX_CM0Plus);
- if(g_msg<=255) g_msg++;
- else
- {g_msg = 0;
- }
- led11_flg ^=1;
- if(1 ==led11_flg )
- {
- LED11_ON();
- }
- else
- {
- LED11_OFF();
- }
- MAILBOX_SetValue(MAILBOX, kMAILBOX_CM4, g_msg);
- MAILBOX_ClearValueBits(MAILBOX, kMAILBOX_CM0Plus, 0xffffffff);
-
- }
复制代码
下面是关键部分,M4核的代码分析
邮箱中断处理部分公用的,收到数据后,通过HexToChar()函数转成字符串ascii码,通过串口0的USART_WriteByte函数发送,发送出去。。。
- uint8_t HexToChar(uint8_t hex,uint8_t * xmg)
复制代码 HexToChar这个函数内容就不贴出来了,测试的写的比较乱,意思就是把hex值得每一位 转成ascii,相信同学们能系诶的比我好。
举个例子:
uint8_t hex = 0x05;
hex += 0x30;
那个hex就转成了ascii码了,分别对个位,十位,百位,等转换下就ok了
- void MAILBOX_IRQHandler()
- {
- g_msg = MAILBOX_GetValue(MAILBOX, kMAILBOX_CM4);
-
- rxIndex = HexToChar(g_msg,demoRingBuffer);
- MAILBOX_ClearValueBits(MAILBOX, kMAILBOX_CM4, 0xffffffff);
- txIndex=0;
- while (rxIndex != 0)
- {
- USART_WriteByte(DEMO_USART, demoRingBuffer[txIndex]);//串口发送
- txIndex++;
- rxIndex--;
- }
- PRINTF("\r\n---------------------------------------------------------\r\n\r\n");
-
- }
复制代码
按键部分:和上个帖子类似,简单说明吧,主循环中扫描按键状态,如果按下调用MAILBOX_SetValue函数触发M0和的邮箱中断
- while (1)
- {
- key_scan();
-
- if(1== key_M)
- {
- key_M=0;
- PRINTF("Press Button :PB2(M4) \n");
- led7_flg ^=1;
- PRINTF("----M4 SEND DATA TO M0 BY BUTTON PB2----\r\n\r\n");
- if(led7_flg==1 )
- {
- LED7_OFF();
- PRINTF("M4:LED7****ON****\r\n\r\n");
- }
- else
- {
- LED7_ON();
- PRINTF("M4-:LED7****OFF****\r\n\r\n");
- }
- PRINTF("-小马哥-USART0 Receive Data(ASCII) from M0 by Button PB2 is: ");
-
- MAILBOX_SetValue(MAILBOX, kMAILBOX_CM0Plus, g_msg);
- MAILBOX_ClearValueBits(MAILBOX, kMAILBOX_CM4, 0xffffffff);
-
- }
- }
复制代码
下面主要讲下串口接收发送部分。。。。。
这里我们还使用usart0,需要添加一个配置,初始化操作
先定义一些与uart0 相关的宏
- #define DEMO_USART USART0
- #define DEMO_USART_CLK_SRC kCLOCK_Flexcomm0
- #define DEMO_USART_CLK_FREQ CLOCK_GetFreq(kCLOCK_Flexcomm0)
- #define DEMO_USART_IRQHandler FLEXCOMM0_IRQHandler
- #define DEMO_USART_IRQn FLEXCOMM0_IRQn
- #define DEMO_RING_BUFFER_SIZE 16
- uint8_t demoRingBuffer[DEMO_RING_BUFFER_SIZE];
- volatile uint16_t txIndex; /* Index of the data to send out. */
- volatile uint16_t rxIndex; /* Index of the memory to save new arrived data. */
复制代码 然后在main函数初始化串口,开启接收中断,等待PC发送数据。
- USART_GetDefaultConfig(&config);
- config.baudRate_Bps = BOARD_DEBUG_UART_BAUDRATE;
- config.enableTx = true;
- config.enableRx = true;
- USART_Init(DEMO_USART, &config, DEMO_USART_CLK_FREQ);
- /* Send g_tipString out. */
- // USART_WriteBlocking(DEMO_USART, g_tipString, sizeof(g_tipString) / sizeof(g_tipString[0]));
- /* Enable RX interrupt. */
- USART_EnableInterrupts(DEMO_USART, kUSART_RxLevelInterruptEnable | kUSART_RxErrorInterruptEnable);
- EnableIRQ(DEMO_USART_IRQn);
复制代码 接收到pc的数据后,进入串口中断函数,并把数据通过MAILBOX_SetValue,发送给M0处理。
- void DEMO_USART_IRQHandler(void)
- {
- uint8_t data;
- /* If new data arrived. */
- if ((kUSART_RxFifoNotEmptyFlag | kUSART_RxError) & USART_GetStatusFlags(DEMO_USART))
- {
- g_msg = USART_ReadByte(DEMO_USART);//data;
- rxIndex = HexToChar(g_msg,demoRingBuffer);
- txIndex=0;
- MAILBOX_SetValue(MAILBOX, kMAILBOX_CM0Plus, g_msg);
- MAILBOX_ClearValueBits(MAILBOX, kMAILBOX_CM4, 0xffffffff);
- PRINTF("****M4 SEND DATA TO M0 BY PC****\r\n\r\n");
- PRINTF("-小马哥-USART0 Receive Data(ASCII) from M0 by PC is: ");
- }
- }
复制代码 到此为止,就完事了,大家多多支持哦。。。
小马哥出品,绝对原创。
-----------------------小马哥系列之【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双核任务二】传送门--------------------
|
|