你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

lcd+rtos模板(6/2号更新红外解码) 精华

[复制链接]
netlhx 发布时间:2015-5-28 16:07
本帖最后由 netlhx 于 2015-6-2 20:14 编辑

RTOS调度+LCD液晶显示模板,使用的是原子的探索者,只所以使用这个来做模板,是在为毕竟NUCLEO上的资源有限,比如FSMC就没法做。而要使用液晶,FSMC还是很有必要的。


看RTOS的资料看了一段时间,最近才勉强明白了一点,希望和大家一起讨论哈!

高手请多包容,多指导!


先看看效果图。

IMG_20150528_154328.jpg


IMG_20150528_154339.jpg


完整的工程可以参考github.com/netlhx/stm32f407,里面的general文件夹包含一个通用的模板,LCD文件夹里将LCD和RTOS的使用结合在一起。

后面准备将其它的模块功能添加进来,虽然以前基于NUCLEOF411做了一个模板,最近折腾原子的探索者,所以那一个就没有更新了。

几点说明:
1. 绘制文字的任务是一个守护者任务(GATEKEEPER TASK),这样输出就不会产生混乱。不过任务在输出实际内容时,每个像素点都带了各自输出的位置,所以如果不使用守护者任务来实现的话,应该也没有问题。这里之所以这样处理,是为了以后的统一处理。
2. 液晶驱动为ILI9341,分辨率为240X320.
3. 没有加注释,大部分代码都比较简单,以后再整理吧


实例一 、添加一个日历任务

框架已经搭好,使用RTOS的好处之一在于:每个任务就是一个模块,所以接下来看看如何添加一个日历模块,并在LCD上显示。

添加一个新任务,需要完成下列步骤:
1. 定义一个任务ID,用来对任务进行管理操作,如果不需要管理该任务,也可以跳过这步
2. 设定任务相关参数,如优先级、堆栈大小等
3. 创建任务
4. 编写任务函数

在freertos.c文件中,添加如下


taskid.png

tasks.png

task.png

完整的任务代码:


  1. <p>void StartShowCalendarTask(void const *argument)
  2. {        
  3.         char calendarStr[30] = "";
  4.         RCC_OscInitTypeDef RCC_OscInitStruct;
  5.         RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct;
  6.                
  7.         RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
  8.         RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  9.         RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  10.         RCC_OscInitStruct.LSIState = RCC_LSI_OFF;
  11.         
  12.         HAL_RCC_OscConfig(&RCC_OscInitStruct);
  13.         
  14.         RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
  15.         RCC_PeriphCLKInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
  16.         
  17.         HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct);
  18.         
  19.         __HAL_RCC_RTC_ENABLE();
  20.         
  21.         RtcHandle.Instance = RTC;
  22.         RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24;
  23.   RtcHandle.Init.AsynchPrediv = 127;
  24.   RtcHandle.Init.SynchPrediv = 255;
  25.   RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE;
  26.   RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  27.   RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  28.         
  29.         HAL_RTC_Init(&RtcHandle);
  30.         
  31.         if(HAL_RTCEx_BKUPRead(&RtcHandle, RTC_BKP_DR0) != 0x32F2)
  32.   {  
  33.     /* Configure RTC Calendar */
  34.     RTC_CalendarConfig();
  35.   }
  36.         
  37.         for(;;)
  38.         {
  39.                 RTC_DateTypeDef sdatestructureget;
  40.                 RTC_TimeTypeDef stimestructureget;
  41.                
  42.                 /* Get the RTC current Time */
  43.                 HAL_RTC_GetTime(&RtcHandle, &stimestructureget, RTC_FORMAT_BIN);
  44.                 /* Get the RTC current Date */
  45.                 HAL_RTC_GetDate(&RtcHandle, &sdatestructureget, RTC_FORMAT_BIN);
  46.                
  47.                 /* Display time Format: hh:mm:ss */
  48.                 sprintf((char*)calendarStr,"%02d:%02d:%02d   %02d-%02d-%04d",stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds,
  49.                         sdatestructureget.Month, sdatestructureget.Date, 2000 + sdatestructureget.Year);
  50.                 ShowString(10, 60, calendarStr);
  51.                
  52.                 osDelay(100);
  53.         
  54.                
  55.         }
  56.         
  57. }
  58. </p><p> </p><p> </p><p>这是任务运行实例效果,外观与没有使用RTOS并没有区别。</p><p> </p><p><img alt="" src="https://www.stmcu.org.cn/module/forum/forum.php?mod=image&aid=344633&size=300x300&key=ef30ab9e6f6ce7f2&nocache=yes&type=fixnone" border="0" aid="attachimg_344633">
  59. </p>
复制代码













IMG_20150528_211414.jpg
收藏 1 评论24 发布时间:2015-5-28 16:07

举报

24个回答
netlhx 回答时间:2015-6-2 20:21:43
suzhe_518 发表于 2015-5-29 11:49
不错哦  能否提供些入门资料 谢谢

很不错的资料,E文版

rtos.pdf (1.33 MB, 下载次数: 6902)
netlhx 回答时间:2015-5-28 16:22:43
本帖最后由 netlhx 于 2015-6-2 20:19 编辑

实例二、加入红外解码,利用红外控制MCU

RTOS支持还是很不错的,加入RTOS之后,所有的任务都是一个独立的模块。

要控制MCU来完成一些任务,主要的方法一般是两个:串口通信、红外遥控。今天来加上红外遥控支持。

板载红外支持的协议是NEC协议,所以加上相应的读取值并解码之后,就能得到输入控制码,利用控制码来完成相应的任务即可。

先看一个逻辑分析仪抓到的信号

QQ截图20150602173539.png

IMG_20150528_211414.jpg

IMG_20150602_201550.jpg


同上一个实例一样,使用任务来处理红外信息。同上一个实例不同的是,加入了中断控制,使用中断来处理编码信息。例程中用到了任务、信号量、队列、中断。上代码,慢慢看


  1. #include "FreeRTOS.h"
  2. #include "task.h"
  3. #include "cmsis_os.h"
  4. #include "stm32f4xx_hal.h"
  5. #include "ili9341.h"
  6. #include "string.h"

  7. extern uint16_t foreColor;

  8. TIM_HandleTypeDef htim1;

  9. uint8_t irState;
  10. uint32_t irData;
  11. uint32_t icValue;
  12. uint8_t irCount;


  13. osThreadId defaultTaskHandle;
  14. //osThreadId displayTaskHandle;
  15. osThreadId drawCharTaskHandle;

  16. //task id
  17. osThreadId showCalendarHandle;
  18. osThreadId IrControlHandle;

  19. RTC_HandleTypeDef RtcHandle;

  20. //IR SEMAPHORE
  21. osSemaphoreId irSemHandle;

  22. static void ShowString(uint16_t x, uint16_t y, char *msg);


  23. //osMessageQId displayQueueHandle;
  24. osMessageQId charQueueHandle;


  25. //add your own task definitions

  26. void StartDefaultTask(void const * argument);
  27. //void StartDisplayTask(void const * argument);
  28. void StartDrawCharTask(void const *argument);
  29. void StartLedTask(void const *argument);

  30. void StartShowCalendarTask(void const *argument);
  31. void StartIrControlTask(void const *argument);

  32. static void ShowString(uint16_t x, uint16_t y, char *msg);


  33. void FREERTOS_Init(void);
  34. static void RTC_CalendarConfig(void);


  35. void FREERTOS_Init(void)
  36. {
  37.         osMessageQDef(charQueue, 16, uint32_t);
  38.         charQueueHandle = osMessageCreate(osMessageQ(charQueue), NULL);
  39.         
  40.         osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
  41.         defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);

  42.         
  43.         osThreadDef(drawCharTask, StartDrawCharTask, osPriorityAboveNormal, 0, 128);
  44.         drawCharTaskHandle = osThreadCreate(osThread(drawCharTask), NULL);
  45.         

  46.         //create your own tasks
  47.         
  48.         osSemaphoreDef(irSem);
  49.         irSemHandle = osSemaphoreCreate(osSemaphore(irSem), 1);
  50.         
  51.         osThreadDef(showCalendarTask, StartShowCalendarTask, osPriorityNormal, 0, 128);
  52.         showCalendarHandle = osThreadCreate(osThread(showCalendarTask), NULL);
  53.         
  54.         osThreadDef(IrControl, StartIrControlTask, osPriorityNormal, 0, 128);
  55.         IrControlHandle = osThreadCreate(osThread(IrControl), NULL);
  56.         


  57. }


  58. void StartDefaultTask(void const * argument)
  59. {
  60.         for(;;)
  61.         {
  62.         
  63.     osDelay(1);
  64.   }
  65.   
  66. }

  67. //your own task implementetions



  68. void StartDrawCharTask(void const * argument)
  69. {
  70.         osEvent event;
  71.         CharTypeDef ch;
  72.         
  73.         for(;;)
  74.         {
  75.                
  76.                 event = osMessageGet(charQueueHandle, osWaitForever);
  77.                 ch.data = event.value.v;
  78.                 lcd_DrawCharEn(ch.charInfo.x, ch.charInfo.y, ch.charInfo.ch, foreColor);
  79.                
  80.         }
  81.         
  82.         
  83. }



  84. static void ShowString(uint16_t x, uint16_t y, char *msg)
  85. {
  86.         
  87.         uint16_t len = strlen(msg);
  88.         uint32_t info;
  89.         
  90.         for(uint16_t i = 0; i < len; i ++)
  91.         {
  92.                 info = 0;
  93.                 info |= x << 24;
  94.                 info |= y << 16;
  95.                 info |= msg[i];
  96.                
  97.                 osMessagePut(charQueueHandle, info, osWaitForever);
  98.                
  99.                 x += 8;
  100.         }
  101.         
  102.         
  103. }

  104. void StartShowCalendarTask(void const *argument)
  105. {        
  106.         char calendarStr[30] = "";
  107.         RCC_OscInitTypeDef RCC_OscInitStruct;
  108.         RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct;
  109.                
  110.         RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
  111.         RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  112.         RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  113.         RCC_OscInitStruct.LSIState = RCC_LSI_OFF;
  114.         
  115.         HAL_RCC_OscConfig(&RCC_OscInitStruct);
  116.         
  117.         RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
  118.         RCC_PeriphCLKInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
  119.         
  120.         HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct);
  121.         
  122.         __HAL_RCC_RTC_ENABLE();
  123.         
  124.         RtcHandle.Instance = RTC;
  125.         RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24;
  126.   RtcHandle.Init.AsynchPrediv = 127;
  127.   RtcHandle.Init.SynchPrediv = 255;
  128.   RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE;
  129.   RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  130.   RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  131.         
  132.         HAL_RTC_Init(&RtcHandle);
  133.         
  134.         if(HAL_RTCEx_BKUPRead(&RtcHandle, RTC_BKP_DR0) != 0x32F3)
  135.   {  
  136.     /* Configure RTC Calendar */
  137.     RTC_CalendarConfig();
  138.   }
  139.         
  140.         for(;;)
  141.         {
  142.                 RTC_DateTypeDef sdatestructureget;
  143.                 RTC_TimeTypeDef stimestructureget;
  144.                
  145.                 /* Get the RTC current Time */
  146.                 HAL_RTC_GetTime(&RtcHandle, &stimestructureget, RTC_FORMAT_BIN);
  147.                 /* Get the RTC current Date */
  148.                 HAL_RTC_GetDate(&RtcHandle, &sdatestructureget, RTC_FORMAT_BIN);
  149.                
  150.                 /* Display time Format: hh:mm:ss */
  151.                 sprintf((char*)calendarStr,"%02d:%02d:%02d   %02d-%02d-%04d",stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds,
  152.                         sdatestructureget.Month, sdatestructureget.Date, 2000 + sdatestructureget.Year);
  153.                 ShowString(10, 60, calendarStr);
  154.                
  155.                 osDelay(100);
  156.         
  157.                
  158.         }
  159.         
  160. }



  161. static void RTC_CalendarConfig(void)
  162. {
  163.   RTC_DateTypeDef sdatestructure;
  164.   RTC_TimeTypeDef stimestructure;

  165.   /*##-1- Configure the Date #################################################*/
  166.   
  167.   sdatestructure.Year = 0x15;
  168.   sdatestructure.Month = RTC_MONTH_MAY;
  169.   sdatestructure.Date = 0x28;
  170.   sdatestructure.WeekDay = RTC_WEEKDAY_THURSDAY;
  171.   
  172.   if(HAL_RTC_SetDate(&RtcHandle,&sdatestructure,RTC_FORMAT_BCD) != HAL_OK)
  173.   {
  174.     /* Error */
  175.     //Error_Handler();
  176.   }
  177.   
  178.   /*##-2- Configure the Time #################################################*/
  179.   /* Set Time: 02:00:00 */
  180.   stimestructure.Hours = 0x21;
  181.   stimestructure.Minutes = 0x38;
  182.   stimestructure.Seconds = 0x00;
  183.   stimestructure.TimeFormat = RTC_HOURFORMAT12_AM;
  184.   stimestructure.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  185.   stimestructure.StoreOperation = RTC_STOREOPERATION_RESET;
  186.   
  187.   if(HAL_RTC_SetTime(&RtcHandle,&stimestructure,RTC_FORMAT_BCD) != HAL_OK)
  188.   {
  189.     /* Error */
  190.     //Error_Handler();
  191.   }
  192.   
  193.   /*##-3- Writes a data in a RTC Backup data Register0 #######################*/
  194.   HAL_RTCEx_BKUPWrite(&RtcHandle,RTC_BKP_DR0,0x32F3);  
  195. }


  196. void StartIrControlTask(void const *argument)
  197. {
  198.   TIM_MasterConfigTypeDef sMasterConfig;
  199.   TIM_IC_InitTypeDef sConfigIC;
  200.         
  201.         GPIO_InitTypeDef GPIO_InitStruct;
  202.         char irMsg[30] = "";
  203.         
  204.         __GPIOA_CLK_ENABLE();
  205.         
  206.         __TIM1_CLK_ENABLE();
  207.         
  208.         GPIO_InitStruct.Pin = GPIO_PIN_8;
  209.         GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  210.         GPIO_InitStruct.Pull = GPIO_PULLUP;
  211.         GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
  212.         GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
  213.         
  214.         HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  215.         /* Peripheral interrupt init*/
  216.         HAL_NVIC_SetPriority(TIM1_CC_IRQn, 5, 0);
  217.         HAL_NVIC_EnableIRQ(TIM1_CC_IRQn);
  218.         HAL_NVIC_SetPriority(TIM1_UP_TIM10_IRQn, 5, 0);
  219.         HAL_NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn);
  220.         
  221.   htim1.Instance = TIM1;
  222.   htim1.Init.Prescaler = 167;
  223.   htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  224.   htim1.Init.Period = 9999;
  225.   htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  226.   htim1.Init.RepetitionCounter = 0;
  227.         
  228. //        sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  229. //  HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig);

  230.   HAL_TIM_IC_Init(&htim1);

  231.   sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  232.   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  233.   HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig);

  234.   sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
  235.   sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
  236.   sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
  237.   sConfigIC.ICFilter = 3;
  238.   HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_1);        
  239.         

  240.         HAL_TIM_Base_Start_IT(&htim1);
  241.         HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1);
  242.         
  243.         osSemaphoreWait(irSemHandle, 0);
  244.         
  245.         for(;;)
  246.         {
  247.                 osSemaphoreWait(irSemHandle, osWaitForever);
  248.                
  249.                 sprintf(irMsg, "Key Code: %4u    ", 0xFF & (irData >> 8));
  250.                
  251.                 ShowString(10, 90, irMsg);
  252.                
  253.                
  254.         }
  255. }



  256. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
  257. {

  258.         if(__HAL_TIM_GET_ITSTATUS(&htim1, TIM_IT_CC1) == SET)
  259.         {
  260.                 if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == GPIO_PIN_SET)
  261.                 {
  262.         
  263.                         __HAL_TIM_SET_CAPTUREPOLARITY(&htim1, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_FALLING);
  264.                         TIM1->CNT = 0;
  265.                         irState |= 0x10;
  266.                         
  267.                 }
  268.                 else
  269.                 {
  270.                         icValue = HAL_TIM_ReadCapturedValue(&htim1, TIM_CHANNEL_1);

  271.                         __HAL_TIM_SET_CAPTUREPOLARITY(&htim1, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);
  272.                         
  273.                         if(irState & 0x10)
  274.                         {
  275.                                 if(irState & 0x80)
  276.                                 {
  277.                                        
  278.                                        
  279.                                         if(icValue > 300 && icValue < 800)
  280.                                         {
  281.                                                 irData <<= 1;
  282.                                                 irData |= 0;
  283.                                                 
  284.                                         }
  285.                                         else if(icValue > 1400 && icValue < 1800)
  286.                                         {
  287.                                                 irData <<= 1;
  288.                                                 irData |= 1;
  289.                                         }
  290.                                         else if(icValue > 2200 && icValue < 2600)
  291.                                         {
  292.                                                 irCount ++;
  293.                                                 irState &= 0xF0;
  294.                                         }
  295.                                 }
  296.                                 else if(icValue > 4200 && icValue < 4700)
  297.                                 {
  298.                                         irState |= 1 << 7;
  299.                                         irCount = 0;
  300.                                        
  301.                                 }
  302.                                 
  303.                         }
  304.                         irState &= ~(1 << 4);
  305.                 }
  306.                
  307.         }
  308.         
  309.         
  310. }

  311. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  312. {
  313.         if(__HAL_TIM_GET_ITSTATUS(&htim1, TIM_IT_UPDATE) == SET)
  314.         {
  315.                 if(irState & 0x80)
  316.                 {
  317.                         irState &= ~0x10;
  318.                         if((irState & 0x0F) == 0)
  319.                         {
  320.                                 irState |= 1 << 6;
  321.                                 osSemaphoreRelease(irSemHandle);
  322.                                 
  323.                         }
  324.                         
  325.                         if((irState & 0x0F) < 14)
  326.                                 irState ++;
  327.                         else
  328.                         {
  329.                                 irState &=  ~(1 << 7);
  330.                                 irState &= 0xF0;
  331.                                 
  332.                         }
  333.                         
  334.                 }
  335.                
  336.                
  337.         }
  338.         
  339.         
  340. }




复制代码
  1. <p> </p>
复制代码

netlhx 回答时间:2015-6-2 20:22:17
qiu-368230 发表于 2015-5-30 18:09
厉害,我是在FREERTOS和MQX之间纠结呢,以后ST没有库函数了,不知道还要不要用,想选个系统,没确定用哪 ...

FREERTOS就不错,免费、简单
netlhx 回答时间:2015-5-28 16:22:58
占楼备注
netlhx 回答时间:2015-5-28 16:23:04
占楼备注
带你看世界 回答时间:2015-5-28 22:06:02
恩恩,不错
你好我好大家好! 回答时间:2015-5-29 00:23:35
挺好                  
ssoman 回答时间:2015-5-29 00:47:12
谢谢分享
沐紫 回答时间:2015-5-29 10:49:52
占楼这么多,感觉要出大事了
netlhx 回答时间:2015-5-29 11:27:24
沐紫 发表于 2015-5-29 10:49
占楼这么多,感觉要出大事了

在模板上添加一些任务,体验RTOS的魅力
qiu-368230 回答时间:2015-5-29 11:29:29
自己画的板子么?FREERTOS?期待后续教程
suzhe1020 回答时间:2015-5-29 11:49:28
不错哦  能否提供些入门资料 谢谢  suzhe1020@163.com
lkl0305 回答时间:2015-5-29 12:20:59
学习学习
lkl0305 回答时间:2015-5-29 12:21:44
学习学习
netlhx 回答时间:2015-5-30 15:55:58
qiu-368230 发表于 2015-5-29 11:29
自己画的板子么?FREERTOS?期待后续教程

准备折腾几个例程
netlhx 回答时间:2015-5-30 15:56:40
suzhe_518 发表于 2015-5-29 11:49
不错哦  能否提供些入门资料 谢谢

官网上有的
12下一页

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版