请选择 进入手机版 | 继续访问电脑版

迪文科技论坛

 找回密码
 立即注册
搜索
查看: 4840|回复: 11

【开源】AIoT LCM平台开发自已的OS内核《一》

[复制链接]

3

主题

4

回帖

48

积分

新手上路

Rank: 1

积分
48
发表于 2020-5-7 11:59:35 | 显示全部楼层 |阅读模式
本帖最后由 神秘の宅叔 于 2022-2-25 15:54 编辑

用户不仅能使用AIoT LCM平台的串口指令集与AIoT LCM平台交互,实现界面的显示以及响应,还可以在AIoT LCM平台上开发自已的OS内核程序,直接在OS内核程序中获取输入事件,控制界面显示。视频演示:
还要请提醒大家的是,示例工程对应的是AIoT LCM平台,采用主频353.8944MHZ主频,显示分辨率为1024X600的设备,其它分辨率或平台如果不修改是无法正常工作的。
由于作者本人开发的这套源码的时间比较早,建议只参考C51的源码,其他的文件都不要直接下载到屏,可能会发生不兼容的现象。


https://v.qq.com/x/page/p0970m0rc5z.html

http://cache.tv.qq.com/qqplayerout.swf?vid=p0970m0rc5z
下面分步详细介绍实现的步骤:
一、安装uVision,推荐版本为V5.25.3.0
二、安装迪文支持库,见附件驱动程序及支持库;
三、创建资源文件,每个需要烧录的文件统一编号,文件名前缀为其编号数值,每个编号占用1MBytes的FLASH区域
       1、字库文件,详见《AIoT LCM_TA指令集V10》
       2、背景图片,使用AllToolForAIOT 转换成ICM文件,(一般编号为32);
       3、图标文件,使用AllToolForAIOT 转换成ICM文件,每个ICM文件中可以包含多个图标,给每个ICM文件编号;
       4、音乐文件,使用AllToolForAIOT转换成WAM文件,给每个WAM文件编号;
       5、UIF文件,使用迪文提供的"UIF生成工具"制作,一般编号为13;
       6、T5LCFGXX.CFG配置文件,详见《AIoT LCM_TA指令集V10》中对配置文件的定义;
四、创建自已的工程
       1、使用Keil创建新的工程

     2、把迪文提供的SFR文件《T5LOS8051.h》,《T5L_OS_8051.INC》放在编译器能够找得到的位置,也可以直接拷贝过来放在工程目录下;     
     3、把参考代码中的文件拷贝到工程目录下,并添加到工程中;
           STARTUP_M5.A51,程序引导汇编入口;         
           sys.c,sys.h:CPU及设备和定时器的初始化,以及相应访问接口
           uart.c,uart.h:串口2的接收与发送,串口指令集的帧通讯实现;
           cmd.c,cmd.h:串口2指令集解析及执行;
           paint.c,paint.h:对AIoT LCM平台GUI系统的访问与控制,实现界面绘制;
    4、创建自已的主控程序,参照main.c以及player.c;

五、程序中调用资源文件实现界面交互,与界面的交互过程实际上就是与用户(操作者)的交互过程,用户通过触摸或者按键控制设备,设备上的显示器显示图形化的界面给用户,因此程序逻辑可以按以下处理:      
       1、初始化界面,通过指定背景图显示,局部通过程序调用资源文件绘制形成;参考代码中已经通过UIF文件指定了32号文件为背景图,同时player.c中initPlayer()函数针对音乐播放界面和视频播放界面进行了局部按钮显示;
       2、用户输入检测:参考player.c中的processInput函数,此函数在cmd.c的checkAndSendTP2Uart函数中被调用,而checkAndSendTP2Uart被主函数定时调用,查询用户是否有操作动作。
       3、用户输入的响应:根据不同的应用,处理输入事件,进行特定的响应,参考代码实现了一个媒体播放器的基本功能,用户操作播放、暂停键,可以上一首,下一首,调节音量,详见processInput函数中对各输入事件的响应处理;
       4、定时响应或内部流程的处理:这些流程不是由用户触发的,而是程序自主监控产生。为了实现播放进度条动态变化,必须在主控流程中增加播放进度查询,从而更新播放进度条,详见player.c中processProgDisplay函数的处理。      
       5、特定功能的实现,对于设备控制,声音视频播放等,他们一般通过控制其它系统完成指定功能,如player.c中播放音视频的相关函数,playAudio,playVideo;
六、参考代码分析     
1、player.c
  1. /***************************************************************************************

  2.                   版权所有 (C), 2020, 北京迪文科技有限公司

  3. ***************************************************************************************
  4.   文 件 名   : player.c
  5.   版 本 号   :
  6.   作    者   :
  7.   生成日期   : 2020年4月30日
  8.   功能描述   : 音乐播放器的逻辑流程实现,包括输入与用户交互流程,界面显示流程;
  9.   修改历史   :
  10.   1.日    期   :
  11.     作    者   :
  12.     修改内容   :
  13. ****************************************************************************************/
  14. #include <stdio.h>
  15. #include  <string.h>
  16. #include "cmd.h"
  17. #include "paint.h"
  18. #include "player.h"
  19. #include "uart.h"

  20. //显示布局;
  21. //进度条左上角位置;
  22. #define X_AUDIO_POS_PROGRESS         262
  23. #define Y_AUDIO_POS_PROGRESS         304
  24. #define X_VIDEO_POS_PROGRESS        106
  25. #define Y_VIDEO_POS_PROGRESS        495

  26. //音量进度条左上角位置和尺寸;
  27. #define X_AUDIO_POS_VOL        943
  28. #define Y_AUDIO_POS_VOL 111
  29. #define X_VIDEO_POS_VOL        943
  30. #define Y_VIDEO_POS_VOL 111
  31. #define VOLUME_PIC_WIDTH 59
  32. #define VOLUME_PIC_HEIGHT 285

  33. //音乐播放界面,文字显示位置;
  34. #define X_POS_PTEXT                 436
  35. #define Y_POS_PTEXT                 420

  36. //音乐播放界面,按钮显示位置;
  37. #define X_AUDIO_BUTTON_PREV 399
  38. #define Y_AUDIO_BUTTON_PREV 313
  39. #define X_AUDIO_BUTTON_PLAY 460
  40. #define Y_AUDIO_BUTTON_PLAY 296
  41. #define X_AUDIO_BUTTON_NEXT        594
  42. #define X_BUTTON_TO_VIDEO                30
  43. #define Y_BUTTON_TO_VIDEO                516

  44. //视频播放界面,按钮显示位置;
  45. #define X_VIDEO_BUTTON_PREV 325
  46. #define Y_VIDEO_BUTTON_PREV 510
  47. #define X_VIDEO_BUTTON_PLAY 449
  48. #define Y_VIDEO_BUTTON_PLAY 507
  49. #define X_VIDEO_BUTTON_NEXT        615

  50. #define X_BUTTON_TO_AUDIO                862
  51. #define Y_BUTTON_TO_AUDIO                524

  52. //按钮文件中各按钮的序号定义;
  53. #define BUTTON_ID_VIDEO_PLAY        0
  54. #define BUTTON_ID_VIDEO_PAUSE 2
  55. #define BUTTON_ID_AUDIO_PLAY  1
  56. #define BUTTON_ID_AUDIO_PAUSE        3
  57. #define BUTTON_ID_VIDEO_PREV        6
  58. #define BUTTON_ID_VIDEO_PREVI        7
  59. #define BUTTON_ID_VIDEO_NEXT        4
  60. #define BUTTON_ID_VIDEO_NEXTI        5
  61. #define        BUTTON_ID_AUDIO_PREV        14
  62. #define BUTTON_ID_AUDIO_PREVI        15
  63. #define BUTTON_ID_AUDIO_NEXT        12
  64. #define BUTTON_ID_AUDIO_NEXTI        13
  65. #define BUTTON_ID_TO_AUDIO                10
  66. #define BUTTON_ID_TO_AUDIOI                11
  67. #define BUTTON_ID_TO_VIDEO                8
  68. #define BUTTON_ID_TO_VIDEOI                9

  69. //背景图片文件中,各背景的页面的定义;
  70. #define PAGE_ID_AUDIO 0
  71. #define PAGE_ID_VIDEO 1

  72. //各文件ID的定义;
  73. #define FILE_ID_BUTTON        36
  74. #define FILE_ID_AUDIO_VOLUME        37
  75. #define FILE_ID_VIDEO_VOLUME        38
  76. #define FILE_ID_VIDEO_PROGRESS 60
  77. #define FILE_ID_AUDIO_PROGRESS 64


  78. //音量控制;
  79. static int audioVolume;

  80. //播放控制;
  81. static u16 playPosition;
  82. static u16 playTotalDuration;
  83. static int oldProgressFrame;//用于记忆上一次刷新的位置,避免频繁调用。
  84. static u8  playStation;//0x00:stop,0x01:playing;0x02:pause;
  85. static u8  pageID;//当前显示的页面;

  86. static int  currPlayIndex;//当前播放的文件索引,包括音乐和视频;

  87. //音乐和视频表,便于通过索引统一访问。
  88. static const unsigned char code m_audioID[3] = { 0x50,0x6C,0x84 };
  89. static const unsigned char code m_videoID[3] = { 186,155, 172};
  90. static const unsigned char code m_videoAudioID[3] = { 181,152,168 };
  91.         
  92. ~

  93. extern u8 xdata send_buffer[260];

  94. /*****************************************************************************************
  95. 初始化音乐播放器相关参数,初始化界面;
  96. ******************************************************************************************/
  97. void initPlayer(void)
  98. {
  99.         audioVolume = 8;        
  100.         switchToAudio();
  101. }

  102. /*****************************************************************************************
  103. 切换到音乐播放页面,显示默认画面,按钮及进度条的初始状态。
  104. ******************************************************************************************/
  105. static void switchToAudio(void)
  106. {
  107.         stopVideo();
  108.         playPosition = 0x0000;
  109.         playTotalDuration = 0xFFFF;
  110.         playStation = 0x00;
  111.         switchPage(PAGE_ID_AUDIO);
  112.         pageID = PAGE_ID_AUDIO;
  113.         oldProgressFrame = -1;
  114.         currPlayIndex = 0;
  115.         
  116.         drawPicture(X_AUDIO_BUTTON_PREV,Y_AUDIO_BUTTON_PREV,FILE_ID_BUTTON,BUTTON_ID_AUDIO_PREV);
  117.         drawPicture(X_AUDIO_BUTTON_PLAY,Y_AUDIO_BUTTON_PLAY,FILE_ID_BUTTON,BUTTON_ID_AUDIO_PLAY);
  118.         drawPicture(X_AUDIO_BUTTON_NEXT,Y_AUDIO_BUTTON_PREV,FILE_ID_BUTTON,BUTTON_ID_AUDIO_NEXT);
  119.         
  120.         drawPicture(X_AUDIO_POS_PROGRESS,Y_AUDIO_POS_PROGRESS,FILE_ID_AUDIO_PROGRESS,0);
  121.         drawPicture(X_AUDIO_POS_VOL,Y_AUDIO_POS_VOL,FILE_ID_AUDIO_VOLUME,audioVolume);
  122.         
  123.         drawPicture(X_BUTTON_TO_VIDEO,Y_BUTTON_TO_VIDEO,FILE_ID_BUTTON,BUTTON_ID_TO_VIDEO);
  124. }

  125. /*****************************************************************************************
  126. 切换到视频播放页面,显示默认画面,按钮及进度条的初始状态。
  127. ******************************************************************************************/
  128. static void SwitchToVideo(void)
  129. {
  130.         stopAudio();
  131.         playPosition = 0x0000;
  132.         playTotalDuration = 0xFFFF;
  133.         playStation = 0x00;
  134.         switchPage(PAGE_ID_VIDEO);
  135.         pageID = PAGE_ID_VIDEO;
  136.         currPlayIndex = 0;
  137.         oldProgressFrame = -1;
  138.         
  139.         drawPicture(X_VIDEO_BUTTON_PREV,Y_VIDEO_BUTTON_PREV,FILE_ID_BUTTON,BUTTON_ID_VIDEO_PREV);
  140.         drawPicture(X_VIDEO_BUTTON_PLAY,Y_VIDEO_BUTTON_PLAY,FILE_ID_BUTTON,BUTTON_ID_VIDEO_PLAY);
  141.         drawPicture(X_VIDEO_BUTTON_NEXT,Y_VIDEO_BUTTON_PREV,FILE_ID_BUTTON,BUTTON_ID_VIDEO_NEXT);
  142.         
  143.         setDrawMode(0x01);//贴图时背景色一起绘上;
  144.         drawPicture(X_VIDEO_POS_PROGRESS,Y_VIDEO_POS_PROGRESS,FILE_ID_VIDEO_PROGRESS,0);
  145.         setDrawMode(0x00);//返回默认模式,不贴背景色;
  146.         drawPicture(X_VIDEO_POS_VOL,Y_VIDEO_POS_VOL,FILE_ID_VIDEO_VOLUME,audioVolume);
  147.         
  148.         drawPicture(X_BUTTON_TO_AUDIO,Y_BUTTON_TO_AUDIO,FILE_ID_BUTTON,BUTTON_ID_TO_AUDIO);
  149. }

  150. /*****************************************************************************************
  151. 响应用户对触摸屏的操作,通过触控文件,已经由GUI核转换成了按键值,根据弹起的按键值,进行各种
  152. 处理。
  153. tp:触摸屏的命令类型与数据;
  154. ******************************************************************************************/
  155. void processInput(u8* tp)
  156. {
  157.         if(tp[0] == 0x78){//弹起
  158.                 switch(tp[2]){
  159.                         case 1://切换到视频播放页面;
  160.                                 SwitchToVideo();
  161.                                 break;
  162.                         case 2://音量增加
  163.                         case 17:
  164.                                 if(audioVolume < 20){
  165.                                         audioVolume++;
  166.                                         adjustVolume();
  167.                                 }
  168.                                 break;
  169.                         case 3://音量减小;
  170.                         case 18:
  171.                                 if(audioVolume > 0){
  172.                                         audioVolume--;
  173.                                         adjustVolume();
  174.                                 }
  175.                                 break;
  176.                         case 4://前一首音乐;
  177.                                 onAudioPrev();
  178.                                 break;
  179.                         case 5://后一首音乐;
  180.                                 onAudioNext();
  181.                                 break;
  182.                         case 6://音乐播放、暂停;
  183.                                 onAudioPlayPause();
  184.                                 break;
  185.                         case 7://切换到音乐播放界面;
  186.                                 switchToAudio();
  187.                                 break;
  188.                         case 8://上一部电影;
  189.                                 onVideoPrev();
  190.                                 break;
  191.                         case 9://下一部电影;
  192.                                 onVideoNext();
  193.                                 break;
  194.                         case 16://视频播放,暂停;
  195.                                 onVideoPlayPause();
  196.                                 break;
  197.                         default:
  198.                                 break;
  199.                 }
  200.         }
  201. }

  202. /*****************************************************************************************
  203. 音乐播放控制,通知GUI核播放哪个文件,以及从什么地方开始播放,使用当前音量和播放类型;
  204. start:播放的起始时间点;
  205. fileid:将播放的文件ID;
  206. ******************************************************************************************/
  207. static void playAudio(u16 starts,u16 fileid)
  208. {
  209.         unsigned short av = 2048/20 * audioVolume;
  210.         memset(send_buffer,0,16);
  211.         send_buffer[0] = 0x5A;
  212.         send_buffer[1] = 0x01;
  213.         send_buffer[2] = (starts >> 8) & 0xFF;
  214.         send_buffer[3] = starts & 0xFF;
  215.         send_buffer[4] = (fileid  >> 8 )& 0xFF;
  216.         send_buffer[5] = (fileid) & 0xFF;
  217.         send_buffer[10] = (unsigned char)((av >> 8)& 0xFF);
  218.         send_buffer[11] = (unsigned char)(av & 0xFF);
  219.         write_dgus_vp(0x00C0,send_buffer,6);
  220. }

  221. /*****************************************************************************************
  222. 停止音乐播放界面的播放,一般用于音视频间的切换;
  223. ******************************************************************************************/
  224. static void stopAudio(void)
  225. {
  226.         if(pageID != PAGE_ID_AUDIO)
  227.                 return;
  228.         
  229.         if(playStation == 0x01 ){
  230.                 send_buffer[0] = 0x5A;
  231.                 send_buffer[1] = 0x02;
  232.                 write_dgus_vp(0x00C0,send_buffer,1);
  233.                 playStation = 0x00;
  234.         }
  235. }

  236. /*****************************************************************************************
  237. 停止视频播放界面的播放,一般用于音视频间的切换;
  238. ******************************************************************************************/
  239. static void stopVideo(void)
  240. {
  241.         if(pageID != PAGE_ID_VIDEO)
  242.                 return;
  243.         
  244.         if(playStation == 0x01 ){
  245.                 send_buffer[0] = 0x5A;
  246.                 send_buffer[1] = 0x02;
  247.                 write_dgus_vp(0x00C8,send_buffer,1);
  248.                 send_buffer[0] = 0x5A;
  249.                 send_buffer[1] = 0x02;
  250.                 write_dgus_vp(0x00C0,send_buffer,1);
  251.                 playStation = 0x00;
  252.         }
  253. }

  254. /*****************************************************************************************
  255. 响应音乐播放及暂停按键,控制GUI进行播放和暂停,同时更新按钮的显示;
  256. ******************************************************************************************/
  257. static void onAudioPlayPause(void)
  258. {
  259.         if(playStation != 0x00 ){
  260.                 memset(send_buffer,0,16);
  261.                 send_buffer[0] = 0x5A;
  262.                 send_buffer[1] = 0x02;
  263.                 write_dgus_vp(0x00C0,send_buffer,1);
  264.                 if(playStation == 0x01){
  265.                         playStation = 0x02;
  266.                         drawPicture(X_AUDIO_BUTTON_PLAY,Y_AUDIO_BUTTON_PLAY,FILE_ID_BUTTON,BUTTON_ID_AUDIO_PLAY);
  267.                 }
  268.                 else{
  269.                         playStation = 0x01;
  270.                         drawPicture(X_AUDIO_BUTTON_PLAY,Y_AUDIO_BUTTON_PLAY,FILE_ID_BUTTON,BUTTON_ID_AUDIO_PAUSE);
  271.                 }
  272.                
  273.         }
  274.         else{
  275.                 u16 fileid = m_audioID[currPlayIndex];
  276.                 playAudio(0x0000,fileid);
  277.                 playStation = 0x01;
  278.                 drawPicture(X_AUDIO_BUTTON_PLAY,Y_AUDIO_BUTTON_PLAY,FILE_ID_BUTTON,BUTTON_ID_AUDIO_PAUSE);
  279.         }
  280. }

  281. /*****************************************************************************************
  282. 响应视频播放及暂停按键,控制GUI进行播放和暂停,同时更新按钮的显示;
  283. ******************************************************************************************/
  284. static void onVideoPlayPause(void)
  285. {
  286.         if(playStation != 0x00 ){
  287.                 memset(send_buffer,0,16);
  288.                 send_buffer[0] = 0x5A;
  289.                 send_buffer[1] = 0x02;
  290.                 write_dgus_vp(0x00C0,send_buffer,1);
  291.                 send_buffer[0] = 0x5A;
  292.                 send_buffer[1] = 0x02;
  293.                 write_dgus_vp(0x00C8,send_buffer,1);
  294.                 if(playStation == 0x01){
  295.                         playStation = 0x02;
  296.                         drawPicture(X_VIDEO_BUTTON_PLAY,Y_VIDEO_BUTTON_PLAY,FILE_ID_BUTTON,BUTTON_ID_VIDEO_PLAY);
  297.                 }
  298.                 else{
  299.                         playStation = 0x01;
  300.                         drawPicture(X_VIDEO_BUTTON_PLAY,Y_VIDEO_BUTTON_PLAY,FILE_ID_BUTTON,BUTTON_ID_VIDEO_PAUSE);
  301.                 }
  302.         }
  303.         else{
  304.                 u16 fileid = m_videoID[currPlayIndex];
  305.                 playVideo(0x0000,fileid);
  306.                 fileid = m_videoAudioID[currPlayIndex];
  307.                 playAudio(0x0000,fileid);
  308.                 playStation = 0x01;
  309.                 drawPicture(X_VIDEO_BUTTON_PLAY,Y_VIDEO_BUTTON_PLAY,FILE_ID_BUTTON,BUTTON_ID_VIDEO_PAUSE);
  310.         }
  311. }

  312. /*****************************************************************************************
  313. 响应音乐播放界面的下一首按键,跳转到下一首,同时更新下一首按钮的显示;
  314. ******************************************************************************************/
  315. static void onAudioNext(void)
  316. {
  317.         u16 fileid;
  318.         if(currPlayIndex >= 2)
  319.                 return;
  320.         
  321.         currPlayIndex++;
  322.         fileid = m_audioID[currPlayIndex];
  323.         playAudio(0x0000,fileid);
  324.         playStation = 0x01;
  325.         drawPicture(X_AUDIO_BUTTON_PLAY,Y_AUDIO_BUTTON_PLAY,FILE_ID_BUTTON,BUTTON_ID_AUDIO_PAUSE);
  326.         if(currPlayIndex == 2){
  327.                 drawPicture(X_AUDIO_BUTTON_NEXT,Y_AUDIO_BUTTON_PREV,FILE_ID_BUTTON,BUTTON_ID_AUDIO_NEXTI);
  328.         }
  329.         drawPicture(X_AUDIO_BUTTON_PREV,Y_AUDIO_BUTTON_PREV,FILE_ID_BUTTON,BUTTON_ID_AUDIO_PREV);
  330. }

  331. /*****************************************************************************************
  332. 响应音乐播放界面的前一首按键,跳转到前一首,同时更新前一首按钮的显示;
  333. ******************************************************************************************/
  334. static void onAudioPrev(void)
  335. {
  336.         u16 fileid;
  337.         
  338.         if( currPlayIndex <= 0 )
  339.                 return;
  340.         
  341.         currPlayIndex--;
  342.         fileid = m_audioID[currPlayIndex];
  343.         playAudio(0x0000,fileid);
  344.         playStation = 0x01;
  345.         drawPicture(X_AUDIO_BUTTON_PLAY,Y_AUDIO_BUTTON_PLAY,FILE_ID_BUTTON,BUTTON_ID_AUDIO_PAUSE);
  346.         if(currPlayIndex == 0){
  347.                 drawPicture(X_AUDIO_BUTTON_PREV,Y_AUDIO_BUTTON_PREV,FILE_ID_BUTTON,BUTTON_ID_AUDIO_PREVI);
  348.         }
  349.         drawPicture(X_AUDIO_BUTTON_NEXT,Y_AUDIO_BUTTON_PREV,FILE_ID_BUTTON,BUTTON_ID_AUDIO_NEXT);
  350. }

  351. /*****************************************************************************************
  352. 响应视频播放界面的前一首按键,跳转到前一首,同时更新前一首按钮的显示;
  353. ******************************************************************************************/
  354. static void onVideoPrev(void)
  355. {
  356.         u16 fileid;
  357.         
  358.         if( currPlayIndex <= 0 )
  359.                 return;
  360.         currPlayIndex--;
  361.         
  362.         fileid = m_videoID[currPlayIndex];
  363.         playVideo(0x0000,fileid);
  364.         fileid = m_videoAudioID[currPlayIndex];
  365.         playAudio(0x0000,fileid);
  366.         playStation = 0x01;
  367.         
  368.         drawPicture(X_VIDEO_BUTTON_PLAY,Y_VIDEO_BUTTON_PLAY,FILE_ID_BUTTON,BUTTON_ID_VIDEO_PAUSE);
  369.         if(currPlayIndex == 0){
  370.                 drawPicture(X_VIDEO_BUTTON_PREV,Y_VIDEO_BUTTON_PREV,FILE_ID_BUTTON,BUTTON_ID_VIDEO_PREVI);
  371.         }
  372.         drawPicture(X_VIDEO_BUTTON_NEXT,Y_VIDEO_BUTTON_PREV,FILE_ID_BUTTON,BUTTON_ID_VIDEO_NEXT);
  373. }

  374. /*****************************************************************************************
  375. 响应视频播放界面的下一首按键,跳转到下一首,同时更新下一首按钮的显示;
  376. ******************************************************************************************/
  377. static void onVideoNext(void)
  378. {
  379.         u16 fileid;
  380.         if(currPlayIndex >= 2)
  381.                 return;
  382.         
  383.         currPlayIndex++;
  384.         
  385.         fileid = m_videoID[currPlayIndex];
  386.         playVideo(0x0000,fileid);
  387.         fileid = m_videoAudioID[currPlayIndex];
  388.         playAudio(0x0000,fileid);
  389.         playStation = 0x01;
  390.         
  391.         drawPicture(X_VIDEO_BUTTON_PLAY,Y_VIDEO_BUTTON_PLAY,FILE_ID_BUTTON,BUTTON_ID_VIDEO_PAUSE);
  392.         if(currPlayIndex == 2){
  393.                 drawPicture(X_VIDEO_BUTTON_NEXT,Y_VIDEO_BUTTON_PREV,FILE_ID_BUTTON,BUTTON_ID_VIDEO_NEXTI);
  394.         }
  395.         drawPicture(X_VIDEO_BUTTON_PREV,Y_VIDEO_BUTTON_PREV,FILE_ID_BUTTON,BUTTON_ID_VIDEO_PREV);
  396. }

  397. /*****************************************************************************************
  398. 播放指定文件ID的视频,指定开始播放的位置;
  399. 发送命令给GUI内核;
  400. ******************************************************************************************/
  401. static void playVideo(u16 starts,u16 fileid)
  402. {
  403.         memset(send_buffer,0,20);
  404.         send_buffer[0] = 0x5A;
  405.         send_buffer[1] = 0x01;
  406.         send_buffer[2] = 0x00;// 使用文件中定义的播放速度;
  407.         send_buffer[3] = 0x5A;// 开始音视频同步播放;
  408.         send_buffer[4] = (starts  >> 8 )& 0xFF;
  409.         send_buffer[5] = (starts) & 0xFF;
  410.         
  411.         send_buffer[6] = (fileid  >> 8 )& 0xFF;
  412.         send_buffer[7] = (fileid) & 0xFF;
  413.         
  414.         send_buffer[8] = 0x00;        // 视频画面中的起始位置;
  415.         send_buffer[9] = 0x00;
  416.         send_buffer[10] = 0x00;
  417.         send_buffer[11] = 0x00;
  418.         
  419.         send_buffer[12] = 0x00;        // 屏幕上的显示位置;
  420.         send_buffer[13] = 0x6A;
  421.         send_buffer[14] = 0x00;  //y;
  422.         send_buffer[15] = 0x0A;
  423.         
  424.         send_buffer[16] = 0x03;        // 视频在屏幕上的显示宽度;
  425.         send_buffer[17] = 0x20;
  426.         send_buffer[18] = 0x01;  //视频在屏幕上的显示高度;
  427.         send_buffer[19] = 0xE0;
  428.         write_dgus_vp(0x00C8,send_buffer,10);
  429. }

  430. /*****************************************************************************************
  431. 处理音量进度条,使用多帧图片切换实现特效;
  432. ******************************************************************************************/
  433. static void adjustVolume(void)
  434. {
  435.         unsigned short av = 2048/20 * audioVolume;
  436.         memset(send_buffer,0,16);
  437.         send_buffer[0] = (unsigned char)((av >> 8)& 0xFF);
  438.         send_buffer[1] = (unsigned char)(av & 0xFF);
  439.         write_dgus_vp(0x00C5,send_buffer,1);
  440.         
  441.         if(pageID == PAGE_ID_AUDIO){//如果是音乐播放界面,调用音乐进度条文件中的图片;
  442.                 drawPartBKGPicture(X_AUDIO_POS_VOL,Y_AUDIO_POS_VOL,VOLUME_PIC_WIDTH,VOLUME_PIC_HEIGHT,X_AUDIO_POS_VOL,Y_AUDIO_POS_VOL,0);
  443.                 drawPicture(X_AUDIO_POS_VOL,Y_AUDIO_POS_VOL,FILE_ID_AUDIO_VOLUME,audioVolume);
  444.         }
  445.         else{
  446.                 drawPartBKGPicture(X_VIDEO_POS_VOL,Y_VIDEO_POS_VOL,VOLUME_PIC_WIDTH,VOLUME_PIC_HEIGHT,X_VIDEO_POS_VOL,Y_VIDEO_POS_VOL,1);
  447.                 drawPicture(X_VIDEO_POS_VOL,Y_VIDEO_POS_VOL,FILE_ID_VIDEO_VOLUME,audioVolume);
  448.         }
  449. }

  450. /*****************************************************************************************
  451. 处理音乐播放进度条,使用多帧图片切换实现特效,并更新显示文字;
  452. ******************************************************************************************/
  453. static void audioProgressDisplay(void)
  454. {
  455.                 int iframe;
  456.                 int m0,s0,m1,s1;
  457.                 char buf[12];
  458.         
  459.                 read_dgus_vp(0x00D2,&buf[0],4);
  460.                 playPosition = ((int)buf[0]) * 60 + (int)buf[1];
  461.                 playTotalDuration = ((int)buf[4]) * 60 + (int)buf[5];
  462.                
  463.                 if(playPosition > playTotalDuration){//过滤掉非正常数据;
  464.                         //printf("audioProgressDisplay>>>pos=%d,total=%d\n",playPosition,playTotalDuration);
  465.                         return;
  466.                 }
  467.                
  468.                 iframe = (playPosition * 100)/ playTotalDuration;
  469.                 if(iframe == oldProgressFrame){//当贴的图没有变化时不必要再刷新;
  470.                         //printf("audioProgressDisplay>>>frame=%d,playPosition=%d,playTotalDuration=%d\n",iframe,playPosition,playTotalDuration);
  471.                         return;
  472.                 }
  473.                
  474.                 oldProgressFrame = iframe;
  475.                
  476.                 drawPicture(X_AUDIO_POS_PROGRESS,Y_AUDIO_POS_PROGRESS,FILE_ID_AUDIO_PROGRESS,iframe);
  477.         
  478.                 m0 = playTotalDuration/60;
  479.                 s0 = playTotalDuration%60;
  480.                
  481.                 m1 = playPosition/60;
  482.                 s1 = playPosition%60;
  483.         
  484.                 setBackground(0x80,0x80,0x80);
  485.                 setForeground(0xFF,0xFF,0xFF);
  486.         
  487.                 sprintf(buf,"%02d:%02d/%02d:%02d",m1,s1,m0,s0);
  488.                 drawText(X_POS_PTEXT,Y_POS_PTEXT,buf);        
  489. }

  490. /*****************************************************************************************
  491. 处理视频播放进度条,使用多帧图片切换实现特效
  492. ******************************************************************************************/
  493. static void videoProgressDisplay(void)
  494. {
  495.                 int iframe;
  496.                 char buf[12];
  497.         
  498.                 read_dgus_vp(0x00D2,&buf[0],4);
  499.                 playPosition = ((int)buf[2]) * 60 + (int)buf[3];
  500.                 playTotalDuration = ((int)buf[6]) * 60 + (int)buf[7];
  501.         
  502.                 if(playPosition > playTotalDuration)
  503.                         return;
  504.                
  505.                 iframe = (playPosition * 100)/ playTotalDuration;
  506.                 if(iframe == oldProgressFrame)
  507.                         return;
  508.                
  509.                 oldProgressFrame = iframe;
  510.                 setDrawMode(0x01);
  511.                 drawPicture(X_VIDEO_POS_PROGRESS,Y_VIDEO_POS_PROGRESS,FILE_ID_VIDEO_PROGRESS,iframe);
  512.                 setDrawMode(0x00);
  513. }
  514. void processProgDisplay(void)
  515. {
  516.                 if(pageID == PAGE_ID_AUDIO)
  517.                         audioProgressDisplay();
  518.                 else if(pageID == PAGE_ID_VIDEO)
  519.                         videoProgressDisplay();        
  520. }
复制代码

版主补充:重要提示:该开源项目是配合20200425日期之前的UI版本内核固件制作,时间版本比较久远。建议用户只需参考os核下的8051c代码内容。
demo不要贸然下载到屏,不然可能会出现底图显示异常现象。



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

3

主题

4

回帖

48

积分

新手上路

Rank: 1

积分
48
 楼主| 发表于 2020-5-7 15:29:41 | 显示全部楼层

【开源】AIoT LCM平台开发自已的OS内核《三》

本帖最后由 lionel1203 于 2020-5-25 09:22 编辑

接上:
六、参考代码分析
3、paint.c
  1. /***************************************************************************************

  2.                   版权所有 (C), 2020, 北京迪文科技有限公司

  3. ***************************************************************************************
  4.   文 件 名   : paint.c
  5.   版 本 号   :
  6.   作    者   :
  7.   生成日期   : 2020年4月23日
  8.   功能描述   : 通过GUI核实现图形界面输出;
  9.   修改历史   :
  10.   1.日    期   :
  11.     作    者   :
  12.     修改内容   :
  13. ****************************************************************************************/
  14. #include <stdio.h>
  15. #include  <string.h>
  16. #include "paint.h"

  17. static u8 dr_ForeColor[4];
  18. static u8 dr_BkgColor[4];
  19. static u8 dr_LineWidth;
  20. static u8 dr_FontId;//0(12X12),1(16x16),2(24x24),3(32X32);
  21. static u8 dr_Mode;

  22. extern u8 xdata send_buffer[260];

  23. /*********************************************************************************************************
  24. 初始化绘图相关的参数,前景与背景颜色,线宽,字体,显示模式等参数初始化;

  25. **********************************************************************************************************/
  26. void initDraw(void)
  27. {
  28.         memset(dr_ForeColor,0,4);
  29.         memset(dr_BkgColor,0,4);
  30.         dr_ForeColor[0] = 0xFF;
  31.         dr_BkgColor[2] = 0xFF;
  32.         dr_LineWidth = 0x02;
  33.         dr_FontId = 0x02;
  34.         dr_Mode = 0x00;
  35. }

  36. void check800CmdFinished(void)
  37. {
  38.         u8 ckbuf[4];
  39.         do{
  40.                 read_dgus_vp(0x1000,&ckbuf[0],1);
  41.         }while(ckbuf[0] != 0x00 );
  42. }


  43. /*********************************************************************************************************
  44. 通过GUI核绘制文本到指定位置,使用当前字体,前景色和背景色;
  45. x:位置
  46. y:位置;
  47. text:将显示的文字;
  48. **********************************************************************************************************/
  49. void drawText(int x,int y,char * text)
  50. {
  51.         int len;
  52.         len = strlen(text) + 4;
  53.         send_buffer[0] = 0x5A;
  54.         send_buffer[1] = (u8)(len >> 8);
  55.         send_buffer[2] = (u8)len & 0xFF;
  56.         
  57.         switch(dr_FontId){
  58.                 case 0:
  59.                         send_buffer[3] = 0x6E;
  60.                         break;
  61.                 case 1:
  62.                         send_buffer[3] = 0x54;
  63.                         break;
  64.                 case 2:
  65.                         send_buffer[3] = 0x6F;
  66.                         break;
  67.                 case 3:
  68.                         send_buffer[3] = 0x55;
  69.                         break;
  70.                 default:
  71.                         return;
  72.         }
  73.         send_buffer[4] = (u8)((x >> 8) & 0xFF);
  74.         send_buffer[5] = (u8)(x & 0xFF);
  75.         send_buffer[6] = (u8)((y >> 8) & 0xFF);
  76.         send_buffer[7] = (u8)(y & 0xFF);
  77.         memcpy(&send_buffer[8],text,len - 4);
  78.         len = (len + 5)/2;
  79.         
  80.         check800CmdFinished();
  81.         write_dgus_vp(0x1000,send_buffer,len);
  82.         
  83. }

  84. /*********************************************************************************************************
  85. 通过GUI核显示图片,图片预处理成ICM文件,并存放在指定位置;
  86. x:位置
  87. y:位置;
  88. libid:文件存放的指定位置,通过文件名数字决定;
  89. picid:文件中的图标ID;
  90. **********************************************************************************************************/
  91. void drawPicture(int x,int y,int libid,int picid)
  92. {
  93.         send_buffer[0] = 0x5A;
  94.         send_buffer[1] = 0x00;
  95.         send_buffer[2] = 0x08;
  96.         send_buffer[3] = 0x97;
  97.         send_buffer[4] = (u8)(x >> 8)& 0xFF;
  98.         send_buffer[5] = (u8)x & 0xFF;
  99.         send_buffer[6] = (u8)( y  >> 8 )& 0xFF;
  100.         send_buffer[7] = (u8)y & 0xFF;
  101.         send_buffer[8] = (u8)libid;
  102.         
  103.         if(dr_Mode == 0x00){
  104.                 send_buffer[9] = (u8)0x00;
  105.         }
  106.         else
  107.                 send_buffer[9] = (u8)0x01;
  108.         
  109.         send_buffer[10] = ( picid  >> 8 )& 0xFF;
  110.         send_buffer[11] = picid & 0xFF;
  111.         
  112.         check800CmdFinished();
  113.         write_dgus_vp(0x1000,send_buffer,6);
  114. }

  115. /**/
  116. void switchPage(int id)
  117. {
  118.         send_buffer[0] = 0x5A;
  119.         send_buffer[1] = 0x00;
  120.         send_buffer[2] = 0x02;
  121.         send_buffer[3] = 0x70;
  122.         send_buffer[4] = 0x00;
  123.         send_buffer[5] = (unsigned char)id;
  124.         check800CmdFinished();
  125.         write_dgus_vp(0x1000,send_buffer,3);
  126. }

  127. /*********************************************************************************************************
  128. 通过GUI核显示局部图片,图片预处理成ICM文件,并存放在指定位置,一般用于背景刷新;
  129. sx,sy:在源图片中的起点位置
  130. sw,sh:在源图片中要显示的区域高度和宽度;
  131. dx,dy:显示在屏幕上的位置,左上角为(0,0);
  132. picid:文件ID;
  133. **********************************************************************************************************/
  134. void drawPartBKGPicture(int sx,int sy,int sw,int sh,int dx,int dy,int picid)
  135. {
  136.         sw += (sx - 1);
  137.         sh += (sy - 1);
  138.         
  139.         send_buffer[0] = 0x5A;
  140.         send_buffer[1] = 0x00;
  141.         send_buffer[2] = 0x0D;
  142.         send_buffer[3] = 0x71;
  143.         send_buffer[4] = (u8)picid;
  144.         send_buffer[5] = (u8)(sx >> 8)& 0xFF;
  145.         send_buffer[6] = (u8)sx & 0xFF;
  146.         send_buffer[7] = (u8)( sy  >> 8 )& 0xFF;
  147.         send_buffer[8] = (u8)sy & 0xFF;
  148.         
  149.         send_buffer[9] = (u8)(sw >> 8)& 0xFF;
  150.         send_buffer[10] = (u8)sw & 0xFF;
  151.         send_buffer[11] = (u8)( sh  >> 8 )& 0xFF;
  152.         send_buffer[12] = (u8)sh & 0xFF;
  153.         
  154.         send_buffer[13] = (u8)(dx >> 8)& 0xFF;
  155.         send_buffer[14] = (u8)dx & 0xFF;
  156.         send_buffer[15] = (u8)( dy  >> 8 )& 0xFF;
  157.         send_buffer[16] = (u8)dy & 0xFF;
  158.         check800CmdFinished();
  159.         write_dgus_vp(0x1000,send_buffer,9);
  160. }


  161. /*********************************************************************************************************
  162. 通过GUI核绘制矩形,使用当前线宽,前景色与背景色;
  163. x,y:起点位置
  164. w,h:矩形的区域高度和宽度;
  165. **********************************************************************************************************/
  166. void drawRectangle(int x,int y,int w,int h)
  167. {
  168. }

  169. /*********************************************************************************************************
  170. 通过GUI核绘制圆,使用当前线宽,前景色与背景色;
  171. cx,cy:中心位置
  172. radius:半径;
  173. **********************************************************************************************************/
  174. void drawCircle(int cx,int cy,int radius)
  175. {
  176. }

  177. /*********************************************************************************************************
  178. 通过GUI核设置前景色;
  179. r,g,b:颜色分量;
  180. **********************************************************************************************************/
  181. void setForeground(u8 r,u8 g,u8 b)
  182. {
  183.         dr_ForeColor[0] = r;
  184.         dr_ForeColor[1] = g;
  185.         dr_ForeColor[2] = b;
  186.         write_dgus_vp(0x0044,dr_ForeColor,2);
  187. }

  188. /*********************************************************************************************************
  189. 通过GUI核设置背景色;
  190. r,g,b:颜色分量;
  191. **********************************************************************************************************/
  192. void setBackground(u8 r,u8 g,u8 b)
  193. {
  194.         dr_BkgColor[0] = r;
  195.         dr_BkgColor[1] = g;
  196.         dr_BkgColor[2] = b;
  197.         write_dgus_vp(0x0046,dr_BkgColor,2);
  198. }

  199. /*********************************************************************************************************
  200. 通过GUI核设置线宽;
  201. width:线的宽度;
  202. **********************************************************************************************************/
  203. void setLineWidth(int width)
  204. {
  205.         dr_LineWidth = width;
  206. }

  207. /*********************************************************************************************************
  208. 通过GUI核设置字体;
  209. fontid:指定的字体;;
  210. **********************************************************************************************************/
  211. void setFont(int fontid)
  212. {
  213.         dr_FontId = fontid;
  214. }

  215. /*********************************************************************************************************
  216. 通过GUI核显示模式;
  217. mode:指定的显示模式;
  218. **********************************************************************************************************/
  219. void setDrawMode(int mode)
  220. {
  221.         dr_Mode = (u8)mode;
  222. }
复制代码

4、cmd.c
  1. /***************************************************************************************

  2.                   版权所有 (C), 2020, 北京迪文科技有限公司

  3. ***************************************************************************************
  4.   文 件 名   : cmd.c
  5.   版 本 号   :
  6.   作    者   :
  7.   生成日期   : 2020年4月23日
  8.   功能描述   : 串口2指令解析及执行;
  9.   修改历史   :
  10.   1.日    期   :
  11.     作    者   :
  12.     修改内容   :
  13. ****************************************************************************************/
  14. #include <stdio.h>
  15. #include  <string.h>
  16. #include "sys.h"
  17. #include "uart.h"
  18. #include "cmd.h"
  19. #include "player.h"

  20. /* Table of CRC values for high-order byte */
  21. static const u8 code table_crc_hi[256] = {
  22.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
  23.     0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  24.     0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
  25.     0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  26.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
  27.     0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  28.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
  29.     0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  30.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
  31.     0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
  32.     0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
  33.     0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  34.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
  35.     0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
  36.     0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
  37.     0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  38.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
  39.     0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  40.     0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
  41.     0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  42.     0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
  43.     0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
  44.     0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
  45.     0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  46.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
  47.     0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
  48. };

  49. /* Table of CRC values for low-order byte */
  50. static const u8 code table_crc_lo[256] = {
  51.     0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
  52.     0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
  53.     0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
  54.     0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
  55.     0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
  56.     0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
  57.     0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
  58.     0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
  59.     0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
  60.     0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
  61.     0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
  62.     0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
  63.     0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
  64.     0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
  65.     0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
  66.     0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
  67.     0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
  68.     0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
  69.     0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
  70.     0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
  71.     0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
  72.     0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
  73.     0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
  74.     0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
  75.     0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
  76.     0x43, 0x83, 0x41, 0x81, 0x80, 0x40
  77. };

  78. //发送命令用缓冲区;
  79. u8 xdata send_buffer[260];

  80. //系统配置信息;
  81. static u8 sys_setting;

  82. unsigned short getUShortFromBuf(u8 * buf);

  83. /************************************************************************************************
  84. 初始化,读取命令执行中需要的系统配置信息;
  85. *************************************************************************************************/
  86. void initCMD(void)
  87. {
  88.         u8  buf[12];
  89.         read_dgus_vp(0x0002,buf,6);
  90.         sys_setting = buf[1];
  91.         printf("initCMD>>>sys_setting=\n");
  92.         UART2_SendBuffer(buf,12);
  93. }

  94. /*************************************************************************************************
  95. 添加帧尾到发送命令缓冲区;
  96.    cmdlen:放入到发送缓冲区中的开始偏移;
  97. 返回:添加完后,发送缓冲区大小;
  98. **************************************************************************************************/
  99. int addTail(int cmdlen)
  100. {
  101.         send_buffer[cmdlen++] = 0xCC;
  102.         send_buffer[cmdlen++] = 0x33;
  103.         send_buffer[cmdlen++] = 0xC3;
  104.         send_buffer[cmdlen++] = 0x3C;
  105.         return cmdlen;
  106. }

  107. /*************************************************************************************************
  108. 添加长整型到发送命令缓冲区;
  109.    cmdlen:放入到发送缓冲区中的开始偏移;
  110. 返回:添加完后,发送缓冲区大小;
  111. **************************************************************************************************/
  112. int addLong(int cmdlen,long value)
  113. {
  114.         u8 * cvp = (u8*)&value;
  115.         send_buffer[cmdlen++] = cvp[0];
  116.         send_buffer[cmdlen++] = cvp[1];
  117.         send_buffer[cmdlen++] = cvp[2];
  118.         send_buffer[cmdlen++] = cvp[3];
  119.         return cmdlen;
  120. }

  121. /*************************************************************************************************
  122. 添加2字节短整型到发送命令缓冲区;
  123.    cmdlen:放入到发送缓冲区中的开始偏移;
  124. 返回:添加完后,发送缓冲区大小;
  125. **************************************************************************************************/
  126. int addShort(int cmdlen,short value)
  127. {
  128.         u8 * cvp = (u8*)&value;
  129.         send_buffer[cmdlen++] = cvp[0];
  130.         send_buffer[cmdlen++] = cvp[1];
  131.         return cmdlen;
  132. }

  133. /*************************************************************************************************
  134. 添加字符串到发送命令缓冲区;
  135.    cmdlen:放入到发送缓冲区中的开始偏移;
  136. 返回:添加完后,发送缓冲区大小;
  137. **************************************************************************************************/
  138. int addString(int cmdlen,const char * s)
  139. {
  140.         while(*s != 0){
  141.                 send_buffer[cmdlen++] = *s++;
  142.                 if(cmdlen > 251 )
  143.                         break;
  144.         }
  145.         return cmdlen;
  146. }

  147. /*************************************************************************************************
  148. 添加缓冲区到发送命令缓冲区;
  149.    cmdlen:放入到发送缓冲区中的开始偏移;
  150. 返回:添加完后,发送缓冲区大小;
  151. **************************************************************************************************/
  152. int addBuffer(int cmdlen,u8 * buff,int len)
  153. {
  154.         memcpy(&send_buffer[cmdlen],buff,len);
  155.         return cmdlen+len;
  156. }

  157. /*************************************************************************************************
  158. 添加CRC校验数据到发送命令缓冲区;
  159.    cmdlen:放入到发送缓冲区中的开始偏移;
  160. 返回:添加完后,发送缓冲区大小;
  161. **************************************************************************************************/
  162. int addCRC(int cmdlen)
  163. {
  164.         if( sys_setting & 0x80 ){
  165.                 unsigned char tmp;
  166.                 int i = 0;
  167.                 u8 crc_hi = 0xFF;
  168.                 u8 crc_lo = 0xFF;

  169.                 while( i < cmdlen ){
  170.                         tmp = crc_hi ^ send_buffer[i];
  171.                         crc_hi = crc_lo ^ table_crc_hi[tmp];
  172.                         crc_lo = table_crc_lo[tmp];
  173.                         i++;
  174.                 }

  175.                 send_buffer[cmdlen++] = crc_hi;
  176.                 send_buffer[cmdlen++] = crc_lo;
  177.                 return cmdlen;
  178.         }
  179.         return cmdlen;
  180. }

  181. /*************************************************************************************************
  182. 对缓冲区中数据进行CRC校验;
  183.    buf:需校验的数据首地址;
  184.    len:需校验的数据长度;
  185. 返回:大于0校验成功;等于0没有校验;小于零校验失败;
  186. **************************************************************************************************/
  187. int checkCRC(u8 * buf,int len)
  188. {
  189.         if( sys_setting & 0x80 ){
  190.                 unsigned char tmp;
  191.                 int i = 0;
  192.                 u8 crc_hi = 0xFF;
  193.                 u8 crc_lo = 0xFF;
  194.                
  195.                 if(len <= 6 )
  196.                         return -1;
  197.                
  198.                 while( i < len - 6 ){
  199.                         tmp = crc_hi ^ send_buffer[i];
  200.                         crc_hi = crc_lo ^ table_crc_hi[tmp];
  201.                         crc_lo = table_crc_lo[tmp];
  202.                         i++;
  203.                 }
  204.                
  205.                 if(crc_hi != buf[i++] ||
  206.                         crc_lo != buf[i] )
  207.                         return -1;
  208.                 return 1;
  209.         }
  210.         return 0;
  211. }

  212. /*************************************************************************************************
  213. 响应用户的握手请求,发送握手回应给用户;
  214. **************************************************************************************************/
  215. void responseUserShakehand(void)
  216. {
  217.         int cmdlen;
  218.         u8  buf[8];
  219.         send_buffer[0] = 0xAA;
  220.         send_buffer[1] = 0x00;
  221.         cmdlen = addString(2,"OK_V1.0");
  222.         send_buffer[cmdlen++] = 0x00;
  223.         send_buffer[cmdlen++] = 0x00;
  224.         
  225.         read_dgus_vp(0x0002,buf,4);
  226.         cmdlen = addBuffer(cmdlen,&buf[1],5);
  227.         read_dgus_vp(0x0040,buf,2);
  228.         cmdlen = addBuffer(cmdlen,&buf[0],4);
  229.         cmdlen = addCRC(cmdlen);
  230.         cmdlen = addTail(cmdlen);
  231.         UART2_SendBuffer(send_buffer,cmdlen);
  232. }

  233. /*************************************************************************************************
  234. 处理调色板设置命令,根据接收到的数据,自动处理16BIT和24BIT数据;如果是16BIT还需要进行565转24位色;
  235.    buf:包括命令字的命令缓冲区首地址;
  236.    len:命令缓冲区中的数据长度,包含了帧尾;
  237. **************************************************************************************************/
  238. void processPaletteSetting(u8 * buf,int len)
  239. {
  240.         u8 tb[8];
  241.         if( sys_setting & 0x80)
  242.                 len -= 6;
  243.         else
  244.                 len -= 4;
  245.         
  246.         if(len > 6){
  247.                 tb[3] = 0x00;
  248.                 memcpy(tb,&buf[1],3);
  249.                 write_dgus_vp(0x0044,tb,2);
  250.                 memcpy(tb,&buf[4],3);
  251.                 write_dgus_vp(0x0046,tb,2);
  252.         }
  253.         else{
  254.                 unsigned short c = getUShortFromBuf(&buf[1]);
  255.                 tb[3] = 0x00;
  256.                 tb[0] = (c & 0xf800) >> 8;
  257.     tb[1] = (c & 0x07e0) >> 3;
  258.     tb[2] = (c & 0x001f) << 3;
  259.                
  260.                 write_dgus_vp(0x0044,tb,2);
  261.                 c = getUShortFromBuf(&buf[3]);
  262.                 tb[0] = (c & 0xf800) >> 8;
  263.     tb[1] = (c & 0x07e0) >> 3;
  264.     tb[2] = (c & 0x001f) << 3;
  265.                 write_dgus_vp(0x0046,tb,2);
  266.         }
  267. }

  268. /*************************************************************************************************
  269. 处理显示间隔设置;
  270.    buf:包括命令字的命令缓冲区首地址;
  271.    len:命令缓冲区中的数据长度,包含了帧尾;
  272. **************************************************************************************************/
  273. void processDisplayGap(u8 * buf,int len)
  274. {
  275.         u8 tb[8];
  276.         if(len < 3)
  277.                 return;
  278.         
  279.         read_dgus_vp(0x00042,tb,2);
  280.         tb[1] = buf[1];
  281.         tb[2] = buf[2];
  282.         write_dgus_vp(0x0042,tb,2);
  283. }

  284. /*************************************************************************************************
  285. 从缓冲区中获取短整型;
  286.   buf:缓冲区首地址;
  287. 返回:获取到的短整型数值;
  288. **************************************************************************************************/
  289. unsigned short getUShortFromBuf(u8 * buf)
  290. {
  291.         unsigned short ret = buf[0];
  292.         ret <<= 8;
  293.         ret |= buf[1];
  294.         return ret;
  295. }

  296. /*************************************************************************************************
  297. 回应给用户CRC校验错误;
  298. **************************************************************************************************/
  299. void responseCRCError(void)
  300. {
  301.         int cmdlen;
  302.         send_buffer[0] = 0xAA;
  303.         send_buffer[1] = 0xFF;
  304.         send_buffer[2] = 0x01;
  305.         cmdlen = addCRC(3);
  306.         cmdlen = addTail(cmdlen);
  307.         UART2_SendBuffer(send_buffer,cmdlen);
  308. }

  309. /*************************************************************************************************
  310. 处理GUI内存直接写命令;
  311.    buf:包括命令字的命令缓冲区首地址;
  312.    len:命令缓冲区中的数据长度,包含了帧尾;
  313. **************************************************************************************************/
  314. void directWriteGUIMem(u8 * buf,int len)
  315. {
  316.         int dlen;
  317.         unsigned short addr = 2 * getUShortFromBuf(buf+1);
  318.         if( sys_setting & 0x80 )
  319.                 dlen = len - 6;//with crc;
  320.         else
  321.                 dlen = len - 4;
  322.         
  323.         dlen = (dlen - 3)/2;
  324.         write_dgus_vp(addr,&buf[3],dlen);
  325. }

  326. /*************************************************************************************************
  327. 处理GUI内存直接读取命令;
  328.    buf:包括命令字的命令缓冲区首地址;
  329. 返回:获取到的数据直接通过串口发送给用户;
  330. **************************************************************************************************/
  331. void directReadGUIMem(u8 * buf)
  332. {
  333.         int len;
  334.         unsigned short addr = 2 * getUShortFromBuf(buf+1);
  335.         len = getUShortFromBuf(buf+3);
  336.         
  337.         send_buffer[0] = 0xAA;
  338.         send_buffer[1] = 0xC2;
  339.         send_buffer[2] = buf[1];
  340.         send_buffer[3] = buf[2];
  341.         
  342.         read_dgus_vp(addr,&send_buffer[4],len * 2);
  343.         len = len * 4 + 4;
  344.         len = addCRC(len);
  345.         len = addTail(len);
  346.         
  347.         UART2_SendBuffer(send_buffer,len);
  348. }

  349. /*************************************************************************************************
  350. 处理默认的其它命令,直接把这些命令发送给GUI去处理;
  351.    buf:包括命令字的命令缓冲区首地址;
  352.    len:命令缓冲区中的数据长度,包含了帧尾;
  353. **************************************************************************************************/
  354. int route2GUIMemDefault(u8 * buf,int len)
  355. {
  356.         int dlen;
  357.         
  358.         if( sys_setting & 0x80 )//delete the tail and CRC,only send the datas and cmd;
  359.                 len -= 6;
  360.         else
  361.                 len -= 4;
  362.         
  363.         dlen = len - 1;
  364.         send_buffer[0] = 0x5A;
  365.         send_buffer[1] = (u8)(dlen >> 8);
  366.         send_buffer[2] = (u8)dlen & 0xFF;
  367.         memcpy(&send_buffer[3],buf,len);
  368.         if(len%2)
  369.                 dlen = (len + 3)/2;
  370.         else
  371.                 dlen = (len + 4)/2;
  372.         
  373.         write_dgus_vp(0x1000,send_buffer,dlen);
  374.         return dlen;
  375. }

  376. /*************************************************************************************************
  377. 检查并发送触摸数据给串口用户;
  378. **************************************************************************************************/
  379. void checkAndSendTP2Uart(void)
  380. {
  381.         u8 buf[8];
  382.         read_dgus_vp(0x0048,buf,4);
  383.         
  384.         if(buf[0] == 0x5A){//the tp is triggered;
  385.                
  386.                 processInput(&buf[3]);
  387.                 send_buffer[0] = 0x00;
  388.                 send_buffer[1] = 0x00;
  389.                 write_dgus_vp(0x0048,send_buffer,1);
  390.                
  391.                 if(sys_setting & 0x20){
  392.                         int len;
  393.                         u8 cmd = buf[3];
  394.                         //filter by the sys_setting;
  395.                         if(sys_setting & 0x40){//on
  396.                                 if(cmd != 0x78 && cmd != 0x79)
  397.                                         return;
  398.                         }
  399.                         else{
  400.                                 if( cmd != 0x72 && cmd != 0x73)
  401.                                         return;
  402.                         }
  403.                         
  404.                         if(sys_setting & 0x08){//not send 73/79;
  405.                                 if( cmd == 0x73 || cmd == 0x79)
  406.                                         return;
  407.                         }
  408.                         
  409.                         send_buffer[0] = 0xAA;
  410.                         send_buffer[1] = cmd;
  411.                         memcpy(&send_buffer[2],&buf[4],4);
  412.                         len = 2 + buf[1];
  413.                         len = addCRC(len);
  414.                         len = addTail(len);
  415.                         UART2_SendBuffer(send_buffer,len);
  416.                 }
  417.                 return;
  418.         }
  419. }
复制代码




回复

使用道具 举报

3

主题

4

回帖

48

积分

新手上路

Rank: 1

积分
48
 楼主| 发表于 2020-5-7 15:36:53 | 显示全部楼层

【开源】AIoT LCM平台开发自已的OS内核《四》

本帖最后由 lionel1203 于 2020-5-25 09:22 编辑

接上
六、参考代码分析
5、uart.c
  1. /***************************************************************************************

  2.                   版权所有 (C), 2020, 北京迪文科技有限公司

  3. ***************************************************************************************
  4.   文 件 名   : uart.c
  5.   版 本 号   :
  6.   作    者   :
  7.   生成日期   : 2020年4月23日
  8.   功能描述   : 串口函数
  9.   修改历史   :
  10.   1.日    期   :
  11.     作    者   :
  12.     修改内容   :
  13. ****************************************************************************************/
  14. #include <stdio.h>
  15. #include "sys.h"
  16. #include "uart.h"
  17. #include "cmd.h"

  18. //串口2发送等待标志;
  19. static u8 uart2_busy;

  20. //串口2接收缓冲区数据总数;
  21. static int recv_num;

  22. //用于读取串口2的指令帧;
  23. static int  recv_head;

  24. //串口2接收缓冲区,其大小根据通讯协议帧的大小可调整;
  25. static u8 xdata uart_buffer[256];

  26. /***************************************************************************************
  27. 串口2的初始化,根据硬件配置参数,读取波特率,并设置给串口
  28. ****************************************************************************************/
  29. void UART2_Init(void)
  30. {
  31.                 long brate = 0L;
  32.                 unsigned short v;
  33.                 //UART2配置
  34.                 read_dgus_vp(0x0006,uart_buffer,2);
  35.         
  36.                 brate |= uart_buffer[0];
  37.                 brate <<= 8;
  38.                 brate |= uart_buffer[1];
  39.                 brate <<= 8;
  40.           brate |= uart_buffer[2];
  41.           v = 1024 - (int)(5529600L/brate);
  42.                
  43.                 MUX_SEL|=0X40;
  44.           P0MDOUT|=0x10;
  45.     ADCON=0x80;
  46.     SCON0=0x50;
  47.                
  48.                 SREL0H = (v >> 8) & 0xFF;
  49.                 SREL0L = v & 0xFF;
  50.         
  51.     //SREL0H=0x03;        //SREL0H/L = 1024 - 5529600/brate;
  52.     //SREL0L=0xD0;
  53.         
  54.           IEN0|=0x10;
  55.           recv_num = 0;
  56.                 recv_head = 0;
  57.         
  58.     ES0=1;
  59.     EA=1;
  60.           uart2_busy=0;
  61. }

  62. /****************************************************************************************
  63. 通过串口2发送,按16进制值发送ASCII给终端,一般用于调试;
  64. dat:发送的数据,在终端用2位16进制数表示;
  65. ****************************************************************************************/
  66. void UART2_SendHex(u8 dat)
  67. {
  68.                 u8 xdata hi,lo;
  69.                 hi = (dat >> 4) & 0x0F;
  70.                 lo = dat & 0x0F;
  71.         
  72.                 if(hi > 9)
  73.                         UART2_Sendbyte('A' + hi - 10 );
  74.                 else
  75.                         UART2_Sendbyte('0' + hi);
  76.                
  77.                 if(lo > 9)
  78.                         UART2_Sendbyte('A' + lo - 10 );
  79.                 else
  80.                         UART2_Sendbyte('0' + lo );
  81. }

  82. /****************************************************************************************
  83. 通过串口2发送一字节数据给终端
  84. dat:发送的数据;
  85. ****************************************************************************************/
  86. void UART2_Sendbyte(u8 dat)
  87. {      
  88.      while(uart2_busy==1);      
  89.      uart2_busy=1;
  90.      SBUF0 = dat;        
  91. }

  92. /***************************************************************************************
  93. 通过串口发送连续内存区域给终端;
  94. buf:缓冲区首地址;
  95. len:发送的字节数;
  96. ****************************************************************************************/
  97. void UART2_SendBuffer(u8 *buf,int len)
  98. {
  99.         while(len--){
  100.            while(uart2_busy==1);      
  101.      uart2_busy=1;
  102.      SBUF0 = *buf++;
  103.         }               
  104. }

  105. /***********************************************************************************************
  106. 串口指令分发并执行;
  107. 串口指令通过串口中断方式接收到缓冲区时,当检查到帧结尾标志后,只有前面接收到的数据处理完成后,
  108. 中断函数才会把新接收的数据放到缓冲区中,而帧数据的分发和命令响应不能放在中断响应函数中;
  109. ************************************************************************************************/
  110. void dispatchCommand(void)
  111. {
  112.         u8 cmd;
  113.         if( recv_head != 1)
  114.                 return;
  115.         
  116.         if(checkCRC(uart_buffer,recv_num) < 0){
  117.                 responseCRCError();
  118.                 recv_num = 0;
  119.                 recv_head = 0;//允许继续接收下一个命令;
  120.                 return;
  121.         }
  122.         
  123.         cmd = uart_buffer[0];
  124.         //printf("dispatchCommand>>>cmd=");
  125.         //UART2_SendHex(cmd);
  126.         //UART2_Sendbyte('\n');
  127.         
  128.         switch(cmd){
  129.                 case 0x00://握手;
  130.                         responseUserShakehand();
  131.                         break;
  132.                 case 0x40://设置调色板;
  133.                         processPaletteSetting(uart_buffer,recv_num);
  134.                         break;
  135.                 case 0x41://设置字符间距
  136.                         processDisplayGap(uart_buffer,recv_num);
  137.                         break;
  138.                 case 0xC0://直接操作与GUI的共用缓冲区;
  139.                         directWriteGUIMem(uart_buffer,recv_num);
  140.                         break;
  141.                 case 0xC2://直接从与GUI的共用缓冲区读取数据;
  142.                         directReadGUIMem(uart_buffer);
  143.                         break;
  144.                 default://把命令打包传送给GUI执行;
  145.                         route2GUIMemDefault(uart_buffer,recv_num);
  146.                         break;        
  147.         }
  148.         
  149.         recv_num = 0;
  150.         recv_head = 0;//允许继续接收下一个命令;
  151.         
  152. }


  153. /********************************************************************************************************
  154. 串口2中断响应函数;
  155. 从底层接收串口数据到接收缓冲区,并按帧数据保存到缓冲区,当recv_head == 1时,停止接收并忽略;
  156. 处理数据发送,当发送成功后把发送标志复位;
  157. *********************************************************************************************************/
  158. void UART2_ISR_PC(void)    interrupt 4
  159. {
  160.     EA=0;
  161.     if(RI0==1){
  162.                                 u8 res = SBUF0;
  163.                                 if(recv_head > 1){//save at buffer;
  164.                                         uart_buffer[recv_num++] = res;
  165.                                         if(recv_num > 255){//the cmd is larger than the buffer,then discard this cmd;
  166.                                                 recv_num = 0;
  167.                                                 recv_head = 0;
  168.                                         }
  169.                                        
  170.                                         switch(recv_head){
  171.                                                 case 5:
  172.                                                         if(res == 0xCC)
  173.                                                                 recv_head--;
  174.                                                         break;
  175.                                                 case 4:
  176.                                                         if(res == 0x33)
  177.                                                                 recv_head--;
  178.                                                         else
  179.                                                                 recv_head = 5;
  180.                                                         break;
  181.                                                 case 3:
  182.                                                         if(res == 0xC3)
  183.                                                                 recv_head--;
  184.                                                         else
  185.                                                                 recv_head = 5;
  186.                                                         break;
  187.                                                 case 2:
  188.                                                         if(res == 0x3C)//fond a frame,discard next until the cmd is processed;
  189.                                                                 recv_head--;
  190.                                                         else
  191.                                                                 recv_head = 5;
  192.                                                         break;
  193.                                                 default:
  194.                                                         break;
  195.                                         }
  196.                                 }
  197.                                 else if(recv_head == 1){//wait for cmd processed;
  198.                                 }
  199.                                 else if( res == 0xAA )
  200.                                         recv_head = 5;               
  201.         RI0=0;      
  202.     }
  203.                
  204.     if(TI0==1){
  205.         TI0=0;
  206.         uart2_busy=0;
  207.     }
  208.     EA=1;
  209. }
复制代码


6、sys.c
  1. /******************************************************************************

  2.                   版权所有 (C), 2020, 北京迪文科技有限公司

  3. ******************************************************************************
  4.   文 件 名   : sys.c
  5.   版 本 号   : V1.0
  6.   作    者   : gaolaihong
  7.   生成日期   : 2020.04.23
  8.   功能描述   : CPU及设备和定时器的初始化,以及相应访问接口;
  9.   修改历史   :
  10.   1.日    期   :
  11.     作    者   :
  12.     修改内容   :
  13. ******************************************************************************/

  14. #include <T5LOS8051.H>
  15. #include "sys.h"
  16. #include "uart.h"

  17. //记录开机以来的TICK数,1TICK = 10MS;
  18. unsigned int sys_time_ticks;

  19. //使用T2定时器,采用两级计数,定时器产生2MS的定时,然后形成10MS定时;
  20. static unsigned char sys_tick_7200;

  21. /***************************************************************************************************
  22. 检查指定DGUS变量地址的DATA3清零的话就退出
  23. ****************************************************************************************************/
  24. static void wait_ok(unsigned int addr)
  25. {
  26.         ADR_H=0x00;
  27.         ADR_M=(unsigned char)(addr>>8);
  28.         ADR_L=(unsigned char)(addr);
  29.         ADR_INC=0x00;
  30.         do{
  31.                 for(addr=0;addr<1000;addr++)        //释放变量空间一段时间
  32.                   DATA2=DATA1;
  33.                   
  34.                 RAMMODE=0xAF;
  35.                 while(APP_ACK==0);
  36.                 APP_EN=1;
  37.                 while(APP_EN==1);
  38.                 RAMMODE=0x00;
  39.                
  40.         }        while(DATA3!=0);
  41. }

  42. /*******************************************************************************************************
  43. 读取DGUS变量数据
  44.   addr=DGUS变量地址  
  45.   *buf=数据返回指针  
  46.   len=读取数据字长度
  47. 返回:无
  48. ********************************************************************************************************/
  49. void read_dgus_vp(u32 addr,u8* buf,u16 len)
  50. {   
  51.         u8 i;     
  52.         i=(unsigned char)(addr&0x01);
  53.         addr=addr/2;
  54.         ADR_H=0x00;
  55.         ADR_M=(unsigned char)(addr>>8);
  56.         ADR_L=(unsigned char)(addr);
  57.         ADR_INC=0x01;
  58.         RAMMODE=0xAF;
  59.         while(APP_ACK==0);
  60.         
  61.         while(len>0){
  62.                 APP_EN=1;
  63.                 while(APP_EN==1);
  64.                 if((i==0)&&(len>0)){   
  65.                         *buf++=DATA3;
  66.                         *buf++=DATA2;                     
  67.                         i=1;
  68.                         len--;        
  69.                 }
  70.                 if((i==1)&&(len>0)){   
  71.                         *buf++=DATA1;
  72.                         *buf++=DATA0;                     
  73.                         i=0;
  74.                         len--;        
  75.                 }
  76.         }
  77.         RAMMODE=0x00;
  78. }

  79. /*******************************************************************************************************
  80. 写DGUS变量数据
  81.    addr=DGUS变量地址
  82.    *buf=写入数据指针  
  83.    len=写入数据字长度
  84. 返回:无
  85. ********************************************************************************************************/
  86. void write_dgus_vp(u32 addr,u8* buf,u16 len)
  87. {   
  88.         unsigned char i;     
  89.         i=(unsigned char)(addr&0x01);
  90.         addr=addr/2;
  91.         ADR_H=0x00;
  92.         ADR_M=(unsigned char)(addr>>8);
  93.         ADR_L=(unsigned char)(addr);   
  94.         ADR_INC=0x01;
  95.         RAMMODE=0x8F;
  96.         
  97.         while(APP_ACK==0);
  98.         if(i && len>0){        
  99.                 RAMMODE=0x83;        
  100.                 DATA1=*buf++;               
  101.                 DATA0=*buf++;        
  102.                 APP_EN=1;
  103.                 while(APP_EN==1);               
  104.                 len--;
  105.         }
  106.         
  107.         RAMMODE=0x8F;
  108.         while(len>=2){
  109.                 DATA3=*buf++;               
  110.                 DATA2=*buf++;
  111.                 DATA1=*buf++;               
  112.                 DATA0=*buf++;
  113.                 APP_EN=1;
  114.                 while(APP_EN==1);               
  115.                 len=len-2;
  116.         }
  117.         
  118.         if(len){
  119.                 RAMMODE=0x8C;
  120.                 DATA3=*buf++;               
  121.                 DATA2=*buf++;
  122.                 APP_EN=1;
  123.                 while(APP_EN==1);
  124.         }
  125.         RAMMODE=0x00;
  126. }        

  127. /******************************************************************************************************
  128. T5L OS CPU初始化   
  129. *******************************************************************************************************/                                       
  130. void INIT_CPU()
  131. {        
  132.         sys_time_ticks = 0;
  133.         sys_tick_7200 = 0;
  134.         CKCON=0x00;
  135.         T2CON=0x70;
  136.         DPC=0x00;
  137.         PAGESEL=0x01;
  138.         D_PAGESEL=0x02;        //DATA RAM 08000-0FFFF
  139.         MUX_SEL=0x60;        //把UART2、UART3 引出来,WDT关闭
  140.         RAMMODE=0x00;        //不占用DGUS变量存储器
  141.         PORTDRV=0x01;   //IO驱动强度 +/-8mA
  142.         IEN0=0x00;      //关闭所有中断
  143.         IEN1=0x00;
  144.         IEN2=0x00;
  145.         IP0=0x00;                //中断优先级用默认值
  146.         IP1=0x00;

  147.         P0=0x00;        //IO配置,输出关闭,是不是输出取决于P0MDOUT   
  148.         P1=0x00;
  149.         P2=0x00;
  150.         P3=0x00;
  151.         P0MDOUT=0x50;        //P0 0101 0000
  152.         P1MDOUT=0x00;        //P1 0000 0000
  153.         P2MDOUT=0x00;        //P2 0000 0000
  154.         P3MDOUT=0x00;        //P3 0000 0000

  155.         ADCON = 0x80;                //UART2 配置 8N1 115200
  156.         SCON0 = 0x50;
  157.         SREL0H=0x03;        //波特率=FCLK/64*(1024-SREL)
  158.         SREL0L=0xD0;

  159.         SCON1=0x90;                        //UART3 配置 8N1 115200
  160.         SREL1H=0x03;        //波特率=FCLK/32*(1024-SREL1)
  161.         SREL1L=0xC8;

  162.         SCON2T=0x80;                //UART4 配置 8N1 115200
  163.         SCON2R=0x80;
  164.         BODE2_DIV_H=0x00;        //波特率=FCLK/8*DIV
  165.         BODE2_DIV_L=0xE0;

  166.         SCON3T=0x80;                //UART5 配置 8N1 115200
  167.         SCON3R=0x80;
  168.         BODE3_DIV_H=0x00;        //波特率=FCLK/8*DIV
  169.         BODE3_DIV_L=0xE0;

  170.         TMOD=0x11;                        //T0 16bit定时器
  171.         TH0=0x00;
  172.         TL0=0x00;
  173.         TR0=0;
  174.         TCON=0x05;                        //EX0 EX1是下跳沿中断

  175.         TH1=0x00;                        //T1 16bit定时器
  176.         TL1=0x00;
  177.         TR1=0;
  178.                
  179.         T2CON=0x70; //T2 16bit Autoload模式
  180.         TH2=0x19;// 65536 - time(us) * 主频(MHZ)/12;
  181.         TL2=0x9a;
  182.         TRL2H=0x19;
  183.         TRL2L=0x9a;
  184.         
  185.   IEN0|=0x20; //定时器2中断使能;
  186.   TR2=0x01;//定时器2开启;
  187. }


  188. sbit RTC_SDA = P3^3                ;
  189. sbit RTC_SCL = P3^2                ;

  190. static void SDA_IN(){        
  191.         P3MDOUT=P3MDOUT&0xF7;
  192. }

  193. static void SDA_OUT()
  194. {   
  195.         P3MDOUT=P3MDOUT|0x0C;
  196. }

  197.         //delay t uS
  198. void delayus(unsigned char t)
  199. {        
  200.         char i;
  201.         while(t){        
  202.                 for(i=0;i<17;i++){
  203.                 i=i;
  204.                 }
  205.                 t--;
  206.         }
  207. }

  208. void T2_IRQHandler() interrupt 5
  209. {
  210.         TF2 = 0;
  211.         sys_tick_7200++;
  212.         if( sys_tick_7200 == 5 ){
  213.                 sys_time_ticks++;
  214.                 sys_tick_7200 = 0;
  215.         }
  216. }

  217. /*********************************************************************************************
  218. 获取自开机已来的TICKS数,每个TICK大约10MS左右;
  219. *********************************************************************************************/
  220. unsigned int getTickCount(void)
  221. {
  222.         return sys_time_ticks;
  223. }

  224. static void i2cstart()
  225. {        
  226.         SDA_OUT();
  227.         RTC_SDA=1;
  228.         RTC_SCL=1;
  229.         delayus(15);
  230.         RTC_SDA=0;
  231.         delayus(15);
  232.         RTC_SCL=0;
  233.         delayus(15);
  234. }

  235. static void i2cstop()
  236. {        
  237.         SDA_OUT();
  238.         RTC_SDA=0;
  239.         RTC_SCL=1;
  240.         delayus(15);
  241.         RTC_SDA=1;
  242.         delayus(15);
  243.         SDA_IN();
  244. }

  245. static void mack()
  246. {        
  247.         SDA_OUT();
  248.         RTC_SDA=0;
  249.         delayus(5);
  250.         RTC_SCL=1;
  251.         delayus(5);
  252.         RTC_SCL=0;
  253.         delayus(5);
  254. }

  255. static void mnak()
  256. {        
  257.         SDA_OUT();
  258.         RTC_SDA=1;
  259.         delayus(5);
  260.         RTC_SCL=1;
  261.         delayus(5);
  262.         RTC_SCL=0;
  263.         delayus(5);
  264. }

  265. static void cack()
  266. {        
  267.         unsigned char i;
  268.         SDA_IN();
  269.         RTC_SDA=1;
  270.         delayus(5);
  271.         RTC_SCL=1;
  272.         delayus(5);
  273.         for(i=0;i<50;i++){   
  274.                 if(!RTC_SDA) break;
  275.                 delayus(5);}
  276.                 RTC_SCL=0;
  277.                 delayus(5);
  278.                 SDA_OUT();
  279. }

  280. static void i2cbw(unsigned char dat)
  281. {        
  282.         char i;
  283.         SDA_OUT();
  284.         for(i=0;i<8;i++){        
  285.                 if(dat&0x80) RTC_SDA=1;
  286.                 else RTC_SDA=0;
  287.                 dat=(dat<<1);
  288.                 delayus(5);
  289.                 RTC_SCL=1;
  290.                 delayus(5);
  291.                 RTC_SCL=0;
  292.                 delayus(5);
  293.         }
  294.         cack();
  295. }

  296. static unsigned char i2cbr()
  297. {        
  298.         char i;
  299.         unsigned char dat;
  300.         SDA_IN();
  301.         for(i=0;i<8;i++){        
  302.                 delayus(5);
  303.                 RTC_SCL=1;
  304.                 delayus(5);
  305.                 dat=(dat<<1);
  306.                 if(RTC_SDA) dat=dat|0x01;
  307.                 else dat=dat&0xFE;
  308.                 RTC_SCL=0;
  309.                 delayus(5);
  310.         }
  311.         return(dat);
  312. }


  313. static unsigned char bcd2Normal(unsigned char bcd)
  314. {
  315.         unsigned char n,m;
  316.         n = bcd / 10;
  317.         m = bcd % 10;
  318.         return n * 16 + m;
  319. }

  320. static unsigned char normal2BCD(unsigned char no)
  321. {
  322.         unsigned char n,m;
  323.         n = no / 16;
  324.         m = no % 16;
  325.         return n * 10 + m;
  326. }

  327. static void rtc_settime(u8 *buf)
  328. {
  329.         i2cstart();
  330.         i2cbw(0x64);
  331.         i2cbw(0x30);
  332.         i2cbw(0x00);
  333.         i2cstop();
  334.         i2cstart();
  335.         i2cbw(0x64);
  336.         i2cbw(0x1C);
  337.         i2cbw(0x48);
  338.         i2cbw(0x00);
  339.         i2cbw(0x40);
  340.         i2cbw(0x10);
  341.         i2cstop();
  342.         i2cstart();
  343.         i2cbw(0x64);
  344.         i2cbw(0x10);
  345.         i2cbw(buf[7]);        
  346.         i2cbw(buf[6]);        
  347.         i2cbw(buf[5]);        
  348.         i2cbw(buf[4]);        
  349.         i2cbw(buf[3]);        
  350.         i2cbw(buf[2]);        
  351.         i2cbw(buf[1]);        
  352.         i2cstop();
  353.         i2cstart();
  354.         i2cbw(0x64);
  355.         i2cbw(0x1E);
  356.         i2cbw(0x00);        
  357.         i2cbw(0x10);                        
  358.         i2cstop();
  359. }


  360. /*********************************************************************************************
  361. 初始化RTC硬件,如果发现掉电,则RTC设置为2017年1月1日星期一,零时零分零秒;
  362. **********************************************************************************************/
  363. void INIT_RTC()
  364. {        
  365.         unsigned char i;
  366.         i2cstart();
  367.         i2cbw(0x64);
  368.         i2cbw(0x1d);
  369.         i2cstop();
  370.         i2cstart();
  371.         i2cbw(0x65);
  372.         i=i2cbr();
  373.         mack();
  374.         i2cbr();
  375.         mnak();
  376.         i2cstop();
  377.         if((i&0x02)==0x02){
  378.                 u8 buf[8];
  379.                 buf[1] = 0x17;
  380.                 buf[2] = 0x01;
  381.                 buf[3] = 0x01;
  382.                 buf[4] = 0x01;
  383.                 buf[5] = 0x00;
  384.                 buf[6] = 0x00;
  385.                 buf[7] = 0x00;
  386.                 rtc_settime(buf);
  387.         }
  388. }

  389. /***********************************************************************************************
  390. 检查寄存器并设置RTC寄存器的初始值
  391. ************************************************************************************************/
  392. void checkAndSetRTC(void)
  393. {
  394.         unsigned char i;
  395.         u8 buf[8];
  396.         read_dgus_vp(0x0050,buf,4);
  397.         if( buf[0] == 0x5A ){
  398.                 for( i = 1; i < 4; i++){
  399.                         buf[i] = bcd2Normal(buf[i]);
  400.                 }
  401.                
  402.                 for( i = 5; i < 8; i++){
  403.                         buf[i] = bcd2Normal(buf[i]);
  404.                 }
  405.                 buf[4] = 1 << buf[4];        
  406.                 rtc_settime(buf);
  407.         }
  408. }

  409. /***************************************************************************************************
  410. 读取RTC寄存器的值,并写入数据缓冲区,供GUI或串口指令查询。
  411. 此函数一般被定时调用,间隔一般要小于500MS。
  412. ****************************************************************************************************/
  413. void rdtime(void)
  414. {        
  415.         unsigned char rtcdata[8];
  416.         unsigned char i,n,m;
  417.         i2cstart();
  418.         i2cbw(0x64);
  419.         i2cbw(0x10);
  420.         i2cstop();
  421.         i2cstart();
  422.         i2cbw(0x65);
  423.         
  424.         for(i=7;i>1;i--){        
  425.                 rtcdata[i]=i2cbr();
  426.                 mack();
  427.         }
  428.         rtcdata[1]=i2cbr();
  429.         mnak();
  430.         i2cstop();
  431.         
  432.         for(i=1;i<4;i++){        //
  433.                 rtcdata[i] = normal2BCD(rtcdata[i]);
  434.         }
  435.         
  436.         for(i=5;i<8;i++){        
  437.                 rtcdata[i] = normal2BCD(rtcdata[i]);
  438.         }
  439.         
  440.         n=0;
  441.         m=rtcdata[4];
  442.         for(i=1;i<8;i++){   
  443.                 if(m&0x01)  break;
  444.                 n++;
  445.                 m=(m>>1);
  446.         }
  447.         
  448.         rtcdata[4]=n;
  449.         rtcdata[0]=0x5A;
  450.         write_dgus_vp(0x004C,rtcdata,0x04);
  451.         
  452. }

  453. /********************************************************************************************************
  454. 微秒延时函数
  455. t:延时值;
  456. 返回:无;
  457. **********************************************************************************************************/
  458. void delay_us(unsigned int t)
  459. {        
  460.         char i;
  461.         while(t){        
  462.                         for(i=0;i<17;i++)
  463.                                 i=i;
  464.                 t--;
  465.         }
  466. }

复制代码


回复

使用道具 举报

3

主题

4

回帖

48

积分

新手上路

Rank: 1

积分
48
 楼主| 发表于 2020-5-25 09:26:59 | 显示全部楼层

【开源】AIoT LCM平台开发自已的OS内核《二》

本帖最后由 lionel1203 于 2020-5-25 09:38 编辑

接上六,参考代码分析
2、main.c(主循环)
/***************************************************************************************

                  版权所有 (C), 2020, 北京迪文科技有限公司

***************************************************************************************
  文 件 名   : main.c
  版 本 号   :
  作    者   :
  生成日期   : 2020年4月23日
  功能描述   : 程序主循环,主控入口;
  修改历史   :
  1.日    期   :
    作    者   :
    修改内容   :
****************************************************************************************/
#include <T5LOS8051.H>
#include <stdio.h>
#include "sys.h"
#include "uart.h"
#include "cmd.h"
#include "paint.h"
#include "player.h"

//触摸数据检查间隔,100MS;
#define TP_CHECK_TIME 10

//显示刷新检查间隔,一般用于进度条刷新;
#define DISP_REFRESH_TIME 50

//RTC设置检查间隔,2秒;
#define RTC_SETTIME        200

//RTC时间更新间隔,400MS;
#define RTC_READTIME 40

//保存了上次检查时间;
static unsigned int tp_checktime;
static unsigned int rtc_checksetting;
static unsigned int rtc_readtime;
static unsigned int disp_refreshtime;

/*************************************************************************************************
修改标准库的putchar函数,直接输出给串口2,用于调试;
**************************************************************************************************/
char putchar (char c)  {
        if(c == '\n')
                UART2_Sendbyte(0x0D);
        
  UART2_Sendbyte(c);
        return c;
}

/***************************************************************************************************
比较时间的间隔大小;
  t0:开始时间;
  t1:结束时间;
返回:开始到续束时间之间的时间长度;
****************************************************************************************************/
static unsigned int tick_diff_time(unsigned int t0,unsigned int t1)
{
        if(t1 >= t0)
                return t1 - t0;
        else
                return (0xFFFF - t0 + t1 + 1);
}

extern unsigned int sys_time_ticks;

/***************************************************************************************************
The main C function.  Program execution starts
here after stack initialization.
****************************************************************************************************/
void main (void) {
        //初始化;
        INIT_CPU();
        INIT_RTC();
        UART2_Init();
        initCMD();
        initDraw();
        initPlayer();
        
        tp_checktime = 0;
        rtc_checksetting = 0;
        rtc_readtime = 0;
        disp_refreshtime = 0;
        while(1){
               
                dispatchCommand();//分发串口命令;
               
                if(tick_diff_time(tp_checktime,sys_time_ticks) > TP_CHECK_TIME){//检查触摸数据时间到;
                        checkAndSendTP2Uart();
                        tp_checktime = sys_time_ticks;
                }
               
                if(tick_diff_time(rtc_checksetting,sys_time_ticks) > RTC_SETTIME){//检查RTC设置命令时间到;
                        checkAndSetRTC();
                        rtc_checksetting = sys_time_ticks;
                }
               
                if(tick_diff_time(rtc_readtime,sys_time_ticks) > RTC_READTIME){//读取RTC时间值
                        rdtime();
                        rtc_readtime = sys_time_ticks;
                }
               
                if(tick_diff_time(disp_refreshtime,sys_time_ticks) > DISP_REFRESH_TIME){//进度条刷新
                        processProgDisplay();
                        disp_refreshtime = sys_time_ticks;
                }
               

        }
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

3

主题

4

回帖

48

积分

新手上路

Rank: 1

积分
48
 楼主| 发表于 2020-5-25 09:41:36 | 显示全部楼层
lionel1203 发表于 2020-5-25 09:26
接上六,参考代码分析
2、main.c(主循环)

DWIN_SET烧录文件中,由于尺寸限制,无法打包电影和音乐的演示文件,请客户参考代码中的文件序号,使用AllToolForAIOT工具打包生成自已的音视频文件。
回复

使用道具 举报

3

主题

4

回帖

48

积分

新手上路

Rank: 1

积分
48
 楼主| 发表于 2020-5-25 09:43:43 | 显示全部楼层
static const unsigned char code m_audioID[3] = { 0x50,0x6C,0x84 };//音乐文件ID,共3个;
static const unsigned char code m_videoID[3] = { 186,155, 172};//电影伴音文件,共3个;
static const unsigned char code m_videoAudioID[3] = { 181,152,168 };//电影视频文件,共3个。
回复

使用道具 举报

3

主题

4

回帖

48

积分

新手上路

Rank: 1

积分
48
 楼主| 发表于 2020-5-25 09:50:06 | 显示全部楼层
还要请提醒大家的是,示例工程对应的是AIoT LCM平台,采用主频353.8944MHZ主频,显示分辨率为1024X600的设备,其它分辨率或平台如果不修改是无法正常工作的。
回复

使用道具 举报

1

主题

3

回帖

28

积分

新手上路

Rank: 1

积分
28
发表于 2020-8-31 22:41:10 | 显示全部楼层
基于DMG19108C156_03W进行二次开发示例演示
问题:
1、DMG19108C156_03W是否支持二次开发?
2、如果支持,内嵌用户OS如何与屏进行交互数据?
最好能给举个例子,如进行一个数值的显示(实时温度值)
以上,谢谢!
回复

使用道具 举报

12

主题

159

回帖

952

积分

高级会员

Rank: 4

积分
952
QQ
发表于 2020-9-10 13:29:00 | 显示全部楼层
这个驱动程序主要是控制那一块?
回复

使用道具 举报

0

主题

5

回帖

99

积分

注册会员

Rank: 2

积分
99
发表于 2021-2-27 19:07:31 | 显示全部楼层
头文件呢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|迪文科技论坛 ( 京ICP备05033781号-1 )

GMT+8, 2024-3-29 14:17 , Processed in 0.119815 second(s), 23 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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