一、舵机简介
舵机是一种根据输入PWM信号占空比来控制输出角度的装置。通过定时器输出比较输出PWM信号,实现舵机不太角度转动。
二、PWM
在本项目中,将舵机代替为门锁,控制舵机的转动来代替门锁开关。所以在本部分需要掌握定时器输出比较相关知识。
PWM(Pulse Width Modulation)脉冲宽度调制
在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速等领域
· TIM_TimeBaseStructure是一个结构体变量,它属于TIM_TimeBaseInitTypeDef类型,该结构体用于保存定时器的基本配置信息。
· TIM_Period是这个结构体中的一个成员,它代表定时器的自动重装值。当定时器的计数器值达到这个自动重装值时,计数器会重新从 0 开始计数。这里使用PWM_PERIOD - 1作为自动重装值,PWM_PERIOD应该是一个预先定义好的常量,减 1 是因为计数器是从 0 开始计数的。
· 自动重装值和定时器的计数频率共同决定了定时器的溢出时间,也就是定时器从 0 计数到自动重装值所花费的时间。
· IM_Prescaler是TIM_TimeBaseInitTypeDef结构体的另一个成员,用于设置定时器的预分频器值。预分频器的作用是对定时器的时钟源进行分频,降低定时器的计数频率。
· 这里将预分频器的值设置为96 - 1,假设定时器的时钟源频率是 96MHz,经过 96 分频后,定时器的计数频率就变为 1MHz,即定时器每 1 微秒(1us)计数一次。同样,减 1 是因为预分频器的值是从 0 开始计数的。
· TIM_ClockDivision成员用于设置定时器的时钟分割值。在某些情况下,定时器的一些功能(如输入捕获、输出比较等)可能需要对时钟进行进一步的分割。这里将其设置为 0,表示不进行额外的时钟分割。
· TIM_CounterMode成员用于设置定时器的计数器模式。TIM_CounterMode_Up表示计数器采用向上计数模式,即计数器的值从 0 开始,每次计数加 1,直到达到自动重装值后重新从 0 开始计数。
这段代码的主要作用是对定时器 2 进行基本配置,设置了定时器的自动重装值、预分频器、时钟分割和计数器模式,最终完成定时器的初始化。经过这样的配置,定时器 2 的计数频率为 1MHz,每 1 微秒计数一次,计数器采用向上计数模式,当计数器值达到PWM_PERIOD - 1时会重新从 0 开始计数。这种配置通常用于生成 PWM 信号、定时中断等应用场景。
· TIM_OCInitStructure是一个TIM_OCInitTypeDef类型的结构体变量,用于存储定时器输出比较(Output Compare,OC)的配置信息。
· TIM_OCMode是该结构体的一个成员,用于指定输出比较模式。这里将其设置为TIM_OCMode_PWM1,表示采用 PWM 模式 1。在 PWM 模式 1 下,当定时器计数器的值小于TIM_Pulse时,输出为高电平;当计数器的值大于等于TIM_Pulse时,输出为低电平。
· TIM_OutputState成员用于控制输出比较通道的输出状态。这里将其设置为TIM_OutputState_Enable,表示使能该通道的输出,即允许定时器在该通道输出 PWM 信号。
· TIM_Pulse成员指定了 PWM 信号的脉冲宽度。在 PWM 模式下,它决定了 PWM 信号的占空比。PWM_MIN应该是一个预先定义好的常量,代表最小的脉冲宽度,也就是初始占空比为最小值。
· TIM_OCPolarity成员用于设置输出比较信号的极性。这里将其设置为TIM_OCPolarity_High,表示当输出比较条件满足时,输出的 PWM 信号为高电平。
· TIM_ARRPreloadConfig是一个标准库函数,用于使能或禁用指定定时器的自动重装寄存器(ARR)的预装载功能。这里将定时器 2 的自动重装寄存器预装载功能使能,意味着对自动重装寄存器的写操作不会立即生效,而是在当前计数周期结束后,下一个计数周期开始时才会更新自动重装寄存器的值。这样可以避免在计数过程中修改自动重装寄存器的值而导致的计数异常。
· TIM_OC1PreloadConfig是一个标准库函数,用于使能或禁用指定定时器的通道 1 的输出比较预装载寄存器。这里将定时器 2 通道 1 的预装载寄存器使能,意味着对TIM_Pulse(脉冲宽度)的写操作不会立即生效,而是在当前计数周期结束后,下一个计数周期开始时才会更新脉冲宽度的值,同样是为了避免在计数过程中修改脉冲宽度而导致的 PWM 信号异常。
这段代码完成了对定时器 2 通道 1 的 PWM 模式配置,设置了 PWM 模式、输出状态、初始占空比和输出极性,并使能了自动重装寄存器和输出比较预装载寄存器,确保定时器能够稳定地输出 PWM 信号。
一、逻辑代码
(一)锁函数
对锁开关进行封装函数,当使能为1时代表锁门,使能为0时关门。
LCD_ShowChinese只能显示一个数字,所以新建一个函数LCD_Show_Chinese能够显示一个字符串。
LCD_Show_Chinese,每个数字占横坐标16像素,由于一个中文字符由两个字节表示,所以将字符串指针 s 向后移动两个字节,从而指向下一个中文字符。若横坐标 x 超出了 127 个像素,就表明已经到达了屏幕的右边界。此时,将横坐标 x 重置为 0,同时将纵坐标 y 增加 16 个像素,从而开始新的一行显示。
(二)指定区域填充颜色
key_init 函数
1. 开启 GPIOC、GPIOD 和 GPIOE 的时钟。
2. 把 PD11 和 PD9 配置成输出推挽模式,速度为 50MHz。
3. 把 PE13 和 PE15 配置成输出推挽模式,速度为 50MHz。
4. 把 PE11、PE9 和 PE7 配置成输入上拉模式,速度为 50MHz。
5. 把 PC5 配置成输入上拉模式,速度为 50MHz。
key_read 函数
此函数的作用是读取按键矩阵的按键状态:
1. 依次将每一行引脚拉低,其余行引脚拉高。
2. 读取每一列引脚的状态,若某一列引脚为低电平,则表明对应的按键被按下,将对应的按键编号赋值给 temp。
3. 最终返回 temp,也就是被按下的按键编号。
一、接线
接线参考手册资料,注意一定不能接错线,否者直接冒烟。
二、下载语音
通过连接模块,然后下载需要的语音。
三、检测模块是否有问题
连接好模块的VCC,GND,喇叭连接在SPK1和SPK2,然后通过触碰I/O口(只能触碰I/O口)与GND,检测模块是否有问题。
四、通过串口发送数据包形式检测语音模块
详细使用说明书都会有。然后将USB转串口的Tx接到语音模块的Rx。波特率为9600。
发送HEX模式。
校验码为长度^操作码^参数1^参数2
例:7E 05 41 00 01 45 EF 第一条语音
串口
串口的中断服务函数,接收中断和发送中断都会触发,所以使用时需要判断是接收中断还是发送中断。
串口发送第一个数据时标志位默认为高,所以会跳过第一个数据。
五、代码部分
Audio.c部分
首先语音模块需要使用串口发送数据,所以audio_init包含uart_init。
其次,通过串口发送数据包,通过串口发送数据包(波特率较快,需要判断是否是否发送完成)。
注意,串口发送过程中,一开始发送标志位初始化时置1的,所以需要清除一下串口发送标志位,否者会跳过第一个数据。
Main.c部分
按键部分代码
一、按键开关锁函数
新建一个开关函数
二、延迟五秒关锁
计时变量,当计时变量超过5s时锁标志位置1。
三、密码清空
需要使用string.h内的memset函数,令数组六位都为10,然后清空索引值。
显示部分代码
一、区域刷新
首先,分为两部分,一个是黄色密码区域,另一个是白色汉字区域,每个区域都需要设置两个标志位(新和旧值),当新标志位不等于旧标志位时,刷新一次。(如果一直刷新,lcd会出现闪的问题)