在线时间223 小时
UID3159710
注册时间2015-9-1
NXP金币182
TA的每日心情 | 擦汗 2017-12-29 14:09 |
---|
签到天数: 144 天 连续签到: 1 天 [LV.7]常住居民III
金牌会员
 
- 积分
- 1857
- 最后登录
- 2025-7-22
|
本帖最后由 liao122 于 2017-7-2 21:02 编辑
上个帖子 (【LPC54114双核任务二】① 双核通讯 mailbox) 中说到双核之间可以通过mailbox来进行通讯;
本帖主要讲的是 用M0+来进行串口数据的收发,M4进行数据处理控制
我们知道通过mailbox 的中断方式 双核间能传递一个的32bit的值,由于串口不可能总是一个值,为了能够一次中断传递多个值,我们可以借助指针,首先创建一个结构体和一个指向该结构体的指针、一个存字符串的数组
- struct mail_message
- {
- uint8_t *string; //传递字符串指针
- uint8_t num; //传递的字符数
- }s_message;
- struct mail_message p_message;
- uint8_t bufferString[50] = {0};
复制代码 然后
- p_message = &s_message; //把s_mssage的地址给指针p_message
- g_msg = (uint32_t)p_message; //把p_message 强制转换为32bit的值给g_msg
- 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的中断函数
- void MAILBOX_IRQHandler()
- {
- g_msg = MAILBOX_GetValue(MAILBOX, kMAILBOX_CM0Plus); // 读取从M0+发来的值
-
- p_message =(struct mail_message *)g_msg; // 将g_msg 转换为指针
- receive_flag = 1; //收到M0+数据标志位
-
- MAILBOX_ClearValueBits(MAILBOX, kMAILBOX_CM0Plus, 0xffffffff);
- }
复制代码
串口接收中断函数
约定PC端发来的数据以‘#’号结束符
- void DEMO_USART_IRQHandler(void)
- {
- uint8_t data;
- /* If new data arrived. */
- if ((kUSART_RxFifoNotEmptyFlag | kUSART_RxError) & USART_GetStatusFlags(DEMO_USART))
- {
- data = USART_ReadByte(DEMO_USART);
- bufferString[pc_receive_index] = data;
- if (bufferString[pc_receive_index] == '#')
- {
- pc_receive_flag = 1; //接收完成PC端数据标志位
- }
- pc_receive_index++; //记录接收的字符数
- }
- }
复制代码
主函数主体
- while (1)
- {
- if (receive_flag == 1) // receive data from cm4
- {
- receive_flag = 0;
- USART_WriteBlocking(DEMO_USART, p_message->string, p_message->num);
- }
- if (pc_receive_flag == 1) //receive data from pc uart
- {
- pc_receive_flag = 0;
- s_message.num = pc_receive_index;
- pc_receive_index = 0;
- s_message.string = bufferString;
- p_message = &s_message;
- g_msg = (uint32_t)p_message;
- MAILBOX_SetValue(MAILBOX, kMAILBOX_CM4, g_msg);
- }
- }
复制代码
M4 这边
mailbox的中断函数
- void MAILBOX_IRQHandler()
- {
- g_msg = MAILBOX_GetValue(MAILBOX, kMAILBOX_CM4);
- p_message =(struct de *)g_msg;
- receive_flag = 1;
- MAILBOX_ClearValueBits(MAILBOX, kMAILBOX_CM4, 0xffffffff);
- }
复制代码
主函数主体
- while (1)
- {
- if (receive_flag == 1) // receive data from cm0+
- {
- receive_flag = 0;
- s_message.num = p_message->num;
- buffer_num = p_message->num;
- s_message.string = p_message->string;
- for (i=0; i<(s_message.num); i++)
- {
- bufferString[i] = *(p_message->string);
- (p_message->string)++;
- }
- if ( (bufferString[0] == 'L') //当收到“LED1 ON”时
- && (bufferString[1] == 'E')
- && (bufferString[2] == 'D')
- && (bufferString[3] == '1')
- && (bufferString[4] == ' ')
- && (bufferString[5] == 'O')
- && (bufferString[6] == 'N'))
- {
- Led(0,15,1); //点亮LED1
- /*********向M0+ 发送“The CM4 receive is: ” 字符串******************/
- s_message.string = string_order_re;
- s_message.num = sizeof(string_order_re)/sizeof(string_order_re[0]);
- p_message = &s_message;
- g_msg = (uint32_t)p_message;
- /* Wr ite g_msg to CM0+ mailbox register - it causes interrupt on CM0+ core */
- MAILBOX_SetValue(MAILBOX, kMAILBOX_CM0Plus, g_msg);
- /*********向M0+回传接收的字符串******************/
- delay(); // 等待M0+ 接收数据
- s_message.string = bufferString;
- p_message = &s_message;
- g_msg = (uint32_t)p_message;
- /* Wr ite g_msg to CM0+ mailbox register - it causes interrupt on CM0+ core */
- MAILBOX_SetValue(MAILBOX, kMAILBOX_CM0Plus, g_msg);
-
- /*********向M0+ 发送“LED1 has been open. ” 字符串******************/
- delay();
- s_message.string = string_order_ledopen;
- s_message.num = sizeof(string_order_ledopen)/sizeof(string_order_ledopen[0]);
- p_message = &s_message;
- g_msg = (uint32_t)p_message;
- /* Wr ite g_msg to CM0+ mailbox register - it causes interrupt on CM0+ core */
- MAILBOX_SetValue(MAILBOX, kMAILBOX_CM0Plus, g_msg);
- delay();
- for (i=0; i<buffer_num; i++) //清除接收数组bufferString中数据
- {
- bufferString[i] = 0;
- }
- }
- else if ( (bufferString[0] == 'L') //当接收到“LED1 OFF”字符串
- && (bufferString[1] == 'E')
- && (bufferString[2] == 'D')
- && (bufferString[3] == '1')
- && (bufferString[4] == ' ')
- && (bufferString[5] == 'O')
- && (bufferString[6] == 'F')
- && (bufferString[7] == 'F'))
- {
- Led(0,15,0); //灭掉LED1
- /*********向M0+ 发送“The CM4 receive is: ” 字符串******************/
- s_message.string = string_order_re;
- s_message.num = sizeof(string_order_re)/sizeof(string_order_re[0]);
- p_message = &s_message;
- g_msg = (uint32_t)p_message;
- /* Wr ite g_msg to CM0+ mailbox register - it causes interrupt on CM0+ core */
- MAILBOX_SetValue(MAILBOX, kMAILBOX_CM0Plus, g_msg);
-
- /*********向M0+回传接收的字符串******************/
- delay();
- s_message.string = bufferString;
- p_message = &s_message;
- g_msg = (uint32_t)p_message;
- /* Wr ite g_msg to CM0+ mailbox register - it causes interrupt on CM0+ core */
- MAILBOX_SetValue(MAILBOX, kMAILBOX_CM0Plus, g_msg);
-
- /*********向M0+ 发送“LED1 has been close. ” 字符串******************/
- delay();
- s_message.string = string_order_ledclose;
- s_message.num = sizeof(string_order_ledclose)/sizeof(string_order_ledclose[0]);
- p_message = &s_message;
- g_msg = (uint32_t)p_message;
- /* Wr ite g_msg to CM0+ mailbox register - it causes interrupt on CM0+ core */
- MAILBOX_SetValue(MAILBOX, kMAILBOX_CM0Plus, g_msg);
- delay();
- for (i=0; i<buffer_num; i++)
- {
- bufferString[i] = 0;
- }
- }
- /*****************其他字符串回传M0+********************/
- else
- {
- s_message.string = string_order_re;
- s_message.num = sizeof(string_order_re)/sizeof(string_order_re[0]);
- p_message = &s_message;
- g_msg = (uint32_t)p_message;
- /* Wr ite g_msg to CM0+ mailbox register - it causes interrupt on CM0+ core */
- MAILBOX_SetValue(MAILBOX, kMAILBOX_CM0Plus, g_msg);
- delay();
- s_message.string = bufferString;
- p_message = &s_message;
- g_msg = (uint32_t)p_message;
- /* Wr ite g_msg to CM0+ mailbox register - it causes interrupt on CM0+ core */
- MAILBOX_SetValue(MAILBOX, kMAILBOX_CM0Plus, g_msg);
- delay(); // wait for M0+ taken data finish
- for (i=0; i<buffer_num; i++) // clear receive data
- {
- bufferString[i] = 0;
- }
- }
- }
- }
复制代码
程序运行结果
注意: 把发送新行的√去掉(勾上运行就不一样了,还没找到原因)
程序是在SDK_2.2.1_LPCXpresso54114\boards\lpcxpresso54114\driver_examples\mailbox\interrupt 例程上修改的,只需替换相应的主函数即可(主函数见附件)
|
|