嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记16:蓝桥杯编程手册

本文主要是介绍嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记16:蓝桥杯编程手册,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、要背的函数汇总(以例子形式)

1.GPIO相关

输出:HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8 | GPIO_PIN_9,GPIO_PIN_SET)

输入:HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0)

翻转:HAL_GPIO_TogglePin(GPIOC,0xFF)

2.LCD相关

格式化输出:sprintf((char*)buf,"%d",val)          (要包含stdio.h)

显示:LCD_DisplayStringLine(Line1,buf)

3.ADC相关

启动转换:HAL_ADC_Start(&hadc1)

获取数字量:HAL_ADC_GetValue(&hadc1)

4.I2C相关

开始:I2CStart()

停止:I2CStop()

发送:I2CSendByte(0xA0)

接收:I2CReceiveByte()

应答:I2CWaitAck()

非应答:I2CSendNotAck()

定时:HAL_Delay(5)

5.串口相关

初始化:MX_USART1_UART_Init()

串口发送:HAL_UART_Transmit(&huart1,(unsigned char *)&ch,1,50)

重定向:help搜retarget第三个

串口接收中断:HAL_UART_Receive_IT(&huart1,uart_buf,1)

中断回调:HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

6.DAC相关(12位右对齐)

设置数字量:HAL_DAC_SetValue(&hdac1,DAC_CHANNEL_1,DAC_ALIGN_12B_R,1365)

转换成模拟量:HAL_DAC_Start(&hdac1,DAC_CHANNEL_1)

7.RTC

获取时间:HAL_RTC_GetTime(&hrtc,&rtc_time,RTC_FORMAT_BIN)

获取日期:HAL_RTC_GetDate(&hrtc,&rtc_date,RTC_FORMAT_BIN)

8.PWM捕获

开启中断:HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1)

中断回调:HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)

获取计数器:tim2_cnt = __HAL_TIM_GetCounter(&htim2)

设置计数器: __HAL_TIM_SetCounter(&htim2,0)

9.PWM输出

启动输出:HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1)

二、流程

1.打开资源数据包,找到LCD参考程序并复制。

2.更改名字为G15302396,并更改MX文件为同名。

3.然后删除MDK-ARM中所有带LCD的文件和文件夹。

4.打开MX文件。根据题目要求和原理图,配置引脚。

5.选择MDK-ARM为v5,选择生成源文件头文件。

6.生成文件后,打开文件,配置魔术棒(微库、debug)

7.加入LCD的源文件(如果有I2C也要加)。

8.解决LCD和LED冲突问题并测试。(在三个Write函数前面加入u16 pout = GPIOC->ODR,在后面加入GPIOC->ODR = pout)

9.编译并编程。

三、LED

1.初始化

PD2选择GPIO输出。

2.编程

实现:输入八位数,点亮对应的灯。

void LED_Control(u8 led_ctrl) 
{HAL_GPIO_WritePin(GPIOC,0xFF00,GPIO_PIN_SET)HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOC,led_ctrl<<8,GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}

四、Systick

1.初始化

2.编程

实现:所有灯每5ms闪烁一次。

__IO u32 ledTick = 0;
void LED_Process() 
{if(uwTick - ledTick < 500) return ; ledTick = uwTick; HAL_GPIO_TogglePin(GPIOC,0xFF00)HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}

五、按键

1.初始化

PA0、PB0、PB1、PB2选择GPIO输入。

2.编程

带长按和松手检测的三行按键法。

#define KB1  HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)
#define KB2  HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)
#define KB3  HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)
#define KB4  HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)
#define KEYPORT  KB1 | (KB2<<1) | (KB3<<2) | (KB4<<3) | 0xf0u8 Trg;
u8 Cont;
void Key_Read()
{u8 ReadData = KEYPORT^0xff;   		   // 1Trg = ReadData & (ReadData ^ Cont);        // 2 Cont = ReadData;                           // 3
}__IO u32 keyTick = 0;
u8 key1_value = 0;
__IO u32 b4Tick = 0;
u8 lock = 0;
void Key_Process()
{if(uwTick - keyTick < 10) return ;keyTick = uwTick;Key_Read();if(Trg & 0x01){key1_value++;}if(Trg & 0x02){}if(Trg & 0x04){}if(Trg & 0x08){}if(Cont & 0x08){b4Tick++;}if(Trg == 0x00 && Cont == 0x00){if(b4Tick >= 100){b4Tick = 0;lock = 1;}else if(b4Tick != 0){b4Tick = 0;lock = 0;}}
}

六、LCD

1.初始化

2.编程

u8 val = 0;
void LCD_Process()
{u8 buf[20];sprintf((char*)buf,"%d",val);LCD_DisplayStringLine(Line1,buf);
}

注意点:使用sprintf要包含stdio.h

3.输出形式

固定长度、左对齐、自动补0、小数、十六进制和八进制、字符和字符串、百分号

    sprintf((char*)buf,"%5d",4000);     //固定长度sprintf((char*)buf,"-%5d",4000);    //左对齐sprintf((char*)buf,"%05d",4000);    //前面不够的位自动补0sprintf((char*)buf,"%5.2f",3.1415926);  //显示小数,总长5位,小数点算1位,小数点后2位sprintf((char*)buf,"%x",15);        //%x显示16进制,%o显示8进制sprintf((char*)buf,"%c",'a');       //%c显示字符,%s显示字符串sprintf((char*)buf,"%d %%",10);     //输出百分号:%

七、ADC

1.初始化

PB15选择ADC2的15通道,配置成单端模式。

2.编程

u16 adc2_val;
float volt_r37;
void ADC_Process()
{HAL_ADC_Start(&hadc2);adc2_val = HAL_ADC_GetValue(&hadc2);volt_r37 = adc2_val*3.3f/4096.0f;
}

八、EEPROM

1.初始化

1.1 复制赛场给的i2c.c和i2c.h文件到源文件和头文件

1.2 生成文件后,把i2c.c加入工程

1.3 包含i2c.h

1.4 调用初始化函数I2CInit()

2.编程

流程:先在i2c.c编写EEPROM读写函数,再在头文件定义一下,然后编写主函数。

EEPROM读写:

void EEPROM_Write(u8 add,u8 dat)
{I2CStart();I2CSendByte(0xa0);I2CWaitAck();I2CSendByte(add);I2CWaitAck();I2CSendByte(dat);I2CWaitAck();I2CStop();HAL_Delay(5);
}u8 EEPROM_Read(u8 add)
{u8 dat;I2CStart();I2CSendByte(0xa0);I2CWaitAck();I2CSendByte(add);I2CWaitAck();I2CStart();I2CSendByte(0xa1);I2CWaitAck();dat = I2CReceiveByte();I2CSendNotAck();I2CStop();return(dat);
}

统计开机次数

u8 startup_times;int main(void)
{I2C_Init();startup_times = EEPROM_Read(0x10);startup_times++;EEPROM_Write(0x10,startup_times);
}

九、MCP4017

1.硬件

总阻值:100k

档位数:127

写入时的器件地址:0x5E

分压电阻:10k

写入x得到的电阻:x*100/0x7F   (千欧)

PB14上得到的电位:3.3*R/(R+10)

2.初始化

2.1 PB14配置成ADC1的5通道,设置为单端模式

2.2 ADC转换的数量改成2,设置采样顺序Rank(先采样几通道),设置采样时间为最大。

3.编程

MCP4017写入函数(放在I2C里面):

void MCP4017_Write(u8 val)
{I2CStart();I2CSendByte(0x5E);I2CWaitAck();I2CSendByte(val);I2CWaitAck();I2CStop();
}

ADC采样(多通道采样只要重复使用start就可以切换通道)

u16 adc1_val,adc2_val;
float volt_r37,volt_r38,volt_mcp;
void ADC_Process(void)
{//rank1HAL_ADC_Start(&hadc1);volt_mcp = HAL_ADC_GetValue(&hadc1)/4095.0f*3.3f;//rank2HAL_ADC_Start(&hadc1);adc1_val = HAL_ADC_GetValue(&hadc1);volt_r37 = adc2_val/4095.0f*3.3f;HAL_ADC_Start(&hadc2);adc2_val = HAL_ADC_GetValue(&hadc2);volt_r38 = adc1_val/4095.0f*3.3f;
}
//……
int main()
{MCP4017_Write(0x3F);while(1);{ADC_Process();}
}

十、串口通信

1.初始化

1.1 配置PA9、PA10为TX、RX

1.2 把USART设置为异步收发Asyn

1.3 配置波特率

1.4 开启中断

2.编程

流程:先重定向printf,再在初始化中开启中断,再定义中断回调函数

重定向(写在usart.c中)

int fputc(int ch,FILE *f)
{HAL_UART_Transmit(&huarl1,(unsigned char *)&ch,1,50);return ch;
}

串口接收固定字长

#include "string.h" //要用memset函数
u8 uart_buf[2];
u8 rx_buf[10];
u8 rx_cnt=0;
_IO uint32_t uartTick=0;
void UART_Process()
{if(uwTick-uartTick<50) return;uartTick=uwTick;rx_cnt=0;memset(rx_buf,'\0',sizeof(rx_buf));
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{uartTick=uwTick;rx_buf[rx_cnt++]=uart_buf[0];if(rx_cnt==3){LED_Control(rx_buf[1]);rx_cnt=0;}HAL_UART_Receive_IT(&huart1,uart_buf,1);
}
int main()
{MX_USART1_UART_Init();HAL_UART_Receive_IT(&huart1,uart_buf,1);while(1){RxIdle_Process();}
}

串口接收带帧尾的不定长

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{uartTick=uwTick;rx_buf[rx_cnt++]=uart_buf[0];if(rx_buf[0]=='\n'){LED_Control(rx_buf[1]);rx_cnt=0;}HAL_UART_Receive_IT(&huart1,uart_buf,1);
}

注意点:使用memset,要包含string.h

十一、DAC

1.初始化

1.1 配置PA4为DAC1的1通道输出,PA5为DAC1的2通道输出。

1.2 设置DAC输出模式为:输出到外部引脚(connected to external pin)

2.编程

void DAC_Process(void)
{HAL_DAC_SetValue(&hdac1,DAC_CHANNEL_1,DAC_ALIGN_12B_L,1365);HAL_DAC_Start(&hdac1,DAC_CHANNEL_1);//PA4输出1.1VHAL_DAC_SetValue(&hdac1,DAC_CHANNEL_2,DAC_ALIGN_12B_L,2730);HAL_DAC_Start(&hdac1,DAC_CHANNEL_2);//PA5输出2.2V
}

十二、RTC

1.初始化

1.1 启动RTC,勾选两个Activate

1.2 设置两个分频,让32KHz分频为1Hz,所以两个分频分别是31和999

1.3 设置时、分、秒分别为23、59、59

1.4 设置日期

2.编程

RTC_TimeTypeDef rtc_time;
RTC_DateTypeDef rtc_date;
void RTC_Process()
{HAL_RTC_GetTime(&hrtc,&rtc_time,RTC_FORMAT_BIN);HAL_RTC_GetDate(&hrtc,&rtc_date,RTC_FORMAT_BIN);
}
u8 buf[20];
void LCD_Process()
{LCD_SetBackColor(Black);LCD_SetTextColor(White);sprintf((char*)buf,"%2d,%2d,%2d",rtc_time.Hours,rtc_time.Minutes,rtc_time.Seconds);LCD_DisplayStringLine(Line1,buf);
}

注意:RTC_TimeTypeDef rtc_time可以不用背,直接仿照MX_RTC_Init(void)里面的第一第二行就行了,定义的这个结构体就是HAL_RTC_GetTime()的第二个变量。

十三、PWM捕获

1.初始化

1.1 配置需要捕获的引脚为TIM

1.2 对应的TIM设置为输入捕获模式

1.3 使能中断

1.4 设置分频值为79,ARR为最高值。

2.编程

捕获双路频率:

u32 tim2_cnt = 0;
u32 tim3_cnt = 0;
u32 f40 = 0;
u32 f39 = 0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if(htim == &htim2){tim2_cnt = __HAL_TIM_GetCounter(&htim2);__HAL_TIM_SetCounter(&htim2,0);f40 = 1000000/tim2_cnt;//得到频率HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);}else if(htim == &htim3){tim3_cnt = __HAL_TIM_GetCounter(&htim3);__HAL_TIM_SetCounter(&htim3,0);f39 = 1000000/tim3_cnt;//得到频率HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);}
}
int main()
{HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);
}

捕获单路占空比:

u32 tim2_cnt1 = 0;
u32 tim2_cnt2 = 0;
u32 f40 = 0;
float d40 =0;
u8 tim2_state = 0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if(tim2_state == 0){__HAL_TIM_SetCounter(&htim2,0);  //开始计时TIM2->CCER |= 0x02;  //开始下降沿中断tim2_state == 1;}else if(tim2_state == 1){tim2_cnt1 = __HAL_TIM_GetCounter(&htim2); //获取t1TIM2->CCER &= ~0x02;  //开始上升沿中断tim2_state == 2;}else if(tim2_state == 2){tim2_cnt2 = __HAL_TIM_GetCounter(&htim2); //获取t2tim2_state == 0;f40 = 1000000/tim2_cnt2;//得到频率d40 = tim2_cnt1*100.0f/tim2_cnt2;//得到占空比}HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);
}
int main()
{HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);
}

十四、PWM输出

1.初始化

1.1 配置需要输出的引脚为TIM

1.2 对应的TIM设置为PWM输出模式

1.3 设置分频值为79,设置ARR,打开预装载,设置CCRx。

2.编程

u16 t2 = 499;
u16 t1 = 250;
void PWM_Out_Process()
{HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);TIM17->ARR = t2;TIM17->CCR1 = t1;
}

这篇关于嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记16:蓝桥杯编程手册的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/889497

相关文章

基于Python开发电脑定时关机工具

《基于Python开发电脑定时关机工具》这篇文章主要为大家详细介绍了如何基于Python开发一个电脑定时关机工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 简介2. 运行效果3. 相关源码1. 简介这个程序就像一个“忠实的管家”,帮你按时关掉电脑,而且全程不需要你多做

Java中的Opencv简介与开发环境部署方法

《Java中的Opencv简介与开发环境部署方法》OpenCV是一个开源的计算机视觉和图像处理库,提供了丰富的图像处理算法和工具,它支持多种图像处理和计算机视觉算法,可以用于物体识别与跟踪、图像分割与... 目录1.Opencv简介Opencv的应用2.Java使用OpenCV进行图像操作opencv安装j

基于Qt开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

C#图表开发之Chart详解

《C#图表开发之Chart详解》C#中的Chart控件用于开发图表功能,具有Series和ChartArea两个重要属性,Series属性是SeriesCollection类型,包含多个Series对... 目录OverviChina编程ewSeries类总结OverviewC#中,开发图表功能的控件是Char

C#反射编程之GetConstructor()方法解读

《C#反射编程之GetConstructor()方法解读》C#中Type类的GetConstructor()方法用于获取指定类型的构造函数,该方法有多个重载版本,可以根据不同的参数获取不同特性的构造函... 目录C# GetConstructor()方法有4个重载以GetConstructor(Type[]

鸿蒙开发搭建flutter适配的开发环境

《鸿蒙开发搭建flutter适配的开发环境》文章详细介绍了在Windows系统上如何创建和运行鸿蒙Flutter项目,包括使用flutterdoctor检测环境、创建项目、编译HAP包以及在真机上运... 目录环境搭建创建运行项目打包项目总结环境搭建1.安装 DevEco Studio NEXT IDE

Python开发围棋游戏的实例代码(实现全部功能)

《Python开发围棋游戏的实例代码(实现全部功能)》围棋是一种古老而复杂的策略棋类游戏,起源于中国,已有超过2500年的历史,本文介绍了如何用Python开发一个简单的围棋游戏,实例代码涵盖了游戏的... 目录1. 围棋游戏概述1.1 游戏规则1.2 游戏设计思路2. 环境准备3. 创建棋盘3.1 棋盘类

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用