您当前的位置: 首页 >  嵌入式

风间琉璃•

暂无认证

  • 1浏览

    0关注

    337博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

嵌入式蓝桥杯省赛模板

风间琉璃• 发布时间:2022-01-29 16:56:37 ,浏览量:1

 1.整体框架

在HAL库底层和MAIN应用层之间建立一个BSP中间层,HAL库底层由官方提供,BSP里用于各种外设硬件的初始化和基本功能函数编写,MAIN应用层编写程序的整个控制流程。

2.BSP模块

使用STM32CubeMX初始化时钟和外设

变量别名定义:

typedef   signed          char int8_t;
typedef   signed short     int int16_t;
typedef   signed           int int32_t;

typedef unsigned          char uint8_t;
typedef unsigned short     int uint16_t;
typedef unsigned           int uint32_t;
#define     __IO    volatile 

__IO的作用(两根下划线) : 为了不让编译器进行优化,即每次读取或者修改值的时候,都必须重新从内存或者寄存器中读取或者修改

(1)系统时钟

a.首先用STM32CubeMX在相应的位置建立一个Source_Project文件工程,配置RCC系统时钟,选择外部高速时钟:Crystall / Ceramic Resonator (晶振)

b.配置系统时钟来源和分频系数

 选择高速外部时钟设置为24Mhz,然后经过 (/3) --> (x20) -->(/2),然后选择PLLCLK时钟源,最终得到SYSCLK,时钟频率80Mhz

(2)Key 和 LED

Key原理图:

 由于按键连接了一个上拉电阻,所以默认高电平,当按下按键时,电路闭合,IO口电平从高电平到低电平,检测IO口电平的变化就是判断按键是否按下的依据。GPIO设置为浮空输入模式(默认输入值不确定,读取值唯一),并且不带上下拉

STM32CubeMX配置:

 按键源码(必背要考!!!)

// 按键扫描
uint8_t Key_Scan(void)
{
	uint8_t val=0;
	if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==0)
		val = 1;
	if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0)
		val = 2;
	if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==0)
		val = 3;
	if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==0)
		val = 4;
	return val;
}

// 按键处理函数
// 在main中声明的全局变量
__IO uint32_t uwTick_Key_Set_Point = 0;  //控制key_Pro执行速度
//按键变量
uint8_t ucKey_Val, unKey_Down, ucKey_Up, ucKey_Old;

//按键扫描子函数
void key_proc(void)
{
	if(uwTick - key_uwTickChannel == HAL_TIM_ACTIVE_CHANNEL_2)   // 通道2
		{
			PWM2_D_Count = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2)+1;
		}	
	}
}

 

普通输入捕获:定时器通道2

 采用定时器2的通道2作为信号的输入,必须将通道2设置为直接捕获模式并且上升沿触发,通道1间接捕获模式并且下降沿触发。注意:使能自动预载值。

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance==TIM2)
	{
		if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_2)
		{
			period_val= HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_2)+1; // arr值
			duty_val = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_1)+1;  // compare值
			if(period_val)
			{
				__HAL_TIM_SET_COUNTER(&htim2,0); // 清0,为下一次捕获做准备
				freq = 1000000/period_val;       // 频率
				duty = duty_val/period_val*100;  // 占空比
			}
		}
		HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2);
		HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);
		
	}
	
}

这里period_val,duty_val,freq,duty都建议采用float,以减小误差。 

(9)输出比较模式(方波) 电平翻转模式

输出通道有8种模式,这里采用的是比较输出模式(2),即电平翻转模式。当匹配时,引脚状态翻转。假设CCR寄存器里面的值设定为100 (注意这个不是控制波形的频率,只是一个初始值,波形频率的设置在中断里面设置),那么计数器从0开始计数,每隔100次,电平将会翻转一次,并且通过中断设置下次比较值,改变波形的频率( __HAL_TIM_SET_COMPARE(htim,TIM_CHANNEL_1,(__HAL_TIM_GetCounter(htim)+500)); //这里最好初始脉冲值设置为500,1Khz),这样就通过设定CCR寄存器里面的值就可以输出不同频率的方波

系统时钟经过分频得到1M作为计数时钟,计一个数需要t=1e-6s, 波的频率 1/[2*( 100*t)] =5khz,__HAL_TIM_SET_COMPARE(htim,TIM_CHANNEL_1,(__HAL_TIM_GetCounter(htim)+100));

STM32CubeMX配置: 设置系统时钟为1Mhz, 频率设置:Pulse脉冲值,一定要使能auto-reload preload,因为每一次中断里面要更改比较寄存器CCR的值

//*输出方波PA2引脚	
HAL_TIM_OC_Start_IT(&htim15,TIM_CHANNEL_1);

//  方波输出中断回调函数
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == TIM15)   // 定时器判断
	{
		if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)  // 通道1
		{
			// 每次中断计数器的值加100  Pulse = 100
			__HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_1, (__HAL_TIM_GetCounter(htim)+100)); // 5khz
			
		}
		else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)   // 通道2
		{
			// 每次中断计数器的值加500  Pulse = 500
			__HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_2, (__HAL_TIM_GetCounter(htim)+500)); // 1khz
		}	
	}
}
(10)输出比较模式(PWM) PWM模式

采用输出比较模式选择PWM模式,PWM(脉冲宽度调制)模式可以产生一个由TIMx_ARR寄存器确定频率(周期)、由TIMx_CCRx寄存器确定占空比的PWM信号

在递增计数模式下,CNT从 0 开始计数到ARR并生成计数器上溢事.,假设 ARR=999,CCR=300, CNT 从 0 开始计数,当 CNT

关注
打赏
1665385461
查看更多评论
立即登录/注册

微信扫码登录

0.0416s