[活动专区] 【AT-START-F425测评】13、RT-Thread多线程、消息队列使用

[复制链接]
1396|0
 楼主| freeelectron 发表于 2022-3-18 16:23 | 显示全部楼层 |阅读模式

1、程序设计

三个线程,一个消息队列(大小是1,长度是12)
线程1:LED 500ms闪烁一次;
线程2:adc采样;
线程3:oled显示;
在线程2中,采样到数据后,通过消息队列发送到线程3,线程3收到消息后,更新oled显示。


2、RT-Thread配置

默认是没有使能消息队列的,需要使能消息队列;

8675062343da4e7620.png


3、代码实现

(1)Led初始化及led线程

  1. static rt_thread_t led_thread = RT_NULL;


  2. void LedInit(void)
  3. {
  4.         gpio_init_type gpio_init_struct;

  5.         /* enable the led clock */
  6.         crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);

  7.         /* set default parameter */
  8.         gpio_default_para_init(&gpio_init_struct);

  9.         /* configure the led gpio */
  10.         gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  11.         gpio_init_struct.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;
  12.         gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
  13.         gpio_init_struct.gpio_pins = GPIO_PINS_2|GPIO_PINS_3|GPIO_PINS_5;
  14.         gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  15.         gpio_init(GPIOC, &gpio_init_struct);
  16. }



  17. static void led_thread_entry(void *parameter)
  18. {
  19.     while (1)
  20.     {
  21.                 gpio_bits_write(GPIOC, GPIO_PINS_2|GPIO_PINS_3|GPIO_PINS_5, (confirm_state)!gpio_output_data_bit_read(GPIOC, GPIO_PINS_2|GPIO_PINS_3|GPIO_PINS_5));

  22.         rt_thread_mdelay(1000);
  23.                 rt_kprintf("led blink\r\n");
  24.     }
  25. }


  26. void LedThreadStart(void)
  27. {
  28.         led_thread = rt_thread_create( "led",     /*线程名字*/                    
  29.                                                                    led_thread_entry,/*线程入口函数*/
  30.                                                                    RT_NULL,/*线程入口函数参数*/
  31.                                                                    256,    /*线程栈大小*/
  32.                                                                    4 ,    /*线程优先级*/
  33.                                                                    20);   /*线程时间片*/
  34.         rt_thread_startup (led_thread);
  35. }

(2)adc初始化以及adc线程

  1. static rt_thread_t adc_thread = RT_NULL;
  2. static uint8_t adc_data[12];

  3. void AdcGpioInit(void)
  4. {
  5.         /* enable the  clock */
  6.         crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
  7.         
  8.         gpio_init_type gpio_init_struct;

  9.         /* set default parameter */
  10.         gpio_default_para_init(&gpio_init_struct);
  11.         /* configure the led gpio */
  12.         gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
  13.         gpio_init_struct.gpio_pins = GPIO_PINS_1  ;
  14.         gpio_init(GPIOA, &gpio_init_struct);
  15. }


  16. void AdcConfig(void)
  17. {
  18.         adc_base_config_type adc_base_struct;
  19.         crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE);
  20.         crm_adc_clock_div_set(CRM_ADC_DIV_6);

  21.         adc_base_default_para_init(&adc_base_struct);
  22.         adc_base_struct.sequence_mode = FALSE;
  23.         adc_base_struct.repeat_mode = FALSE;
  24.         adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT;
  25.         adc_base_struct.ordinary_channel_length = 1;
  26.         adc_base_config(ADC1, &adc_base_struct);

  27.         adc_ordinary_conversion_trigger_set(ADC1, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE);
  28.         adc_tempersensor_vintrv_enable(TRUE);

  29.         adc_enable(ADC1, TRUE);
  30.         
  31.         adc_calibration_init(ADC1);
  32.         while(adc_calibration_init_status_get(ADC1));
  33.         
  34.         adc_calibration_start(ADC1);
  35.         while(adc_calibration_status_get(ADC1));
  36. }


  37. uint16_t AdcSample(uint8_t channel)
  38. {
  39.         adc_ordinary_channel_set(ADC1, (adc_channel_select_type)channel, 1, ADC_SAMPLETIME_239_5);
  40.         adc_ordinary_software_trigger_enable(ADC1,TRUE);
  41.         while(!adc_flag_get(ADC1, ADC_CCE_FLAG));
  42.         adc_flag_clear(ADC1, ADC_CCE_FLAG);

  43.         return adc_ordinary_conversion_data_get(ADC1);
  44. }


  45. void AdcInit(void)
  46. {
  47.         AdcGpioInit();
  48.         AdcConfig();
  49. }


  50. static void adc_thread_entry(void *parameter)
  51. {
  52.         uint16_t ref=0;

  53.         float vdd=0;
  54.         float ch16=0;
  55.         float ch1=0;
  56.         uint16_t part1=0,part2=0;
  57.             
  58.         int result;
  59.         uint8_t *p=(uint8_t *)parameter;

  60.         while(1)
  61.         {
  62.                 ref=AdcSample(ADC_CHANNEL_17);
  63.                 vdd=1.2/(float)ref*4095;
  64.                
  65.                 part1=(uint32_t)vdd;
  66.                 part2=vdd*1000-part1*1000;
  67.                 rt_kprintf("\r\nVdd=%d.%d V\r\n",part1,part2);
  68.                
  69.                 rt_memcpy(&p[0],(uint8_t *)&part1,2);
  70.                 rt_memcpy(&p[2],(uint8_t *)&part2,2);

  71.                 ch1=AdcSample(ADC_CHANNEL_1)*vdd / 4095;
  72.                 part1=(uint32_t)ch1;
  73.                 part2=ch1*1000-part1*1000;
  74.                 rt_kprintf("Channel 1=%d.%d V\r\n",part1,part2);
  75.                         
  76.                 rt_memcpy(&p[4],(uint8_t *)&part1,2);
  77.                 rt_memcpy(&p[6],(uint8_t *)&part2,2);
  78.                
  79.                
  80.                 ch16=AdcSample(ADC_CHANNEL_16)*vdd / 4095;
  81.                 part1=(uint32_t)ch16;
  82.                 part2=ch16*1000-part1*1000;
  83.                 rt_kprintf("Channel 16=%d.%d V\r\n",part1,part2);
  84.                         
  85.                 rt_memcpy(&p[8],(uint8_t *)&part1,2);
  86.                 rt_memcpy(&p[10],(uint8_t *)&part2,2);
  87.                

  88.                 extern rt_mq_t adc_to_oled_mq;
  89.                
  90.                 result = rt_mq_send(adc_to_oled_mq, p,12);

  91.                 if (result != RT_EOK)
  92.         {
  93.                         rt_kprintf("%s,send mq err\r\n",adc_thread->name);
  94.         }
  95.                 else
  96.                 {
  97.                         rt_kprintf("%s,send mq success\r\n",adc_thread->name);
  98.                 }
  99.                
  100.                 rt_memset(p,'\0',12);
  101.                         
  102.                 rt_thread_mdelay(2000);
  103.         }
  104. }


  105. void AdcThreadStart(void)
  106. {
  107.         adc_thread = rt_thread_create("adc",
  108.                                                                   adc_thread_entry,
  109.                                                                   &adc_data,
  110.                                                   512,
  111.                                       5,
  112.                                                       20);
  113.                
  114.         rt_thread_startup (adc_thread);
  115. }

(3)oled初始化、oled线程、消息队列创建

  1. static rt_thread_t oled_thread=RT_NULL;

  2. rt_mq_t adc_to_oled_mq=RT_NULL;
  3. static uint8_t oled_data[12];
  4. static char temp[16];

  5. static  void oled_thread_entry(void *parameter)
  6. {
  7.         uint8_t *p =(uint8_t *)parameter;
  8.         
  9.         while(1)
  10.         {
  11.                 if(rt_mq_recv(adc_to_oled_mq,p,12,RT_WAITING_FOREVER)==RT_EOK)
  12.                 {
  13.                         rt_kprintf("%s,recv message queue \r\n",oled_thread->name);
  14.                         
  15.                         rt_memset(temp,' ',sizeof(temp));
  16.                         rt_sprintf(temp,"Vdd=%d.%d V",*(uint16_t*)(&p[0]),*(uint16_t*)(&p[2]));
  17.                         OledShowString(10,0,temp,16);
  18.                         rt_kprintf("%s\r\n",temp);
  19.                                                 
  20.                         rt_memset(temp,' ',sizeof(temp));
  21.                         rt_sprintf(temp,"Ch1=%d.%d V",*(uint16_t*)(&p[4]),*(uint16_t*)(&p[6]));
  22.                         OledShowString(10,2,temp,16);
  23.                         rt_kprintf("%s\r\n",temp);
  24.                                                 
  25.                         rt_memset(temp,' ',sizeof(temp));
  26.                         rt_sprintf(temp,"Ch16=%d.%d V",*(uint16_t*)(&p[8]),*(uint16_t*)(&p[10]));
  27.                         OledShowString(10,4,temp,16);
  28.                         rt_kprintf("%s\r\n",temp);
  29.                 }
  30.         }
  31. }


  32. void OledThreadStart(void)
  33. {
  34.         adc_to_oled_mq=rt_mq_create("adc_oled", 12,1, RT_IPC_FLAG_PRIO);
  35.         
  36.         oled_thread= rt_thread_create("oled",oled_thread_entry,oled_data,512,7,20);
  37.         
  38.         rt_thread_startup(oled_thread);
  39. }

4、现象

7271762344170bde3d.gif







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

本版积分规则

个人签名:stm32/LoRa物联网:304350312

66

主题

786

帖子

11

粉丝
快速回复 在线客服 返回列表 返回顶部