STM32CubeMX-HAL库开发笔记-基于Proteus仿真

Posted Preference for stars

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32CubeMX-HAL库开发笔记-基于Proteus仿真相关的知识,希望对你有一定的参考价值。

STM32CubeMX-HAL库开发笔记

前言

这是自己编写的一个打地鼠的小游戏,串口显示程序运行位置,右方小灯显示分数,达到17分进入彩蛋程序。
在这里插入图片描述
Proteus 8 配置工程
Proteus 8
使用Proteus 8可以仿真STM32F103系列T4、T6、C4、C6、R4、R6单片机,可以帮助项目前期少走一点弯路,学习者前期可以少花点钱去学习STM32。
STM32F103系列
使用STM32CubeMX配置基础工程的部分不做讲解,因为图形化真的很简单。本文章主要记录在配置工程后,HAL库函数的使用。

1、GPIO

读取IO:

GPIO_Iuput

HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
HAL_GPIO_ReadPin(GPIOA,BUTTONO_Pin);

写入IO:

GPIO_Output

HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
HAL_GPIO_WritePin(GPIOA,LED0_Pin,GPIO_Pin_RESET)			//置1;
HAL_GPIO_WritePin(GPIOA,LED0_Pin,GPIO_Pin_SET)			//置0;

翻转IO:

HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
HAL_GPIO_TogglePin(GPIOA, LED0_Pin);	

按键例子:

if(HAL_GPIO_ReadPin(GPIOA,BUTTONO_Pin) == GPIO_Pin_SET);
{
	while(HAL_GPIO_ReadPin(GPIOA,BUTTONO_Pin) == GPIO_Pin_SET);//等待按键抬起
	HAL_GPIO_TogglePin(GPIOA, LED0_Pin);					//翻转
	HAL_Delay(200);											//延时200ms
	HAL_GPIO_TogglePin(GPIOA, LED0_Pin);					//翻转
}

2、串口通信

串口通信

串口通信模式:

Asynchronous:异步通信

发送、接收数据

//发送数据
HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
uint8_t temp[] = "Hello World!\\n\\r";
HAL_UART_Transmit(&huart1,temp,12,50);
//接收数据
HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);

printf 重定向

在Private includes中引入
#include <stdio.h>
在USER CODE BEGIN 0 添加
int fputc(int ch,FILE *f){
	uint8_t temp[1]={ch};
	HAL_UART_Transmit(&huart1,temp,1,2); //h-uart1需要根据自己的配置修改
	return ch;
}
然后就可以在任意地方使用printf语句方便的输出你想要的内容。
printf("Hello World!\\n\\r");
HAL_Delay(200);

PROTEUS仿真

LOG信息打印

主流嵌入式输出格式:[日志级别] 文件名: 日志信息
"[info] main.c : init ok!"
"[debug] adc.c : adc_getvalue -> 3.3V"
printf("[info] main.c : HAL_Init ok! \\r\\n");

条件编译

在单片机开发过程中,需要大量的LOG信息;但是开发结束后,不需要一直打印(拖慢单片机速度)。
所以在main.h头文件添加:
#define Log 1 //打印Log信息,不想打印时改为0即可
再把.c文件中所有printf语句包裹上#id Log 与 #endif:
#if Log
printf("[info] main.c : HAL_Init ok! \\r\\n");
# endif

个性化串口输出

字符转ASCII码网站: 个性化

#define Log 1 //打印Log信息,不想打印时改为0即可
#if Log
printf("  _____  ______ _______ _    _ _____  _   _ \\r\\n");
printf(" |  __ )|  ____|__   __| |  | |  __ )( ) | |\\r\\n");
printf(" | |__) | |__     | |  | |  | | |__) |  )| |\\r\\n");
printf(" |  _  /|  __|    | |  | |  | |  _  /| . ` |\\r\\n");
printf(" | | ) )| |____   | |  | |__| | | ) (| |(  |\\r\\n");
printf(" |_|  )_)______|  |_|  (_____/|_|  )_(_| (_|\\r\\n");	  
# endif

个性化输出

可变参数宏

在Private includes中引入
#include <stdio.h>
在USER CODE BEGIN 0 添加
int fputc(int ch,FILE *f){
	uint8_t temp[1]={ch};
	HAL_UART_Transmit(&huart1,temp,1,2); //h-uart1需要根据自己的配置修改
	return ch;
}
在USER CODE BEGIN 0 添加
#define USER_LOG		//注释此行,不打印

#ifdef USER_LOG
#define user_main_printf(format,...) printf(format "\\r\\n",##__VA_ARGS__)
#define user_main_info(format,...) printf("[main]info:" format "\\r\\n",##__VA_ARGS__)
#define user_main_debug(format,...) printf("[main]debug:" format "\\r\\n",##__VA_ARGS__)
#define user_main_error(format,...) printf("[main]error:" format "\\r\\n",##__VA_ARGS__)
#else
#define user_main_printf(format,...)
#define user_main_info(format,...) 
#define user_main_debug(format,...)
#define user_main_error(format,...)
#endif
在while()中添加
user_main_info("Hello World!");	
HAL_Delay(200);
自动添加报头和报尾

可变参数宏

发送、接收中断

//发送中断
HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
//接收中断
HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

DMA

//使用DMA发送
HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
//使用DMA接收
HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
//DMA暂停
HAL_UART_DMAPause(UART_HandleTypeDef *huart);
//DMA恢复
HAL_UART_DMAResume(UART_HandleTypeDef *huart);
//DMA停止
HAL_UART_DMAStop(UART_HandleTypeDef *huart);

3、外部中断

回调函数

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
 {
	if(GPIO_Pin == BUTTON0_Pin); //多个外部中断,需要进一步判断
 }

4、定时器

定时器配置参数
开启使能

使能

HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim)HAL_TIM_Base_Start_IT(&htim1);	//定时器1使能

回调函数

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == htim1.Instance)
	{
	//定时器1中断业务
	}
}
//读取定时器1的数值
int time_num = __HAL_TIM_GET_COUNTER(&htim1);	//读取定时器1的数值

以上是关于STM32CubeMX-HAL库开发笔记-基于Proteus仿真的主要内容,如果未能解决你的问题,请参考以下文章

STM32CubeMX-HAL库开发笔记(常用语句)-基于Proteus仿真

STM32cubemx-HAL库串口断线问题

小熊派开发笔记-串口读取RS485输出的土壤七合一传感器数据(基于STM32CubeMX)

STM32F4 HAL库开发 -- 独立看门狗(IWDG)

STM32F4 HAL库开发 -- 独立看门狗(IWDG)

STM32F4 HAL库开发 -- 独立看门狗(IWDG)