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

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-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?期待后续教程
123下一页

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

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