- 打开systic
- 生成工程
- 编译查看是否有问题
- 同时打开对应需要的文档
修改名称的要求
5.简单浏览赛题
选择题,跟单片机有关的可以查相关手册
- 答题顺序
先从显示开始看
1,2
- 所以先打开PA1的定时器这次选TIM2
从模式、TI2FP2二通道、内部时钟、1通道设为直接2通道设置为间接、通道配置为:间接通道1设置为下降沿,直接通道设置为上升沿
所以先打开PA7的定时器这次选TIM17_CH1
3后续再看
4 先在产品手册找到R37
检测一下J11跳线帽是否在,需要是连上的
定时器配置及参数扫描
选择单边模式
参数配置
连续不需要,用程序驱动就可以
配置过采样、使能过采样,3bit,方便滤波,采样时间,防止程序卡死
6、通过按键完成界面切换、参数设置等功能
按键配置
Led配置
PD2设置默认为低电平
生成文件---10ms定时器用与按键使用
3.3显示界面
- 实时数据界面
- 报警参数界面
- 报警统计界面
4)回放设置界面
3.6 按键功能
3) B3:定义为“加”按键。 ① 在报警参数界面下,按下 B3 按键: 若当前选择的是频率上限参数(FH),FH 值加 1000Hz。 若当前选择的是电压上限参数(AH),AH 值加 0.3V。 若当前选择的是温度上限参数(TH),TH 值加 1℃。 ② 在回放设置界面下,按下 B3 按键: 若当前选择的是脉冲信号回放分频系数(FP),FP 值加 1。 若当前选择的是电压信号回放最小值(VP),VP 值加 0.3V。 若当前选择的是记录回放时间(TT),TT 值加 2 秒。 ③ 在实时数据界面下,按下 B3 按键: 若设备已经完成了数据记录,则通过 PA7 引脚回放“电压信号”。
4) B4:定义为“减”按键。 ① 在报警参数界面下,按下 B4 按键: 若当前选择的是频率上限参数(FH),FH 值减 1000Hz。 若当前选择的是电压上限参数(AH),AH 值减 0.3V。 若当前选择的是温度上限参数(TH),TH 值减 1℃。 ② 在回放设置界面下,按下 B4 按键: 若当前选择的是脉冲信号回放分频系数(FP),FP 值减 1。 若当前选择的是电压信号回放最小值(VP),VP 值减 0.3V。 若当前选择的是记录回放时间(TT),TT 值减 2 秒。 ③ 在实时数据界面下,按下 B4 按键: 若设备已经完成了数据记录,则通过 PA7 引脚回放“脉冲信号”。
5) B3、B4。 在任何一个界面下,所检测到 B3、B4 按键均处于按下状态,且持续时间超- 6 - 过 2 秒,设备回到初始状态。(4. 初始状态说明) 6) 通用按键要求: l 按键应进行有效的防抖处理,避免出现一次按键动作触发多次功能等 情形。 l 按键动作不应影响数据采集过程和屏幕显示效果。 l 有效区分长、短按键功能,互不影响。 l 参数调整应考虑边界值,不出现无效参数。 l 当前界面下无功能的按键按下,不触发其它界面的功能。
这里灯
LED处理完之后再写
要求基本符合
验证
没问题的功能标绿,
有问题的标绿
后半场难点
初值随便设置,在程序中也能更改
案例程序
extern struct Bkeys bkey[];
uint8_t led_sta=0x00;
char text[30];
float DS_temp;
int frq=0;
int duty=0;
float adc_data_PB15;
uint32_t time100ms;
uint8_t view=0;
uint16_t FN,AN,TN;//频率报警次数(FN)、电压报警次数(AN)和温度报警次数(TN)。
uint16_t FH=2000,TH=30;//频率上限参数\温度上限参数
float AH=3.0f;//电压上限参数
uint16_t FP=1,TT=6;//脉冲信号回放分频系数、记录回放时间
float VP=0.9;//电压信号回放最小值
int16_t FH_t=2000,TH_t=30;//频率上限参数\温度上限参数 临时显示
float AH_t=3.0f;//电压上限参数 临时显示
uint16_t FP_t=1,TT_t=6;//脉冲信号回放分频系数、记录回放时间 临时显示
float VP_t=0.9;//电压信号回放最小值 临时显示
uint8_t para_sel;//按键参数选择
uint8_t rec_en;//记录使能
uint8_t is_rec;//已记录数据
uint8_t replay_V_en;//回放电压使能
uint8_t replay_PWM_en;//回放电压使能
#define rec_maxLen 1000
float rec_V[rec_maxLen];
uint16_t rec_frq[rec_maxLen];
uint8_t rec_duty[rec_maxLen];
uint16_t rec_pointer;//当前记录的数组下标
uint16_t rec_interval;//每两个数之间的时间间隔
void LED_Disp(uint8_t 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);
}
void LED_Chg(uint8_t num,uint8_t sta)
{
uint8_t pos=0x01<<(num-1);
led_sta=(led_sta&(~pos))|(pos*sta);
LED_Disp(led_sta);
}
float adc_read_os(ADC_HandleTypeDef *hadc)
{
//定义两个变量一个接收传回值,最后一个接收经过处理的函数
uint16_t adc_val;
float adc_f;
HAL_ADC_Start(hadc);
adc_val=HAL_ADC_GetValue(hadc);
adc_f=adc_val*3.3f/65536.0f;
return adc_f;
}
void LCD_Show(void)
{
if(view==0)//实时数据界面
{
sprintf(text," DATA ");
LCD_DisplayStringLine(Line1,(uint8_t *)text);
sprintf(text," F=%d ",frq);//输入到 PA1 引脚的信号频率
LCD_DisplayStringLine(Line3,(uint8_t *)text);
sprintf(text," D=%d%% ",duty);//占空比
LCD_DisplayStringLine(Line4,(uint8_t *)text);
sprintf(text," A=%.1f ",adc_data_PB15);//电位器 R37 输出的实时电压值
LCD_DisplayStringLine(Line5,(uint8_t *)text);
sprintf(text," T=%.1f ",DS_temp);//采集到的环境温度值(T)
LCD_DisplayStringLine(Line6,(uint8_t *)text);
}
if(view==1)//报警参数界面
{
sprintf(text," PARA ");
LCD_DisplayStringLine(Line1,(uint8_t *)text);
sprintf(text," FH=%d ",FH_t);//频率上限参数
LCD_DisplayStringLine(Line3,(uint8_t *)text);
sprintf(text," AH=%.1f ",AH_t);//电压上限参数
LCD_DisplayStringLine(Line4,(uint8_t *)text);
sprintf(text," TH=%d ",TH_t);//温度上限参数
LCD_DisplayStringLine(Line5,(uint8_t *)text);
}
if(view==2)// 报警统计界面
{
sprintf(text," RECD ");
LCD_DisplayStringLine(Line1,(uint8_t *)text);
sprintf(text," FN=%d ",FN);//频率报警次数
LCD_DisplayStringLine(Line3,(uint8_t *)text);
sprintf(text," AN=%d ",AN);//电压报警次数
LCD_DisplayStringLine(Line4,(uint8_t *)text);
sprintf(text," TN=%d ",TN);//温度报警次数
LCD_DisplayStringLine(Line5,(uint8_t *)text);
}
if(view==3)// 回放设置界面
{
sprintf(text," FSET ");
LCD_DisplayStringLine(Line1,(uint8_t *)text);
sprintf(text," FP=%d ",FP_t);//脉冲信号回放分频系数
LCD_DisplayStringLine(Line3,(uint8_t *)text);
sprintf(text," VP=%.1f ",VP_t);//电压信号回放最小值
LCD_DisplayStringLine(Line4,(uint8_t *)text);
sprintf(text," TT=%d ",TT_t);// 记录回放时间
LCD_DisplayStringLine(Line5,(uint8_t *)text);
}
}
void key_proc()
{
if(bkey[1].short_flag==1)
{
view++;
if(view>3)view=0;
LCD_Clear(Black);
para_sel=0;
if(view==2)//生效
{
FH=FH_t;
AH=AH_t;
TH=TH_t;
}
if(view==0)
{
FP=FP_t;
VP=VP_t;
TT=TT_t;
}
bkey[1].short_flag=0;
}
if(bkey[2].short_flag==1)
{
if(view==0)
{
rec_en=1;
rec_interval=(TT*1000)/rec_maxLen;
rec_pointer=0;
for(int i=0;i<rec_maxLen;i++)
{
rec_V[i]=0;
rec_frq[i]=0;
rec_duty[i]=0;
}
}
if(view==1||view==3)
{
para_sel++;
if(para_sel>2)para_sel=0;
}
if(view==2) FN=AN=TN=0;
bkey[2].short_flag=0;
}
if(bkey[3].short_flag==1)
{
if(view==1)
{
if(para_sel==0)FH_t+=1000;
else if(para_sel==1)AH_t+=0.3f;
else if(para_sel==2)TH_t+=1;
if(FH_t>10000)FH_t=10000;
if(AH_t>3.3f)AH_t=3.3f;
if(TH_t>80)TH_t=80;
}
if(view==3)
{
if(para_sel==0)FP_t+=1;
else if(para_sel==1)VP_t+=0.3f;
else if(para_sel==2)TT_t+=2;
if(FP_t>10)FP_t=10;
if(VP_t>3.3f)VP_t=3.3f;
if(TT_t>10)TT_t=10;
}
if(view==0&&is_rec==1)
{
replay_V_en=1;
HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);
rec_pointer=0;
}
bkey[3].short_flag=0;
}
if(bkey[4].short_flag==1)
{
if(view==1)
{
if(para_sel==0)FH_t-=1000;
else if(para_sel==1)AH_t-=0.3f;
else if(para_sel==2)TH_t-=1;
if(FH_t<1000)FH_t=1000;
if(AH_t<0.0f)AH_t=0.0f;
if(TH_t<0)TH_t=0;
}
if(view==3)
{
if(para_sel==0)FP_t-=1;
else if(para_sel==1)VP_t-=0.3f;
else if(para_sel==2)TT_t-=2;
if(FP_t<1)FP_t=1;
if(VP_t<0.0f)VP_t=0.0f;
if(TT_t<2)TT_t=2;
}
if(view==0&&is_rec==1)
{
replay_PWM_en=1;
HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);
rec_pointer=0;
}
bkey[4].short_flag=0;
}
static uint8_t Llong=0;
if(bkey[5].long_flag==1)
{
if(Llong==0)
{
FN=AN=TN=0;//频率报警次数(FN)、电压报警次数(AN)和温度报警次数(TN)。
FH=2000;TH=30;//频率上限参数\温度上限参数
AH=3.0f;//电压上限参数
FP=1;TT=6;//脉冲信号回放分频系数、记录回放时间
VP=0.9;//电压信号回放最小值
view=0;
is_rec=0;
replay_V_en=0;//回放电压使能
replay_PWM_en=0;//回放电压使能
FH_t=2000;TH_t=30;//频率上限参数\温度上限参数
AH_t=3.0f;//电压上限参数
FP_t=1;TT_t=6;//脉冲信号回放分频系数、记录回放时间
VP_t=0.9;//电压信号回放最小值
Llong=1;
}
bkey[3].short_flag=0;bkey[4].short_flag=0;
}
else Llong=0;
}
void LED_proc()
{
if(uwTick-time100ms>100)
{
static uint8_t blink=0;
blink=!blink;
if(rec_en) LED_Chg(1,blink);
else LED_Chg(1,0);
if(replay_PWM_en) LED_Chg(2,blink);
else LED_Chg(2,0);
if(replay_V_en) LED_Chg(3,blink);
else LED_Chg(3,0);
time100ms=uwTick;
}
if(frq>FH) LED_Chg(4,1);
else LED_Chg(4,0);
if(adc_data_PB15>AH) LED_Chg(5,1);
else LED_Chg(5,0);
if(DS_temp>TH) LED_Chg(6,1);
else LED_Chg(6,0);
}
void alarm_proc()
{
static uint8_t LF=0,LA=0,LT=0;
if(frq>FH)
{
if(LF==0)
{
FN++;
LF=1;
}
}
else LF=0;
if(adc_data_PB15>AH)
{
if(LA==0)
{
AN++;
LA=1;
}
}
else LA=0;
if(DS_temp>TH)
{
if(LT==0)
{
TN++;
LT=1;
}
}
else LT=0;
}
void rec_proc()
{
adc_data_PB15=adc_read_os(&hadc2);
frq=1000000.0f/(HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2)+1);
duty=((HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1)+1)*100.0f/((HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2)+1)));
static uint16_t time_inv=0;
if(rec_en==1)
{
if(time_inv>=rec_interval)
{
rec_V[rec_pointer]=adc_data_PB15;
rec_frq[rec_pointer]=frq;
rec_duty[rec_pointer]=duty;
rec_pointer++;
time_inv=0;
if(rec_pointer>=rec_maxLen)
{
rec_en=0;
is_rec=1;
}
}
time_inv++;
}
}
void replay_proc()
{
static uint16_t time_inv=0;
if(replay_PWM_en==1)
{
if(time_inv>=rec_interval)
{
__HAL_TIM_SET_AUTORELOAD(&htim17,(10000000/(rec_frq[rec_pointer]/FP))-1);
__HAL_TIM_SET_COMPARE(&htim17,TIM_CHANNEL_1,((10000000/(rec_frq[rec_pointer]/FP))-1)*(rec_duty[rec_pointer]/100.0f));
rec_pointer++;
time_inv=0;
if(rec_pointer>=rec_maxLen)
{
HAL_TIM_PWM_Stop(&htim17,TIM_CHANNEL_1);
replay_PWM_en=0;
}
}
time_inv++;
}
if(replay_V_en==1)
{
__HAL_TIM_SetAutoreload(&htim17,10000-1);
if(time_inv>=rec_interval)
{
uint16_t duty_temp;
if(rec_V[rec_pointer]<VP)duty_temp=1000;
else if(rec_V[rec_pointer]>3.3f)duty_temp=10000;
else duty_temp=10000*((0.9f/(3.3f-VP))*(rec_V[rec_pointer]-3.3f)+1);
__HAL_TIM_SET_COMPARE(&htim17,TIM_CHANNEL_1,duty_temp);
rec_pointer++;
time_inv=0;
if(rec_pointer>=rec_maxLen)
{
HAL_TIM_PWM_Stop(&htim17,TIM_CHANNEL_1);
replay_V_en=0;
}
}
time_inv++;
}
}
void setup()
{
HAL_TIM_Base_Start_IT(&htim6);
//TIM2_CH2输入 PA1
HAL_TIM_IC_Start(&htim2,TIM_CHANNEL_1);
HAL_TIM_IC_Start(&htim2,TIM_CHANNEL_2);
HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED);
LED_Disp(0x00);//关掉所有LED
LCD_Init();//LCD初始化
LCD_Clear(Black);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
ds18b20_init_x();
time100ms=uwTick;
}
void loop()
{
LCD_Show();
key_proc();
LED_proc();
alarm_proc();
DS_temp=ds18b20_read();
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM6)
if(rec_en==0)key_serv_long();
}
----------------------------key------------------------------------------------
#include "key.h"
struct Bkeys bkey[6]={0,0,0,0};
uint8_t key_read()
{
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==0&&HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==0)return 5;
else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==0) return 1;
else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0) return 2;
else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==0) return 3;
else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==0) return 4;
else return 0;
}
/*长按快速增加功能*/
void key_serv_long()
{
uint8_t key_sta=key_read();
if(key_sta!=0)
{
bkey[key_sta].age++;
if(bkey[key_sta].age>1) bkey[key_sta].press=1;
}
else
{
for(int i=0;i<6;i++)
{
if(bkey[i].press==1&&bkey[i].long_flag==0)
bkey[i].short_flag=1;
bkey[i].age=0;
bkey[i].press=0;
bkey[i].long_flag=0;
}
}
if(bkey[key_sta].age>199) bkey[key_sta].long_flag=1;
}
/------------------------stm32g4xx_it------------------------/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
rec_proc();
replay_proc();
/* USER CODE END SysTick_IRQn 1 */
}