STM32 通用底层函数集锦, 自用

发布者:知识智慧最新更新时间:2024-10-21 来源: cnblogs关键字:STM32 手机看文章 扫描二维码
随时随地手机看文章

#include 'xustm32.h'

#include 'xucommon.h'


//#define COM_DEBUG

#include 'xudebug.h'


//-------------------- STM32通用函数集锦 ---------------------------------------------------

#if 0

HardFault_Handler

                PROC

; EXPORT HardFault_Handler [WEAK]

; B .

                IMPORT hard_fault_handler_c

                TST LR, #4

                ITE EQ

                MRSEQ R0, MSP

                MRSNE R0, PSP

                B hard_fault_handler_c

                ENDP

#endif

// hard fault handler in C, with stack frame location as input parameter

void hard_fault_handler_c(unsigned long * hardfault_args)

{

  unsigned long stacked_r0, stacked_r1, stacked_r2, stacked_r3, stacked_r12, stacked_lr, stacked_pc, stacked_psr;


  stacked_r0 = ((unsigned long) hardfault_args[0]);

  stacked_r1 = ((unsigned long) hardfault_args[1]);

  stacked_r2 = ((unsigned long) hardfault_args[2]);

  stacked_r3 = ((unsigned long) hardfault_args[3]);

  stacked_r12 = ((unsigned long) hardfault_args[4]);

  stacked_lr = ((unsigned long) hardfault_args[5]);

  stacked_pc = ((unsigned long) hardfault_args[6]);

  stacked_psr = ((unsigned long) hardfault_args[7]);


  UARTprintf ('[Hard fault handler]????n');

  UARTprintf ('R0 = %x, R1 = %x, R2 = %x, R3 = %x, R12 = %xn', stacked_r0, stacked_r1, stacked_r2, stacked_r3);

  UARTprintf ('R12 = %x, LR = %x, PC = %x, PSR = %xn', stacked_r12, stacked_lr, stacked_pc, stacked_psr);

  UARTprintf ('BFAR = %xn', (*((volatile unsigned long *)(0xE000ED38))));

  UARTprintf ('CFSR = %xn', (*((volatile unsigned long *)(0xE000ED28))));

  UARTprintf ('HFSR = %xn', (*((volatile unsigned long *)(0xE000ED2C))));

  UARTprintf ('DFSR = %xn', (*((volatile unsigned long *)(0xE000ED30))));

  UARTprintf ('AFSR = %xn', (*((volatile unsigned long *)(0xE000ED3C))));


#if 0

    Debug ('Now Task : %snr',OSTCBPrioTbl[OSTCBCur->OSTCBPrio]->OSTCBTaskName);

    OS_TaskStkCheck(TRUE);

    OS_DebugHeap();

    Q_ErrorStopScreen('HardFaultException');

#endif


  while(1) { }

}


void GetSerialNO(void)

{

    u32 Dev_Serial0, Dev_Serial1, Dev_Serial2;


    Dev_Serial0 = HWREG(0x1FFFF7E8);

  Dev_Serial1 = HWREG(0x1FFFF7EC);

  Dev_Serial2 = *(vu32*)(0x1FFFF7F0);


  DEBUG_PRINT('SerialNO = %08X %08X %08Xn', Dev_Serial0, Dev_Serial1, Dev_Serial2);

  //SerialNO = 066C0036 33315330 43184129

}


//本函数名不可改, uCOS中应用到

u32 GetClocksFreq(void)

{

    RCC_ClocksTypeDef rcc_clocks;


  RCC_GetClocksFreq(&rcc_clocks);    //获取系统频率

  return(rcc_clocks.HCLK_Frequency);

}


//--- 独立看门狗

void IWDG_Init(unsigned char ucSecond)

{

    IWDG->KR = 0X5555;                //使能对IWDG->PR和IWDG->RLR的写

  IWDG->PR = IWDG_Prescaler_64; //设置分频系数

  IWDG->RLR = 625*ucSecond;         //从加载寄存器 IWDG->RLR

    IWDG->KR = 0XAAAA;                //reload

  IWDG->KR = 0XCCCC;                //使能看门狗

}


//THUMB指令不支持汇编内联, 采用如下方法实现执行汇编指令WFI

__asm void WFI_SET(void)

{

    WFI;

}


//进入待机模式

void SystemStandby(void)

{

    SCB->SCR      |= 1<<2;        //使能SLEEPDEEP位 (SYS->CTRL)

  RCC->APB1ENR |= 1<<28;     //使能电源时钟

    RCC->APB1ENR |= 1<<27;     //使能备份时钟

    PWR->CSR      |= 1<<8; //设置WKUP用于唤醒

    PWR->CR      |= 1<<2; //清除Wake-up 标志

    PWR->CR      |= 1<<1; //PDDS置位

    WFI_SET();                     //执行WFI指令

}


//--------------------- UART Begin -----------------------------------------------------

extern COM_TypeDef g_DebugComNo;


#define EVAL_COM1 USART1

#define EVAL_COM1_GPIO GPIOA

#define EVAL_COM1_CLK RCC_APB2Periph_USART1

#define EVAL_COM1_GPIO_CLK RCC_APB2Periph_GPIOA

#define EVAL_COM1_RxPin GPIO_Pin_10

#define EVAL_COM1_TxPin GPIO_Pin_9


#define EVAL_COM2 USART2

#define EVAL_COM2_GPIO GPIOA

#define EVAL_COM2_CLK RCC_APB1Periph_USART2

#define EVAL_COM2_GPIO_CLK RCC_APB2Periph_GPIOA

#define EVAL_COM2_RxPin GPIO_Pin_3

#define EVAL_COM2_TxPin GPIO_Pin_2


#define COMn 2

USART_TypeDef* COM_USART[COMn] = {EVAL_COM1, EVAL_COM2};

GPIO_TypeDef* COM_PORT[COMn] = {EVAL_COM1_GPIO, EVAL_COM2_GPIO};

const uint32_t COM_USART_CLK[COMn] = {EVAL_COM1_CLK, EVAL_COM2_CLK};

const uint32_t COM_POR_CLK[COMn] = {EVAL_COM1_GPIO_CLK, EVAL_COM2_GPIO_CLK};

const uint16_t COM_TX_PIN[COMn] = {EVAL_COM1_TxPin, EVAL_COM2_TxPin};

const uint16_t COM_RX_PIN[COMn] = {EVAL_COM1_RxPin, EVAL_COM2_RxPin};


/*typedef enum {

    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                 //复用(推挽)输出. 乱码

} GPIOMode_TypeDef; */

void USART_Set(COM_TypeDef COM, uint32 BaudRate)

{

    USART_InitTypeDef USART_InitStructure;

    GPIO_InitTypeDef GPIO_InitStructure;


    USART_InitStructure.USART_BaudRate = BaudRate;

    USART_InitStructure.USART_WordLength = USART_WordLength_8b;

    USART_InitStructure.USART_StopBits = USART_StopBits_1;

    USART_InitStructure.USART_Parity = USART_Parity_No;

    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;


    /* Enable GPIO clock */

    RCC_APB2PeriphClockCmd(COM_POR_CLK[COM] | RCC_APB2Periph_AFIO, ENABLE);    //使能串口所有GPIO模块时钟,并使能AFIO模块时钟


    /* Enable UART clock */

    if (COM == COM1) {

        RCC_APB2PeriphClockCmd(COM_USART_CLK[COM], ENABLE);     //使能串口模块时钟

    }

    else {

        RCC_APB1PeriphClockCmd(COM_USART_CLK[COM], ENABLE);        //使能串口模块时钟

    }


    /* Configure USART Tx as alternate function push-pull */

    GPIO_InitStructure.GPIO_Pin = COM_TX_PIN[COM];        //设置TX引脚

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽输出

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(COM_PORT[COM], &GPIO_InitStructure);


    /* Configure USART Rx as input floating */

    GPIO_InitStructure.GPIO_Pin = COM_RX_PIN[COM];            //设置RX引脚

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;    //浮空输入

    GPIO_Init(COM_PORT[COM], &GPIO_InitStructure);


    /* USART configuration */

    USART_Init(COM_USART[COM], &USART_InitStructure);        //初始化USART


    /* Enable USART Receive and Transmit interrupts */

    USART_ITConfig(COM_USART[COM], USART_IT_RXNE, ENABLE);

    //USART_ITConfig(COM_USART[COM], USART_IT_TXE, ENABLE);


    /* Enable USART */

    USART_Cmd(COM_USART[COM], ENABLE);        //使能串口模块

    //USART_DMACmd(COM, USART_DMAReq_Rx, ENABLE); //使能UART DAM传输

}


void UARTSendChar(COM_TypeDef COM, uint8_t ch)

{

    /* Loop until the end of transmission */

    //USART_SendData(COM_USART[COM], ch);

    while (USART_GetFlagStatus(COM_USART[COM], USART_FLAG_TC) == RESET);

    USART_SendData(COM_USART[COM], ch);

}


void UARTOut(COM_TypeDef COM, uint8_t *Data, uint16_t Len)

{

    uint16_t i;


    for(i=0; i        UARTSendChar(COM, Data[i]);

    }

}


//--- used by UARTprintf

void UARTwrite(const char *pucBuffer, unsigned long ulCount)

{

    // Loop while there are more characters to send, Write the next character to the UART.

    while(ulCount--) {

        if(*pucBuffer == 'n') {

            UARTSendChar(g_DebugComNo, 'r');

        }

        UARTSendChar(g_DebugComNo, *pucBuffer++);

    }

}


#if 0

#define UARTSOF '$'

#define UARTEOF 0x0d

unsigned char RxBuffer1[100];

unsigned short RxCounter1;


void USART1_IRQHandler(void)

{

  unsigned char ucTmp;

#ifdef RTX_KERNEL

  void *msg;

#endif

#ifdef UCOS_KERNEL

    INPUT_EVENT IE;


    OS_IntEnter();

#endif


  if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)

  {

    /* Read one byte from the receive data register */

    ucTmp = USART_ReceiveData(USART1);


    if (ucTmp == UARTSOF) {

        RxCounter1 = 1;

        RxBuffer1[0] = ucTmp;

    }

    else if(ucTmp == UARTEOF) {

      /* Disable the USART1 Receive interrupt */

      //USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);

      RxBuffer1[RxCounter1] = '';        //结束符.


#ifdef RTX_KERNEL

        msg = malloc(RxCounter1);

[1] [2]
关键字:STM32 引用地址:STM32 通用底层函数集锦, 自用

上一篇:STM32的三种延时方法的代码实现_纯软件延时, 系统定时器延时, 定时器延时
下一篇:UCGUI在STM32平台移植经验(无操作系统)

推荐阅读最新更新时间:2026-03-24 00:20

STM32 通用底层函数集锦, 自用
#include xustm32.h #include xucommon.h //#define COM_DEBUG #include xudebug.h //-------------------- STM32通用函数集锦 --------------------------------------------------- #if 0 HardFault_Handler PROC ; EXPORT HardFault_Handler ; B . IMPORT hard_fault_handler_c TST LR, #4 ITE EQ
[单片机]
基于机智云与STM32的智能拐杖安全监测系统在养老物联网中的应用
随着老龄化加剧与科技进步,“ + 养老” 成为智慧养老核心方向,老年人出行安全与健康监测需求日益迫切。针对传统拐杖智能化不足、功能单一的痛点,本文提出一种融合多与物联网平台的智能拐杖系统,以 为核心主控,集成 GPS、姿态检测、超声波等传感模块,搭配 本地显示与机智云 App,实现定位、防摔、报警及云端监测一体化功能,为老年人安全出行与家庭照护提供技术支撑。 01系统总体设计 拐杖系统主要能实现GPS定位、防摔倒、障碍物检测、液晶显示、短信报警、语音提示、联网App等功能。系统总体设计结构如图1所示。 图1智能拐杖系统总体设计结构 02硬件设计 智能拐杖系统通过STM32主控芯片来传输和处理各传感设
[单片机]
基于机智云与<font color='red'>STM32</font>的智能拐杖安全监测系统在养老物联网中的应用
让人神往的STM32经验大抵如此
单片机用处这么广,尤其是STM32生态这么火!如何快速上手学习呢? 你要考虑的是,要用STM32实现什么? 为什么使用STM32而不是用8051?是因为51的频率太低,无法满足计算需求?是51的管脚太少,无法满足众多外设的IO?是51的功耗太大,电池挺不住?是51的内存太小而你要存储的东西太多?还是51的功能太弱,而你要使用SPI、I2C、ADC、DMA? 当你需要使用STM32某些功能,而51实现不了的时候,那STM32自然不需要学习,你会直接去寻找STM32某方面的使用方法。比如要用spi协议的网卡、要使用串口通信、要使用rtos等等。 寄存器vs库函数 我的观点是:当你debug的时候寄存器很重要,当你需要理解芯片工作
[单片机]
使用Rust开发STM32嵌入式程序入门教程
Why? Rust作为一门新兴语言,其安全、可靠、运行效率高等特点让它成为一门非常适合嵌入式开发的语言。本文主要介绍如何搭建Rust嵌入式开发环境,然后使用stm32h7开发板点个灯。 在嵌入式开发领域,C语言的地位是无法被撼动的(至少在2023年是这样)。用Rust开发嵌入式目前就两个目的: 玩 战未来 :) 适用对象 如果你没有接触过嵌入式编程,或者完全不懂gcc系列的开源工具链,或者完全没有接触过Rust,那么建议先了解一下相关的背景知识。 OK,Let's GO! 搭建Rust开发环境 安装Rust 首先第一步是安装Rust的开发环境。Rust开发环境的安装非常简单,参考https://ru
[单片机]
使用micropython开发STM32
一、前言 MicroPython(官网:https://micropython.org),是Python3编程语言的一个完整软件实现,用C语言编写,被优化于运行在微控制器之上。MicroPython是运行在微控制器硬件之上的完全的Python编译器和运行时系统。提供给用户一个交互式提示符(REPL)来立即执行所支持的命令。除了包括选定的核心Python库,MicroPython还包括了给予编程者访问低层硬件的模块。(摘抄自weact微行工作室)。 用我的理解简单来说,就是使用C语言往单片机里写了一个Python的解释器,再将MicroPython程序脚本保存到单片机(或外部存储器)内,然后由内部的解释器运行脚本代码。优点就是接
[单片机]
基于stm32标准库独立按键的多按键状态机的实现
写在前面 一般引用都写在最后,但是这篇博文(https://www.cnblogs.com/ZzJan/p/11334869.html)对我这个状态机的影响很大,我这里有许多借鉴他的思维。所以写在前面,以表敬意 简单按键检测 一开始学习单片机的时候我接触到按键的时候就知道按键有抖动,记得当初按键消抖分为硬件和软件,硬件上常用于复位按键如下图 硬件消抖 软件上来说,最经典的消抖 if(KEY1 == 0) { delay_ms(20); // 延时消抖 if(KEY1 == 0) { while(KEY1 == 0);//堵塞,等待松开 // 按键按下处理代码 } }
[单片机]
基于<font color='red'>stm32</font>标准库独立按键的多按键状态机的实现
STM32单片机学习】第11章 基础重点—SysTick定时器
本章实验的目的让读者熟悉STM32F103的SysTick定时器,SysTick定时器和NVIC一样,都属于Cortex-M3的内核外设资源。SysTick定时器比较简单,借此机会感受HAL库和寄存器之间调用关系,以及SysTick定时器的中断处理。本章阅读提示:11.1 关于(介绍STM32的SysTick定时器工作方式和寄存器,需要理解)11.2 硬件设计(SysTick定时器不涉及硬件)11.3 软件设计(讲解如何配置SysTick定时器、SysTick定时器的中断函数如何处理,需要理解)11.4 实验效果(展示实验效果,操作即可) 11.1 关于SysTick定时器 SysTick定时器(又名系统滴答定时器)是存在于C
[单片机]
【<font color='red'>STM32</font>单片机学习】第11章 基础重点—SysTick定时器
为什么我学了几天 STM32 感觉一脸茫然?
如果你只有C语言基础就马上学习STM32,你一定会有这些疑惑: 为什么有这么多没见过的API函数?没见过的变量(寄存器)名称? 为什么工程除了main.c,还有这么多其它没见过的文件?它们有什么用? 什么是Flash?什么是RAM?什么是ROM? 什么是寄存器?什么是时钟?什么是中断?什么是定时器?什么是DMA? 什么是端口复用与重映射?什么是ADC?什么是PWM?什么是UART?什么是IIC?什么是SPI? 什么是原理图?什么是PCB?什么是晶振?什么是复位?什么是电平?什么是上拉下拉浮空? 为什么我的helloworld c语言程序不能下载到STM32中运行?为什么下载的固是.hex文件?.hex .bin .exe文件有什么
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved