首页 > 其他分享 >蓝桥杯嵌入式国三备赛经验分享

蓝桥杯嵌入式国三备赛经验分享

时间:2024-09-07 09:23:27浏览次数:12  
标签:HAL 国三备赛 uint8 嵌入式 蓝桥 TIM Key GPIO IC

1 学习STM32入门视频

向大家推荐一套宝藏级别的视频:
【STM32入门教程-2023版 细致讲解 中文字幕】

如果已经比过蓝桥杯单片机或学习过单片机相关课程的同学,你们可以尝试不需要STM32套件进行学习。如果没有学过单片机相关课程的同学,可以买套件边用边学。

尽量把这套视频看完,无论是对参加蓝桥杯嵌入式设计与开发竞赛(蓝桥杯)、嵌入式芯片与系统设计大赛STM32赛道(嵌入式大赛)或全国大学生物联网设计竞赛(华为杯)都有好处!

2 学习嵌入式开发板备赛视频

我主要看的是这套嵌入式视频:

【【备战2024蓝桥杯 嵌入式组】CT117E-M4 新款开发板 3小时省赛模块  速成总结】

从视频中可以学习到一些好的代码编写方式,从而避免各个外设的冲突、提高硬件运行效率。

3 备赛笔记

GPIO_Mode_AIN = 0x0,  //模拟输入

GPIO_Mode_IN_FLOATING = 0x04, //浮空输入

GPIO_Mode_IPD = 0x28, //下拉输入

GPIO_Mode_IPU = 0x48, //上拉输入

GPIO_Mode_Out_OD = 0x14, //开漏输出

GPIO_Mode_Out_PP = 0x10, //推挽输出

GPIO_Mode_AF_OD = 0x1C,  //复用开漏

GPIO_Mode_AF_PP = 0x18   //复用推挽

GPIO_SetBits //设置成高电平

GPIO_ResetBits //设置成低电平  

HAL_GPIO_Write();//写GPIO电平状态函数

Key_State 里面的Key一定要初始化Key = 0;

长按键需要给25延时(Key_Time1)+长按键启用标志位

双击按键需要给40延时(Key_Time2)+双击按键启用标志位+暂时双击按键号

通用定时器可以产生4路频率相同,占空比不同的PWM输出

高级定时器可以产生7路频率相同,占空比不同的PWM输出

%d数据后面加空格 防止数据末位不清除

__HAL_TIM__SETCOMPARE(定时器,通道x, 占空比);

AT24C02 写一条语句延时5ms

MCP4017的从机地址(写操作):0X5E

随着我们向MCP中输入的数越大,他对应的电阻也就越大,当我们传入0x7f时,对应的电阻就是100K。这里要注意的一点是,我们写进去的一个数字(0-127),读出来也是一个数字,转化为电阻阻值:R = 787.4 * read_resistor 欧,电压:3.3*(R/(R+10)) (假设外接的电压为3.3)

新建工程

开启时钟(选择外部时钟) -> 配置时钟树 -> 配置DAP下载模式 -> 工程名 -> 配置MDK文件 -> 勾上生成code选项 -> 生成文件 -> 打开Keil -> 配置DAP下载 -> 勾上清除并更新 -> 建立bsp文件夹

LED

在CubeMX选择PC8-PC15、PD2为推挽输出模式 -> 配置PC8-PC15为高电平,PD2为低电平 -> 更新文件

->

void LED_Display(uchar data)
{
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_All, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOC, (~data)<<8, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}

(在main.c文件写代码时,写在Bagin和End注释之间)

LCD

复制资源包里LCD例程中2.h文件、1.c文件 -> 打开main.c,复制以下代码

LCD_Init();

LCD_Clear(Black);

LCD_SetBackColor(Black);

LCD_SetTextColor(White);

LCD_DisplayStringLine(Line9, (unsigned char *)str);

-> 创建char str[30];、引用”stdio.h”使用sprintf函数

Key(短按键)

在CubeMX打开TI63时钟配置外部时钟源 -> 配置PSC、ARR -> 使能中断 -> 更新文件

->

uint8_t Key_State(void)

{

    uchar Key = 0;

    if(!HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0))

    Key = 1;
  
    if(!HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1))

    Key = 2;

    if(!HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2))

    Key = 3;

    if(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0))
    
    Key = 4;



    return Key;

}

void Key_Loop(void)

{

    static uint8_t LastState, NowState;

    uint8_t i;

    LastState = NowState;
    
    NowState = Key_State();

    for(i = 1;i <= 4;i ++)

    {

    if(LastState == 0 && NowState == i)

    KeyNum = i;

    }

}

->

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//中断回调函数(中断服务函数)

{

    static uint8_t Count0;

    if(htim -> Instance == TIM6)

    {

        if(++Count0 >= 20)
    
        {

            Count0 = 0;

            KeyStart = 1;

        }

    }

}

->

HAL_TIM_Base_Start_IT(&htim6);//使能定时器中断

Key(长按键)

uint8_t Key_Short, Key_Long, Key_Time, Long_State = 1;

void Key_Loop(void)
{
	static uint8_t LastState, NowState;
	uint8_t i;
	LastState = NowState;
	NowState = Key_State();
	for(i = 1;i <= 4;i ++)
	{
		if(LastState == 0 && NowState == i)
		Key_Time = 0;
		if(LastState == i && NowState == i)
		{
			if(++Key_Time >= 25 && Long_State)
			{
				Key_Long = i;
				Long_State = 0;
			}
		}
		if(LastState == i && NowState == 0)
		{
			if(Key_Time < 25)
			Key_Short = i;
			Long_State = 1;
		}
	}
}

PWM

在CubeMX打开相应定时器选择PWM生成选项 -> 配置时钟PSC:待定频率,ARR:100-1、CCR:占空比初值 -> 更新文件

->

HAL_TIM_PWM_Start(&htim16, TIM_CHANNEL_1);//使能PWM某通道输出

->

__HAL_TIM_SetCompare(&htim16, TIM_CHANNEL_1, PA6_PWM);//改变占空比

IC(测频率+占空比):

在CubeMX打开相应定时器 - > 配置Clock Source -> 选择CH1为直接通道、CH2为间接通道 -> 配置时钟PSC:80-1、ARR满重装值 -> CH1为上升沿触发、CH2为下降沿触发 -> 配置从模式(Combined Reset Trigger Mode) -> 选择触发源(TI1FP1)-> 更新文件 -> 创建IC.c、IC.h文件 -> 引入tim.h头文件 ->

uint32_t Read_Fre(uint8_t Command)
{

	if(Command == 15) return 1000000 / (HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_1) + 1);
	else if(Command == 4) return 1000000 / (HAL_TIM_ReadCapturedValue(&htim3, TIM_CHANNEL_1) + 1);
	else return 0;
}

double Read_Buty(uint8_t Command)
{
    if(Command == 15) return (HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_2) + 1) * 100.0 / (HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_1) + 1);
	else if(Command == 4) return (HAL_TIM_ReadCapturedValue(&htim3, TIM_CHANNEL_2) + 1) * 100.0 / (HAL_TIM_ReadCapturedValue(&htim3, TIM_CHANNEL_1) + 1);
	else return 0;
}

->

HAL_TIM_IC_Start(&htim2, TIM_CHANNEL_1);
HAL_TIM_IC_Start(&htim3, TIM_CHANNEL_1);//使能通道1
HAL_TIM_IC_Start(&htim2, TIM_CHANNEL_2);
HAL_TIM_IC_Start(&htim3, TIM_CHANNEL_2);//使能通道2

IC(中断测频率)

在CubeMX打开相应定时器TIMx的时钟 -> 选择相应通道CHx -> 配置时钟PSC:80-1、ARR满重装值-> 使能中断 -> 更新文件 -> 创建IC.c、IC.h文件 ->

uint32_t TIM2_IC_CRR1;

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	if(htim -> Instance == TIM2)
	{
		TIM2_IC_CRR1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
		__HAL_TIM_SetCounter(htim, 0);
	}
}

uint32_t Read_Fre(void)
{
	return 1000000 / (TIM2_IC_CRR1 + 1);
}

->

HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);//使能输入捕获中断

ADC + DMA

在CubeMX打开相应引脚ADC通道 -> 配置ADC1、ADC2中相应通道使能(Single-ended) -> 使能连续转换 -> 添加DAM -> 配置循环模式Circular -> 使能DMA请求为连续模式 -> 失能DMA中断 -> 更新文件 ->

HAL_ADC_Start_DMA(&hadc1,(uint32_t *)adc1,1); 
HAL_ADC_Start_DMA(&hadc2,(uint32_t *)adc2,1); //使能DAM转运

IIC

在CubeMX设置PB6、PB7引脚为输出模式 ->

void Write_AT24C02(uint8_t Command, uint8_t Data)
{
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	I2CSendByte(Command);
	I2CWaitAck();
	I2CSendByte(Data);
	I2CWaitAck();
	I2CStop();
}

uint8_t Read_AT24C02(uint8_t Command)
{
	uint8_t Data;
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	I2CSendByte(Command);
	I2CWaitAck();
	I2CStart();
	I2CSendByte(0xa0 | 0x01);
	I2CWaitAck();
	Data = I2CReceiveByte();
	I2CSendNotAck();//不需要继续读就给非应答
	I2CStop();
	
	return Data;
}

uint8_t Read_AT24C02(uint8_t Command)
{
	uint8_t Data;
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	I2CSendByte(Command);
	I2CWaitAck();
	I2CStart();
	I2CSendByte(0xa0 | 0x01);
	I2CWaitAck();
	Data = I2CReceiveByte();
	I2CSendNotAck();//不需要继续读就给非应答
	I2CStop();
	
	return Data;
}

USART1

在CubeMX配置USART1模式为Asynchronous -> 配置波特率 -> 使能中断 -> 配置PA9、PA10为USART1 -> 更新文件 -> 创建MyUSART.c、.h文件 -> 引用usart.h->

uint8_t Rxdata,Receive_Over, pRxPacket;
char RxPacket[30];

void Send_USART(char *data)
{
	HAL_UART_Transmit(&huart1, (uint8_t  *)data, strlen(data), 50);
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart -> Instance == USART1)
	{
		HAL_UART_Receive_IT(huart, &Rxdata, 1);
		RxPacket[pRxPacket ++] = RXdata;
	}
}

void Receive_USART(void)
{
	static uint8_t p;
	if(pRxPacket != 0)
	{
		p = pRxPacket;
		HAL_Delay(1);
		if(p == pRxPacket)
		{
			Receive_Over =1;
Send_USART(RxPacket);
			pRxPacket = 0;
memset(RxPacket, 0, 30);
		}
	}
}

->

HAL_UART_Receive_IT(&huart1, &Rxdata, 1);//使能接收中断
4 备赛过程

嵌入式省赛备赛过程与单片机备赛过程类似,这里不再赘述,详情可以查看博主的另一篇博客:

【蓝桥杯单片机大一零基础到国二经验分享】

奇数届嵌入式国赛备赛时,可以多学习一些串口方面的c语言函数,比如第十五届嵌入式串口相关的收发数据及提取数据就比较多。

偶数届嵌入式国赛备赛时,需要学习扩展板相关外设的使用。

5 资料

 如需十五届嵌入式资料可以私信我,本人很乐意开源,欢迎大家在评论区交流学习,预祝大家在蓝桥杯嵌入式设计与开发竞赛中取得优异成绩!!!

标签:HAL,国三备赛,uint8,嵌入式,蓝桥,TIM,Key,GPIO,IC
From: https://blog.csdn.net/TNT_JQR/article/details/141827631

相关文章

  • 蓝桥杯-STM32G431RBT6工程创建和程序烧录(保姆级图文详解)
    文章目录前言蓝桥杯嵌入式赛道所使用的开发板为STM32G431RBT6 CT117E-M4开发板(新版),如下图:一、需要安装的环境keilMDK,stm32cubemx,官方提供的资源包二、使用步骤(STM32cubemx部分)1,首先打开STM32cubemx注:蓝桥杯用HAL库更节省比赛时间,也更方便修改2,创建项......
  • 无风扇嵌入式工控机的技术优势
    无风扇嵌入式工控机专为优先考虑低维护和可靠性的应用而设计。这些工控机是不间断性能至关重要的行业的完美选择,因为它们消除了与风扇相关的故障风险。通过消除对风扇的需求,无风扇工控机提供了无缝且可靠的性能,不会受到潜在风扇故障或故障的影响。此外,无风扇嵌入式工控机几乎不需......
  • 第十三届蓝桥杯大赛软件赛省赛C/C++ 大学 A 组
    之前没接触过oi赛制打了一下心态小崩。。以为会了五题写出来对了两题,我就是纯纯小丑哈哈。只打了两个小时也不能算正经vp把,就当是一个补题2.灭鼠先锋推必败必胜局面即可。具体的我就是乱推的,对于必胜的可能要稍微多想一会,对于必败的只要找出一种必败情况那显然就是必败了。但是......
  • 嵌入式linux就业前景怎么样?
    嵌入式Linux的就业前景在当前科技快速发展的背景下显得尤为广阔和乐观。以下是对嵌入式Linux就业前景的详细分析:一、行业背景与需求增长技术普及与应用广泛:嵌入式Linux作为一种操作系统,广泛应用于各种嵌入式设备中,如智能手机、智能家居、工业自动化等领域。随着物联网技术的......
  • 嵌入式day38
    内存泄漏:手动申请的空间没有及时释放,导致系统发生内存泄漏valgrind:在程序运行过程中,测试是否发生内存泄露快慢指针法:链表倒置:链表插入排序:双向链表:双向链表与单向链表的区别:单向链表(SinglyLinkedList)结构:单向链表的每个节点包含两部分信息:一部分是存储的数据(da......
  • 北京迅为RK3568开发板嵌入式学习之Linux驱动全新更新-CAN+网络设备
    iTOP-3568开发板采用瑞芯微RK3568处理器,22nm工艺制程,集成4核A55架构处理器和MaliG522EE图形处理器,支持4K解码和1080P编码,内置独立的NPU,可用于轻量级人工智能应用。 iTOP-3568开发板连接器版本:  iTOP-3568开发板邮票版本:     关注:北京迅为电子,在线观看 ---......
  • 影石嵌入式面试题及参考答案(7万字长文)
    内核启动的完整流程内核启动是一个复杂的过程,主要包括以下几个关键步骤:硬件上电与引导程序加载当系统上电后,首先由硬件执行一些初始化操作,如设置处理器状态、初始化内存控制器等。接着,引导程序(如U-Boot)被加载到内存中并开始执行。引导程序的主要任务是初始化硬件设备......
  • 嵌入式24千兆电口+4万兆光口管理型三层交换机RTL9301模块
    核心模块概述:嵌入式RTL9301模块可以支持4口万兆上联+24口千兆三层管理型以太网交换机,也就是最多可以提供24个10/100/1000自适应电口、4个10GbSFP+端口、1个console口、1个USB串口。完善的安全控制策略及CPU保护策略(CPUprotectpolicy)提高容错能力,保证网络的稳定运行和链路......
  • [蓝桥杯 2018 省 A] 付账问题--贪心题解
    题目重述:[蓝桥杯2018省A]付账问题-洛谷#[蓝桥杯2018省A]付账问题##题目描述几个人一起出去吃饭是常有的事。但在结帐的时候,常常会出现一些争执。现在有$n$个人出去吃饭,他们总共消费了$S$元。其中第$i$个人带了$a_i$元。幸运的是,所有人带的钱的总数是......
  • 蓝桥杯2019省A糖果题解
     附上链接:[蓝桥杯2019省A]糖果-洛谷,有兴趣的小伙伴可以去试试哦~#[蓝桥杯2019省A]糖果##题目描述糖果店的老板一共有$M$种口味的糖果出售。为了方便描述,我们将$M$种口味编号$1$∼$M$。小明希望能品尝到所有口味的糖果。遗憾的是老板并不单独出售糖果,而......