RT-Thread Studio学习(十四)ADC

RT-Thread Studio学习(十四)ADC

  • 一、简介
  • 二、新建RT-Thread项目并使用外部时钟
  • 三、启用ADC
  • 四、测试

一、简介

本文将基于STM32F407VET芯片介绍如何在RT-Thread Studio开发环境下使用ADC设备。硬件及开发环境如下:

  • OS WIN10
  • STM32F407VET6
  • STM32CubeMX v6.10.0
  • STM32Cube MCU Package for STM32F4 Series v1.28.0
  • RT-Thread Studio v2.2.7
  • RT-Thread Source Code v5.0.2
  • STM32F4 chip support packages v0.2.3

二、新建RT-Thread项目并使用外部时钟

打开RT-Thread Studio软件新建基于芯片的项目,并使用外部时钟系统,具体参见《RT-Thread Studio学习(一)使用外部时钟系统》。

三、启用ADC

  1. 打开ADC驱动框架
    RT-Thread Setting 中借助图形化配置工具打开软件ADC的驱动框架,如下图所示:
    在这里插入图片描述
  2. 定义ADC相关的宏
    board.h文件中使能宏定义:
#define BSP_USING_ADC1
#define BSP_USING_ADC2
#define BSP_USING_ADC3
  1. 复制ADC初始化函数
    双击RT-Thread Studio工程中的cubemx.ioc文件,使能ADC1、ADC2和ADC3,具体如下图:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    3个ADC分别对应引脚PC0、PC1和PC2。

使能ADC后再重新生成STM32CubeMX代码,将.\cubemx\Src\adc.c中的函数HAL_DAC_MspInit(DAC_HandleTypeDef* dacHandle)复制到board.c的末尾。

void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{GPIO_InitTypeDef GPIO_InitStruct = {0};if(adcHandle->Instance==ADC1){/* USER CODE BEGIN ADC1_MspInit 0 *//* USER CODE END ADC1_MspInit 0 *//* ADC1 clock enable */__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_GPIOC_CLK_ENABLE();/**ADC1 GPIO ConfigurationPC0     ------> ADC1_IN10*/GPIO_InitStruct.Pin = GPIO_PIN_0;GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);/* USER CODE BEGIN ADC1_MspInit 1 *//* USER CODE END ADC1_MspInit 1 */}else if(adcHandle->Instance==ADC2){/* USER CODE BEGIN ADC2_MspInit 0 *//* USER CODE END ADC2_MspInit 0 *//* ADC2 clock enable */__HAL_RCC_ADC2_CLK_ENABLE();__HAL_RCC_GPIOC_CLK_ENABLE();/**ADC2 GPIO ConfigurationPC1     ------> ADC2_IN11*/GPIO_InitStruct.Pin = GPIO_PIN_1;GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);/* USER CODE BEGIN ADC2_MspInit 1 *//* USER CODE END ADC2_MspInit 1 */}else if(adcHandle->Instance==ADC3){/* USER CODE BEGIN ADC3_MspInit 0 *//* USER CODE END ADC3_MspInit 0 *//* ADC3 clock enable */__HAL_RCC_ADC3_CLK_ENABLE();__HAL_RCC_GPIOC_CLK_ENABLE();/**ADC3 GPIO ConfigurationPC2     ------> ADC3_IN12*/GPIO_InitStruct.Pin = GPIO_PIN_2;GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);/* USER CODE BEGIN ADC3_MspInit 1 *//* USER CODE END ADC3_MspInit 1 */}
}
  1. 定义.\cubemx\Inc\stm32f4xx_hal_conf.h中的相关宏
#define HAL_ADC_MODULE_ENABLED

四、测试

修改main.c的代码为:

/** Copyright (c) 2006-2024, RT-Thread Development Team** SPDX-License-Identifier: Apache-2.0** Change Logs:* Date           Author       Notes* 2024-01-15     RT-Thread    first version*/#include <rtthread.h>
#include "stm32f4xx.h"
#include <rtdevice.h>#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>// PC0     ------> ADC1_IN10
// PC1     ------> ADC2_IN11
// PC2     ------> ADC3_IN12
// PA4     ------> DAC_OUT1
// PA5     ------> DAC_OUT2#define ADC_DEV_NAME        "adc1"      /* ADC 设备名称 */
#define REFER_VOLTAGE       330         /* 参考电压 3.3V,数据精度乘以100保留2位小数*/
#define CONVERT_BITS        (1 << 12)   /* 转换位数为12位 */#define DAC_DEV_NAME        "dac1"  /* DAC 设备名称 */
#define DAC_DEV_CHANNEL     1       /* DAC 通道 */
#define REFER_VOLTAGE       330         /* 参考电压 3.3V,数据精度乘以100保留2位小数*/
#define CONVERT_BITS        (1 << 12)   /* 转换位数为12位 */// 读取adc的使用命令get_adc adc1 1
// 第一个参数为命令,第二个参数为 adc 设备名称,第 3 个参数为 adc 通道,
// 返回值为 adc 电压值
static int adc_get(int argc, char *argv[])
{if(argc!=3){rt_kprintf("Usage:    adc_get <device name> <channel>\n");rt_kprintf("Example:  adc_get adc1 1\n");return RT_ERROR;}rt_adc_device_t adc_dev;rt_uint32_t value, vol, channel;rt_err_t ret = RT_EOK;char adcdevname[RT_NAME_MAX];rt_strncpy(adcdevname, argv[1], RT_NAME_MAX);channel = atoi(argv[2]);  // ADC channel/* 查找设备 */adc_dev = (rt_adc_device_t)rt_device_find(adcdevname);if (adc_dev == RT_NULL){rt_kprintf("adc sample run failed! can't find %s device!\n", adcdevname);return RT_ERROR;}/* 使能设备 */ret = rt_adc_enable(adc_dev, channel);/* 读取采样值 */value = rt_adc_read(adc_dev, channel);rt_kprintf("the value is :%d \n", value);/* 转换为对应电压值 */vol = value * REFER_VOLTAGE / CONVERT_BITS;rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100);/* 关闭通道 */ret = rt_adc_disable(adc_dev, channel);rt_kprintf("adc_get %s channel:%d\n", adcdevname, channel);return ret;
}// 设置dac的使用命令 dac_set dac1 1 200
// 第一个参数为命令,第二个参数为 dac 设备名称,第 3 个参数为 dac 通道,
// 第 4 个参数为 dac 输出数值
static int dac_set(int argc, char *argv[])
{if(argc!=4){rt_kprintf("Usage:    dac_set <device name> <channel> <value>\n");rt_kprintf("Example:  dac_set dac1 1 1000\n");return RT_ERROR;}rt_dac_device_t dac_dev;rt_uint32_t value, vol, channel;rt_err_t ret = RT_EOK;char dacdevname[RT_NAME_MAX];rt_strncpy(dacdevname, argv[1], RT_NAME_MAX);channel = atoi(argv[2]);  // DAC channelvalue = atoi(argv[3]);/* 查找设备 */dac_dev = (rt_dac_device_t)rt_device_find(dacdevname);if (dac_dev == RT_NULL){rt_kprintf("dac sample run failed! can't find %s device!\n", dacdevname);return RT_ERROR;}/* 打开通道 */ret = rt_dac_enable(dac_dev, channel);/* 设置输出值 */rt_dac_write(dac_dev, channel, value);rt_kprintf("the value is :%d \n", value);/* 转换为对应电压值 */vol = value * REFER_VOLTAGE / CONVERT_BITS;rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100);/* 延时查看效果,关闭通道后无输出 */
//    rt_thread_mdelay(500);/* 关闭通道 */
//    ret = rt_dac_disable(dac_dev, channel);return ret;
}static int dac1_vol_sample()
{rt_dac_device_t dac_dev;rt_uint32_t value, vol;rt_err_t ret = RT_EOK;/* 查找设备 */dac_dev = (rt_dac_device_t)rt_device_find(DAC_DEV_NAME);if (dac_dev == RT_NULL){rt_kprintf("dac sample run failed! can't find %s device!\n", DAC_DEV_NAME);return RT_ERROR;}/* 打开通道 */ret = rt_dac_enable(dac_dev, DAC_DEV_CHANNEL);/* 设置输出值 */value=1000;rt_dac_write(dac_dev, DAC_DEV_CHANNEL, value);rt_kprintf("the value is :%d \n", value);/* 转换为对应电压值 */vol = value * REFER_VOLTAGE / CONVERT_BITS;rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100);/* 延时查看效果,关闭通道后无输出 */// rt_thread_mdelay(500);/* 关闭通道 */// ret = rt_dac_disable(dac_dev, DAC_DEV_CHANNEL);return ret;
}int main(void)
{int count = 1;LOG_D("Hello RT-Thread! 2024.1.17");LOG_D("System CLock information");LOG_D("SYSCLK_Frequency = %d", HAL_RCC_GetSysClockFreq());LOG_D("HCLK_Frequency   = %d", HAL_RCC_GetHCLKFreq());LOG_D("PCLK1_Frequency  = %d", HAL_RCC_GetPCLK1Freq());LOG_D("PCLK2_Frequency  = %d", HAL_RCC_GetPCLK2Freq());LOG_D("SysTick->LOAD    = %d", SysTick->LOAD);LOG_D("Current tick     = %d", rt_tick_get());dac1_vol_sample();while (count++){LOG_D("Hello RT-Thread! %d", rt_tick_get());rt_thread_mdelay(60000);}return RT_EOK;
}/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(adc_get, get adc voltage);
MSH_CMD_EXPORT(dac_set, set dac voltage. Useage: dac_set adc2 11 200);

将引脚PA4和PC1短接,运行结果如下:
在这里插入图片描述

在PA4脚用万用表测得输出电压为0.8080V

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/630430.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于Springboot的摄影分享网站系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的摄影分享网站系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…

Python文件自动化处理

os模块 Python标准库和操作系统有关的操作创建、移动、复制文件和文件夹文件路径和名称处理 路径的操作 获取当前Python程序运行路径不同操作系统之间路径的表示方式 windows中采用反斜杠(\)作为文件夹之间的分隔符 Mac和Linux中采用斜杠(/)作为文件夹之间的分隔符 把文件…

详解React与Vue的性能对比

React 和 Vue 是当前最流行的前端开发框架之一。它们都具有高度的灵活性和可扩展性&#xff0c;但在某些方面有所不同。在本篇文章中&#xff0c;我将详细介绍 React 和 Vue 这两个技术&#xff0c;并比较它们的优点和缺点。 目录 1. React&#xff1a; 1.1 优点&#xff1a; …

2023年第十四届蓝桥杯软件赛省赛总评

报名明年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列&#xff1a;备赛20周合集 20周的完整安排请点击&#xff1a;20周计划 每周发1个博客&#xff0c;共20周。 在QQ群上交流答疑&am…

[AI争霸] 普通人看ChatGPT和文心一言那个更好

文章目录 引言便利性准确性总结 引言 从2022/2/24号openAI正式发布chatgpt第一个版本以来&#xff0c;到2023年中旬openAI宣布chatgpt成为用户增长量最快的软件&#xff0c;随后掀起的大模型热。随后国内的各大厂商纷纷推出自己的大模型&#xff0c;首当其冲的就是百度的文心一…

Redis 消息队列和发布订阅

文章目录 基本模式生产者消费者原理&模型redis实现java实现 发布者订阅者原理&模型redis实现java实现 stream模式原理&模型工作原理redis实现Java实现 选型外传 基本模式 采用redis 三种方案&#xff1a; ● 生产者消费者&#xff1a;一个消息只能有一个消费者 ●…

Smart Tomcat

Smart Tomcat插件可以让idea图形化界面让代码部署到tomcat上达成一键打包部署的过程 下面是idea安装使用Smart Tomcat的过程 我们直接在plugins(插件)里搜索Tomcat 然后下载第一个 然后点击Apply(应用) 在一个项目中 第一次使用时要进行配置Smart Tomcat Name 可以不配置…

vscode安装和基本设置

目录 vscode安装和基本设置1.HTML标签2.标签属性3.HTML基本结构4.安装vscode5.安装Live Server插件6.HTML注释7.文档说明8.HTML字符编码9.HTML设置语言10.HTML标准结构 vscode安装和基本设置 1.HTML标签 标签 又称 元素&#xff0c;是HTML的基本组成单位。标签分为&#xff1…

JSP简单学习

jsp是在html中嵌入java代码 jsp也是在j2ee服务端中的java组件 第一次运行 在第一次运行jsp代码时会经历以下步骤&#xff0c;将jsp转为java代码&#xff0c;将java代码转为class文件。 所以通常会比较慢&#xff0c;编译后就好多了。 四大作用域 requestsessionpageapplica…

使用pdfbox 为 PDF 增加水印

使用pdfbox 为 PDF增加水印https://www.jylt.cc/#/detail?activityIndex2&idbd410851b0a72dad3105f9d50787f914 引入依赖 <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>3.0.1</ve…

【栈】【字符串和int类型转化】Leetcode 150 逆波兰表达式求值

【栈】【字符串和int类型转化】Leetcode 150 逆波兰表达式求值 解法1 栈 ---------------&#x1f388;&#x1f388;题目链接 Leetcode 150 逆波兰表达式求值 &#x1f388;&#x1f388;------------------- 解法1 栈 字符串转化为int类型数据: Integer.parseInt(s) Long.p…

java多线程传参数

package com.myThread;public class AdminThread extends Thread{private String name;public void AdminThread(String name){this.name name;}Overridepublic void run() {//线程开始之后执行的代码for (int i 0; i < 100; i) {System.out.print(getName()"线程…

Web前端-移动web开发——flex布局

移动web开发——flex布局 1.0传统布局和flex布局对比 1.1传统布局 兼容性好布局繁琐局限性&#xff0c;不能再移动端很好的布局 1.2 flex布局 操作方便&#xff0c;布局极其简单&#xff0c;移动端使用比较广泛pc端浏览器支持情况比较差IE11或更低版本不支持flex或仅支持部…

ChatGPT 与生成式 AI 的崛起:第二十六章到第三十三章

原文&#xff1a;Rise of Generative AI and ChatGPT 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 第二十五章&#xff1a;ChatGPT 用于国家网络安全和技术政策 介绍 恐怖分子、罪犯、警察、国防、执法机构、工程师、作家和学生等都在使用 ChatGPT&#xff0c;这是…

如何进行产品的人机交互设计?

产品的人机交互设计是指通过用户界面和用户体验设计来优化产品与用户之间的交互过程&#xff0c;从而提高产品的易用性、可用性和用户满意度。人机交互设计需要考虑用户的需求、行为模式、心理感受以及技术实现&#xff0c;下面我将介绍如何进行产品的人机交互设计。 首先&…

蓝桥备战 每日一题 (1)

二分法 代码如下&#xff1a; #include<iostream> #define ll long long using namespace std;ll query(ll n) {ll ret 0;while (n > 0) {ret n / 5; // 要计算 从 1 到 n 中 是 5 的倍数的个数&#xff0c;但是要注意 如果是 25 &#xff0c;要计算两次n / 5;}r…

kubeadm常用命令

一 kubeadm token 命令 "kubectl和kubeadm命令执行的时候" 默认情况下,kubectl 在 $HOME/.kube 目录下查找名为config的文件可以通过设置KUBECONFIG环境变量或设置--kubeconfig参数来指定其他Kubeconfig文件 ​ 解决1&#xff1a; k8s token 过期 的解决方法 ① 总…

目标检测开源数据集——道路坑洼

一、危害 对车辆的影响&#xff1a;道路坑洼会导致车辆行驶不稳&#xff0c;增加车辆的颠簸&#xff0c;不仅影响乘坐舒适度&#xff0c;还可能对车辆的悬挂系统、轮胎等造成损害。长期在坑洼路面上行驶&#xff0c;车辆的减震系统、悬挂系统等关键部件容易受损&#xff0c;进…

Redis和MySQL如何保持数据一致性

前言 在高并发的场景下&#xff0c;大量的请求直接访问Mysql很容易造成性能问题。所以&#xff0c;我们都会用Redis来做数据的缓存&#xff0c;削减对数据库的请求。但是&#xff0c;Mysql和Redis是两种不同的数据库&#xff0c;如何保证不同数据库之间数据的一致性就非常关键…

Mybatis----面向接口

让mybatis自动生成dao层接口的实现类 这是dao层接口的实现类&#xff0c;在mybatis中我们可以省略这种实现接口的方式&#xff0c;直接面向接口操作数据库&#xff0c;mybatis可以帮我们自动生成接口的实现类&#xff0c;也就是下面这个实现类mybatis帮我们生成了。 1、修改se…