玩转RT 您所在的位置:网站首页 adc采样数据流过大怎么办 玩转RT

玩转RT

2024-06-06 13:08| 来源: 网络整理| 查看: 265

玩转RT-Thread系列教程(8)–ADC—光敏数据的采集 一、查看电路原理图

光敏电阻

二、添加ADC—DMA配置 1.配置Cubemx

为ADC设置频率,72/6=12分频

DMA配置

关闭终端

生成代码

2.添加Kconfig中ADC配置

3.打开env,配置ADC3

menuconfig

4.保存配置,生成mdk工程

三、ADC外设的使用 1.添加adc外设初始化

打开stm32f1xx_hal_msp.c我们可以看见,cubemx生成的代码自动添加到了该文件中。

接下来我们打开main.c复制一下初始化部分。

/** * @brief ADC3 Initialization Function * @param None * @retval None */ static void MX_ADC3_Init(void) { /* USER CODE BEGIN ADC3_Init 0 */ /* USER CODE END ADC3_Init 0 */ ADC_ChannelConfTypeDef sConfig = {0}; /* USER CODE BEGIN ADC3_Init 1 */ /* USER CODE END ADC3_Init 1 */ /** Common config */ hadc3.Instance = ADC3; hadc3.Init.ScanConvMode = ADC_SCAN_DISABLE; hadc3.Init.ContinuousConvMode = ENABLE; hadc3.Init.DiscontinuousConvMode = DISABLE; hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc3.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc3.Init.NbrOfConversion = 1; if (HAL_ADC_Init(&hadc3) != HAL_OK) { Error_Handler(); } /** Configure Regular Channel */ sConfig.Channel = ADC_CHANNEL_5; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5; if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN ADC3_Init 2 */ /* USER CODE END ADC3_Init 2 */ } /** * Enable DMA controller clock */ static void MX_DMA_Init(void) { /* DMA controller clock enable */ __HAL_RCC_DMA2_CLK_ENABLE(); } 2.编写业务逻辑,获取光敏传感器数值

因为开发板IO引脚的电压最高为3.3v,同时ADC采用16字节对齐,所以最大数值为4096,经过换算得出换算电压公式:

V(adc) = ADC * 3.3 / 4096

完整代码:

#include #include #include #include "button_app.h" ADC_HandleTypeDef hadc3; DMA_HandleTypeDef hdma_adc3; //定义key 控制块 struct key_state_type key0 = { 0 }; struct key_state_type key1 = { 0 }; static void MX_ADC3_Init(void); static void MX_DMA_Init(void); static void Get_Light_Value(void); static uint16_t adc_data; static uint32_t light_value; int main(void) { MX_DMA_Init(); MX_ADC3_Init(); HAL_ADC_Start(&hadc3); HAL_ADC_Start_DMA(&hadc3,(uint32_t*)&adc_data,(uint32_t)1); while (1) { Get_Light_Value(); rt_pin_write(LED0_PIN, PIN_HIGH); rt_thread_mdelay(500); rt_pin_write(LED0_PIN, PIN_LOW); rt_thread_mdelay(500); } } void Get_Light_Value(void) { light_value = adc_data * 330/4096; rt_kprintf("light value is:%d.%02d\r\n",light_value/100,light_value%100); } /** * @brief ADC3 Initialization Function * @param None * @retval None */ static void MX_ADC3_Init(void) { /* USER CODE BEGIN ADC3_Init 0 */ /* USER CODE END ADC3_Init 0 */ ADC_ChannelConfTypeDef sConfig = {0}; /* USER CODE BEGIN ADC3_Init 1 */ /* USER CODE END ADC3_Init 1 */ /** Common config */ hadc3.Instance = ADC3; hadc3.Init.ScanConvMode = ADC_SCAN_DISABLE; hadc3.Init.ContinuousConvMode = ENABLE; hadc3.Init.DiscontinuousConvMode = DISABLE; hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc3.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc3.Init.NbrOfConversion = 1; if (HAL_ADC_Init(&hadc3) != HAL_OK) { Error_Handler(); } /** Configure Regular Channel */ sConfig.Channel = ADC_CHANNEL_6; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5; if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN ADC3_Init 2 */ /* USER CODE END ADC3_Init 2 */ } /** * Enable DMA controller clock */ static void MX_DMA_Init(void) { /* DMA controller clock enable */ __HAL_RCC_DMA2_CLK_ENABLE(); } 3.编译、下载、验证

adc

可以看见当用手去靠近光敏传感器时,电压明显增加。

四、结合LVGL使用

上次我们学习了LVGL的移植,那么我们今天就将其应用起来做一个综合案例吧

4.1.案例分析

使用LVGL创建仪表盘,通过仪表盘来动态显示我们采集到的ADC数据。

4.2.编码实现 4.2.1创建LVGL线程 static int _lv_init = 0; static void lvgl_tick_run(void *p) { if (_lv_init) { //LVGL心跳 lv_tick_inc(1); } } static int lvgl_tick_handler_init(void) { rt_timer_t timer = RT_NULL; int ret; timer = rt_timer_create("lv_tick", lvgl_tick_run, RT_NULL, 1, RT_TIMER_FLAG_PERIODIC); if (timer == RT_NULL) { return RT_ERROR; } ret = rt_timer_start(timer); return ret; } static void lvgl_th_run(void *p) { tp_dev.init(); //触摸屏初始化 // lv_init(); //lvgl系统初始化 lv_port_disp_init(); //lvgl显示接口初始化 lv_port_indev_init(); //lvgl输入接口初始化 _lv_init = 1; //开启心跳 lvgl_tick_handler_init(); //心跳定时器 // lv_test_theme_1(lv_theme_night_init(210,NULL)); while(1) { tp_dev.scan(0); lv_task_handler(); rt_thread_mdelay(5); } } int rt_lvgl_init(void) { rt_err_t ret = RT_EOK; rt_thread_t thread = RT_NULL; thread = rt_thread_create("lvgl", lvgl_th_run, RT_NULL, 2048, 15, 10); if(thread == RT_NULL) { return RT_ERROR; } rt_thread_startup(thread); return RT_EOK; } INIT_APP_EXPORT(rt_lvgl_init); 4.2.2编写UI显示 /********************* * INCLUDES *********************/ #include "lv_test_theme_1.h" #include #include #include #include #if LV_USE_TESTS /********************* * DEFINES *********************/ /* defined the LED0 pin: PB5 */ #define LED0_PIN GET_PIN(B, 5) /* defined the LED1 pin: PE5 */ #define LED1_PIN GET_PIN(E, 5) /********************** * TYPEDEFS **********************/ /********************** * STATIC PROTOTYPES **********************/ static void create_tab1(lv_obj_t * parent); static void create_tab2(lv_obj_t * parent); static void create_tab3(lv_obj_t * parent); /********************** * STATIC VARIABLES **********************/ lv_style_t gauge_style; lv_obj_t * gauge1; lv_obj_t * label1; //结构体赋值 lv_color_t needle_colors1[1];//指针的颜色 extern float light_value; /********************** * MACROS **********************/ /********************** * GLOBAL FUNCTIONS **********************/ /** * Create a test screen with a lot objects and apply the given theme on them * @param th pointer to a theme */ void lv_test_theme_1(lv_theme_t * th) { lv_theme_set_current(th); th = lv_theme_get_current(); lv_obj_t * scr = lv_cont_create(NULL, NULL); lv_disp_load_scr(scr); lv_obj_t * tv = lv_tabview_create(scr, NULL); lv_obj_set_size(tv, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL)); lv_obj_t * tab1 = lv_tabview_add_tab(tv, "RB_Team"); lv_gauge_test_start(tab1); } //任务回调函数 void task_cb(lv_task_t * task) { //设置指针的数值 lv_gauge_set_value(gauge1, 0, (rt_int16_t)light_value * 10); } void lv_gauge_test_start(lv_obj_t * parent) { //1.创建自定义样式 lv_style_copy(&gauge_style, &lv_style_pretty_color); gauge_style.body.main_color = LV_COLOR_MAKE(0x5F, 0xB8, 0x78); //关键数值点之前的刻度线的起始颜色,为浅绿色 gauge_style.body.grad_color = LV_COLOR_MAKE(0xFF, 0xB8, 0x00); //关键数值点之前的刻度线的终止颜色,为浅黄色 gauge_style.body.padding.left = 13;//每一条刻度线的长度 gauge_style.body.padding.inner = 8;//数值标签与刻度线之间的距离 gauge_style.body.border.color = LV_COLOR_MAKE(0x33, 0x33, 0x33); //中心圆点的颜色 gauge_style.line.width = 4;//刻度线的宽度 gauge_style.text.color = LV_COLOR_WHITE;//数值标签的文本颜色 gauge_style.line.color = LV_COLOR_OLIVE;//关键数值点之后的刻度线的颜色 //仪表盘 gauge1 = lv_gauge_create(parent, NULL);//创建仪表盘 lv_obj_set_size(gauge1, 300, 300); //设置仪表盘的大小 lv_gauge_set_style(gauge1, LV_GAUGE_STYLE_MAIN, &gauge_style); //设置样式 lv_gauge_set_range(gauge1, 0, 50); //设置仪表盘的范围 needle_colors1[0] = LV_COLOR_TEAL; lv_gauge_set_needle_count(gauge1, 1, needle_colors1); //设置指针的数量和其颜色 lv_gauge_set_value(gauge1, 0, (rt_int16_t)light_value * 10); //设置指针1指向的数值 lv_gauge_set_critical_value(gauge1, 40); //设置关键数值点 lv_gauge_set_scale(gauge1, 240, 41, 10); //设置角度,刻度线的数量,数值标签的数量 lv_obj_align(gauge1, NULL, LV_ALIGN_IN_LEFT_MID, 50, 0); //设置与屏幕居中对齐 //3.创建一个标签来显示指针1的数值 label1 = lv_label_create(parent, NULL); lv_label_set_long_mode(label1, LV_LABEL_LONG_BREAK); //设置长文本模式 lv_obj_set_width(label1, 80); //设置固定的宽度 lv_label_set_align(label1, LV_LABEL_ALIGN_CENTER); //设置文本居中对齐 lv_label_set_style(label1, LV_LABEL_STYLE_MAIN, &lv_style_pretty); //设置样式 lv_label_set_body_draw(label1, true); //使能背景重绘制 lv_obj_align(label1, gauge1, LV_ALIGN_CENTER, 0, 60); //设置与gauge1的对齐方式 lv_label_set_text(label1, "0.0 V/h"); //设置文本 lv_label_set_recolor(label1, true); //使能文本重绘色 //4.创建一个任务来模拟速度指针的变化 lv_task_create(task_cb, 300, LV_TASK_PRIO_MID, NULL); } #endif /*LV_USE_TESTS*/ 4.3.编译、下载、验证



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有