当前位置:首页 > 单片机 > 单片机
[导读]STM32的库函数操作给设计开发人员带来了诸多的便利,开发人员不必十分了解STM32的内部寄存器及硬件机制,只要有C语言基础,即可完成单片机的开发,缩短了开发周期,降低了开发难度,因而备受工程师喜爱。基于库函数的

STM32的库函数操作给设计开发人员带来了诸多的便利,开发人员不必十分了解STM32的内部寄存器及硬件机制,只要有C语言基础,即可完成单片机的开发,缩短了开发周期,降低了开发难度,因而备受工程师喜爱。

基于库函数的开发模式,与基于API(Application Programming Interface)的软件开发有着异曲同工之处,程序员通过调用 API 函数对应用程序进行开发,而又无需访问源码,或理解内部工作机制的细节,可以减轻编程任务。STM32的基于函数库的开发模式也是一样的道理,因此对于有单片机开发经验的工程师来说,学习STM32,很容易就可以上手。

虽然可以不考虑库函数内部的细节,不考虑如何实现硬件寄存器的配置,但是深入了解库函数对于提高编程能力是很有好处的,下面以系统滴答时钟为例,详解其工作流程。

滴答时钟是STM32内部的一个24位定时器,其操作相对简单,配置寄存器较少。大体的工作流程是这样的,定时器首先要有时钟源,时钟源配置好之后,设置定时时间,然后定时器启动,当定时时间到时,置位标志位,重载定时器初值,系统可采用查询标志位和中断两种工作方式做出相应的响应,下面来看看程序如何实现延时功能。

//初始化配置函数

Void Delay_Init()

{

RCC_ClocksTypeDef RCC_ClocksStatus;

RCC_GetClocksFreq(&RCC_ClocksStatus);//获取时钟频率

SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//时钟源配置为系统主时钟频率/8

SysTick_ITConfig(DISABLE);//不使能中断,采用查询方式

delay_fac_us = RCC_ClocksStatus.HCLK_Frequency / 8000000;// 1us的定时初值

}

//实现延时Nus的延时功能

void Delay_us(u32 Nus)

{

SysTick_SetReload(delay_fac_us * Nus);//载入初值

SysTick_CounterCmd(SysTick_Counter_Clear);//计数器清零

SysTick_CounterCmd(SysTick_Counter_Enable);//计数器开始计数

do

{

Status = SysTick_GetFlagStatus(SysTick_FLAG_COUNT);

}while (Status != SET);//不断查询标志位,当载入初值与计数器相等时,标志位置位。

SysTick_CounterCmd(SysTick_Counter_Disable);//关闭计数器

SysTick_CounterCmd(SysTick_Counter_Clear);//清零计数器

}

//实现闪灯

Delay_Init();

While(1)

{

LED1(ON);

Delay_us(500000);//延时500ms

LED1(OFF);

}

下面来看看库函数如何实现相应的寄存器配置。

void SysTick_ITConfig(FunctionalState NewState)

{

/* Check the parameters */

assert_param(IS_FUNCTIONAL_STATE(NewState));

if (NewState != DISABLE)

{

SysTick->CTRL |= CTRL_TICKINT_Set;

}

else

{

SysTick->CTRL &= CTRL_TICKINT_Reset;

}

}

这个函数的作用是配置寄存器开启/关闭中断,FunctionalState是自定义的数据类型,是一个枚举类型,typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;

枚举类型是一种基本数据类型而不是构造类型,它用于声明一组命名的常数,将变量的值一一列出来,变量的值只限于列举出来的值的范围内,因此当一个变量有几种可能的取值时,可以将它定义为枚举类型。

assert_param(IS_FUNCTIONAL_STATE(NewState));

这句话的作用是判断参数NewState的值是否正确,如果发现参数出错,它会调用函数assert_failed()向程序员报告错误。

void assert_failed(uint8_t* file, uint32_t line)

{

while (1)

{}

}

SysTick->CTRL |= CTRL_TICKINT_Set;这句话就是用来配置寄存器的语句, SysTick是系统定义的一个结构体如下,SysTick->CTRL即为滴答时钟的控制寄存器。

typedef struct

{

__IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */

__IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */

__IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */

__I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */

} SysTick_Type; //声明一个SysTick_Type型的结构体。

#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */

#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */

#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */

定义一个SysTick_Type类型的结构体实例SysTick,而从根本上来说这是一个地址,就是STM32芯片内部分配给滴答时钟的实际地址0xE000E000UL+0x0010UL。

CTRL_TICKINT_Set是一个宏定义,定义如下

/* CTRL TICKINT Mask */

#define CTRL_TICKINT_Set ((u32)0x00000002)

#define CTRL_TICKINT_Reset ((u32)0xFFFFFFFD)

至此,SysTick->CTRL |= CTRL_TICKINT_Set;这句话的意义已经很清晰了,就是给地址0xE000E000+0x0010 +0x000赋一个0x00000002的值,对应滴答时钟的CTRL寄存器的第2位置1。即为开启中断的意思。

上面讲的是用查询的方式,下面再说下中断触发。只需调用下面这个函数即可完成中断的设置。

SysTick_Config(uint32_t ticks);具体实现如下:

__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)

{

if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1);

SysTick->LOAD = ticks - 1;

NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);

SysTick->VAL = 0;

SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |

SysTick_CTRL_TICKINT_Msk |

SysTick_CTRL_ENABLE_Msk;

return (0);

}

函数的参数为ticks,是要装入寄存器SysTick->LOAD的计数值,如果系统时钟为72M,把ticks赋值为SystemFrequency/10000,表示计数到720个时钟周期产生一次中断,而一个时钟周期的时间为(1/72)us,所以720x(1/72)=10us,也就实现了定时10us的功能。

NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);为SysTick中断设置优先级。将寄存器SysTick->VAL的值清0。然后使能中断,使能SysTick定时器,时钟源选择为AHB时钟。当定时时间到时,进入中断函数

void SysTick_Handler(void)

{

//具体函数实现由用户编写。

}

通过对这样一个简单定时器的操作,我们可以初步了解到STM32库函数的使用方法,其实开发人员没必要深究库函数内部是如何处理实现的,只需要了解已经封装好的库函数,进行调用即可,因此可以大大降低开发周期,提高开发效率,更多的功能留给读者自行研究开发。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

智能合灯控制系统由环境光照检测、人体接近检测、语音识别、按键控制、合灯控制、数据显示、蓝牙通信、报警提示功能模块组成。

关键字: STM32 智能台灯

捡球机的移动装置以直流电机驱动,寻球装置以摄像头图像传感器模块构成,并搭配以图像检测算法。避障装置以红外检测和报警模块为主,以防在行动过程中触碰障碍物。

关键字: STM32 捡球机

ST于近期发布了“STM32WBA”无线MCU、“STM32U0”超低功耗入门级MCU、“STM32H7R/S”高性能MCU和“STM32MP2”四大重磅新品,还透露将会在今年推出18nm的STM32新品。

关键字: STM32 MCU NPU AI 超低功耗

在微控制器领域,MSP430与STM32无疑是两颗璀璨的明星。它们各自凭借其独特的技术特点和广泛的应用领域,在市场上占据了重要的位置。本文将深入解析MSP430与STM32之间的区别,探讨它们在不同应用场景下的优势和局限...

关键字: MSP430 STM32 单片机

STM32是由意法半导体公司(STMicroelectronics)推出的基于ARM Cortex-M内核的32位微控制器系列,以其高性能、低功耗、丰富的外设接口和强大的生态系统深受广大嵌入式开发者喜爱。本文将详细介绍S...

关键字: STM32 单片机

STM32与51单片机之间有什么差异呢?两者可以说是一场科技与性能的较量了。在科技飞速发展的今天,微控制器(MCU)已广泛应用于各类电子设备和系统中,发挥着举足轻重的作用。其中,STM32和51单片机作为两种常见的微控制...

关键字: STM32 51单片机 MCU

电磁铁是一种利用电流产生磁场的装置,具有快速响应、易于控制等特点,在工业自动化、电子设备、科学实验等领域有着广泛的应用。STM32是一款功能强大的微控制器,具有高性能、低功耗、易于编程等优点,是控制电磁铁的理想选择。本文...

关键字: 电磁铁 微控制器 STM32

边缘人工智能的实现涉及到三个基本 要素:安全性,连接性、自主性,而其中自主性是AI能力的体现,也是边缘AI有别于其他传统的物联网的关键。而通过ST Edge AI套件,就可以帮助各种不同类型的开发者实现覆盖全硬件平台的全...

关键字: 边缘人工智能 AI STM32

今天,小编将在这篇文章中为大家带来STM32单片机最小系统的有关报道,通过阅读这篇文章,大家可以对它具备清晰的认识,主要内容如下。

关键字: 单片机 单片机最小系统 STM32

STM32是一款由STMicroelectronics生产的微控制器系列,具有高性能、低功耗和丰富的外设资源。其中,串口通信是一种常用的通信方式,可以实现与其他设备之间的数据传输。

关键字: STM32 串口通信 微控制器
关闭
关闭