STM32学习之GPIO与SYSTICK使用+软件仿真

发布者:MindfulYogi最新更新时间:2021-06-30 来源: eefocus关键字:STM32  GPIO  软件仿真 手机看文章 扫描二维码
随时随地手机看文章

简介:小弟也是刚刚学习STM32,有什么不懂的还望大师们指点。以下程序是利用SYSTICK作为延时程序使GPIOA_Pin0产生1S的电压变化。初学,也就会这些了,拿出来与大家分享一下。

#include"stm32f10x_conf.h"

void delay_ms(u32 ms); 声明延时函数

void GPIO_Config(void); 声明GPIO配置函数

int main(void) 主程序

{

SystemInit(); 初始化系统时钟默认72MHZ

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 使能GPIOA时钟

GPIO_Config(); 调用GPIO配置函数

while(1)

{

GPIO_SetBits(GPIOA,GPIO_Pin_0); GPIOA的 Pin0脚置1(高电平

delay_ms(1000); 延时1000ms=1s

GPIO_ResetBits(GPIOA,GPIO_Pin_0);GPIOA的 Pin0脚置0(低电平)

delay_ms(1000); 延时1000ms=1s


}


}

void GPIO_Config(void) 配置GPIOA函数

{

GPIO_InitTypeDef GPIO_InitStruct;

GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;

GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;

GPIO_InitStruct.GPIO_Speed=GPIO_Speed_2MHz;

GPIO_Init(GPIOA,&GPIO_InitStruct);


}


void delay_ms(u32 ms) 延时函数,重点!

{

int temp;

SysTick->CTRL=0x01;

SysTick->LOAD=9000*ms;

SysTick->VAL=0x00;

do

{

temp=SysTick->CTRL;

}

while((temp&0x01)&&(!(temp&(1<<16))));


}


下面我把延时函数系统讲一下:


延时函数主要用到的是systick,也叫滴答系统时钟。我只知道systick其中的一个功能就是可以做定时器用而且非常精准,其他的许多功能还在研究。


systick的4个寄存器,CTRL-控制寄存器,LOAD-重装载寄存器,VAL-当前值寄存器,CALIB-校准寄存器。


SYSTICK_CTRL 寄存器中只有0,1,2,16这四位是有效的。


第 0 位:ENABLE,Systick 使能位 (0:关闭 Systick 功能;1:开启 Systick功能)

第 1 位:TICKINT,Systick 中断使能位 (0:关闭 Systick 中断;1:开启Systick 中断)

第 2 位:CLKSOURCE,Systick 时钟源选择 (0:使用 HCLK/8 作为 Systick时钟;1:使用 HCLK 作为 Systick 时钟)

第16 位:COUNTFLAG,有些人这样说的: SysTick 已经数到了 0,则该位为 1。如果读取该位,该位将自动清零(我不太理解这句话,我的疑问是SYSTICK数到了0是不是说VAL寄存器从重装载值递减到了0,第二个就是SYSTICK数到0之后这个位是保持1还是返回到0,读取该位自动清0是什么时候读取。)这个先埋个疑问一会说说我的理解。


SYSTICK_LOAD重装载寄存器,不用多说,假如你让systick_val寄存器从100递减到0,这个寄存器里面装的就是100,只不过用二进制表示,但是这个寄存器虽然是32位的,但只有24位有效,其最高的八位保留,它能装入最大值为0xFFFFFF(0xFFFFFF==0x00FFFFFF,C语言中二者的值是一样的,如0x01==0x0001==0x00000001)。


SYSTICK_CAL 当前值寄存器,书上说读取它时返回当前寄存器的值,对他进行写操作则清0,同时也对上面所说SYSTICK_CTRL中 第16位清0。我理解是这样的,这个寄存器里面的值是不断变化的,一个指令周期完成一次自减,至于如何自减我们无须讨论太多,只需知道若选择1KHZ的频 率,则它在1秒的时间里可以变化1000次,每变化一次便可自减一次,换句话说,我们将1000装入它时开始计时,逐步递减999,998......到 它减到0计时结束刚好耗时1秒。


SYSTICK_CALIB 校准寄存器,这个还没研究透(都说一般用不到,但最终还得弄明白它),sorry!


那么SYSTICK 的工作流程到底是怎样实现定时的呢,下面以定时1ms为例。


1s=1000ms=1000000us,首先配置SysTick->CTRL=0x01;对照上面便知,先使能SYSTICK,关闭了中断,选择HCLK/8位工作频率,状态标志位清零;然后SysTick->LOAD=9000*ms;设置重装载寄存器的值,我们的系统时钟是72MHZ,上面我们选择的8分频也就是9MHZ,也就是说1ms变化9000次,然后SysTick->VAL=0x00;清 零当前寄存器值,前面我们说了,VAL寄存器是不断自减的,并且只要它为0(无论是被写入0还是自减到0)就自动装入LOAD寄存器中的值再一次开始递 减,这样循环往复,那么VAL为0时的第二个动作是将CTAL寄存器的16位状态位置1,而我们就是通过读取CTAL寄存器的16位状态位才能知道是否到 了1ms,这里也说一下上面埋下的疑问,这个状态位其实像一个监视器一样监视着VAL寄存器,只要VAL为0,它立刻置1,并且一直保持,直到对它读取时 它才又一次被清0。


紧接着判断1ms是否达到,do{...}while(...)语句,主要判断CTRL寄存器中的16位是否为1,temp=SysTick->CTRL;将CTRL中的值传递给变量temp,注意while中的是重点,while((temp&0x01)&&(!(temp&(1<<16))));说 实话我看到这个语句真的不知道什么意思,C语言学的还不算透彻,这里面其实不只是判断CTRL中的标志位,还判断了systick是否失能,如果 systick失能则在此处为0继续执行程序不再进行判断。先整体看看这个语句的结构,语句1&&语句2,这个“&&” 表示逻辑与操作和按位与“&”相似,是有顺序执行的,先判断语句1,如果是真则判断语句2,语句2为真则结果为真(1),语句2为假则结果为假 (0);若语句1为假,则不再对语句2进行判断,直接输出为假(0)。那么如上,语句1(temp&0x01)是判断systick是使能还是失 能,若使能则语句1为真继续判断语句2,若失能则语句1为假,则整个语句为假程序向下执行,不再循环。既然语句1为真则继续判断语句2(!(temp&(1<<16)),它才是真正判断CTRL标志位的,这个应该很好理解,如果CTRL标志位为1,则语句2为假(0),则整个语句为假(0),向下执行程序(systick正好产生了1ms的时间间隔)。




这么点程序,其实要说的可真不少,ARM真的太深奥了。以上这种方式是对寄存器直接操作,也可用stm32 提供的SYSTICK函数,不过我感觉想弄懂它是怎么工作的还是要学习它相关的寄存器。函数库只是为了方便开发,在开发大程序是有一定的优势。好了最后看一下我的软仿图吧:





关键字:STM32  GPIO  软件仿真 引用地址:STM32学习之GPIO与SYSTICK使用+软件仿真

上一篇:基于STM32LED书写点阵屏设计与实现
下一篇:关于STM32的I2C硬件DMA实现

推荐阅读最新更新时间:2024-11-10 16:46

stm32看门狗的特点是什么
stm32看门狗部分内容当中较难理解的是窗口看门狗,其中窗口值设置以及如何引发复位更是很难搞懂,因此从根本上分析一下窗口看门狗的工作原理,而与其有关的中断则略过。 stm32有两个看门狗,独立看门狗和窗口看门狗,其实两者的功能是类似的,只是喂狗的限制时间不同。独立看门狗有自己独立的40Khz时钟,不存在使能问题;而窗口看门狗使用的是PCLK1时钟,需要先使能时钟。以下是关于看门狗的具体说明: ①、独立看门狗是限制喂狗时间在0-x内,x由你的相关寄存器决定。喂狗的时间不能过晚。 ②、窗口看门狗,所以称之为窗口就是因为其喂狗时间是一个有上下限的范围内,你可以通过设定相关寄存器,设定其上限时间和下限时间。喂狗的时间不能过早也不能过晚
[单片机]
如何修改STM32系统时钟
一般的STM32控制板搭载的是8M晶振。我们也熟悉了8M晶振的使用方法。但是,当遇到12M晶振是如何修改STM32系统时钟呢? 具体步骤如下: 第一步,全局搜索HSE_VALUE #define HSE_VALUE ((uint32_t)8000000) /*! Value of the External oscillator in Hz */ 修改为: #define HSE_VALUE ((uint32_t)12000000) /*! Value of the External oscillator in Hz */ 第二步,打开system_stm32f10x.c,修改PLL参数,将 /* PLL
[单片机]
用C++开发STM32程序
我们知道KEIL是支持C++的,网上一搜索也能找到一些使用C++的方法,无非是在Keil里的options- C/C++- Misc Controls里添加—cpp,如果要支持c++11,还需要指定—cpp11。事实上这样的C++并不是完整意义的上的C++,本人测试过,有好多C++的新功能都是没有办法实现的。这里需要注明的是,在KEIL5.18a以前的版本(包括5.18a)所支持的Arm Compiler只有ARM Compiler 5以及更低的版本,C++11支持不完整,而对C++11有完整支持就必须要使用Arm Compiler 6 即 AC6。 为了使用对C++11有完整支持的Arm Compiler 6(AC6),今天所使
[单片机]
用C++开发<font color='red'>STM32</font>程序
stm32的中断与事件
事件:是表示检测有一某件触发事件发生了。 中断:有某个事件发生并产生中断,并跳转到对应的中断处理程序中。 事件可以触发中断,也可以不触发 中断有可能被更优先的中断屏蔽,事件不会 事件本质上就是一个触发信号,是用来触发特定的外设模块或核心本身(唤醒). 事件只是一个触发信号(脉冲),而中断则是一个固定的电平信号
[单片机]
STM32】HAL库-系统滴答定时器SysTick
SysTick定时器被捆绑在NVIC中,是一个简单的定时器,对于CM3、CM4内核芯片,都有Systick定时器。Systick定时器常用来做延时,或者实时系统的心跳时钟。这样可以节省MCU资源,不用浪费一个定时器。 Systick定时器就是系统滴答定时器,一个24 位的倒计数定时器,计到0 时,将从RELOAD 寄存器中自动重装载定时初值。 系统滴答定时器有4个寄存器 时钟源 该定时器的时钟源可以是 内部时钟(FCLK,CM3上的自由运行时钟) 外部时钟( CM3处理器上的STCLK信号) 通过SysTick控制及状态寄存器的第2位来确定 STM32的时钟树 RCC通过AHB时钟(HCLK)8分频或者不分
[单片机]
【<font color='red'>STM32</font>】HAL库-系统滴答定时器<font color='red'>SysTick</font>
STM8库函数开发手册(1) //工程模板、GPIO、时钟
第一部分 创建库函数工程 1、创建文件目录 BSP文件夹中存放自定义底层驱动程序文件; IAR文件夹存放IAR工程文件; LIB 文件夹中引入C 语言自己的库函数; USR 文件夹中存放自定义主程序及数据库头文件等; Readme 文件夹中存放自定义程序设计说明文件; 2、将STM8库函数文件拷贝入LIB文件夹 链接: https://pan.baidu.com/s/1llVx9meEhhk0VYKbsKzLxwpan.baidu.com 提取码:iy3v 下载解压后进入官方库函数目录: 打开LibrariesSTM8S_StdPeriph_Driver文件夹,找到inc 和src文件夹 就是我们的官方库文件啦 将
[单片机]
STM8库函数开发手册(1) //工程模板、<font color='red'>GPIO</font>、时钟
STM32上移植FreeModbus RTU的一点经验总结
这几天因为工作需要,移植了modbus RTU到STM32来,之前也听说过modbus,但是没有深入了解过,还以为会像usb 那样复杂的,经过这几天的折腾,发现真的太简单了。为了防止过段时间又忘记了怎么移植,在这里把移植过程记录下来,也为了方便初次接触modbus的人。 废话少说,首先去下载源码,我下载的是freemodbus-v1.5.0,解压后如图所示: 在demo文件夹中有很多移植好的例子,但是没有STM32的,不要紧,我们参考已有的例子来操作就可以了。在demo文件夹下新建一个文件夹,命名为STM32,将BARE文件夹里的文件全部复制过来。 然后,我们建立一个STM32的工程,我用的是mdk4.72,关于怎么建
[单片机]
在<font color='red'>STM32</font>上移植FreeModbus RTU的一点经验总结
stm32 ADC理解
神通广大的各位互联网的网友们、大家早上中午晚上好好好、今早起来很准时的收到了两条10086的扣月租的信息、心痛不已、怀着这心情、又开始了STM32的研究、早上做了计算机控制的PID实验,又让我想起了飞思卡尔的电磁小车、、曾经的电感电压采集让我心碎的多少次、又让我开心了多少次、但已经成为过去、(软件和硬件都会影响),呵呵、估计有人已经猜到我接下来要介绍什么了、在你们面前、我已无秘密、额、其实标题也直接“表白”了、看到标题,别吓到哈、并不是要用英文写、至于原因是什么、请往下看: 好吧、言归正传:STM32的ADC模块,请允许我用如此通俗的语言:普通话 来介绍STM32ADC模块的特色 1、1MHz转换速率、12位转换结果(12
[单片机]
<font color='red'>stm32</font> ADC理解
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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