[蓝桥杯物联网从0开始]15届蓝桥杯省赛备赛,串口与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

代码编写

加入头文件

#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个字节或无法处理。

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

  • 22
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Azhuo9527

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值