【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 */

源文件见个人主页。

相关推荐
Uitwaaien542 小时前
51 单片机矩阵键盘密码锁:原理、实现与应用
c++·单片机·嵌入式硬件·51单片机·课程设计
小关1232 小时前
STM32补充——FLASH
stm32·单片机·嵌入式硬件
7yewh4 小时前
嵌入式知识点总结 操作系统 专题提升(一)-进程和线程
linux·arm开发·驱动开发·stm32·嵌入式硬件·mcu·物联网
怪小庄吖6 小时前
翻译:How do I reset my FPGA?
经验分享·嵌入式硬件·fpga开发·硬件架构·硬件工程·信息与通信·信号处理
雯宝13 小时前
STM32 GPIO工作模式
stm32·单片机·嵌入式硬件
辰哥单片机设计14 小时前
STM32项目分享:智能厨房安全检测系统
stm32·单片机·嵌入式硬件
lshzdq15 小时前
【嵌入式开发】stm32 st-link 烧录
嵌入式硬件
山羊硬件Time16 小时前
详解单片机学的是什么?(电子硬件)
单片机·硬件工程师·硬件开发·电子工程师·电子硬件
Chambor_mak17 小时前
stm32单片机个人学习笔记14(USART串口数据包)
stm32·单片机·学习
tadus_zeng17 小时前
51单片机(三) UART协议与串口通信实验
单片机·嵌入式硬件·51单片机