SHARE
TWEET

Untitled

a guest Jun 18th, 2019 60 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "mcu_support_package/inc/stm32f10x.h"
  2.  
  3. #include <app_cfg.h>
  4.  
  5. #include  <ucos_ii.h>
  6.  
  7. #include  <cpu.h>
  8. #include  <lib_def.h>
  9. #include  <lib_mem.h>
  10. #include  <lib_str.h>
  11.  
  12. #include  <bsp.h>
  13.  
  14. #define APP_ASSERT( statement ) do { if(! (statement) ) { __disable_irq(); while(1){ __BKPT(0xAB); if(0) break;} }  } while(0)
  15.  
  16. /***************************************************************************************************
  17.                                  Стеки для тасков
  18.  ***************************************************************************************************/
  19.  
  20. static OS_STK App_TaskStartStack[APP_TASK_START_STACK_SIZE];
  21.  
  22. static OS_STK App_ButtonStack[APP_TASK_BUTTON_STACK_SIZE];
  23.  
  24. static OS_STK App_TaskLed8Stack[APP_TASK_LED8_STACK_SIZE];
  25.  
  26. static OS_STK App_TaskScanKeyboardStack[APP_TASK_KEYBOARD_STACK_SIZE];
  27.  
  28. static OS_STK App_TaskPlaySoundStack[APP_TASK_SOUND_STACK_SIZE];
  29.  
  30. static OS_STK App_TaskSendButtonNumStack[APP_TASK_SEND_BUTTON_NUM_STACK_SIZE];
  31.  
  32. /***************************************************************************************************
  33.                                  Таски - объявления
  34.  ***************************************************************************************************/
  35.  
  36. static void App_TaskStart( void * p_arg );
  37.  
  38. static void App_TaskButton( void * p_arg );// сканирование кнопки PA0
  39.  
  40. static void App_TaskLed8( void * p_arg ); // зажигание светодиода PC8 по нажатию PA0
  41.  
  42. static void App_TaskScanKeyboard( void * p_arg ); // сканирование клавиатуры
  43.  
  44. static void App_TaskPlaySound( void * p_arg ); // играть звук согласно нажатой кнопке
  45.  
  46. static void App_TaskSendButtonNum( void * p_arg ); // отправлять номер нажатой клавиши
  47. //на клавиатуре по USART
  48. OS_EVENT * semaphore;// указатель на семафор
  49. OS_EVENT * queue;// указатель на очередь
  50. #define QUEUE_SIZE 128
  51. static void * queueStorage[ QUEUE_SIZE ]; // массив, в котором будут лежать сообщения
  52.  
  53. int main(void) {
  54.  
  55.     // запрет прерываний и инициализация ОС
  56.     BSP_IntDisAll();
  57.     OSInit();
  58.  
  59.     // создание стартового таска - в нем создаются все остальные
  60.     // почему не создавать всё сразу в main'e?
  61.     // возможно, вы хотите создавать их в зависимости от каких-нибудь условий,
  62.     // для которых уже должна работать ОС
  63.    
  64.     INT8U res = OSTaskCreate(
  65.                     App_TaskStart,     // указатель на таск        
  66.                     NULL,              // параметр вызова (без параметра)
  67.                     &App_TaskStartStk[APP_TASK_START_STK_SIZE - 1], // указатель на стек
  68.                     APP_TASK_START_PRIO // приоритет
  69.                 );
  70.  
  71.  
  72.    
  73.     APP_ASSERT( res == OS_ERR_NONE );
  74.  
  75.     // запуск многозадачности
  76.     OSStart();
  77.  
  78.     // до сюда выполнение доходить не должно
  79.     return 0;
  80.  
  81. }
  82.  
  83. /***************************************************************************************************
  84.                                  Таски
  85.  ***************************************************************************************************/
  86.  
  87. // стартовый таск
  88. static void App_TaskStart(void * p_arg) {
  89.     // это чтобы убрать warning о неиспользуемом аргументе
  90.     (void)p_arg;
  91.  
  92.     //  Фактически - только настройка RCC - 72 МГц от ФАПЧ  (Initialize BSP functions)
  93.     BSP_Init();
  94.  
  95.     // настройка СисТика
  96.     OS_CPU_SysTickInit();
  97.  
  98.     // таск для сбора статистики - если он нужен                            
  99. #if (OS_TASK_STAT_EN > 0)
  100.     OSStatInit();
  101. #endif
  102.  
  103.     // дальше создаются пользовательские таски
  104.    
  105.     INT8U res;
  106.  
  107.     res = OSTaskCreate(
  108.               App_TaskButton, // указатель на функцию      
  109.               NULL,            // параметр - без параметра              
  110.               &App_ButtonStack[APP_TASK_BUTTON_STACK_SIZE - 1], // указатель на массив для стека  
  111.               APP_TASK_BUTTON_PRIO // приоритет
  112.           );
  113.                
  114.     APP_ASSERT( res == OS_ERR_NONE );
  115.  
  116.     res = OSTaskCreate(
  117.               App_TaskLed8,
  118.               NULL,
  119.               &App_TaskLed8Stack[APP_TASK_LED8_STACK_SIZE - 1],
  120.               APP_TASK_LED8_PRIO
  121.           );
  122.                
  123.     APP_ASSERT( res == OS_ERR_NONE );
  124.  
  125.     res = OSTaskCreate(  
  126.               App_TaskScanKeyboard, // указатель на функцию
  127.               NULL, // параметр - без параметра
  128.               &App_TaskScanKeyboardStack[APP_TASK_KEYBOARD_STACK_SIZE - 1], // указатель на массив для стека
  129.               APP_TASK_SCAN_KEYBOARD_PRIO // приоритет
  130.           );
  131.                      
  132.     APP_ASSERT(res == OS_ERR_NONE);
  133.        
  134.     res = OSTaskCreate(
  135.               App_TaskPlaySound, // указатель на функцию
  136.               NULL, // параметр - без параметра
  137.               &App_TaskPlaySoundStack[APP_TASK_SOUND_STACK_SIZE - 1], // указатель на массив для стека
  138.               APP_TASK_PLAY_SOUND_PRIO // приоритет
  139.           );
  140.  
  141.     APP_ASSERT( res == OS_ERR_NONE );
  142.        
  143.     res = OSTaskCreate(
  144.               App_TaskSendButtonNum, // указатель на функцию
  145.               NULL, // параметр - без параметра
  146.               &App_TaskSendButtonNumStack[APP_TASK_SEND_BUTTON_NUM_STACK_SIZE - 1], // указатель на массив для стека
  147.               APP_TASK_SEND_BUTTON_NUM_PRIO // приоритет
  148.           );
  149.  
  150.     APP_ASSERT( res == OS_ERR_NONE );
  151.  
  152.     // этот таск больше не нужен
  153.     OSTaskDel (OS_PRIO_SELF);
  154.                      
  155. }
  156.  
  157. static bool is_button_on = false; // запоминает состояние кнопки PA0
  158.  
  159. // этот таск зажигает светодиод по нажатию кнопки
  160. static void App_TaskLed8( void * p_arg ) {
  161.     // это чтобы убрать warning о неиспользуемом аргументе
  162.     (void)p_arg;
  163.  
  164.     // настройка портов светодиодов и кнопки - делается при первом вызове таска
  165.     // подаем тактирование
  166.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE );
  167.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );
  168.  
  169.     // делаем РС.0 - floating input
  170.     GPIO_InitTypeDef gpioA;
  171.     gpioA.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  172.     gpioA.GPIO_Pin = GPIO_Pin_0;
  173.     gpioA.GPIO_Speed = GPIO_Speed_10MHz;
  174.  
  175.     GPIO_Init( GPIOA, &gpioA );
  176.     // делаем РС.8 - выходом пуш-пулл
  177.     GPIO_InitTypeDef gpioC;
  178.     gpioC.GPIO_Mode = GPIO_Mode_Out_PP;
  179.     gpioC.GPIO_Pin = GPIO_Pin_8;
  180.     gpioC.GPIO_Speed = GPIO_Speed_10MHz;
  181.  
  182.     GPIO_Init( GPIOC, &gpioC );
  183.  
  184.     // таск никогда не должен завершаться через закрывающую скобку
  185.     // поэтому внутри или удаление или бесконечный цикл
  186.     while (1) {
  187.         if (is_button_on == true)
  188.         GPIOC -> ODR |= 1 << 8; // зажечь светодиод при нажатой кнопке
  189.         else GPIOC -> ODR &= ~(1 << 8); // иначе погасить
  190.         // засыпаем на 5 миллисекунд,чтобы поток кнопки захватил управление
  191.         OSTimeDlyHMSM(0, 0, 0, 5);
  192.     }
  193. }
  194.  
  195. // все что делает этот таск - сканирует кнопку
  196. static void App_TaskButton( void * p_arg ) {
  197.     // это чтобы убрать warning о неиспользуемом аргументе
  198.     (void)p_arg;
  199.  
  200.     // настройка портов - делается при первом вызове таска
  201.     // да, в таске для кнопки порты тоже настраиваются - но ведь другой таск может
  202.     // быть и не активен!
  203.  
  204.     // подаем тактирование
  205.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE );
  206.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );
  207.  
  208.     // делаем РС.0 - floating input
  209.     GPIO_InitTypeDef gpioA;
  210.     gpioA.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  211.     gpioA.GPIO_Pin = GPIO_Pin_0;
  212.     gpioA.GPIO_Speed = GPIO_Speed_10MHz;
  213.  
  214.     GPIO_Init( GPIOA, &gpioA );
  215.     // делаем РС.8 - выходом пуш-пулл
  216.     GPIO_InitTypeDef gpioC;
  217.     gpioC.GPIO_Mode = GPIO_Mode_Out_PP;
  218.     gpioC.GPIO_Pin = GPIO_Pin_8;
  219.     gpioC.GPIO_Speed = GPIO_Speed_10MHz;
  220.  
  221.     GPIO_Init( GPIOC, &gpioC );
  222.  
  223.     // таск никогда не должен завершаться через закрывающую скобку
  224.     // поэтому внутри или удаление или бесконечный цикл
  225.     while (1) {
  226.         //если кнопка нажата
  227.         if(((GPIOA->IDR)&1))
  228.         is_button_on = true;
  229.         else is_button_on = false;
  230.         // засыпаем на 5 миллисекунд, чтобы дать время поменять состояние светодиода
  231.         OSTimeDlyHMSM(0, 0, 0, 5);
  232.     }
  233. }
  234.  
  235. static uint8_t button_num = 0;
  236.  
  237. static void App_TaskScanKeyboard(void * p_arg) {
  238.  
  239.     (void) p_arg;
  240.  
  241.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  242.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
  243.     GPIO_InitTypeDef PortA;
  244.     PortA.GPIO_Mode = GPIO_Mode_IPU;
  245.     PortA.GPIO_Pin = (GPIO_Pin_1) | (GPIO_Pin_2) | (GPIO_Pin_3) | (GPIO_Pin_4);
  246.     PortA.GPIO_Speed = GPIO_Speed_50MHz;
  247.     GPIO_Init(GPIOA, &PortA); // строки клавиатуры
  248.  
  249.     GPIO_InitTypeDef PortC;
  250.     PortC.GPIO_Mode = GPIO_Mode_Out_OD;
  251.     PortC.GPIO_Pin = (GPIO_Pin_1) | (GPIO_Pin_2) | (GPIO_Pin_3);
  252.     PortC.GPIO_Speed = GPIO_Speed_50MHz;
  253.     GPIO_Init(GPIOC, &PortC); // столбцы клавиатуры
  254.     GPIO_SetBits(GPIOC, (GPIO_Pin_1) | (GPIO_Pin_2) | (GPIO_Pin_3)); // установим столбцы в 1
  255.  
  256.     while (1) {
  257.         INT8U err;
  258.         OSSemPend(semaphore, 0, &err);
  259.         APP_ASSERT(err == OS_ERR_NONE);
  260.         button_num = 0;
  261.         for (uint8_t cols = 1; cols < 4; cols++) {
  262.             GPIO_ResetBits(GPIOC, 1 << cols); // ставим 0 по очереди по столбцам
  263.             OSTimeDlyHMSM(0, 0, 0, 4); // подождать 4 миллисекунды
  264.         for (uint8_t rows = 1; rows < 5; rows++) { // по очереди проверяем строки
  265.             if (!(GPIOA->IDR&(1«rows))) {
  266.                 button_num = (cols-1)+3*(rows-1) + 1; // запоминает номер нажатой кнопки, иначе 0
  267.                 break;
  268.                 }
  269.             //GPIOB->ODR ^= 1«10; // apply alternating voltage to the dynamic membrane
  270.             //delay(1000000/(2*ar[(cols-1)+3*(rows-1)]));
  271.             }
  272.         GPIO_SetBits(GPIOC, 1 << cols);
  273.         }
  274.     OSSemPost(semaphore); // освобождение семафора
  275.     OSTimeDlyHMSM(0, 0, 0, 10);
  276.     }
  277. }
  278.  
  279. static void TIM3_IRQHandler() {
  280.     TIM_ClearFlag(TIM3, TIM_IT_Update);
  281.     GPIOB-> ODR ^= 1 << 5;
  282. }
  283.  
  284. static void App_TaskPlaySound(void * p_arg) {
  285.  
  286.     (void)p_arg;
  287.  
  288.     static const uint16_t freq[12] = {600, 800, 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2400, 2600,
  289. 2800}; // массив частот в Герцах для каждой из кнопок
  290.  
  291.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );
  292.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
  293.  
  294.     TIM_TimeBaseInitTypeDef tim3_struct;
  295.     TIM_TimeBaseStructInit(&tim3_struct);
  296.     tim3_struct.TIM_Period = 100;
  297.     tim3_struct.TIM_CounterMode = TIM_CounterMode_Down;
  298.     TIM_TimeBaseInit(TIM3,&tim3_struct);
  299.  
  300.     TIM_ITConfig(TIM3,TIM_IT_Update, ENABLE);//настройка прерываний TIM3
  301.     TIM_Cmd(TIM3,ENABLE);//запуск таймера
  302.     BSP_IntVectSet(BSP_INT_ID_TIM3,TIM3_IRQHandler);//разрешаем прерывания
  303.  
  304.     GPIO_InitTypeDef gpioB; // настройка динамика
  305.     gpioB.GPIO_Mode = GPIO_Mode_Out_PP;
  306.     gpioB.GPIO_Pin = GPIO_Pin_5;
  307.     gpioB.GPIO_Speed = GPIO_Speed_10MHz;
  308.     GPIO_Init(GPIOB, &gpioB);
  309.  
  310.     while(1) {
  311.         INT8U err;
  312.         OSSemPend(semaphore, 0, &err);
  313.         APP_ASSERT(err == OS_ERR_NONE);
  314.         //если кнопка нажата           
  315.         if(button_num) {
  316.             tim3_struct.TIM_Prescaler = (72000000 / (200*freq[button_num - 1]))-1;
  317.             TIM_TimeBaseInit(TIM3,&tim3_struct);
  318.             NVIC_EnableIRQ(TIM3_IRQn);//разрешение прерываний таймера TIM3
  319.             //если ничего не нажато
  320.             } else {
  321.             NVIC_DisableIRQ(TIM3_IRQn);
  322.             GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  323.             }
  324.         OSSemPost(semaphore);
  325.         OSTimeDlyHMSM(0, 0, 0, 10);
  326.         }
  327. }
  328.  
  329. volatile char tx_buffer[16];
  330. static int8_t counter = 0;
  331.  
  332. static void USART1_IRQHandler(void) {
  333.     if(USART_GetITStatus(USART1, USART_IT_TC) == SET){ //прерывание по передаче
  334.     USART_SendData(USART1,tx_buffer[counter++]);
  335.     }
  336.     if (counter > 15) {
  337.     counter = 0;
  338.     USART_ITConfig(USART1, USART_IT_TC, DISABLE);
  339.     }
  340. }
  341.  
  342. static void App_TaskSendButtonNum(void * p_arg) {
  343.  
  344.     (void)p_arg;
  345.  
  346.     char ASCII;//значение кнопки в ASCII
  347.  
  348.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
  349.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  350.  
  351.     GPIO_InitTypeDef gpioB;
  352.     gpioB.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  353.     gpioB.GPIO_Pin = GPIO_Pin_7; //настройка ножки RX USART1
  354.  
  355.     gpioB.GPIO_Mode = GPIO_Mode_AF_PP;
  356.     gpioB.GPIO_Pin = GPIO_Pin_6; //настройка ножки TX USART1
  357.  
  358.     gpioB.GPIO_Speed = GPIO_Speed_2MHz;
  359.     GPIO_Init(GPIOB,&gpioB);
  360.  
  361.     USART_InitTypeDef Usart_struct;
  362.     Usart_struct.USART_BaudRate = 57600;
  363.     Usart_struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  364.     Usart_struct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  365.     Usart_struct.USART_Parity = USART_Parity_No;
  366.     Usart_struct.USART_StopBits = USART_StopBits_1;
  367.     Usart_struct.USART_WordLength = USART_WordLength_8b;
  368.     USART_Init(USART1,&Usart_struct);//настройка режима работы USART
  369.  
  370.     USART_ITConfig(USART1,USART_IT_TC,DISABLE);
  371.     USART_Cmd(USART1, ENABLE);
  372.     BSP_IntVectSet(BSP_INT_ID_USART1,USART1_IRQHandler);//разрешаем прерывания
  373.     NVIC_EnableIRQ(USART1_IRQn);//разрешение прерываний USART1
  374.     while(1) {
  375.         INT8U err;
  376.         OSSemPend( semaphore,0,&err);
  377.         APP_ASSERT(err == OS_ERR_NONE);
  378.         if(button_num) {
  379.             // перевод кнопки в ASCII
  380.             if(button_num==12) ASCII = 35;// #
  381.             if(button_num==11) ASCII = 48;// 0
  382.             if(button_num==10) ASCII = 42;// *
  383.             else if(button_num<10) ASCII = button_num + 0x30;
  384.             tx_buffer[0] = 'p';
  385.             tx_buffer[1] = 'r';
  386.             tx_buffer[2] = 'e';
  387.             tx_buffer[3] = 's';
  388.             tx_buffer[4] = 's';
  389.             tx_buffer[5] = 'e';
  390.             tx_buffer[6] = 'd';
  391.             tx_buffer[7] = ' ';
  392.             tx_buffer[8] = 'b';
  393.             tx_buffer[9] = 'u';
  394.             tx_buffer[10] = 't';
  395.             tx_buffer[11] = 't';
  396.             tx_buffer[12] = 'o';
  397.             tx_buffer[13] = 'n';
  398.             tx_buffer[14] = ' ';
  399.             tx_buffer[15] = ASCII; // место в сообщении, где должен стоять номер кнопки
  400.             USART_ITConfig(USART1, USART_IT_TC, ENABLE);
  401.         }
  402.                
  403.         //если ничего не нажато
  404.         if(!button_num) {
  405.             tx_buffer[0] = 'n';
  406.             tx_buffer[1] = 'o';
  407.             tx_buffer[2] = 't';
  408.             tx_buffer[3] = 'h';
  409.             tx_buffer[4] = 'i';
  410.             tx_buffer[5] = 'n';
  411.             tx_buffer[6] = 'g';
  412.             tx_buffer[7] = ' ';
  413.             tx_buffer[8] = 'p';
  414.             tx_buffer[9] = 'r';
  415.             tx_buffer[10] = 'e';
  416.             tx_buffer[11] = 's';
  417.             tx_buffer[12] = 's';
  418.             tx_buffer[13] = 'e';
  419.             tx_buffer[14] = 'd';
  420.             tx_buffer[15] = ' ';
  421.             USART_ITConfig(USART1, USART_IT_TC, ENABLE);
  422.         }
  423.         counter = 0;
  424.         OSSemPost(semaphore);
  425.         OSTimeDlyHMSM(0, 0, 0, 8);
  426.     }
  427. }
  428.  
  429. #ifdef USE_FULL_ASSERT
  430.  
  431. // эта функция вызывается, если assert_param обнаружил ошибку
  432. void assert_failed(uint8_t * file, uint32_t line) {
  433.     /* User can add his own implementation to report the file name and line number,
  434.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  435.  
  436.     (void)file;
  437.     (void)line;
  438.  
  439.     __disable_irq();
  440.     while(1) {
  441.         // это ассемблерная инструкция "отладчик, стой тут"
  442.         // если вы попали сюда, значит вы ошиблись в параметрах вызова функции из SPL.
  443.         // Смотрите в call stack, чтобы найти ее
  444.         __BKPT(0xAB);
  445.     }
  446. }
  447.  
  448. #endif
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top