STM32-写一个自己的通用文件
首先我们用HAL库开发一个非常大的好处就是方便移植,针对不同内核可以使用相同的函数
结合stm32CubeMx可以更好的方便初始化我们的代码
由此萌生出写一个万能的头文件,类似于板级支持包,只需要修改几个宏定义就可以快速一些一个工程所需要的基本功能,包括但不限于1.printf--debug,2.自带us延时,3.快速支持Freertos
以上我认为最重要的就是1,printf–debug,提前写好函数,只需要用宏定义就可以快速debug输出
代码其实并不复杂,但宏定义一多就容易看起来特别杂乱
直接贴代码:
my_sys.c
#include "my_sys.h"
void HAL_Delay_us(uint32_t us)//延时us函数
{//需要cubemx配置时SYS时基源选择SysTick
__IO uint32_t currentTicks = SysTick->VAL;
/* Number of ticks per millisecond */
const uint32_t tickPerMs = SysTick->LOAD + 1;
/* Number of ticks to count */
const uint32_t nbTicks = ((us - ((us > 0) ? 1 : 0)) * tickPerMs) / 1000;
/* Number of elapsed ticks */
uint32_t elapsedTicks = 0;
__IO uint32_t oldTicks = currentTicks;
do {
currentTicks = SysTick->VAL;
elapsedTicks += (oldTicks < currentTicks) ? tickPerMs + oldTicks - currentTicks :
oldTicks - currentTicks;
oldTicks = currentTicks;
} while (nbTicks > elapsedTicks);
}
#if SYS_Delay_Tim_En
void HAL_TimDelay_us(uint32_t us)//延时us函数
{
__HAL_TIM_SetCounter(&US_TIM,0);//清零
HAL_TIM_Base_Start(&US_TIM);//开启定时器
while(__HAL_TIM_GetCounter(&US_TIM)<us){};
HAL_TIM_Base_Stop(&US_TIM);//关闭定时器
}
void HAL_TimDelay_ms(uint32_t ms)//延时ms函数
{
for(uint32_t Delay_Cnt=0;Delay_Cnt<ms;Delay_Cnt++)
HAL_TimDelay_us(997);//考虑实际代码运行损耗,不写1000,差一点点补上
}
#endif
uint32_t millis(void)//获取系统时间,单位ms
{
return HAL_GetTick();
}
uint32_t micros(void)//获取系统时间,单位us
{
return getCurrentMicros();
}
__STATIC_INLINE uint32_t GXT_SYSTICK_IsActiveCounterFlag(void)
{
return ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == (SysTick_CTRL_COUNTFLAG_Msk));
}
uint32_t getCurrentMicros(void)
{
/* Ensure COUNTFLAG is reset by reading SysTick control and status register */
GXT_SYSTICK_IsActiveCounterFlag();
uint32_t m = HAL_GetTick();
const uint32_t tms = SysTick->LOAD + 1;
__IO uint32_t u = tms - SysTick->VAL;
if (GXT_SYSTICK_IsActiveCounterFlag()) {
m = HAL_GetTick();
u = tms - SysTick->VAL;
}
return (m * 1000 + (u * 1000) / tms);
}
//串口 printf 函数
//确保一次发送数据不超过USART_MAX_SEND_LEN字节
#if GXT_Uart_Print_En
uint8_t USART1_TX_BUF[USART_MAX_SEND_LEN]={0};
void gxt_printf(char* fmt,...)
{
uint16_t i;
va_list ap;
va_start(ap,fmt);
vsprintf((char*)USART1_TX_BUF,fmt,ap);
va_end(ap);
i=strlen((const char*)USART1_TX_BUF); //此次发送数据的长度
HAL_UART_Transmit(&SEND_U,(uint8_t *)USART1_TX_BUF,i,1000);//hal库发送数据
}
#endif
my_sys.h
/**
******************************************************************************
* @file : my_sys.h
* @brief : Header for my_sys.c file.
* This file contains the common defines of the application.
******************************************************************************
* @attention
*
* Copyright (c) 2022 GXT.
*
* NO LICENSE
*
* Version: 1.1
* Last Update: 2022/1/9
******************************************************************************
*/
#ifndef __MY_SYS_H__
#define __MY_SYS_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
/*加入头文件支持*/
#define STM32F4 //宏定义支持
#define CORTEX_M4 //宏定义支持
/*包含头文件*/
/****************private*************************************/
#ifdef STM32F0
#include "stm32f0xx_hal.h"
#endif
#ifdef STM32F1
#include "stm32f1xx_hal.h"
#endif
#ifdef STM32F2
#include "stm32f2xx_hal.h"
#endif
#ifdef STM32F4
#include "stm32f4xx_hal.h"
#endif
#ifdef STM32F7
#include "stm32f7xx_hal.h"
#endif
#ifdef STM32H7
#include "stm32H7xx_hal.h"
#endif
#ifdef STM32G0
#include "stm32g0xx_hal.h"
#endif
#ifdef STM32G4
#include "stm32g4xx_hal.h"
#endif
#ifdef STM32L0
#include "stm32l0xx_hal.h"
#endif
/****************private*************************************/
/****************private*************************************/
typedef int32_t s32;
typedef int16_t s16;
typedef int8_t s8;
typedef const int32_t sc32; /*!< Read Only */
typedef const int16_t sc16; /*!< Read Only */
typedef const int8_t sc8; /*!< Read Only */
typedef __IO int32_t vs32;
typedef __IO int16_t vs16;
typedef __IO int8_t vs8;
typedef __I int32_t vsc32; /*!< Read Only */
typedef __I int16_t vsc16; /*!< Read Only */
typedef __I int8_t vsc8; /*!< Read Only */
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;
typedef const uint32_t uc32; /*!< Read Only */
typedef const uint16_t uc16; /*!< Read Only */
typedef const uint8_t uc8; /*!< Read Only */
typedef __IO uint32_t vu32;
typedef __IO uint16_t vu16;
typedef __IO uint8_t vu8;
typedef __I uint32_t vuc32; /*!< Read Only */
typedef __I uint16_t vuc16; /*!< Read Only */
typedef __I uint8_t vuc8; /*!< Read Only */
/****************private*************************************/
/*USART_DEBUG-GXT*/
#define GXT_Uart_Print_En 1 //加入对串口debug的支持,1为支持
#define SEND_U huart1 //选择发送的串口,参数为串口句柄
#define GXT_DEBUG 1 //是否使用打印debug功能,1为打印
/*==================================================*/
#if GXT_Uart_Print_En
#include "usart.h" //包含头文件
#define USART_MAX_SEND_LEN 256
#define printf gxt_printf //把全局debug打印映射到串口1(不使用microlib库,自己重新写)
void gxt_printf(char* fmt,...);
#endif
/****************private*************************************/
/****************public*************************************/
/*Function-GXT*/
#define SYS_Delay_Tim_En 1 //使能使用TIM来延时
#define US_TIM htim7 //定义对应延时tim
/*==================================================*/
#if SYS_Delay_Tim_En
#include "tim.h"//包含tim头文件
void HAL_TimDelay_us(uint32_t us);//延时us函数,用TIM
void HAL_TimDelay_ms(uint32_t ms);//延时ms函数,用TIM
#endif
/****************public*************************************/
/*FREERTOS-GXT*/
#define GXT_FREERTOS 0 //加入对FREERTOS的支持,1为支持
/****************private*************************************/
#if GXT_FREERTOS
/*包含freertos头文件*/
#include "FreeRTOS.h"
#include "task.h"
#include "list.h"//列表
#include "queue.h"//队列
#include "semphr.h"//信号量
/*包含freertos头文件*/
#endif
/****************private*************************************/
/****************public*************************************/
void HAL_Delay_us(uint32_t us);//延时us函数,用SysTick
uint32_t millis(void);//获取系统时间,单位ms
uint32_t micros(void);//获取系统时间,单位us//当前版本暂时无效,等待后期填坑
/****************public*************************************/
/****************private*************************************/
//获取系统us函数,来自Arduino,做了一点修改
__STATIC_INLINE uint32_t GXT_SYSTICK_IsActiveCounterFlag(void);
uint32_t getCurrentMicros(void);
/****************private*************************************/
/*位带操作,cortex-M7不支持位带操作*/
/****************private*************************************/
#ifdef CORTEX_M4
//IO口操作宏定义----M4
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
//IO口地址映射----M4
#define GPIOA_ODR_Addr (GPIOA_BASE+20) //0x40020014
#define GPIOB_ODR_Addr (GPIOB_BASE+20) //0x40020414
#define GPIOC_ODR_Addr (GPIOC_BASE+20) //0x40020814
#define GPIOD_ODR_Addr (GPIOD_BASE+20) //0x40020C14
#define GPIOE_ODR_Addr (GPIOE_BASE+20) //0x40021014
#define GPIOF_ODR_Addr (GPIOF_BASE+20) //0x40021414
#define GPIOG_ODR_Addr (GPIOG_BASE+20) //0x40021814
#define GPIOH_ODR_Addr (GPIOH_BASE+20) //0x40021C14
#define GPIOI_ODR_Addr (GPIOI_BASE+20) //0x40022014
#define GPIOA_IDR_Addr (GPIOA_BASE+16) //0x40020010
#define GPIOB_IDR_Addr (GPIOB_BASE+16) //0x40020410
#define GPIOC_IDR_Addr (GPIOC_BASE+16) //0x40020810
#define GPIOD_IDR_Addr (GPIOD_BASE+16) //0x40020C10
#define GPIOE_IDR_Addr (GPIOE_BASE+16) //0x40021010
#define GPIOF_IDR_Addr (GPIOF_BASE+16) //0x40021410
#define GPIOG_IDR_Addr (GPIOG_BASE+16) //0x40021810
#define GPIOH_IDR_Addr (GPIOH_BASE+16) //0x40021C10
#define GPIOI_IDR_Addr (GPIOI_BASE+16) //0x40022010
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入
#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入
#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入
#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出
#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入
#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出
#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入
#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出
#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入
#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出
#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入
#define PHout(n) BIT_ADDR(GPIOH_ODR_Addr,n) //输出
#define PHin(n) BIT_ADDR(GPIOH_IDR_Addr,n) //输入
#define PIout(n) BIT_ADDR(GPIOI_ODR_Addr,n) //输出
#define PIin(n) BIT_ADDR(GPIOI_IDR_Addr,n) //输入
#endif
#ifdef CORTEX_M3
//IO口操作宏定义----M3
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
//IO口地址映射----M3
#define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C
#define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C
#define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C
#define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C
#define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C
#define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C
#define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C
#define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808
#define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08
#define GPIOC_IDR_Addr (GPIOC_BASE+8) //0x40011008
#define GPIOD_IDR_Addr (GPIOD_BASE+8) //0x40011408
#define GPIOE_IDR_Addr (GPIOE_BASE+8) //0x40011808
#define GPIOF_IDR_Addr (GPIOF_BASE+8) //0x40011A08
#define GPIOG_IDR_Addr (GPIOG_BASE+8) //0x40011E08
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入
#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入
#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入
#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出
#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入
#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出
#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入
#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出
#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入
#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出
#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入
#endif
/****************private*************************************/
#ifdef __cplusplus
}
#endif
#endif /* __MY_SYS_H__ */