一.LED
先配置LED的八个引脚为GPIO_OutPut,锁存器PD2也是,然后都设置为起始高电平,生成代码时还要去解决引脚冲突问题
二.按键
按键配置,由原理图按键所对引脚要GPIO_Input
生成代码,在文件夹中添加code文件夹,code中添加fun.c、fun.h、headfile.h文件,去资源包中把lcd.c、lcd.h、fonts.h添加到code中,然后去写按键控制灯亮灭的程序,看是否有问题
三.LCD显示函数
按键控制led没有问题后写lcd显示代码,显示没问题后,解决lcd与led引脚冲突问题,方法在我的 CSDN文章中
HAL_GPIO_WritePin (GPIOD,GPIO_PIN_2,GPIO_PIN_RESET ); //为解决引脚冲突初始化lcd时 LCD_Init (); 要将锁存器锁存器来;
LCD_Clear (Black);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
void lcd_show(void)
{
sprintf(text," hello world");
LCD_DisplayStringLine (Line0 ,(uint8_t *)text);
}
根据题目要求我们要配置PA1PWM输出,PA7脉冲捕获,模拟输入等,先对其进行基本的配置,就是能实现这些功能后再去现在具体的功能。
四.PA1PWM输出低频要求配置
初始状态要求PWM输出模式为低频模式,所以我们先配置低频的要求,这时候我们再去看低频模式有什么要求
低频要求输出信号为4000HZ,根据这个要求去计算相关参数如何配置,注意到下方要求频率5s内均匀升高和降低,配置的时候也要考虑到这个问题
配置相关参数分析如下
TIM2_CH2用于输出PWM,初始化的时候为低频(4000HZ),配置的时候TIM的频率就需要为4000HZ。假设的时间100ms也可以是10ms或者1s只要符合要求都行,这个是到时候频率变换要配置的;
配置PA1引脚输出PWM,这个不用开启中断,生成代码添加tim.h文件,main中开定时器 HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
在main总配置一下占空比,TIM2->CCR2=50; ccr/(arr+1)=占空比
此时PA1输出功能现实了,我们要去配置PA7脉冲捕获功能,通过这个来判断我们设置的初始模式是否为输出4000HZ的低频模式
五.PA7脉冲捕获功能配置(含)
脉冲捕获使用PWM输入捕获测量比较准确,也可以使用其他方法如这篇文章中的CSDN
配置引脚
这个要开启定时器中断,main中启动 HAL_TIM_IC_Start_IT(&htim3 ,TIM_CHANNEL_2);
写输入捕获函数
在tim.h中找到输入捕获回调函数void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
功能语句
}
加一是因为少了一个周期,加一可以使得测量更精确,记得将PA7与PA1用杜邦线连接起来
六.高频与低频之间的转换
上面内容完成之后就把功能部分全配置了,现在去写高频与低频之间的转换。
题目要求是5s内均匀的变化,这就需要定时器计时,所以要求配置一个定时器,定时时间按上面假设的100ms定时。定时器是要开中断的
main中 HAL_TIM_Base_Start_IT(&htim4);
然后找到定时器回调函数写定时器代码
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
检测代码,先检测一下是否好用
}
检测没有问题后我们进行低频与高频的转换
根据下面的计算公式知道,频率的大小是与PSC,ARR有关。我们就通过改变ARR的值来现实频率转换。这里要插入ARR相关知识。
*(重点)ARR知识点
Auto-reload preload (ARRin)是什么?
功能定义:
定时器的 ARR (Auto-Reload Register)是决定PWM周期(频率)的关键寄存器。当启用 Auto-reload preload 时,对ARR的修改不会立即生效,而是会等到当前计数周期结束后(即 发 生 更新事件时)才会加载新的ARR值。这确保了在修改ARR时不会打断当前周期的计数。
作用:
避免在定时器运行时直接修改ARR导致的计数混乱或PWM输出异常(如停止输出、占空比错 误 等)。
启用ARR预装载后的行为:
当你通过CubeMX启用此功能后,任何对ARR的修改都会暂存在一个“缓冲寄存器“中,只有当 下 一个更新事件(如计数器溢出)发生时,新的ARR值才会生效。这保证了:
计数器完整完成当前周期。
ARR和CCR的修改是同步的。
1. 计数器与ARR冲突:
如果当前计数器值(TIN2->CNT)已经超过新设置的ARR值,定时器会立即触发更新事件,导 致周期异常。
2. 硬件状态不一致:
直接修改ARR可能与其他寄存器(如CCR)的更新不同步,导致PWM输出停止。
根据上面的内容我们知道,要改变ARR的值又要不影响PWM输出就要采用两种方法中的一种 解决
第一个:在代码上改变ARR时让CNT=0;
第二个:启用ARR预装载,在配置的定时器设置哪里打开
5秒内按键不起作用代码
解决ARR的问题后写代码
七.输出占空比的电压调节
先配置ADC功,然后写ADC转换电压函数,再写电压转换占空比函数
题目要求用R37调节,手册里找到R37对应的引脚是PB15去配置PB15。
电压测量的配置讲解我的文章创作中心-CSDN 有详细教程,不会的伙伴可以查看
写好代码区测是否好用
由图知道0~1v时占空比为10%,3v以上为85%,10%~85%之间线性增加,这需要一个线性方程,求解过程如下
根据占空比转换公式与关系图区写一个转换函数,之前设置的占空比代码就要全都删除,以后占空比就根据这个函数显示
八.测量PA7频率并转换为速度值
PA7测量频率的功能我们上面已经做好,fre为测量的频率值,现在根据题目给的公式进行转换输出就行,输出这里就要看题目data界面的显示要求。在写速度转换代码时顺便把显示的功能和参数写了。
九.显示页面
参数界面
、
统计界面
十.按键
B1按键界面切换
B2选择按键
①在数据界面下, 用于切换选择低频或高频模式。 按键按下后, 5 秒内不
可再次触发切换功能。data_fre==2的作用是在切换模式完成之前,再次按下按键不起作用
②在参数界面下,按下 B 2 按键,切换选择 R 或 K 参数 。每次从数据界面进入参数界面,默认当前可调整的参数(需要一个标志位完成) 为 R 参数 从参数界面退出时,新的 R 参数 和 K 参数生效。
B3B4加减按键
参数界面下的加减按键
数据界面下的B4按键
这里需要用到长按键,用到长按键就要判断是否松开,从按下到松开的时间是否大于两秒。长按键使用定时器来定时所需的时间长度,用两个标志位为共同完成长按键。uint8_t time2s,time2sstart(用于开启定时器),定时器我们之前配置的时候是0.1s。
十一.锁定占空比(难点)
这里2s长按键判断就写好了,接下来写长按键2s后的空能语句也就是锁定占空比
十二. 统计功能(难点)
1.低频模式、高频模式切换次数 N 。,只要在数据界面下按下B2,N就加一就行,不管从低频到高频,还是反过来都是切换了一次。
2.高频、低频输出模式下的最大速度分开统计 保持时间不足 2 秒的速度值不纳入统计 。则会也就是说在转换过程中的数据是不计入的。
由速度公式知道它的值与频率、R K有关,而频率只有在模式转换的过程中才会改变,这时速度的值是维持不了2s的,所以这里记录的最大值就是,P K变化带来的。
HAL_GetTick()函数
HAL_GetTick()函数是STM32 HAL库中的一个重要函数,主要用于获取系统自启动以来的毫秒级时间戳。该函数基于SysTick中断实现,每当SysTick定时器定时中断时,全局变量uwTick会自增1ms,因此通过读取uwTick的值,HAL_GetTick()能够返回自系统启动以来经过的毫秒数1。
应用场景
- 时间延迟:通过HAL_GetTick()函数可以实现精确的时间延迟功能,适用于需要等待特定时间后再执行操作的场景。
- 任务调度:在任务调度中,HAL_GetTick()可以用来实现基于时间的任务调度,例如每隔一定时间执行一次特定任务。
- 事件触发:在需要精确时间控制的事件触发场景中,HAL_GetTick()可以提供准确的时间戳,确保事件按照预定时间触发。
使用方法
在具体应用中,可以通过以下方式使用HAL_GetTick()函数:
- 获取当前时间:通过调用
current_tick = HAL_GetTick();
获取当前时间。 - 时间差计算:通过比较两次调用HAL_GetTick()的结果,可以计算出时间差,例如用于按键消抖等场景。
- 任务调度:定义任务执行间隔和上次运行时间,通过比较当前时间和上次运行时间来决定是否执行任务。
十三.LED指示灯
LED1
LED2
LED3