那么,既然知道是哪个定时器控制PA8接口了,接下来的问题自然就是调节定时器1通道1的PWM输出频率和占空比,我们都知道,蜂鸣器发出声音的高低阶效果不同,取决于PWM,占空比改变的效果可以忽略不计(除了占空比0%值,占空比0%即意味着恒定的低电平,蜂鸣器不发出声音),定时器1配置如下:
void
tiM1_Init(int per)
{
__HAL_RCC_TIM1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
htim1.Instance = TIM1;
htim1.Init.Prescaler =7200;
//72000000
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period=per;
htim1.Init.ClockDivision = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
HAL_TIM_PWM_Init(&htim1);
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig);
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 50;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_PWM_ConfigChannel(&htim1,&sConfigOC, TIM_CHANNEL_1);
HAL_TIM_OC_ConfigChannel(&htim1,&sConfigOC, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);
HAL_TIM_OC_Start(&htim1,TIM_CHANNEL_1);
}
占空比计数值(Period)设置为100,OC比较输出模式为模式1,即定时器的CCR1值在0~100之间变化,与占空比正相关且等比例,此设置与第一帖中操作RGB灯亮度的操作完全相同,占空比为0时灯灭,占空比为100时灯最亮。然后就是定时器1通道1的输出频率了,这个输出频率取决于定时器1的分频数值(Prescaler)和分频系数ClockDivision,当ClockDivision设置为0时,系统时钟除以分频即systemclock/Prescaler值就是PWM输出频率,因此分频值越大输出频率越低,经过实际测试,Prescaler=48时,蜂鸣器输出频率为人耳分辨频率上限,Prescaler=720000之后人耳无法分辨低频音,所以Prescaler可以取48~720000之间的值,当然这个范围不是每个数值都是值得取的,分频值越高,蜂鸣器变化的声音就越不明显,声音也会变得冗长难听,即分频数值与声音感官感受并非等比例变化,数值越大变化越不敏感,所以分频数值的设置,应该是用粗调+微调两条刻度尺的结合算法进行,由此,一个控制界面的成形了:
蜂鸣器PWM分频值P=粗调尺*100+微调尺,粗调尺范围为0~50,微调尺范围为48~148,因此分频值变化就在48~5148之间,蜂鸣器频率f=72000000/P。
开发板与电脑直接通过CH340模块进行串口
通信,因此电脑对开发板的控制代码极为简单:
void UART1_DMA_Get()
{
int i;
if(recv_end_flag==1)
{
recv_end_flag=0;
if(rx_buf[0]==0x01&&rx_buf[7]==0x0d)
{
TIM2->CCR1=rx_buf[1]*2.5;
TIM2->CCR2=rx_buf[2]*2.5;
TIM2->CCR3=rx_buf[3]*2.5;
TIM1->PSC=rx_buf[4]*100+rx_buf[5]+48;
TIM1->CCR1=rx_buf[6];
}
for(i=0;i
rx_buf
=0;
}
HAL_UART_Receive_DMA(&huart1,(uint8_t*)rx_buf,BUFFERSIZE);
}
看看效果:
上传开发板工程文件:
上传上位机:
`