题目
CubeMX配置
引脚配置
ADC2(PB15)配置
题目中要求使用R37电位器,将PB15配置为ADC2_IN15
输入捕获(PA1配置)
PA1对应TIM2->CH2,将TIM2->CH2配置为直接输入捕获模式即可
脉冲输出(PA7)
PA7使用TIM17->CH1,打开PWM Generation CH1即可
代码实现
初始化
//led:
void led_disp(uchar dsled)
{
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC,dsled<<8,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
//key:
struct keys{
unsigned char judge_sta;//判断进程
bool key_sta;//按键进程
bool single_flag; //判断按键是否按下
unsigned int key_time;//判断按下时间
};
struct keys key[4]={0,0,0,0};
void HAL_TIM_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(GPIOA,GPIO_PIN_0);
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;
key[i].single_flag=1;
}
else
key[i].judge_sta=0;
}
break;
case 2:
{
if(key[i].key_sta==1)
key[i].judge_sta=0;
}
break;
}
}
}
}
//adc:
double getADC(ADC_HandleTypeDef *pin)
{
uint adc;
HAL_ADC_Start(pin);
adc=HAL_ADC_GetValue(pin);
return adc*3.3/4096;
}
//输入捕获(PA1)
double ccr1_vala=0,ccr1_valb=0;
uint frq1=0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM2)
{
if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_2)//中断源选择直接输入的通道
{
ccr1_vala=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_2)+1;
__HAL_TIM_SetCounter(htim,0);//计时值清零
frq1=(80000000/80)/ccr1_vala;
HAL_TIM_IC_Start(htim,TIM_CHANNEL_2);
}
}
}
按键功能
//key按键函数key_pro
void key_pro(){
//B1标志位为1切换界面并重置标志位
if(key[0].single_flag==1){
view=!view;
LCD_Clear(Black);
key[0].single_flag=0;
}
//初始界面为数据界面(view=1),数据界面时B2,B3失效
if(view==1){
key[1].single_flag=0;
key[2].single_flag=0;
}
//在参数界面(view=0)时按下B2,R增加2
if(view==0&&key[1].single_flag==1&&R<=8){
R+=2;
LCD_Clear(Black);
key[1].single_flag=0;
}
if(R>=10) key[1].single_flag=0;
if(R<=2) key[2].single_flag=0;
//在参数界面(view=0)时按下B3,R减少2
if(view==0&&key[2].single_flag==1&&R>=4){
R-=2;
LCD_Clear(Black);
key[2].single_flag=0;
}
}
LCD显示
//lcd显示函数disp_pro
void disp_pro(){
//数据界面(view=1)
if(view==1){
LCD_DisplayStringLine(Line1, (uchar *)" Data");
sprintf(text," FRQ:%dHz",frq1);
LCD_DisplayStringLine(Line3, (uint8_t *)text);
sprintf(text," R37:%.2fV",getADC(&hadc2));
LCD_DisplayStringLine(Line5, (uint8_t *)text);
}
//参数界面(view=0)
if(view==0){
LCD_DisplayStringLine(Line1, (uchar *)" Para:");
sprintf(text," R:%d",R);
LCD_DisplayStringLine(Line3, (uint8_t *)text);
}
}
LED显示
//led显示函数led_proc
void led_pro()
{
double VR37=getADC(&hadc2);
//led_times用于B4按键的开关灯,初始led_times=1
if(led_times==1)
{
//数据界面
if(view==1)
{
if(VR37<1|VR37>=3)
{
if(frq1<1000|frq1>=5000)
led_disp(0x01);
if(frq1>=1000&&frq1<5000)
led_disp(0x09);
}
if(VR37>=1&&VR37<3)
{
if(frq1<1000|frq1>=5000)
led_disp(0x05);
if(frq1>=1000&&frq1<5000)
led_disp(0x0d);
}
}
//参数界面
if(view==0)
{
if(VR37<1|VR37>=3)
{
if(frq1<1000|frq1>=5000)
led_disp(0x02);
if(frq1>=1000&&frq1<5000)
led_disp(0x0a);
}
if(VR37>=1&&VR37<3)
{
if(frq1<1000|frq1>=5000)
led_disp(0x06);
if(frq1>=1000&&frq1<5000)
led_disp(0x0e);
}
}
//在led_times=1时按下B4按键,led_times变为2且重置标志位
if(key[3].single_flag==1)
{
led_times=2;
key[3].single_flag=0;
}
}
//led_times=2时关闭所有led
if(led_times==2)
{
led_disp(0x00);
//再次按下B4按键回到led_times=1并重置标志位
if(key[3].single_flag==1)
{
led_times=1;
key[3].single_flag=0;
}
}
}
脉冲输出
//脉冲输出函数pa7_Control
void pa7_Control(void){
pa7_frq = ccr1_vala * R;
htim17.Init.Period = pa7_frq;
HAL_TIM_Base_Init(&htim17);
pa7_duty = pa7_frq *getADC(&hadc2)/3.30;
__HAL_TIM_SET_COMPARE(&htim17,TIM_CHANNEL_1,pa7_duty);
}
注意事项
HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);
HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_2);//直接测量捕获
HAL_TIM_Base_Start_IT(&htim2);
HAL_TIM_Base_Start_IT(&htim4);
__HAL_TIM_SetCompare(&htim17,TIM_CHANNEL_1,pa7_duty);//设置初始pwm频率
主函数
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
led_pro();//led显示函数
key_pro();//key按键功能
disp_pro();//lcd显示函数
pa7_Control();//pa7脉冲输出
}
/* USER CODE END 3 */