查看: 3752|回复: 8

[原创] 【LPC54114双核最终任务】 标准化考试的语音进程提示装置

[复制链接]
  • TA的每日心情
    奋斗
    2023-2-15 00:12
  • 签到天数: 969 天

    [LV.10]以坛为家III

    175

    主题

    2843

    帖子

    34

    金牌会员

    Rank: 6Rank: 6

    积分
    7092
    最后登录
    2023-4-20
    发表于 2017-7-31 00:21:26 | 显示全部楼层 |阅读模式
    开发背景:
    在各高校,英语四、六级考试是典型的标准化考试形式,它同常规的考试相比流程相对要复杂些。一般情况下,如果不是被轮到很少有人愿意去监这种考试。此次就借LPC54114 Lite 开发板来解决这个问题,以自动在指定的时段给出任务提示并执行一些控制操作。
    设计思路:
    借助LPC54114内部的RTC通过时间基准,并在指定的多个时段向3类对象给出不同的提示信息或控制信号。
    3类对象分别是监考人员、考生及屏蔽器,监考人员的主要任务是控制考试进程、收发试卷和答题卡、填写开场记录等;考生则按考场要求按进程完成考试;屏蔽器则除测试听力外,将一直处于开通状态,以屏蔽外部的电子信号进入。
    为此,以TFT屏为监考人员显示提示信息;用语言模块和音箱来向考生发送不同时段的语音提示,以降低若采用显示器件所造成的产本提升;采用继电器则可以自动控制屏蔽器的开关。
    由于RTC在断电时,会停止计时,为此时常要设置RTC的初始时间。为了避免不必要的键入操作,特采用串行通讯的方法,通过辅助软件来巧用计算机系统的时间值来设置RTC初始值。
    整体构成:
    为达到设计功能,其整体构成如图1所示。
    图片1.png
    图1 系统构成图

    图片2.png
    图2 实物图

    在双核结构下,该装置的处理流程如图3所示。
    图片3.png
    图3 处理流程图

    技术实现:
    该设计涉及:双核方式运行、核间通讯、核间数据共享、RTC、温度检测、数字语音录制、flash语音存储、I2S语音播放、TFT屏显示、LED进程指示、继电器控制、串行通讯等。
      
    1.核间通讯
    进程传送程序:
    1. // M4:
    2. uint8_t JC;
    3. void MAILBOX_IRQHandler()   // M4
    4. {
    5.      g_msg = MAILBOX_GetValue(MAILBOX, kMAILBOX_CM4);
    6.      MAILBOX_ClearValueBits(MAILBOX, kMAILBOX_CM4, 0xffffffff);
    7. }

    8. // Initialize Mailbox
    9.     MAILBOX_Init(MAILBOX);
    10.     // Enable mailbox interrupt
    11. NVIC_EnableIRQ(MAILBOX_IRQn);
    12.         JC=i;
    13.         MAILBOX_SetValue(MAILBOX, kMAILBOX_CM0Plus,i);
    14. LED进程指示程序:
    15. //M0+:
    16. uint8_t JCH;
    17. void MAILBOX_IRQHandler()   //M0+
    18. {
    19.         JCH = MAILBOX_GetValue(MAILBOX,kMAILBOX_CM0Plus);  //kMAILBOX_CM4
    20.             //PRINTF(" *time* %02d\r\n",g_msg);
    21.             MAILBOX_ClearValueBits(MAILBOX, kMAILBOX_CM0Plus, 0xffffffff);
    22.             if(JCH==1) GPIO_SetPinsOutput(GPIO, 0, 1u << 15);
    23.             if(JCH==2) GPIO_SetPinsOutput(GPIO, 0, 1u << 19);
    24.         if(JCH==3) GPIO_SetPinsOutput(GPIO, 0, 1u << 21);
    25.             if(JCH==4) GPIO_SetPinsOutput(GPIO, 0, 1u << 22);
    26.             if(JCH==5)GPIO_ClearPinsOutput(GPIO, 0, 1u << 25);
    27.             if(JCH==6)GPIO_ClearPinsOutput(GPIO, 0, 1u << 26);
    28.         if(JCH==7)GPIO_ClearPinsOutput(GPIO, 0, 1u << 29);
    29.             //if(JCH==8)GPIO_ClearPinsOutput(GPIO, 0, 1u << 30);
    30.       }
    复制代码
    2.RTC计时
    在该设计中,RTC计时是整个系统的进程管控核心,实现RTC计时与显示功能的程序如下:
    1. while(len<7);//等待RTC初始值的读取
    2.           rtc_datetime_t date;
    3.           RTC_Init(RTC);
    4. //设置RTC初始值
    5.           date.year         = 2017;
    6.           date.month         = 07;
    7.           date.day                 = 27;
    8.           date.hour  = (bufferString[0]-'0')*10+bufferString[1]-'0';
    9. date.minute = (bufferString[3]-'0')*10+bufferString[4]-'0';
    10.           date.second = (bufferString[6]-'0')*10+bufferString[7]-'0';
    11.       RTC_StopTimer(RTC);
    12.       RTC_SetDatetime(RTC, &date);
    13.       RTC_StartTimer(RTC);
    14.           RTC_GetDatetime(RTC, &date);
    15.       //PRINTF("Current date: %04d-%02d-%02d\r\n",date.year,date.month,date.day);
    16.           //PRINTF("Current time: %02d:%02d:%02d\r\n",date.hour,date.minute,date.second);
    17.                 LCD_ShowNum(20,100,date.hour,2,16);  
    18.                 LCD_ShowChar(36,100,':',16,0);
    19.                 LCD_ShowNum(44,100,date.minute,2,16);
    20.                 LCD_ShowChar(60,100,':',16,0);
    21.                 LCD_ShowNum(68,100,date.second,2,16);
    22. //实现RTC计时值/
    23. secondp=date.second;
    24.                 i=0;
    25.                 LCD_ShowNum(200,100,i,1,16);
    26.                 while(1)
    27.         {
    28.                                 RTC_GetDatetime(RTC, &date);
    29.                                 if(secondp != date.second)  
    30.                                 {
    31.                                         //PRINTF("Current time: %02d:%02d:%02d\r\n",date.hour,date.minute,date.second);
    32.                                     secondp=date.second;
    33.                                 if((t[i]==date.hour)&&(p[i]==date.minute)&&(0==date.second))
    34.                 {
    35.                                         //PRINTF(" *time*: %02d:%02d:%02d\r\n",date.hour,date.minute,date.second);
    36.                                     LCD_ShowChar(200,120+i*30,'*',16,0);
    37.                                         i++;       
    38.                                     LCD_ShowNum(200,100,i,1,16);
    39.                                         MAILBOX_SetValue(MAILBOX, kMAILBOX_CM0Plus,i);
    40.                         if(i==7)
    41.                                         {       
    42.                                          i=0;
    43.                                          for(j=0;j<6;j++)
    44.                                          {
    45.                                                  LCD_ShowChar(200,120+j*30,' ',16,0);
    46.                                          }
    47.                                 }
    48.                         }
    49.                         LCD_ShowNum(20,100,date.hour,2,16);   
    50.                     LCD_ShowNum(44,100,date.minute,2,16);
    51.                     LCD_ShowNum(68,100,date.second,2,16);       
    52.                         }       
    53.         }
    复制代码
    图片4.png
    图4 RTC计时验证

    3.温度检测
    (在需要的情况下,通过添加光隔继电器来控制电扇、空调的温度调节设备。)
    通过添加以下2个函数即可进行温度的检测。
    uint8_t pct2075_i2c_init(void)
    uint8_t pct2075_i2c_read(float *data)
    具体的温度读取过程由以下程序实现:
    1. pct2075_i2c_init();
    2. while(1)
    3. {   
    4. pct2075_i2c_read((float *)&fPCTValue);
    5. if(fPCTValue>=0)
    6.    {
    7. n=(int)(fPCTValue*100)/100;
    8. M0_TO_M4_T=(int)(fPCTValue*100)/100;
    9.    if(n!=M0_TO_M4_T)
    10.    {
    11. //只传送零度之上的温度供显示
    12. PRINTF("Temperature Value is +%d.%d oC.\r", (int)(fPCTValue*100)/100, (int)(fPCTValue*100)%100);
    13.     M0_TO_M4_T=(int)(fPCTValue*100)/100;
    14. }
    15. }
    16. else
    17. PRINTF("Temperature Value is -%d.%d oC.\r", (int)((0-fPCTValue)*100)/100, (int)((0-fPCTValue)*100)%100);
    18. delay();
    19. }
    复制代码
    实现温度值的显示的语句如下:
    LCD_ShowNum(120,100,M0_TO_M4_R,2,16);
                    LCD_ShowChar(138,100,'C',16,0);
    4.TFT屏显示
    在该设计中,为了更多地显示信息特采用TFT屏来完成显示任务,并选取串口屏以节省GPIO资源。TFT屏与LPC54114开发板的引脚连接关系:
      SCE --P0.11
    RST --P0.13
    DC  --P0.12
      DIN --P0.14
      SCLK--P1.8
      LED+--P1.9
    界面显示函数如下:
    1. void xianshi(void)  
    2. {   uint8_t i;         
    3.         LCD_Clear(RED);     
    4.         BACK_COLOR=RED;
    5.         POINT_COLOR=WHITE;   
    6.         //32*32  标准化考试进程调试器
    7. showhanzi32(20,20,0);            
    8.         showhanzi32(60,20,1);            
    9.         showhanzi32(100,20,2);     
    10.         showhanzi32(140,20,3);          
    11.         showhanzi32(180,20,4);          
    12.         showhanzi32(20,60,5);            
    13.         showhanzi32(60,60,6);     
    14.         showhanzi32(100,60,9);          
    15.         showhanzi32(140,60,10);   
    16.         showhanzi32(180,60,11);          
    17.         showhanzi16(120,120,0);          //入场
    18.         showhanzi16(140,120,1);          
    19.   showhanzi16(120,150,2);          //开考
    20.         showhanzi16(140,150,3);          
    21.         showhanzi16(120,180,4);          //写作
    22.         showhanzi16(140,180,5);          
    23.         showhanzi16(120,210,6);          //听力
    24.         showhanzi16(140,210,7);          
    25.         showhanzi16(120,240,8);          //答题
    26.         showhanzi16(140,240,9);                 
    27.         showhanzi16(120,270,10);  //结束
    28.         showhanzi16(140,270,11);          
    29.         LCD_ShowString(20,120,120,16,16,"8:00-9:00 "); //1
    30.         LCD_ShowString(20,150,120,16,16,"9:00-9:10 "); //2
    31.         LCD_ShowString(20,180,120,16,16,"9:10-9:40 "); //3
    32.         LCD_ShowString(20,210,140,16,16,"9:40-10:10 "); //4
    33.         LCD_ShowString(20,240,140,16,16,"10:10-11:20 "); //5
    34.         LCD_ShowString(20,270,140,16,16,"11:20-11:30 "); //6
    35. }
    复制代码

    图片5.png
    图5 TFT显示界面

    5.串行通讯
    借助串行通讯功能可从外部来接收必要的数据信息,在该设计中是通过串行通讯来接收RTC的初始时间值,具体的使用方法如下。
    uint8_t bufferString[8] = {0};
    uint8_t len=0;
    串行通讯中断接收函数如下:
    1. void FLEXCOMM0_IRQHandler(void)
    2. {
    3.     char ch=0;
    4.     if ((kUSART_RxFifoNotEmptyFlag | kUSART_RxError) & USART_GetStatusFlags(USART0))
    5. {
    6.                         ch = USART_ReadByte(USART0);
    7.                         bufferString[len]=ch;
    8.                         //PRINTF("\r\nM0 Receive from PC :  %c\r\n", ch);
    9.                         if(len<7) len++;
    10. }
    11. }
    复制代码
    6.I2S语音播放
    为进行语音播放,是采用数字录音芯片事先进行语音录制并存在FLASH芯片中,在播放是再通过I2S芯片进行语音的再现。期间使用的关键函数有spiflash_init()dmic_init()pct2075_i2c_init()wm8904_i2s_init()等。鉴于FLASH中存储的语音约16秒,故暂且播放一段语音信息。解决SD卡存储后再改为多时段语音播放。
    受速度的影响,在进行语音再现是通过2个内存作为缓冲区来交替工作的,当一个在读取时,另一个在加速填充数据,以便连续播放不出现间断。
    图片6.png
    图6 以通讯方式接收RTC起始值

    结语:
    十分感谢论坛组织的这次活动及坛友所分享的经验,使自己从单核设计迈进了双核设计的门槛,并掌握了双核间的协作通讯问题,进而能将单核上实现的一些功能移植到双核上来实现该设计。限于时间和水平所,尽管整体上基本达到了设计的需要,但也仍存在尚需改进与完善之处,如实现多语音段录制与播放及以文件方式来管理语音库的播放等,期待对LPC5414的应用能跨上一个新的高度。

    回复

    使用道具 举报

  • TA的每日心情

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

    [LV.6]常住居民II

    8

    主题

    238

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    488
    最后登录
    2019-9-18
    发表于 2017-7-31 08:47:34 | 显示全部楼层
    厉害了!!!
    回复

    使用道具 举报

    该用户从未签到

    656

    主题

    6312

    帖子

    0

    超级版主

    Rank: 8Rank: 8

    积分
    20053
    最后登录
    2024-4-28
    发表于 2017-7-31 09:25:37 | 显示全部楼层
    谢谢楼主分享!!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2019-10-17 08:07
  • 签到天数: 273 天

    [LV.8]以坛为家I

    74

    主题

    2338

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    7351
    最后登录
    2021-8-30
    发表于 2017-7-31 10:19:24 | 显示全部楼层
    非常不错
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2023-2-15 00:12
  • 签到天数: 969 天

    [LV.10]以坛为家III

    175

    主题

    2843

    帖子

    34

    金牌会员

    Rank: 6Rank: 6

    积分
    7092
    最后登录
    2023-4-20
     楼主| 发表于 2017-7-31 12:50:13 | 显示全部楼层

    感谢支持,总算基本完成了,但还有待完善。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2023-9-15 08:42
  • 签到天数: 1952 天

    [LV.Master]伴坛终老

    1

    主题

    4686

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    9405
    最后登录
    2023-9-15
    发表于 2017-7-31 15:28:11 | 显示全部楼层
    不错,学习!
    今天天气不错!签到!
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2020-6-20 16:19
  • 签到天数: 46 天

    [LV.5]常住居民I

    3

    主题

    270

    帖子

    0

    高级会员

    Rank: 4

    积分
    591
    最后登录
    2023-1-9
    发表于 2017-12-30 22:18:35 | 显示全部楼层
    学学习,好的达到
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2017-11-15 10:33
  • 签到天数: 79 天

    [LV.6]常住居民II

    89

    主题

    2169

    帖子

    3

    金牌会员

    Rank: 6Rank: 6

    积分
    1779
    最后登录
    2020-8-22
    发表于 2018-1-3 19:41:43 | 显示全部楼层
    学习了
    签到
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2018-5-16 21:35
  • 签到天数: 1 天

    [LV.1]初来乍到

    2

    主题

    22

    帖子

    0

    注册会员

    Rank: 2

    积分
    107
    最后登录
    2020-7-26
    发表于 2018-5-16 21:22:45 | 显示全部楼层
    不错哦,顶一个
    keep moving
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

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

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

    GMT+8, 2024-4-28 19:00 , Processed in 0.147742 second(s), 28 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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