思索模块:
按键中断,LCD屏幕,通用定时器计时亮度
按键中断
技巧
通用第一步:开时钟
第二步:配模式
第三步:复用要看AFIO需要需要配置
第四步:其他模块(第一步同样时钟,模式)
最后一部:使能--使能放在最后一部,如果放在前面使能一配置,有些信息将无法修改。
cs
#include "key.h"
void KEY_Init(void)
{
// 1.GPIO配置
// 1.1 PF10 下拉输入模式
// 1.1.1 开时钟
RCC->APB2ENR |= RCC_APB2ENR_IOPFEN;
// 1.1.2 下拉输入模式 CNF 10 MODE 00 ODR 0
GPIOF->CRH |= GPIO_CRH_CNF10_1;
GPIOF->CRH &= ~GPIO_CRH_CNF10_0;
GPIOF->CRH &= ~GPIO_CRH_MODE10;
GPIOF->ODR &= ~GPIO_ODR_ODR10;
GPIOF->CRH |= GPIO_CRH_CNF11_1;
GPIOF->CRH &= ~GPIO_CRH_CNF11_0;
GPIOF->CRH &= ~GPIO_CRH_MODE11;
GPIOF->ODR &= ~GPIO_ODR_ODR11;
// 2.AFIO配置 线这么连
// 2.1开时钟
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
AFIO->EXTICR[2] |= AFIO_EXTICR3_EXTI10_PF;
AFIO->EXTICR[2] |= AFIO_EXTICR3_EXTI11_PF;
// 3.EXTI配置 上升沿还是下降沿触发
// 3.1 EXTI特殊 不需要配置时钟信号
// 3.2 上升沿触发
EXTI->RTSR |= EXTI_RTSR_TR10;
EXTI->RTSR |= EXTI_RTSR_TR11;
// 3.3 中断使能
EXTI->IMR |= EXTI_IMR_MR10;
EXTI->IMR |= EXTI_IMR_MR11;
// 4.NVIC配置 中断优先级
// 4.1 NVIC划分多少用于嵌套优先级,多少用于排队对优先级
NVIC_SetPriorityGrouping(3); // 让4个bit全是嵌套优先级
// 4.2 给我们的中断设置一个具体的优先级
NVIC_SetPriority(EXTI15_10_IRQn, 3);
// 4.3NVIC有自己的使能位,需要给当前中断配置使能
NVIC_EnableIRQ(EXTI15_10_IRQn);
}
uint8_t light_count = 0;
void EXTI15_10_IRQHandler(void)
{
if (EXTI->PR & EXTI_PR_PR10)
{
EXTI->PR |= EXTI_PR_PR10;
Delay_ms(10);
if ((GPIOF->IDR & GPIO_IDR_IDR10) != 0)
{
if (light_count > 0)
{
light_count--;
}
}
}
if (EXTI->PR & EXTI_PR_PR11)
{
EXTI->PR |= EXTI_PR_PR11;
Delay_ms(10);
if ((GPIOF->IDR & GPIO_IDR_IDR11) != 0)
{
if (light_count < 10)
{
light_count++;
}
}
}
}
LCD屏幕
技巧:
FNF0:表示第FNF标志位两位。
FNF0_0:表示第FNF的低位
FNF0_1:表示第FNF的高位
都是1,用&~和|来清零和置1。
cs
#include "lcd.h"
void Lcd_Init(void){
//开始时钟
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
//配置推挽输出模式
GPIOB->CRL |= GPIO_CRL_CNF0_1;
GPIOB->CRL &= ~GPIO_CRL_CNF0_0;
GPIOB->CRL |= GPIO_CRL_MODE0;
}
通用定时器计时亮度
技巧:
手册从头往下查询寄存器,使能最后开启,这里直接将使能封装成函数了。
cs
#include "tim3.h"
void TIM3_Init(void){
//2.定时器 tim5 的配置
//2.1 先放时钟
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
//三大块
// 控制器(时钟源)配置 默认不改就是就是72MHz
//时基单元
//输入和输出通道
//2.2 时基单元
//2.2.1 计数方向(默认像上,其实可以不用配置)
// TIM3->CR1 |= TIM_CR1_DIR;
//2.2.2 预分频
TIM3->PSC = 7200 - 1;
//2.2.3 自动重装载
TIM3->ARR = 100 - 1;
//3 输入输出通道
//3.1 让通道2使用输出模式(默认就是输出,可以不用配置)
TIM3->CCMR2 &= ~TIM_CCMR2_CC3S;
//3.2 配置比较寄存器 具体的比较模式 (8选1 我们选择PWM模式1)
TIM3->CCMR2 |= (TIM_CCMR2_OC3M_1|TIM_CCMR2_OC3M_2);
TIM3->CCMR2 &= ~TIM_CCMR2_OC3M_0;
//3.3 低电平有效,为了让CCR的值 能很好地表示亮度
TIM3->CCER |= TIM_CCER_CC3P;
}
void TIM3_PWMStart(void){
//计数器是使能
TIM3->CR1 |= TIM_CR1_CEN;
//通道2使能
TIM3->CCER |= TIM_CCER_CC3E;
}
void TIM3_PWMStop(void){
//关闭计数器使能
TIM5->CR1 &= ~TIM_CR1_CEN;
//关闭通道2使能
TIM3->CCER &= ~TIM_CCER_CC3E;
}
void TIM3_SetDuty(uint16_t duty){
TIM3->CCR3 = duty;
}
main.c
技巧:
引入头文件
初始化
while循环打底
cs
#include "lcd.h"
#include "key.h"
#include "tim3.h"
extern light_count;
int main(void)
{
KEY_Init();
Lcd_Init();
TIM3_Init();
TIM3_PWMStart();
while (1)
{
TIM3_SetDuty(light_count*10);
}
}