Chinaunix首页 | 论坛 | 博客
  • 博客访问: 831597
  • 博文数量: 281
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2770
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-02 19:45
个人简介

邮箱:zhuimengcanyang@163.com 痴爱嵌入式技术的蜗牛

文章分类
文章存档

2020年(1)

2018年(1)

2017年(56)

2016年(72)

2015年(151)

分类: 嵌入式

2015-09-22 11:16:10

这一篇主要讲一个例子吧。

硬件:
1. stm32f103 开发板
2. 有一个按键,一个LED灯。

功能:
1. 按键检测:
可以检测按键按下的状态:短按,长按,并保存键值。
短按键值: 0x01
第一次长按键值: 0x02
后面的长按键值: 0x03
2. LED
LED任务实现LED闪烁,1s时间间隔。
功能实现:
1. 建立一个LED任务,实现LED每1s闪烁一次的功能;
2. 建立一个KEY扫描的任务,每10ms轮询一次,去按键抖动功能;并且检测是否有按键按下,是短按还是长按状态,并把按键值写入到定义的队列当中;
3. 建立一个读取队列的任务,这个任务的优先级大于按键扫描任务。所以队列中最多只有一个数据,当读取完队列数据(也就是按键值),该任务进入阻塞态;KEY扫描任务得到运行,检测是否有按键按下;如果有按键按下,则写键值到队列中;一旦写入,将唤醒读队列任务,打印读取到的键值。LED任务和按键扫描任务为相同的优先级,在读取队列任务进入阻塞态的时候,两者分享时间片,轮询执行。
关键代码:
main.c

点击(此处)折叠或打开

  1. #include "led.h"
  2. #include "key.h"
  3. #include "delay.h"
  4. #include "sys.h"
  5. #include "usart.h"

  6. // FreeRTOS head file, add here.
  7. #include "FreeRTOS.h"
  8. #include "task.h"
  9. #include "queue.h"
  10. #include "list.h"
  11. #include "portable.h"
  12. #include "FreeRTOSConfig.h"


  13. /* declare a queueHandle variable, using to save queue handler. */
  14. xQueueHandle xQueue;


  15. void vReceiveTask(void *pvParameters)
  16. {
  17.     char key ;
  18.     
  19.     portBASE_TYPE status;

  20.     while(1)
  21.     {
  22.         if( uxQueueMessagesWaiting( xQueue ) != 0 )
  23.         {
  24.            /* 由于读取队列的优先级最高,则导致queue队列一直为空,使得这句话不会执行。 */
  25.             printf( "Queue should have been empty! \r\n");
  26.         }
  27.         
  28.         /* 1. 设置成 100/portTICK_RATE_MS,表示超时等待时间,当超过这个时间还没有数据到来,任务同样返回,从阻塞态转变为就绪态。*/
  29.         //status = xQueueReceive( xQueue, &key, 100 / portTICK_RATE_MS );
  30.         
  31.         /**
  32.          * \brief: 2. 设置成portMAX_DELAY将永久等待,直到queue有数据可以读取。
  33.          */
  34.         status = xQueueReceive( xQueue, &key, portMAX_DELAY );
  35.         if( status == pdPASS )
  36.         {
  37.             printf("Queue received Key pressed msg, key value: %d \r\n", key);
  38.         }
  39.         else
  40.         {
  41.             printf( "Could not receive from the queue.\r\n" );
  42.         }
  43.     }
  44. }

  45. void board_Init(void)
  46. {
  47.     LED_Init();    
  48.     KEY_Init();
  49.     uart_init(115200);
  50. }


  51. void keyScan_Task(void *pvParameters)
  52. {
  53.     char key = 0x00;
  54.     portBASE_TYPE status;

  55.     while(1)
  56.     {
  57.         // add your key scan code here.
  58.         keyScan();
  59.         if((key = keyScan_readBuff()) != 0)
  60.         {
  61.             switch(key)
  62.             {
  63.                 case ( KEY_CODE + SHORT_KEY):
  64.                     printf("short key pressed \r\n");
  65.                 break;
  66.                 
  67.                 case ( KEY_CODE+FIRSTLONG_KEY_CODE):
  68.                     printf("long first pressed \r\n");
  69.                 break;
  70.                 
  71.                 case ( KEY_CODE+AFTERLONG_KEY_CODE):
  72.                     printf("long after pressed \r\n");
  73.                 break;
  74.             }
  75.             
  76.             status = xQueueSendToBack(xQueue, &key, 0);
  77.             if(status != pdPASS)
  78.             {
  79.                 printf("could not send to the queue. \r\n");
  80.             }
  81.         }
  82.         
  83.         vTaskDelay(10/portTICK_RATE_MS);
  84.     }
  85. }

  86. void LED_task(void *pvParameters)
  87. {
  88.     char state = 0;
  89.     
  90.     while(1)
  91.     {
  92.         ((state = !state) == 1) ? RED_ON() : RED_OFF();
  93.         vTaskDelay(1000 / portTICK_RATE_MS);
  94.     }
  95. }



  96. int main(void)
  97. {
  98.     // board initialize.
  99.     board_Init();
  100.     
  101.     // create queue, can store 3 value which data type is data_type
  102.     xQueue = xQueueCreate(3, sizeof(char));
  103.     
  104.     if(xQueue != NULL) // adjust the return value, to confirm whether create queue successful.
  105.     {
  106.         xTaskCreate(vReceiveTask, "RecTask", configMINIMAL_STACK_SIZE, NULL, 2, NULL);
  107.         xTaskCreate(keyScan_Task, "KeyScanTask", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
  108.         xTaskCreate(LED_task, "LEDTask", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
  109.         
  110.         // start scheduler now
  111.         vTaskStartScheduler();
  112.     }
  113.     else
  114.     {
  115.         // queue create unsuccessful here. add your code.
  116.     }
  117.     
  118.     return 0;
  119. }

key.c

点击(此处)折叠或打开

  1. #include "key.h"


  2. #define KEYBUFFSIZE 4
  3. char keybuff[KEYBUFFSIZE] = {0};
  4. char key_indexW = 0;
  5. char key_indexR = 0;
  6. char length = 0;
  7. static uint32_t keyCounterL = 0, keyCounterS = 0;
  8. char keyState = 0;

  9. #define KEY_IN() KEY0




  10. extern void vPortEnterCritical( void );
  11. extern void vPortExitCritical( void );



  12. void keyScan_writeBuff(char keyValue)
  13. {
  14.     if(length >= KEYBUFFSIZE )
  15.         return;
  16.     
  17.     vPortEnterCritical();
  18.     
  19.     length ++;
  20.     keybuff[key_indexW] = keyValue;
  21.     if(++key_indexW >= KEYBUFFSIZE)
  22.         key_indexW = 0;
  23.     
  24.     vPortExitCritical();
  25. }


  26. char keyScan_readBuff(void)
  27. {
  28.     char key;
  29.     if(length == 0) return 0;
  30.     
  31.     vPortEnterCritical();
  32.     
  33.     length --;
  34.     key = keybuff[key_indexR];
  35.     if(++key_indexR >= KEYBUFFSIZE)
  36.         key_indexR = 0;
  37.     
  38.     vPortExitCritical();
  39.     
  40.     return key;
  41. }


  42. void keyScan(void)
  43. {
  44.     // scan key and write key code to buffer.
  45.     if(keyState == LONG_KEY)
  46.         keyCounterL++;
  47.     else
  48.         keyCounterL =0;
  49.     
  50.     if(keyState == SHORT_KEY)
  51.         keyCounterS++;
  52.     else
  53.         keyCounterS =0;
  54.     
  55.     
  56.     switch(keyState)
  57.     {
  58.         case NO_KEY:
  59.             if(KEY_IN() == 0) keyState = SHORT_KEY;
  60.             else keyState = NO_KEY;
  61.         break;
  62.         
  63.         case SHORT_KEY:
  64.             if(KEY_IN() != 0) // release key, short key
  65.             {
  66.                 keyScan_writeBuff(KEY_CODE + SHORT_KEY_CODE);
  67.                 keyState = NO_KEY;
  68.             }
  69.             else
  70.             {
  71.                 if(keyCounterS >= 2000/10)
  72.                 {
  73.                     keyCounterS = 0;
  74.                     keyScan_writeBuff(KEY_CODE + FIRSTLONG_KEY_CODE);
  75.                     keyState = LONG_KEY;
  76.                 }
  77.             }
  78.         break;
  79.             
  80.         case LONG_KEY:
  81.             if(KEY_IN() != 0) // release key, short key
  82.             {
  83.                 keyState = NO_KEY;
  84.             }
  85.             else
  86.             {
  87.                 if(keyCounterL >= 250/10)
  88.                 {
  89.                     keyCounterL = 0;
  90.                     keyScan_writeBuff(KEY_CODE + AFTERLONG_KEY_CODE);
  91.                 }
  92.             }
  93.         break;
  94.     }
  95. }



  96. void KEY_Init(void)
  97. {
  98.     GPIO_InitTypeDef GPIO_InitStructure;

  99.      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC,ENABLE);//????PORTA,PORTC?±??

  100.     GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//??±?jtag??????SWD????????SWD?????÷??
  101.     
  102.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;//PA15
  103.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //?è????????????
  104.      GPIO_Init(GPIOA, &GPIO_InitStructure);//??????GPIOA15
  105.     
  106.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//PC5
  107.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //?è????????????
  108.      GPIO_Init(GPIOC, &GPIO_InitStructure);//??????GPIOC5
  109.  
  110.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//PA0
  111.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0?è??????????????????    
  112.     GPIO_Init(GPIOA, &GPIO_InitStructure);//??????GPIOA.0
  113. }

key.h

点击(此处)折叠或打开

  1. #ifndef __KEY_H
  2. #define __KEY_H    


  3. #include "sys.h"

  4. #define KEY0 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)

  5. #define NO_KEY 0
  6. #define SHORT_KEY 1
  7. #define LONG_KEY 2

  8. #define KEY_CODE (unsigned char)0x00
  9. #define SHORT_KEY_CODE (unsigned char)0x01
  10. #define FIRSTLONG_KEY_CODE (unsigned char)0x02
  11. #define AFTERLONG_KEY_CODE (unsigned char)0x03


  12. void KEY_Init(void);
  13. void keyScan(void);
  14. char keyScan_readBuff(void);


  15.                          
  16. #endif

打印结果:
短按,长按结果,板子上LED也开始闪烁。







阅读(1809) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~