【stm32/CubeMX、HAL库】swjtu嵌入式实验七 ADC 实验

相关电路与IO引脚

注意:串口打印重定向后使用printf打印需要在keil里勾选 Use MicroLIB ,否则会卡住。

参看:https://zhuanlan.zhihu.com/p/565613666

串口重定向:

/* USER CODE BEGIN Includes */
 
#include <stdio.h>// 包含标准输入输出头文件
 

/* USER CODE END Includes */


int fputc(int ch,FILE *f)
 
{
 
//采用轮询方式发送1字节数据,超时时间设置为无限等待
 
HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,HAL_MAX_DELAY);
 
return ch;
 
}

int fgetc(FILE *f)
 
{
 
uint8_t ch=0;
 
// 采用轮询方式接收 1字节数据,超时时间设置为无限等待
 
HAL_UART_Receive( &huart1,(uint8_t*)&ch,1, HAL_MAX_DELAY );
 
return ch;
 
}

ADC的GPIO复用引脚表:

参考:

视频教程:14.1和14.2节

【【14.1】STM32 ADC模数转换器 感知世界的钥匙------Kevin带你读《STM32Cube高效开发教程基础篇》】 https://www.bilibili.com/video/BV1CV4y1k71M/?share_source=copy_web\&vd_source=9332b8fc5ea8d349a54c3989f6189fd3

博客:

https://blog.csdn.net/little_grapes/article/details/121154513

ADC相关函数:

实验内容

1、利用 ADC1 通道 3 采样 PA3 的电压值,将 ADC 采样值和转换的电压值通过串行口返回, 调节电位器,观察运行结果。

根据前面的复用引脚表,选择ADC1的通道IN3。

CubeMX配置如下,

采样时间(sampling time)选择55.5cycles,采样时间长一些结果更准确。

因为也要使用中断方式,所以要开启中断

轮询方式:

  /* USER CODE BEGIN 2 */
   HAL_ADCEx_Calibration_Start(&hadc1);
  
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		
		//轮询
		HAL_ADC_Start(&hadc1);
		HAL_ADC_PollForConversion(&hadc1,50);//is it finished?
		if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1),HAL_ADC_STATE_REG_EOC))
		{
		adc_res=HAL_ADC_GetValue(&hadc1);
			printf("voltage value:%.1f V\r\n",adc_res*3.3/4095);
		}
		//延时一段时间再启动转换
		HAL_Delay(1000);
		
  }
  /* USER CODE END 3 */

中断方式(直接把轮询相关的代码替换,详见参考的文章)

  /* USER CODE BEGIN 2 */
	
	//中断方式启动ADC转换
  HAL_ADC_Start_IT(&hadc1);
	
  /* USER CODE END 2 */

回调函数:

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
  if(hadc->Instance==ADC1){
	adc_res=HAL_ADC_GetValue(&hadc1);
		printf("voltage value:%.2f V,original value:%d \r\n",adc_res*3.3/4095,adc_res);
	
	}
}

2、编写程序,利用光敏电阻设计光电开关,控制 LED1 点亮和熄灭。

光敏电阻对应引脚PA2,选择ADC1的IN2通道,选择使用定时器作为中断源,注意此时要关闭连续转换,cubemx配置:

记得开启ADC中断。

然后配置定时器,这里用定时器3,频率为72mhz/(7200*5000)

代码:

  /* USER CODE BEGIN 2 */

//中断方式启动ADC转换
  HAL_ADC_Start_IT(&hadc1);
	//开启定时器3
	HAL_TIM_Base_Start(&htim3);

  /* USER CODE END 2 */

回调函数(这里设置设置计算电压的方法也是按照3.3V作为参考电压,大于2.1V就点亮灯(这里点亮了两个灯),灯的引脚看前面的GPIO实验)

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
  if(hadc->Instance==ADC1){
	adc_res=HAL_ADC_GetValue(&hadc1);
	//	printf("voltage value:%.1f V\r\n",adc_res*3.3/4095);
	  if(adc_res*3.3/4095>2.1){
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,0);
		HAL_GPIO_WritePin(GPIOF,GPIO_PIN_0,1);
			
		}	else{
		
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,1);
			
			HAL_GPIO_WritePin(GPIOF,GPIO_PIN_0,0);
		}
	
	}
}

3、设计一个室内温控系统,PA3 采样电压表示采集的温度,阈值上限为 2.5V,下限为 1V,采样电压显示在数码管上。

(1)当采样电压低于 1V(温度过低),蜂鸣器鸣叫(模拟声音报警),LED1 闪烁(模 拟光报警),全彩灯打开(模拟加热)。

(2)当采样电压位于 1V~2.5V 时,正常,蜂鸣器不叫,发光二极管不亮,电机不转。

(3)当采样电压高于 2.5V 时(温度过高),蜂鸣器鸣叫(模拟声音报警),LED1 闪烁 (模拟光报警),电机旋转(模拟风扇降温)。

这里蜂鸣器(PB8)用定时器4通道3输出一定频率的PWM控制,led闪烁间隔时间用cnt控制,循环了一定次数才翻转电平。配置如下:

段码表10以后是原来的数字加上了小数点显示

/* USER CODE BEGIN 0 */

uint8_t flag=0;
 int res=0;
//uint8_t table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x80 };//10表示'-'
uint8_t table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x80+0x3f,0x80+0x06,0x80+0x5b,0x80+0x4f,0x80+0x66,0x80+0x6d,0x80+0x7d,0x80+0x07,
0x80+0x7f,0x80+0x6f, };//10表示'-'
uint8_t s[]={0,0,0,0,0,0,10,0};
uint16_t adc_res=0;
int light_flag=0;
			uint8_t n1;
			uint8_t n2;

void write_byte(uint8_t date){
    unsigned char i;
	for(i=0;i<8;i++){
	  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,(date>>(7-i))&0x01);
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,1);
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,0);
	}
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,1);
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,0);
 
}




int fputc(int ch,FILE *f)
 
{
 
//采用轮询方式发鿿1字节数据,超时时间设置为无限等待
 
HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,HAL_MAX_DELAY);
 
return ch;
 
}

int fgetc(FILE *f)
 
{
 
uint8_t ch=0;
 
// 采用轮询方式接收 1字节数据,超时时间设置为无限等待
 
HAL_UART_Receive( &huart1,(uint8_t*)&ch,1, HAL_MAX_DELAY );
 
return ch;
 
}

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
  if(hadc->Instance==ADC1){
	adc_res=HAL_ADC_GetValue(&hadc1);
   float vol=adc_res*3.3/4095;
		printf("voltage value:%.2f V\r\n",vol);
	  if(vol <1){
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,0);

			light_flag=1;
			 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, 0);
        HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, 0);
			HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_3);
			
		}	else if(adc_res*3.3/4095 >=1 &&adc_res*3.3/4095<=2.5){
		
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,1);
			 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, 0);
        HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, 0);
			HAL_TIM_PWM_Stop(&htim4,TIM_CHANNEL_3);

			light_flag=0;
		}else{
		light_flag=1;
        HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, 1);
        HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, 0);
			
			HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_3);       
		}
		
		n1=(uint8_t)vol;
		n2=(uint8_t)(vol*10)%10;
		
		//printf(" value:%d V\r\n",n1);
		//printf(" value:%d V\r\n",n2);
	
	}
}

  int cnt=0;
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		if(light_flag==1){
			cnt++;
			if(cnt==50){
			cnt=0;
			HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_0);
			}
		  
		}else{
			HAL_GPIO_WritePin(GPIOF,GPIO_PIN_0,0);
			cnt=0;
		}
		
		s[7]=n2;
		s[6]=n1+10;
		
		
		for(int i=8;i<11;i++){
		write_byte(table[s[15-i]]);
		HAL_GPIO_WritePin(GPIOF,0x01<<i,0);
		HAL_Delay(1);
		HAL_GPIO_WritePin(GPIOF,0x01<<i,1);
		}
		
		
  }
  /* USER CODE END 3 */

源文件见个人主页。

相关推荐
好家伙VCC3 小时前
STM32与51单片机的区别:是否应该直接学习STM32?
stm32·学习·51单片机
szpc16213 小时前
28V_1MHZ电子烟,无线鼠标,医疗器械等专用恒频升压转换器超小体积封装
单片机·嵌入式硬件·计算机外设
luckyluckypolar4 小时前
STM32——SPI
stm32·单片机·嵌入式硬件·物联网
极客小张6 小时前
基于STM32MP157与OpenCV的嵌入式Linux人脸识别系统开发设计流程
linux·stm32·单片机·opencv·物联网
OH五星上将6 小时前
OpenHarmony(鸿蒙南向开发)——小型系统内核(LiteOS-A)【扩展组件】上
linux·嵌入式硬件·harmonyos·openharmony·鸿蒙开发·liteos-a·鸿蒙内核
浅陌pa7 小时前
24:RTC实时时钟
c语言·stm32·单片机·嵌入式硬件
敲上瘾7 小时前
多态的使用和原理(c++详解)
开发语言·数据结构·c++·单片机·aigc·多态·模拟
小熊在忙fpga7 小时前
STM32如何修改外部晶振频率和主频
stm32·单片机·嵌入式硬件
我命由我123457 小时前
GPIO 理解(基本功能、模拟案例)
linux·运维·服务器·c语言·c++·嵌入式硬件·c#
学习日记hhh8 小时前
STM32G431RBT6(蓝桥杯)串口(发送)
stm32·单片机·嵌入式硬件