事件集机制及ADC的使用 ---- RT-thread&&STM32

一、需求

利用线程间同步-事件集机制,实现当一个ADC通道采样值大于3V 或者另外一个ADC通道采样值小于0.5V时,实现报警功能。ADC通道自由选择。

二、实现

  • 1.1、使用STM32CubeMX配置好ADC通道,选择的是ADC1的通道0和通道1。
    事件集机制及ADC的使用 ---- RT-thread&&STM32_第1张图片
  • 1.2、创建一个ADC采集线程,由采到的AD值换算得到电压,同时判断通道0的电压是否大于3V,若是,发送事件一。判断通道1的电压是否小于0.5V,若是,发送事件二。
  • 1.3、创建一个另一个线程,在其入口函数上接收事件,若接收到事件1或者事件2,报警。

三、代码实现

#define EVENT_FLAG1 (1 << 1)
#define EVENT_FLAG2 (1 << 2)
extern ADC_HandleTypeDef hadc1;
ADC_ChannelConfTypeDef adConfig;
rt_event_t adc_event = RT_NULL;

// AD值获取
uint32_t adc_value_get(uint32_t channel)
{
    /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */
    adConfig.Channel = channel;
    adConfig.Rank = 1;
    adConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
    HAL_ADC_ConfigChannel(&hadc1, &adConfig);
    // 启动ADC转换
    HAL_ADC_Start(&hadc1);
    // 等待转换完成,第二个参数表示超时时间,单位ms
    HAL_ADC_PollForConversion(&hadc1, 10);
    // 为换取ADC状态
    return HAL_ADC_GetValue(&hadc1);
}

// 获取AD值和事件发送
void adc_thread_entry(void *parameter)//用户消息处理入口函数
{
    float voltage1 = 0.0;
    float voltage2 = 0.0;
	while(1)    
	{  
       rt_thread_mdelay(500);
       // 获取通道一电压值,采取的右对齐除以2的12次方,参考电压为3.3V
       voltage1 = (float)adc_value_get(ADC_CHANNEL_0)/ 4096 * 3.3;
       if(voltage1 > 3.0)
            rt_event_send(adc_event, EVENT_FLAG1);
       else
            rt_kprintf("voltage1 < 3V\n");
       
       rt_thread_mdelay(500);
       // 获取通道2电压值,采取的右对齐除以2的12次方,参考电压为3.3V
       voltage2 = (float)adc_value_get(ADC_CHANNEL_1)/ 4096 * 3.3;
       if(voltage2 < 0.5)
            rt_event_send(adc_event, EVENT_FLAG2);
       else
           rt_kprintf("voltage2 > 0.5V\n");
	}
}

void alarm_thread_entry(void *parameter)//用户消息处理入口函数
{
    rt_uint32_t e;
	while(1)    
	{  
        /* 事件 1 或事件 2 任意一个发生都会报警,接收完后清除事件标志 */
        if (rt_event_recv(adc_event, (EVENT_FLAG1 | EVENT_FLAG2),
                          RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
                          RT_WAITING_FOREVER, &e) == RT_EOK)
        {
            rt_kprintf("Warning, abnormal voltage\n");
        }
	}	
}


int abc_init(void)
{
    rt_thread_t adc_tid = RT_NULL;
    rt_thread_t alarm_tid = RT_NULL;
    
    adc_event = rt_event_create("adc_event", RT_IPC_FLAG_FIFO );
  
    adc_tid = rt_thread_create("adc_thread",
                           adc_thread_entry, 
                           RT_NULL,
                           512, 
                           4, 
                           10
                           );
    if(adc_tid != NULL)
        rt_thread_startup(adc_tid);
    
    alarm_tid = rt_thread_create("alarm_tid",
                           alarm_thread_entry, 
                           RT_NULL,
                           256, 
                           5, 
                           10
                           );
    if(alarm_tid != NULL)
        rt_thread_startup(alarm_tid);
    return 0;
}
INIT_APP_EXPORT(abc_init);

四、实验结果

  • 4.1、实验设备如下,使用两个相等的电阻分压,所以两个通道的电压值大概是3.3/2V。
  • 4.2、通道1的引线接到地,之后将通道0的引线接到3.3V。
  • 4.3、整个过程的打印效果如下,可知事件集的使用是成功的。
    事件集机制及ADC的使用 ---- RT-thread&&STM32_第2张图片

参考资料

  • RT-thread文档中心 – 事件集
  • 《STM32F7开发指南-HAL库版本_V1.2.pdf》-- 第25章 ADC实验

你可能感兴趣的:(#,RT-thread,应用)