STM32+串口通信、定时器、ADC

器件选择

硬件平台选择STM32F103C8T6最小系统开发板。
STM32代码配置工具使用STM32CubeMX的HAL库进行开发。
光敏模块选择4线光敏电阻传感器模块,(光敏电阻型号5516)。
注1:数据下载使用ST-LINK下载。
注2:串口数据接收使用USB转TTL传输,USB转TTL的TXD接STM32的PA10引脚RXD,RXD接STM32的PA9引脚TXD。

工程案例:

STM32上电后,上位机显示字符串“%%%%%%%Welcome to xiang–ying%%%%%%%”。发送完字符串后,启动系统定时器。上位机通过发送命令读取从ADC通道连接的光敏电阻得到的相应值。发送控制字与返回值如下:

控制字返回信息
A1“XX:XX:XX Sampling value:XXXX ”
A2“XX:XX:XX Voltage value:X.XX ”
A3“XX:XX:XX Sampling value:XXXX Voltage value:X.XX ”
其他“XX:XX:XX Error!!! ”

定时器相关知识

中等容量的STM32F103增强型系列有7个定时器,包括:1个高级控制定时器、3个普通定时器,以及2个看门狗定时器和1个系统嘀嗒定时器。其中TIM1挂在APB2总线上,而TIM2-TIM4则挂在APB1总线上。定时器工作时:将时钟信号送入16位可编程预分配器(Prescaler),该预分配器系数为0~65535之间的任意数值。预分配器溢出后,会向16位的主计数器(Counter Period)发出一个脉冲信号。
定时器发生中断时间的计算方法如下:
定时时间=(Presecaler+1)×(1/定时器时钟频率)×(Counter Period+1)

CubeMX定时器配置

CubeMX的基础配置在上一篇文章STM32+光敏模块已经做出了详细介绍,故在此不在叙述,只介绍定时器的相关配置。
对系统的时钟进行如下配置:设置为72MHz,在红色方框中输入后,回车即可。
在这里插入图片描述
下面进行定时器的配置,由于定时器在此处仅作定时功能,因此只进行简单的配置即可。将预分配器(Prescaler)设定为7199,主计数器(Counter Period)设定为4999,则定时时间为:(7199/72000000)*4999=0.5S。
在这里插入图片描述
其他配置同上篇文章STM32+光敏模块中的配置。
同样配置相关的使能配置
在这里插入图片描述

代码主体部分

1、引入头文件,为后续使用变参函数sprintf以及使用清空数组函数memset做准备。

#include "stdio.h"
#include "string.h"

2、变量预先定义。

uint8_t str1[] = "\r\n%%%%%%%Welcome to xiang--ying%%%%%%%";//上电发送字符串
uint8_t h = 0, m = 0, s = 0, ss = 0;//h是时,m是分,s是秒,ss是0.5秒
uint16_t ADC_Sample = 0,ADC_Volt = 0;//DC_Value为采样值,ADC_Volt为电压值
uint8_t str[100];//给定一个数组空间,存放sprintf的内容
uint8_t RX[16];//定义一个数组存放控制字

3、定时器相关函数。回调函数,实现时间功能。

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	ss++;
	if(ss == 2)//0.5S满2进一
	{
		ss = 0;
		s++;
		if(s == 60)//S满60进一
		{
			s = 0;
			m++;
			if(m == 60)//m满60进一
			{
				m = 0;
				h++;
			}
		}
	}
}

4、串口通信相关函数。

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance == USART1)//判断是否是串口一
	{
			switch(RX[0])
			{
				case 0xa1:
					sprintf((char*)str,"\r\n%d:%d:%d Sampling value:%d",h,m,s,ADC_Sample);
				break;
					
				case 0xa2:
					sprintf((char*)str,"\r\n%d:%d:%d Voltage value:%d.%d%d",h,m,s,ADC_Volt/100,(ADC_Volt/10)%10,ADC_Volt%10);
				break;
				
				case 0xa3:
					sprintf((char*)str,"\r\n%d:%d:%d Sampling value:%d Voltage value:%d.%d%d",h,m,s,ADC_Sample,ADC_Volt/100,(ADC_Volt/10)%10,ADC_Volt%10);
				break;
				
				default:
					sprintf((char*)str,"\r\n%d:%d:%d Error!!!",h,m,s);
				break;
			}
			HAL_UART_Transmit(&huart1,str,sizeof(str),10000);//将str里面的内容发送到上位机
			HAL_UART_Receive_IT(&huart1,RX,1);//串口接收。
			memset(str,0,100);//清空数组内容,为下次存放内容做准备
		}
}
	

5、ADC数据的获取。

void Get_ADC_Sample()
{
	HAL_ADC_Start(&hadc1);//打开ADC转换
	if(HAL_ADC_PollForConversion(&hadc1,10) == HAL_OK)
	{
		ADC_Sample = HAL_ADC_GetValue(&hadc1);//将得到的ADC采样值放入变量ADC_Sample中
		ADC_Volt = ADC_Sample * 330/4096;//数据转换,电压为3.3V,数据时12位,保留两位小数
	}
	HAL_ADC_Stop(&hadc1);//停止ADC转换
}

6、主函数中加入下面代码段。

  /* USER CODE BEGIN 2 */
	HAL_UART_Transmit(&huart1,str1,sizeof(str1),10000);
	HAL_TIM_Base_Start_IT(&htim2);
  /* USER CODE END 2 */

7、在main函数的while循环中加入写入的代码

  /* USER CODE BEGIN WHILE */
  while (1)
  {
		Get_ADC_Sample();
		HAL_Delay(500);
		HAL_UART_Receive_IT(&huart1,RX,1);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

结果展示

在这里插入图片描述
注:博主是跟随小蜜蜂老师学习,故代码可能与小蜜蜂老师有重复,如侵权,请告知删除。
(2022年05月15日写于郑州)

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

xiang--ying

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

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

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

打赏作者

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

抵扣说明:

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

余额充值