//需要C语言基础
任务目标
当串口受到字符'E’时,ADC采集停止,并向串口返回“ADC采集停止”;当串口收到字符'S’时,ADC采集开始,并向串口返回,采集数据,格式为“ADCVolt:0.24V”
理论知识
在完成任务前,先简单学习基本理论知识,对串口与ADC有所了解。
UART和USART
STM32L0系列提供了4个USART接口,USART1、2、4、5,传输速度最高4Mbit/S。
将这个翻译过来是,UART(通用异步收发传输器),USART(通用同步异步收发传输器),简单来说加了S的功能更强大,主要有以下几个方面:
-
数据传输方式:
- UART使用异步传输方式,也就是说发送和接收的数据是以不同的时钟信号进行传输的。
- USART可以同时支持异步传输和同步传输方式,即可以使用外部时钟信号进行同步传输,也可以使用内部时钟信号进行异步传输。
-
通信速率:
- UART的通信速率受限于波特率发生器的时钟频率,通常为115200、9600等。
- USART支持更高的通信速率,可以根据需要选择更高的波特率。
-
数据帧格式:
- UART的数据帧通常包含起始位、数据位、校验位和停止位,其中数据位通常为5、6、7或8位。
- USART的数据帧格式更加灵活,可以根据需要选择数据位的数量,还可以选择是否使用校验位和停止位。
-
错误检测:
- UART通常只支持基本的奇偶校验错误检测。
- USART可以支持更复杂的错误检测,包括奇偶校验、帧错误和溢出错误等。
ADC
在STM32L071系列微控制器中嵌入了原生的12位模数转换器,通过硬件过采样扩展到16位模数转换器。它有多达19个多路复用通道,允许它测量来自16个外部和3个内部来源的信号。各种通道的A/D转换可以在单、连续、扫描或不连续模式下进行。ADC的结果存储在左对齐或右对齐的16位数
据寄存器中。
16个外部通道在转换时分为注入通道和规则通道,规则通道:最多有16路,相当于正常运行的程序,平时ADC的转换都是使用规则通道来实现的;注入通道:最多有4路,相当于中断,当注入通道需要转换时,规则通道的转换就会停止,优先执行注入通道的转换,当注入通道转换完成后,再继续执行规则通道的转换。
写代码
如果你没写过,从这里开始
[蓝桥杯物联网从0开始]第15届蓝桥杯物联网省赛CubeMx、Keil5软件的学习与使用。
工程创建
ADC、串口默认配置,打开nvic中断,系统时钟32MHz
代码编写
加入头文件
#include "main.h"
#include "adc.h"
#include "usart.h"
#include "gpio.h"
#include "stdio.h"
声明以下变量
/**
串口字符接收缓冲区 RxBuf
串口字符发送缓冲区 RxBuf
串口接收数据标志位 RxFlg
sprintf字符缓冲区 StrBuf
ADC采集量化值 AdcValue
ADC采集换算电压值 AdcVolt
**/
uint8_t RxBuf[256];
uint8_t TxBuf[256];
uint8_t RxFlg = 0;
uint8_t StrBuf[50];
uint16_t AdcValue = 0;
float AdcVolt = 0;
初始化串口接收为中断模式
HAL_UART_Receive_IT(&huart2,RxBuf,2);
重新串口中断回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART2)
{
if(strcmp((const char*)RxBuf,"Op")==0)
{
RxFlg = 1;
}
else if(strcmp((const char*)RxBuf,"Cl")==0)
{
HAL_ADC_Stop_IT(&hadc);
RxFlg = 0;
}
else
{
HAL_UART_Transmit_IT(&huart2,RxBuf,strlen(RxBuf));
HAL_UART_Transmit_IT(&huart2,"Data Err",sizeof("Data Err"));
}
}
HAL_UART_Receive_IT(&huart2,RxBuf,2);
}
重写ADC读回调函数
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
if(hadc->Instance==ADC1)
{
AdcValue = HAL_ADC_GetValue(hadc);
AdcVolt = AdcValue * 3.3 / 4096;
}
}
main函数中添加if
if(RxFlg)
{
HAL_Delay(1000);
HAL_ADC_PollForConversion(&hadc,50);
sprintf((char*)StrBuf,"AdcValue: %d ADC: %.2f\r\n",AdcValue,AdcVolt);
HAL_UART_Transmit_IT(&huart2,StrBuf,strlen(StrBuf));
}
效果
发送Op,开始单片机读取ADC1并发送给串口
发送Cl,单片机停止读取ADC并不发送给串口
发送任意字符,单片机返回指令错误给串口
最后
我自己从0开始学这个串口,以前都是用别人写的库,现在自己了解hal库,看了两天才看明白,如果要一个个解释就太多了,所以这次直接放代码,我也懵懵懂懂的,这次的接收是定长接收,如果发送的不是2个字节,单片机只能处理2个字节或无法处理。
总结一下:初始化->中断初始化->中断回调->数据处理