1.(定时器) 假设定时器内部时钟为16MHz,(1)完成下面的注释。(2)可以定时的时间为(5)ms。
htim3.Instance = TIM3;
htim3.Init.Prescaler = 799; //预分频系数为799
htim3.Init.CounterMode = TIM_COUNTERMODE_UP; //向上计数器
htim3.Init.Period = 99; //自动重载值为99
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
定时的时间=(799+1)*(99+1)/16=5000us=5ms
2.(GPIO口)请对其作出注释。
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct; //定义GPIO结构体变量
__HAL_RCC_GPIOB_CLK_ENABLE(); //总线时钟使能
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2,GPIO_PIN_RESET) //向PC2引脚输出低电平
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; //(GPIO的工作模式为)推挽输出
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; //低速输出
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
3.(串口)(1)完成下面的注释。(2)分析该程序实现的功能。(串口通信)
uint8_t Tx_str1[]="Welcome \r\n";
uint8_t Tx_str2[]="LED1 ON! \r\n";
uint8_t Tx_str3[]="LED1 OFF! \r\n";
uint8_t Tx_str4[]="COMMAND not found! \r\n";
uint8_t rx_dat=0;//定义接收的数据为signed char型,并赋初始值为0。
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)(串口回调函数)
{
if(huart==&huart1) //判断是否为串口1
{switch(rx_dat) //选择判断接收的数据
{
case 0x01:HAL_UART_Transmit(&huart1,Tx_str1sizeof(Tx_str1,1000); break; //若接收到的数据为0x01,向上位机发送“Welcome”,后跳出循环
case 0x02: HAL_UART_Transmit(&huart1,Tx_str2,sizeof(Tx_str2),1000); break;
case 0x03 :HAL_UART_Transmit(&huart1,Tx_str2,sizeof(Tx_str3,1000); break;
default: HAL_UART_Transmit(&huart1,Tx_str2,sizeof(Tx_str4,1000); break;
}}
4.(中断)完成下面的注释。
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pins : PC0 PC2 */
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_2; //选中PC0,PC2引脚
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; //具有下降边缘触发检测的外部中断模式
GPIO_InitStruct.Pull = GPIO_NOPULL; //没有上拉或下拉电阻
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI0_IRQn, 1, 0); //配置EXTI0_IRQn中断,抢先优先级1,响应优先级0
HAL_NVIC_EnableIRQ(EXTI0_IRQn); //使能中断通道EXTI0_IRQn
HAL_NVIC_SetPriority(EXTI2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI2_IRQn);
}
5.(定时器输出PWM)阅读下面的程序,简述其实现的功能,假设定时器内部时钟频率为8MHz。
static void MX_TIM3_Init(void) //定时器3初始化
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
htim3.Instance = TIM3;
htim3.Init.Prescaler = 7999;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 1000;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 500;//脉冲值
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_MspPostInit(&htim3);
}
功能:将PWM配置为周期为1000个定时器周期,高电平持续时间为500个定时器时钟周期,输出信号占空比为500/1000=50%,每个定时器周期为1us。
一个定时器周期:(T=8000/8Mhz=1us)
占空比:500/1000=50%(Pulse /Period )
6.阅读下面的程序,写出注释,并简述其实现的功能。
已知PC10和PC11连接的是直流电机的输入引脚,rf为串行通信的标志位,cmpv为PWM输出信号的占空比。
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) //(中断回调函数)
{
if(GPIO_Pin==GPIO_PIN_0)
//若GPIO_Pin测试等于GPIO_PIN_0(若GPIO_PIN_0按键按下)
{
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_11,GPIO_PIN_RESET);
}else if(GPIO_Pin==GPIO_PIN_2)
{
if(cmpv<100)
cmpv=cmpv+10; //占空比在原有基础上加10
__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_4,cmpv);
//设置定时器3通道4的PWM输出占空比
}
else if(GPIO_Pin==GPIO_PIN_3)
{
if(cmpv>0)
cmpv=cmpv-10;
__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_4,cmpv);
}else if(GPIO_Pin==GPIO_PIN_4)
{
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_11|GPIO_PIN_10,GPIO_PIN_RESET);
//设置PC10,PC11输出低电平
}}
功能:控制电机转速。(若GPIO_Pin==GPIO_PIN_0,电机转动;若GPIO_Pin==GPIO_PIN_2,占空比在原有基础上加10;若GPIO_Pin==GPIO_PIN_3,占空比在原有基础上减10;若GPIO_Pin==GPIO_PIN_4,电机停止转动)