打印
[活动专区]

【AT-START-F425测评】13、RT-Thread多线程、消息队列使用

[复制链接]
830|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

1、程序设计

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


2、RT-Thread配置

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


3、代码实现

(1)Led初始化及led线程

static rt_thread_t led_thread = RT_NULL;


void LedInit(void)
{
        gpio_init_type gpio_init_struct;

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

        /* set default parameter */
        gpio_default_para_init(&gpio_init_struct);

        /* configure the led gpio */
        gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
        gpio_init_struct.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;
        gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
        gpio_init_struct.gpio_pins = GPIO_PINS_2|GPIO_PINS_3|GPIO_PINS_5;
        gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
        gpio_init(GPIOC, &gpio_init_struct);
}



static void led_thread_entry(void *parameter)
{
    while (1)
    {
                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));

        rt_thread_mdelay(1000);
                rt_kprintf("led blink\r\n");
    }
}


void LedThreadStart(void)
{
        led_thread = rt_thread_create( "led",     /*线程名字*/                    
                                                                   led_thread_entry,/*线程入口函数*/
                                                                   RT_NULL,/*线程入口函数参数*/
                                                                   256,    /*线程栈大小*/
                                                                   4 ,    /*线程优先级*/
                                                                   20);   /*线程时间片*/
        rt_thread_startup (led_thread);
}

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

static rt_thread_t adc_thread = RT_NULL;
static uint8_t adc_data[12];

void AdcGpioInit(void)
{
        /* enable the  clock */
        crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
        
        gpio_init_type gpio_init_struct;

        /* set default parameter */
        gpio_default_para_init(&gpio_init_struct);
        /* configure the led gpio */
        gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
        gpio_init_struct.gpio_pins = GPIO_PINS_1  ;
        gpio_init(GPIOA, &gpio_init_struct);
}


void AdcConfig(void)
{
        adc_base_config_type adc_base_struct;
        crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE);
        crm_adc_clock_div_set(CRM_ADC_DIV_6);

        adc_base_default_para_init(&adc_base_struct);
        adc_base_struct.sequence_mode = FALSE;
        adc_base_struct.repeat_mode = FALSE;
        adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT;
        adc_base_struct.ordinary_channel_length = 1;
        adc_base_config(ADC1, &adc_base_struct);

        adc_ordinary_conversion_trigger_set(ADC1, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE);
        adc_tempersensor_vintrv_enable(TRUE);

        adc_enable(ADC1, TRUE);
        
        adc_calibration_init(ADC1);
        while(adc_calibration_init_status_get(ADC1));
        
        adc_calibration_start(ADC1);
        while(adc_calibration_status_get(ADC1));
}


uint16_t AdcSample(uint8_t channel)
{
        adc_ordinary_channel_set(ADC1, (adc_channel_select_type)channel, 1, ADC_SAMPLETIME_239_5);
        adc_ordinary_software_trigger_enable(ADC1,TRUE);
        while(!adc_flag_get(ADC1, ADC_CCE_FLAG));
        adc_flag_clear(ADC1, ADC_CCE_FLAG);

        return adc_ordinary_conversion_data_get(ADC1);
}


void AdcInit(void)
{
        AdcGpioInit();
        AdcConfig();
}


static void adc_thread_entry(void *parameter)
{
        uint16_t ref=0;

        float vdd=0;
        float ch16=0;
        float ch1=0;
        uint16_t part1=0,part2=0;
            
        int result;
        uint8_t *p=(uint8_t *)parameter;

        while(1)
        {
                ref=AdcSample(ADC_CHANNEL_17);
                vdd=1.2/(float)ref*4095;
               
                part1=(uint32_t)vdd;
                part2=vdd*1000-part1*1000;
                rt_kprintf("\r\nVdd=%d.%d V\r\n",part1,part2);
               
                rt_memcpy(&p[0],(uint8_t *)&part1,2);
                rt_memcpy(&p[2],(uint8_t *)&part2,2);

                ch1=AdcSample(ADC_CHANNEL_1)*vdd / 4095;
                part1=(uint32_t)ch1;
                part2=ch1*1000-part1*1000;
                rt_kprintf("Channel 1=%d.%d V\r\n",part1,part2);
                        
                rt_memcpy(&p[4],(uint8_t *)&part1,2);
                rt_memcpy(&p[6],(uint8_t *)&part2,2);
               
               
                ch16=AdcSample(ADC_CHANNEL_16)*vdd / 4095;
                part1=(uint32_t)ch16;
                part2=ch16*1000-part1*1000;
                rt_kprintf("Channel 16=%d.%d V\r\n",part1,part2);
                        
                rt_memcpy(&p[8],(uint8_t *)&part1,2);
                rt_memcpy(&p[10],(uint8_t *)&part2,2);
               

                extern rt_mq_t adc_to_oled_mq;
               
                result = rt_mq_send(adc_to_oled_mq, p,12);

                if (result != RT_EOK)
        {
                        rt_kprintf("%s,send mq err\r\n",adc_thread->name);
        }
                else
                {
                        rt_kprintf("%s,send mq success\r\n",adc_thread->name);
                }
               
                rt_memset(p,'\0',12);
                        
                rt_thread_mdelay(2000);
        }
}


void AdcThreadStart(void)
{
        adc_thread = rt_thread_create("adc",
                                                                  adc_thread_entry,
                                                                  &adc_data,
                                                  512,
                                      5,
                                                      20);
               
        rt_thread_startup (adc_thread);
}

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

static rt_thread_t oled_thread=RT_NULL;

rt_mq_t adc_to_oled_mq=RT_NULL;
static uint8_t oled_data[12];
static char temp[16];

static  void oled_thread_entry(void *parameter)
{
        uint8_t *p =(uint8_t *)parameter;
        
        while(1)
        {
                if(rt_mq_recv(adc_to_oled_mq,p,12,RT_WAITING_FOREVER)==RT_EOK)
                {
                        rt_kprintf("%s,recv message queue \r\n",oled_thread->name);
                        
                        rt_memset(temp,' ',sizeof(temp));
                        rt_sprintf(temp,"Vdd=%d.%d V",*(uint16_t*)(&p[0]),*(uint16_t*)(&p[2]));
                        OledShowString(10,0,temp,16);
                        rt_kprintf("%s\r\n",temp);
                                                
                        rt_memset(temp,' ',sizeof(temp));
                        rt_sprintf(temp,"Ch1=%d.%d V",*(uint16_t*)(&p[4]),*(uint16_t*)(&p[6]));
                        OledShowString(10,2,temp,16);
                        rt_kprintf("%s\r\n",temp);
                                                
                        rt_memset(temp,' ',sizeof(temp));
                        rt_sprintf(temp,"Ch16=%d.%d V",*(uint16_t*)(&p[8]),*(uint16_t*)(&p[10]));
                        OledShowString(10,4,temp,16);
                        rt_kprintf("%s\r\n",temp);
                }
        }
}


void OledThreadStart(void)
{
        adc_to_oled_mq=rt_mq_create("adc_oled", 12,1, RT_IPC_FLAG_PRIO);
        
        oled_thread= rt_thread_create("oled",oled_thread_entry,oled_data,512,7,20);
        
        rt_thread_startup(oled_thread);
}

4、现象







使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

65

主题

785

帖子

11

粉丝