文章目录

  • 1- ADC(Analog-to-Digital Converter)
  • 2- 原理图分析
  • 3- 配置使能ADC
  • 4- 添加代码
  • 5- 烧录连接测试
  • 6- 蜂鸣器原理图
  • 7- 配置蜂鸣器
  • 8- 添加代码



1- ADC(Analog-to-Digital Converter)

什么是ADC:

单片机中的ADC是Analog(模拟量)-to-Digital(数字量) Converter(转换器)的缩写,指模/数转换器或者模数转换器。真实世界的模拟信号,例如温度、压力、声音或者图像等,需要转换成更容易储存、处理和发射的数字形式,模/数转换器可以实现这个功能。
ADC就是数模转换,将模拟量转换为数字量

2- 原理图分析

我们可以看见开发板上的声音传感器和光强传感器,他们工作的原理都是ADC采样。

stm32 cubemx adc过采样_c语言

原理图我们可以看见,声音传感器连接在了CPU的PA6管脚上,环境光强传感器连接在了CPU的PA4管脚上。

stm32 cubemx adc过采样_物联网_02

从原理图和CPU的管脚我们看到,环境光强传感器使用的是ADC_IN9(第一个ADC采样的第9个通道上),声音传感器使用的是ADC_IN11。后面我们配置的时候也是需要注意的。

stm32 cubemx adc过采样_单片机_03


3- 配置使能ADC

配置ADC1,使能通道IN9 和IN11,选择Single-ended (Differential为差分信号)。这时候PA4 和PA6两个管脚就设置为ADC输入模式了,另外我们也可以鼠标右键点在这两个管脚上,对这两个管脚重命名,分别为AdcLux和AdcMix。

stm32 cubemx adc过采样_物联网_04

stm32 cubemx adc过采样_c语言_05

我们将ADC的时钟设置为12MHZ。

stm32 cubemx adc过采样_单片机_06

按住Ctrl+s生成代码。


4- 添加代码

修改adc.c文件,添加环境光强传感器和的声音传感器实现。

/* USER CODE BEGIN 1 */
enum
{
	ADCCHN_NOISY,
	ADCCHN_LUX,
	ADCCHN_MAX,
};

int adc_sample_lux_noisy(uint32_t *lux, uint32_t *noisy)
{
	uint8_t i;
	uint32_t  timeout = 0xffffff;
	for(i=0; i<ADCCHN_MAX; i++)
	{
		HAL_ADC_Start(&hadc1);
		HAL_ADC_PollForConversion(&hadc1, timeout);
		if(ADCCHN_NOISY == i)
		{
			*noisy = HAL_ADC_GetValue(&hadc1);
		}
		else if(ADCCHN_LUX == i)
		{
			*lux = HAL_ADC_GetValue(&hadc1);
		}
		HAL_Delay(10);
	}
	HAL_ADC_Stop(&hadc1);
	return 0;
}
/* USER CODE END 1 */

adc.h中添加ADC采样的函数声明。

/* USER CODE BEGIN Includes */
extern int adc_sample_lux_noisy(uint32_t *lux, uint32_t *noisy);
/* USER CODE END Includes */

在main.c添加源代码:

while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  adc_sample_lux_noisy(&lux, &noisy);
	  printf("Lux:[%lu] Noisy[%lu]\r\n", lux, noisy);
	  HAL_Delay(500);
  }
  /* USER CODE END 3 */

5- 烧录连接测试

烧录之后连接sscom进行测试,我们对着开发板声音改变或者光强改变的时候数字是不一样的,说明测试成功。

stm32 cubemx adc过采样_单片机_07


6- 蜂鸣器原理图

下图是BearKE1开发板原理图上蜂鸣器的电路图,由下图可知它受PA1管脚的控制。
在该开发板上我们采用的是无源蜂鸣器,因为人耳能听到的频率范围在20Hz–20kHz之间,此时我们只需要使用PA1管脚的定时器PWM输出功能,输出一个2.4KHz左右的PWM方波蜂鸣器就会发声了,通过调整PWM的频率就可以调整蜂鸣器的音色了。

stm32 cubemx adc过采样_物联网_08


PWM(Pulse Width Modulation,脉冲宽度调制)是通过对一系列脉冲的宽度进行调制,输出所需要的波形(包含形状以及幅值)。在PWM里有两个重要的专业术语:

  • 频率是指1秒内高低电平周期性出现的次数。
  • 占空比就是指在一个周期内,信号处于高电平的时间占据整个信号周期的百分比,例如下图所示的PWM波形占空比为25%,而方波则是指占空比为50%的PWM波形。

PWM在很多场合都会使用,我们经常见到的就是交流调光电路,也可以说是无级调速,高电平占多一点,也就是占空比大一点亮度就亮一点,占空比小一点亮度就没有那么亮,前提是PWM的频率要大于我们人眼识别频率,要不然会出现闪炼现象。除了在调光电路应用,还有在直流斩波电路、蜂鸣器驱动、电机驱动、逆变电路、加湿机雾化量等都会有应用。

在STM32的通用定时器中有两个重要的寄存器:

  • ARR(Auto-reload register,自动重装载寄存器)是个16位的寄存器,这里面装着计数器能计数的最大数值。如果使能了中断,当计数到达这个值时定时器就产生溢出中断;
  • CCR(Capture/Compare Registers,捕获/比较寄存器), CCR与定时器的值进行比较:如果CCR大则输出低电平,反之则输出高电平。通过改变CCR值可以改变PWM的占空比;

7- 配置蜂鸣器

首先配置使能TIM2,让Channel2输出PWM。这时PA1管脚的状态就被设置成TIM2_CH2功能模式了。

stm32 cubemx adc过采样_单片机_09

因为PWM会输出高低电平,接着设置GPIO下拉防止蜂鸣器误发声音。

stm32 cubemx adc过采样_stm32_10

配置预分频:
TIM2的输入时钟为APB1时钟80MHz,这个速率对定时器来说实在太快,这时需要对它做个预分频: CK_CNT = TIMxCLK/(PSC+1)=80MHz/(80-1+1)=1MHz

配置PWM时钟:
通过TIM2定时器的ARR(自动重装载寄存)的值可以调整PWM的输出频率,这里想让蜂鸣器工作在2.7KHz,则: ARR=1MHz/2700 约等于 370

配置占空比:

这里我们设置占空比为50%,则Pulse=370/2=185

stm32 cubemx adc过采样_stm32 cubemx adc过采样_11

Ctrl+s生成代码。


8- 添加代码

修改tim.c文件,添加蜂鸣器操作函数beep_start()实现,其中times为蜂鸣器响几次,而interval 为响、停的时间间隔。

/* USER CODE BEGIN 1 */
void beep_start(uint8_t times, uint16_t interval)
{
	while(times--)
	{
		if(HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2) != HAL_OK)
		{
			Error_Handler();
		}
		HAL_Delay(interval);
		if(HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_2) != HAL_OK)
		{
			Error_Handler();
		}
		HAL_Delay(interval);
	}
}
/* USER CODE END 1 */

修改tim.h,添加蜂鸣器操作函数的声明。

/* USER CODE BEGIN Includes */
void beep_start(uint8_t times, uint16_t interval);
/* USER CODE END Includes */

main.c函数中调用 beep_start(2, 300);

/* USER CODE BEGIN WHILE */
  /*响两次,间隔300毫秒*/
  beep_start(2, 300);
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    /*这一部分为ADC采样的例子*/
	  adc_sample_lux_noisy(&lux, &noisy);
	  printf("Lux:[%lu] Noisy[%lu]\r\n", lux, noisy);
	  HAL_Delay(500);

  }
  /* USER CODE END 3 */

运行测试之后会听见开发板滴滴叫两声。