当前位置:   article > 正文

[蓝桥杯物联网从0开始]15届蓝桥杯省赛备赛,串口与ADC的使用方法,简单代码例程,代码详解_蓝桥杯物联网adc

蓝桥杯物联网adc

//需要C语言基础

任务目标

当串口受到字符'E’时,ADC采集停止,并向串口返回“ADC采集停止”;当串口收到字符'S’时,ADC采集开始,并向串口返回,采集数据,格式为“ADCVolt:0.24V”

理论知识

在完成任务前,先简单学习基本理论知识,对串口与ADC有所了解。

UART和USART

STM32L0系列提供了4个USART接口,USART1、2、4、5,传输速度最高4Mbit/S。

将这个翻译过来是,UART(通用异步收发传输器),USART(通用同步异步收发传输器),简单来说加了S的功能更强大,主要有以下几个方面:

  1. 数据传输方式:

    • UART使用异步传输方式,也就是说发送和接收的数据是以不同的时钟信号进行传输的。
    • USART可以同时支持异步传输和同步传输方式,即可以使用外部时钟信号进行同步传输,也可以使用内部时钟信号进行异步传输。
  2. 通信速率:

    • UART的通信速率受限于波特率发生器的时钟频率,通常为115200、9600等。
    • USART支持更高的通信速率,可以根据需要选择更高的波特率。
  3. 数据帧格式:

    • UART的数据帧通常包含起始位、数据位、校验位和停止位,其中数据位通常为5、6、7或8位。
    • USART的数据帧格式更加灵活,可以根据需要选择数据位的数量,还可以选择是否使用校验位和停止位。
  4. 错误检测:

    • UART通常只支持基本的奇偶校验错误检测。
    • USART可以支持更复杂的错误检测,包括奇偶校验、帧错误和溢出错误等。

ADC

在STM32L071系列微控制器中嵌入了原生的12位模数转换器,通过硬件过采样扩展到16位模数转换器。它有多达19个多路复用通道,允许它测量来自16个外部和3个内部来源的信号。各种通道的A/D转换可以在单、连续、扫描或不连续模式下进行。ADC的结果存储在左对齐或右对齐的16位数
据寄存器中。
16个外部通道在转换时分为注入通道和规则通道,规则通道:最多有16路,相当于正常运行的程序,平时ADC的转换都是使用规则通道来实现的;注入通道:最多有4路,相当于中断,当注入通道需要转换时,规则通道的转换就会停止,优先执行注入通道的转换,当注入通道转换完成后,再继续执行规则通道的转换。

写代码

如果你没写过,从这里开始

[蓝桥杯物联网从0开始]第15届蓝桥杯物联网省赛CubeMx、Keil5软件的学习与使用

工程创建

ADC、串口默认配置,打开nvic中断,系统时钟32MHz

代码编写

加入头文件

  1. #include "main.h"
  2. #include "adc.h"
  3. #include "usart.h"
  4. #include "gpio.h"
  5. #include "stdio.h"

声明以下变量

  1. /**
  2. 串口字符接收缓冲区 RxBuf
  3. 串口字符发送缓冲区 RxBuf
  4. 串口接收数据标志位 RxFlg
  5. sprintf字符缓冲区 StrBuf
  6. ADC采集量化值 AdcValue
  7. ADC采集换算电压值 AdcVolt
  8. **/
  9. uint8_t RxBuf[256];
  10. uint8_t TxBuf[256];
  11. uint8_t RxFlg = 0;
  12. uint8_t StrBuf[50];
  13. uint16_t AdcValue = 0;
  14. float AdcVolt = 0;

初始化串口接收为中断模式

HAL_UART_Receive_IT(&huart2,RxBuf,2);

重新串口中断回调函数

  1. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  2. {
  3. if(huart->Instance == USART2)
  4. {
  5. if(strcmp((const char*)RxBuf,"Op")==0)
  6. {
  7. RxFlg = 1;
  8. }
  9. else if(strcmp((const char*)RxBuf,"Cl")==0)
  10. {
  11. HAL_ADC_Stop_IT(&hadc);
  12. RxFlg = 0;
  13. }
  14. else
  15. {
  16. HAL_UART_Transmit_IT(&huart2,RxBuf,strlen(RxBuf));
  17. HAL_UART_Transmit_IT(&huart2,"Data Err",sizeof("Data Err"));
  18. }
  19. }
  20. HAL_UART_Receive_IT(&huart2,RxBuf,2);
  21. }

重写ADC读回调函数

  1. void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
  2. {
  3. if(hadc->Instance==ADC1)
  4. {
  5. AdcValue = HAL_ADC_GetValue(hadc);
  6. AdcVolt = AdcValue * 3.3 / 4096;
  7. }
  8. }

main函数中添加if

  1. if(RxFlg)
  2. {
  3. HAL_Delay(1000);
  4. HAL_ADC_PollForConversion(&hadc,50);
  5. sprintf((char*)StrBuf,"AdcValue: %d ADC: %.2f\r\n",AdcValue,AdcVolt);
  6. HAL_UART_Transmit_IT(&huart2,StrBuf,strlen(StrBuf));
  7. }

效果

发送Op,开始单片机读取ADC1并发送给串口

发送Cl,单片机停止读取ADC并不发送给串口

发送任意字符,单片机返回指令错误给串口

最后

我自己从0开始学这个串口,以前都是用别人写的库,现在自己了解hal库,看了两天才看明白,如果要一个个解释就太多了,所以这次直接放代码,我也懵懵懂懂的,这次的接收是定长接收,如果发送的不是2个字节,单片机只能处理2个字节或无法处理。

总结一下:初始化->中断初始化->中断回调->数据处理

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/516994
推荐阅读
相关标签
  

闽ICP备14008679号