cube配置
1、定时器输出捕获
第11届第二场
引脚配置
只能用带由TIMx_CH的由于3已经被占用所以只能用16
TIM1_CHN1不能选,这是用生产互补PWM波的正常是高的时候他就是低,正常是低的时候他就是高
定时器参数配置
找到tim16使能点击activated 然后选择PWM Generation CH1
频率计算
80M=80000000
经过两次相除变成100ms
/100/8000=100 后面调占空比用的是百分制 100Hz
占空比配置
TIM17 200Hz的定时器
Pwm初始设置程序中可以更改 这里就随便设一个值
配置完之后点击生成code即可
真题案例
切换过程中要清贫操作。
程序代码
interrupt与上一节一样
/------------------------main.c--------------------------------/
/* Private includes --------*/
/* USER CODE BEGIN Includes */
#include "led.h"
#include "lcd.h"
#include "stdio.h"
#include "interrupt.h"
/* USER CODE END Includes *//* USER CODE BEGIN PTD */
void key_proc(void);//按键的过程
void disp_proc(void);//显示界面的过程extern struct keys key[];
uchar view=0;uchar pa6_duty = 10;//pwm的占空比
uchar pa7_duty = 10;/* USER CODE END PTD */
int main(void)
{LED_Disp(0x00);//LED初始化LCD_Init();//LCD初始化LCD_Clear(Black);LCD_SetBackColor(Black);LCD_SetTextColor(White);HAL_TIM_Base_Start_IT(&htim3); //定时器中断HAL_TIM_PWM_Start(&htim16,TIM_CHANNEL_1);//打开pwm的输出通道HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);//打开pwm的输通道/* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE */ /* USER CODE BEGIN 3 */key_proc();disp_proc();}/* USER CODE END 3 */
}}
设置PWM的占空比
void key_proc(void)//按键的过程
{if(key[0].single_flag ==1){view=!view;key[0].single_flag=0;}if(key[1].single_flag ==1)//按键2按下一次加10%{pa6_duty+=10;if(pa6_duty>=100) pa6_duty=10;__HAL_TIM_SetCompare(&htim16,TIM_CHANNEL_1,pa6_duty);//设置比较key[1].single_flag=0;}if(key[2].single_flag ==1&& view==1)//按键3 按下一次加10%{pa7_duty+=10;if(pa7_duty>=100) pa7_duty=10;__HAL_TIM_SetCompare(&htim17,TIM_CHANNEL_1,pa7_duty);//设置比较key[2].single_flag=0;}
}
按键设置及界面显示函数封装
void disp_proc(void)//显示界面的过程
{if(view==0){char text[30];sprintf(text," Data ");LCD_DisplayStringLine(Line2, (uint8_t *)text);} if(view==1)//参数显示界面{char text[30];sprintf(text," Para ");LCD_DisplayStringLine(Line2, (uint8_t *)text);sprintf(text," PA6:%d ",pa6_duty);LCD_DisplayStringLine(Line3, (uint8_t *)text);sprintf(text," PA7:%d ",pa7_duty);LCD_DisplayStringLine(Line4, (uint8_t *)text);}
}
实验现象展示
2、定时器输入捕获
信号发生器原理图
配置引脚
同样是CH1,带N的不能用
参数配置
模式设置
TIM2和TIM3同理
原理
模式设置
通道配置1为直接测量
通道2配置为间接测量通道二也要打开不然会有问题---PA7的占空比会显示0
通道设置为1为上升沿,通道2为下降沿
由于定时器3被按键使用过所以切换为tim4,除了在cube内配置分频系数参数外,主函数中也要加入定时器中断。
/-----------------------------interrupt.h--------------------------------------------/
#ifndef __INTERRUPT_H__
#define __INTERRUPT_H__#include "main.h"
#include "stdbool.h"
struct keys
{uchar judge_sta;bool key_sta;bool single_flag;//确认被按下他为1uint key_time; //判断按下的时间,时间比较长uchar long_flag;
};void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim);#endif
/-----------------------------interrupt.c--------------------------------------------/
key函数部分
struct keys key[4] = {0,0,0};
void HAL_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM4)
{key[0].key_sta = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);key[1].key_sta = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);key[2].key_sta = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);key[3].key_sta = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);for(int i = 0;i<4;i++)
{switch(key[i].judge_sta)
{case 0:{if(key[i].key_sta == 0)//发现按键被按下
{key[i].judge_sta=1;key[i].key_time=0;//将时间清零
}
}break;case 1:
{if(key[i].key_sta == 0)//消抖的过程里面就不能确定他短按键会与长按键冲突
{key[i].judge_sta = 2;
}else key[i].judge_sta=0;}break;case 2:
{if(key[i].judge_sta==1)
{key[i].judge_sta=0;if(key[i].key_time<70)
{key[i].single_flag = 1;
}else
{key[i].key_time++;//在他没有松开的打断时间内if(key[i].key_time>70) key[i].ling_flag = 1;
}
}
}break;case 3 :
{}break;}
}
}
}
///测量频率+占空比
double ccrl_val1a = 0,ccrl_cal2a = 0;
uint ccr1_val1b=0,ccr1_val2b=0;
uint frq1=0,frq2=0;//频率
float duty1=0,duty2=0;void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM2){if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
{ccr1_val1a=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);//计时值hal库的计时函数 直接ccr1_val1b=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);//计时值hal库的计时函数 间接__HAL_TIM_SetCounter(htim,0);frq1=(80000000/80)/ccrl_val1a;//计算频率duty1=(ccrl_val1b/ccrl_val1a)*100;HAL_TIM_IC_Start(htim,TIM_CHANNEL_1);//从新打开定时器HAL_TIM_IC_Start(htim,TIM_CHANNEL_2);
}
}if(htim->Instance==TIM3){if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)//中段消息来源 选择直接输入的通道{ccrl_val2a= HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1); //计时值hal库的计时函数 直接ccr1_val2b= HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_2); //计时值hal库的计时函数 间接__HAL_TIM_SetCounter(htim,0);//计时值清零frq2=(80000000/80)/ccrl_val2a;//计算频率duty2=(ccr1_val2b/ccrl_val2a)*100;HAL_TIM_IC_Start(htim,TIM_CHANNEL_1);//从小打开定时器HAL_TIM_IC_Start(htim,TIM_CHANNEL_2);//从小打开定时器}}
}
/--------------------------main.c-------------------------------/
定义变量
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "led.h"
#include "lcd.h"
#include "stdio.h"
#include "interrupt.h"
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
void key_proc(void);//按键的过程
void disp_proc(void);//显示界面的过程extern struct keys key[];
extern uint frq1,frq2;//计算的到的回调值
extern float duty1,duty2;
uchar view=0;uchar pa6_duty = 10;
uchar pa7_duty = 10;/* USER CODE END PTD */
主函数
int main(void)
{LED_Disp(0x00);//LED初始化LCD_Init();//LCD初始化LCD_Clear(Black);LCD_SetBackColor(Black);LCD_SetTextColor(White);HAL_TIM_Base_Start_IT(&htim4); //定时器中断HAL_TIM_PWM_Start(&htim16,TIM_CHANNEL_1);//打开pwm的输出通道HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);//打开pwm的输通道//打开定时器HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1); //定时器中断 频率测量捕获定时器开启HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1); //定时器中断/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */key_proc();disp_proc();
// LED_Disp(0x02);
// HAL_Delay(500);
// LED_Disp(0x00);
// HAL_Delay(1000);}/* USER CODE END 3 */
}
按键的过程
/* USER CODE BEGIN 4 */void key_proc(void)//按键的过程
{if(key[0].single_flag ==1){view=!view;key[0].single_flag=0;}if(key[1].single_flag ==1)//按键2按下一次加10%{pa6_duty+=10;if(pa6_duty>=100) pa6_duty=10;__HAL_TIM_SetCompare(&htim16,TIM_CHANNEL_1,pa6_duty);//设置比较key[1].single_flag=0;}if(key[2].single_flag ==1)//按键3 按下一次加10%{pa7_duty+=10;if(pa7_duty>=100) pa7_duty=10;__HAL_TIM_SetCompare(&htim17,TIM_CHANNEL_1,pa7_duty);//设置比较key[2].single_flag=0;}
}
显示界面的过程
void disp_proc(void)//显示界面的过程
{if(view==0){char text[30];sprintf(text," Data ");LCD_DisplayStringLine(Line1, (uint8_t *)text);sprintf(text," FRQ1=%d ",frq1);LCD_DisplayStringLine(Line2, (uint8_t *)text);sprintf(text," duty1=%.3f ",duty1);LCD_DisplayStringLine(Line3, (uint8_t *)text);sprintf(text," FRQ2=%d ",frq2);LCD_DisplayStringLine(Line4, (uint8_t *)text);sprintf(text," duty2=%.3f ",duty2);LCD_DisplayStringLine(Line5, (uint8_t *)text);}if(view==1)//参数显示界面{char text[30];sprintf(text," Para ");LCD_DisplayStringLine(Line1, (uint8_t *)text);sprintf(text," PA6:%d ",pa6_duty);LCD_DisplayStringLine(Line3, (uint8_t *)text);sprintf(text," PA7:%d ",pa7_duty);LCD_DisplayStringLine(Line4, (uint8_t *)text);//界面清理 sprintf(text," ");LCD_DisplayStringLine(Line2, (uint8_t *)text);sprintf(text," ");LCD_DisplayStringLine(Line5, (uint8_t *)text);}
}