STM32跑马灯实验

3.1 跑马灯实验

通过本节的学习,你将了解到STM32的IO口作为输出使用的方法。本节分为如下几个小节:

3.1.1 STM32 IO口简介 3.1.2 硬件设计 3.1.3 软件设计 3.1.4 仿真与下载

3.1.1 STM32 IO简介

作为所有开发板的经典入门实验,莫过于跑马灯了。ALIENTEK MiniSTM32开发板板载了2个LED,DS0和DS1,本实验将通过教你如何控制这两个灯实现交替闪烁的类跑马灯效果。

该实验的关键在于如何控制STM32的IO口输出。了解了STM32的IO口如何输出的,就可以实现跑马灯了。通过这一节的学习,你将初步掌握STM32基本IO口的使用,而这是迈向STM32的第一步。

STM32的IO口可以由软件配置成8种模式: 1、输入浮空 2、输入上拉 3、输入下拉 4、模拟输入 5、开漏输出 6、推挽输出

7、推挽式复用功能 8、开漏复用功能

每个IO口可以自由编程,单IO口寄存器必须要按32位字被访问。STM32的很多IO口都是5V兼容的,这些IO口在与5V电平的外设连接的时候很有优势,具体哪些IO口是5V兼容的,可以从该芯片的数据手册管脚描述章节查到(I/O Level标FT的就是5V电平兼容的)。

STM32的每个IO端口都有7个寄存器来控制。他们分别是:配置模式的2个32位的端口配置寄存器CRL和CRH;2个32位的数据寄存器IDR和ODR;1个32位的置位/复位寄存器BSRR;一个16位的复位寄存器BRR;1个32位的所存寄存器LCKR;这里我们仅介绍常用 的几个寄存器,我们常用的IO端口寄存器只有4个:CRL、CRH、IDR、ODR。

CRL和CRH控制着每个IO口的模式及输出速率。 STM32的IO口位配置表如表3.1.1.1所示:

表3.1.1.1 STM32的IO口位配置表 STM32输出模式配置如表3.1.1.2所示:

表3.1.1.2 STM32输出模式配置表

接下来我们看看端口低配置寄存器CRL的描述,如下图所示:

图3.1.1.1 端口低配置寄存器CRL各位描述

该寄存器的复位值为0X4444 4444,从上图可以看到,复位值其实就是配置端口为浮空输入模式。从上图还可以得出:STM32的CRL控制着每个IO端口(A~G)的低8位的模式。每个IO端口的位占用CRL的4个位,高两位为CNF,低两位为MODE。这里我们可以记住几个常用的配置,比如0X4表示模拟输入模式(ADC用)、0X3表示推挽输出模式(做输出口用,50M速率)、0X8表示上/下拉输入模式(做输入口用)、0XB表示复用输出(使用IO口的第二功能,50M速率)。

CRH的作用和CRL完全一样,只是CRL控制的是低8位输出口,而CRH控制的是高8位输出口。这里我们对CRH就不做详细介绍了。

给个实例,比如我们要设置PORTC的11位为上拉输入,12位为推挽输出。代码如下: GPIOC->CRH&=0XFFF00FFF;//清掉这2个位原来的设置,同时也不影响其他位的设置 GPIOC->CRH|=0X00038000; //PC11输入,PC12输出 GPIOC->ODR=1

通过这3句话的配置,我们就设置了PC11为上拉输入,PC12为推挽输出。

IDR是一个端口输入数据寄存器,只用了低16位。该寄存器为只读寄存器,并且只能以16位的形式读出。该寄存器各位的描述如下图所示:

图3.1.1.2 端口输入数据寄存器IDR各位描述

要想知道某个IO口的状态,你只要读这个寄存器,再看某个位的状态就可以了。使用起来是比较简单的。

ODR是一个端口输出数据寄存器,也只用了低16位。该寄存器虽然为可读写,但是从该寄存器读出来的数据都是0。只有写是有效的。其作用就是控制端口的输出。该寄存器的各位描述如下图所示:

图3.1.1.3 端口输出数据寄存器ODR各位描述

了解了这几个寄存器,我们就可以开始跑马灯实验的真正设计了。关于IO口更详细的介绍,请参考《STM32参考手册》第69页7.1节。

3.1.2 硬件设计

该实验的硬件电路在ALIENTEM Mini STM32开发板上已经连接好了。DS0接PA8,DS1接PD2。所以在硬件上不需要动任何东西。其连接原理图如下:

图3.1.2.1 LED与STM32连接原理图

3.1.3 软件设计

首先,找到之前新建的TEST工程,在该文件夹下面新建一个HARDWARE的文件夹,用来存储以后与硬件相关的代码。然后在HARDWARE文件夹下新建一个LED文件夹,用来存放与LED相关的代码。如下图所示:

图3.1.3.1 新建HARDWARE文件夹

按钮新建一个文件,然后保存在

然后我们打开USER文件夹下的TEST.Uv2

工程,按

HARDWARE->LED文件夹下面,保存为led.c。在该文件中输入如下代码:

#include #include

//Mini STM32开发板 //LED驱动代码 //正点原子@ALIENTEK //2010/5/27

// V1.0

//初始化PA8和PD2为输出口.并使能这两个口的时钟

//LED IO初始化 void LED_Init(void) { RCC->APB2ENR|=1

RCC->APB2ENR|=1CRH&=0XFFFFFFF0; GPIOA->CRH|=0X00000003;//PA8 推挽输出 GPIOA->ODR|=1CRL&=0XFFFFF0FF;

GPIOD->CRL|=0X00000300;//PD.2推挽输出 GPIOD->ODR|=1

该代码里面就包含了一个函数void LED_Init(void),该函数的功能就是用来实现配置PA8和PD2为推挽输出。在配置STM32外设的时候,任何时候都要先使能该外设的时钟!APB2ENR是APB2总线上的外设时钟使能寄存器,其各位的描述如下:

图3.1.3.2 寄存器APB2ENR各位描述

我们要使能的PORTA和PORTD的时钟使能位,分别在bit2和bit5,只要将这两位置1就可以使能PORTA和PORTD的时钟了。该寄存器还包括了很多其他外设的时钟使能。大家在以后会慢慢使用到的。关于这个寄存器的详细说明在《STM32参考手册》的第61页。

在设置完时钟之后就是配置完时钟之后,LED_Init配置了PA8和PD2的模式为推挽输出,并且默认输出1。这样就完成了对这两个IO口的初始化。

保存led.c代码,然后我们按同样的方法,新建一个led.h文件,也保存在LED文件夹下面。在led.h中输入如下代码:

#ifndef __LED_H #define __LED_H #include

//Mini STM32开发板 //LED驱动代码 //正点原子@ALIENTEK //2010/5/27

//LED端口定义

#define LED0 PAout(8)// PA8 #define LED1 PDout(2)// PD2 void LED_Init(void);//初始化 #endif

这段代码里面最关键就是2个宏定义: #define LED0 PAout(8)// PA8 #define LED1 PDout(2)// PD2

这里使用的是位带操作来实现操作某个IO口的1个位的,关于位带操作前面已经有介绍,这里不再多说。需要说明的是,这里可以使用另外一种操作方式实现。如下:

#define LED0 (1

#define LED1 (1

#define LED0_SET(x) GPIOA->ODR=(GPIOA->ODR&~LED0)|(x ? LED0:0) #define LED1_SET(x) GPIOD->ODR=(GPIOD->ODR&~LED1)|(x ? LED1:0)

后者通过LED0_SET(0)和LED0_SET(1)来控制PA8的输出0和1。而前者的类似操作为:LED0=0和LED0=1。显然前者简单很多,从而可以看出位带操作带来的好处。以后像这样的IO口操作,我们都使用位带操作来实现,而不使用第二种方法。

将led.h也保存一下。接着,我们在Manage Components管理里面新建一个HARDWARE的组,并把led.c加入到这个组里面,如下图所示:

图3.1.3.3 给工程新增HARDWARE组

单击OK,回到工程,然后你会发现在Project Workspace里面多了一个HARDWARE的组,在改组下面有一个led.c的文件。如下图所示:

图3.1.3.4给工程新增HARDWARE组

然后用之前介绍的方法将led.h头文件的路径加入到工程里面。回到主界面,在main函数里面编写如下代码:

#include

#include

//Mini STM32开发板范例代码1 //跑马灯实验

//正点原子@ALIENTEK //2010.5.27 int main(void) {

Stm32_Clock_Init(9); //系统时钟设置 delay_init(72); //延时初始化 LED_Init(); //初始化与LED连接的硬件接口 while(1) {

LED0=0; LED1=1;

delay_ms(300); LED0=1; LED1=0;

delay_ms(300); } }

代码先包含了#include

然后按

,编译工程,得到结果如下图所示:

图3.1.3.5编译结果

可以看到没有错误,也没有警告。接下来,我们就先进行软件仿真,验证一下是否有错误的地方,然后下载到Mini STM32看看实际运行的结果。

3.1.4 仿真与下载

我们可以先用软件仿真,看看结果对不对,根据软件仿真的结果,然后再下载到MINI

STM32板子上面看运行是否正确。

首先,我们进行软件仿真。

先按

开始仿真,接着按

,显示逻辑分析窗口,点击Setup,

新建两个信号PORTA.8和PORTD.2,如下图所示:

图3.1.4.1逻辑分析设置

Display Type选择bit,然后单击Close关闭该对话框,可以看到逻辑分析窗口出来了2个信号,如下图所示:

图3.1.4.2设置后的逻辑分析窗口

,开始运行。运行一段时间之后,按

按钮,暂停仿真回到逻辑分析窗口,

接着,点击

可以看到如下波形:

图3.1.4.3 仿真波形

这里注意Gird要调节到0.25s左右比较合适,可以通过Zoom里面的In按钮来放大波形,通过Out按钮来缩小波形,或者按All显示全部波形。从上图中可以看到PORTD.2和PORTA.8交替输出,周期可以通过中间那根红线来测量。至此,我们的软件仿真已经顺利通过。

在软件仿真没有问题了之后,我们就可以把代码下载到Mini STM32观看运行结果是否与我们仿真的一致。运行结果如下图所示:

图3.1.4.4 执行结果

至此,我们的第一节学习就结束了,这一节,作为STM32的入门第一个例子,详细介绍了STM32的IO口操作,同时巩固了前面的学习,并进一步介绍了MDK的软件仿真功能。希望大

3.1 跑马灯实验

通过本节的学习,你将了解到STM32的IO口作为输出使用的方法。本节分为如下几个小节:

3.1.1 STM32 IO口简介 3.1.2 硬件设计 3.1.3 软件设计 3.1.4 仿真与下载

3.1.1 STM32 IO简介

作为所有开发板的经典入门实验,莫过于跑马灯了。ALIENTEK MiniSTM32开发板板载了2个LED,DS0和DS1,本实验将通过教你如何控制这两个灯实现交替闪烁的类跑马灯效果。

该实验的关键在于如何控制STM32的IO口输出。了解了STM32的IO口如何输出的,就可以实现跑马灯了。通过这一节的学习,你将初步掌握STM32基本IO口的使用,而这是迈向STM32的第一步。

STM32的IO口可以由软件配置成8种模式: 1、输入浮空 2、输入上拉 3、输入下拉 4、模拟输入 5、开漏输出 6、推挽输出

7、推挽式复用功能 8、开漏复用功能

每个IO口可以自由编程,单IO口寄存器必须要按32位字被访问。STM32的很多IO口都是5V兼容的,这些IO口在与5V电平的外设连接的时候很有优势,具体哪些IO口是5V兼容的,可以从该芯片的数据手册管脚描述章节查到(I/O Level标FT的就是5V电平兼容的)。

STM32的每个IO端口都有7个寄存器来控制。他们分别是:配置模式的2个32位的端口配置寄存器CRL和CRH;2个32位的数据寄存器IDR和ODR;1个32位的置位/复位寄存器BSRR;一个16位的复位寄存器BRR;1个32位的所存寄存器LCKR;这里我们仅介绍常用 的几个寄存器,我们常用的IO端口寄存器只有4个:CRL、CRH、IDR、ODR。

CRL和CRH控制着每个IO口的模式及输出速率。 STM32的IO口位配置表如表3.1.1.1所示:

表3.1.1.1 STM32的IO口位配置表 STM32输出模式配置如表3.1.1.2所示:

表3.1.1.2 STM32输出模式配置表

接下来我们看看端口低配置寄存器CRL的描述,如下图所示:

图3.1.1.1 端口低配置寄存器CRL各位描述

该寄存器的复位值为0X4444 4444,从上图可以看到,复位值其实就是配置端口为浮空输入模式。从上图还可以得出:STM32的CRL控制着每个IO端口(A~G)的低8位的模式。每个IO端口的位占用CRL的4个位,高两位为CNF,低两位为MODE。这里我们可以记住几个常用的配置,比如0X4表示模拟输入模式(ADC用)、0X3表示推挽输出模式(做输出口用,50M速率)、0X8表示上/下拉输入模式(做输入口用)、0XB表示复用输出(使用IO口的第二功能,50M速率)。

CRH的作用和CRL完全一样,只是CRL控制的是低8位输出口,而CRH控制的是高8位输出口。这里我们对CRH就不做详细介绍了。

给个实例,比如我们要设置PORTC的11位为上拉输入,12位为推挽输出。代码如下: GPIOC->CRH&=0XFFF00FFF;//清掉这2个位原来的设置,同时也不影响其他位的设置 GPIOC->CRH|=0X00038000; //PC11输入,PC12输出 GPIOC->ODR=1

通过这3句话的配置,我们就设置了PC11为上拉输入,PC12为推挽输出。

IDR是一个端口输入数据寄存器,只用了低16位。该寄存器为只读寄存器,并且只能以16位的形式读出。该寄存器各位的描述如下图所示:

图3.1.1.2 端口输入数据寄存器IDR各位描述

要想知道某个IO口的状态,你只要读这个寄存器,再看某个位的状态就可以了。使用起来是比较简单的。

ODR是一个端口输出数据寄存器,也只用了低16位。该寄存器虽然为可读写,但是从该寄存器读出来的数据都是0。只有写是有效的。其作用就是控制端口的输出。该寄存器的各位描述如下图所示:

图3.1.1.3 端口输出数据寄存器ODR各位描述

了解了这几个寄存器,我们就可以开始跑马灯实验的真正设计了。关于IO口更详细的介绍,请参考《STM32参考手册》第69页7.1节。

3.1.2 硬件设计

该实验的硬件电路在ALIENTEM Mini STM32开发板上已经连接好了。DS0接PA8,DS1接PD2。所以在硬件上不需要动任何东西。其连接原理图如下:

图3.1.2.1 LED与STM32连接原理图

3.1.3 软件设计

首先,找到之前新建的TEST工程,在该文件夹下面新建一个HARDWARE的文件夹,用来存储以后与硬件相关的代码。然后在HARDWARE文件夹下新建一个LED文件夹,用来存放与LED相关的代码。如下图所示:

图3.1.3.1 新建HARDWARE文件夹

按钮新建一个文件,然后保存在

然后我们打开USER文件夹下的TEST.Uv2

工程,按

HARDWARE->LED文件夹下面,保存为led.c。在该文件中输入如下代码:

#include #include

//Mini STM32开发板 //LED驱动代码 //正点原子@ALIENTEK //2010/5/27

// V1.0

//初始化PA8和PD2为输出口.并使能这两个口的时钟

//LED IO初始化 void LED_Init(void) { RCC->APB2ENR|=1

RCC->APB2ENR|=1CRH&=0XFFFFFFF0; GPIOA->CRH|=0X00000003;//PA8 推挽输出 GPIOA->ODR|=1CRL&=0XFFFFF0FF;

GPIOD->CRL|=0X00000300;//PD.2推挽输出 GPIOD->ODR|=1

该代码里面就包含了一个函数void LED_Init(void),该函数的功能就是用来实现配置PA8和PD2为推挽输出。在配置STM32外设的时候,任何时候都要先使能该外设的时钟!APB2ENR是APB2总线上的外设时钟使能寄存器,其各位的描述如下:

图3.1.3.2 寄存器APB2ENR各位描述

我们要使能的PORTA和PORTD的时钟使能位,分别在bit2和bit5,只要将这两位置1就可以使能PORTA和PORTD的时钟了。该寄存器还包括了很多其他外设的时钟使能。大家在以后会慢慢使用到的。关于这个寄存器的详细说明在《STM32参考手册》的第61页。

在设置完时钟之后就是配置完时钟之后,LED_Init配置了PA8和PD2的模式为推挽输出,并且默认输出1。这样就完成了对这两个IO口的初始化。

保存led.c代码,然后我们按同样的方法,新建一个led.h文件,也保存在LED文件夹下面。在led.h中输入如下代码:

#ifndef __LED_H #define __LED_H #include

//Mini STM32开发板 //LED驱动代码 //正点原子@ALIENTEK //2010/5/27

//LED端口定义

#define LED0 PAout(8)// PA8 #define LED1 PDout(2)// PD2 void LED_Init(void);//初始化 #endif

这段代码里面最关键就是2个宏定义: #define LED0 PAout(8)// PA8 #define LED1 PDout(2)// PD2

这里使用的是位带操作来实现操作某个IO口的1个位的,关于位带操作前面已经有介绍,这里不再多说。需要说明的是,这里可以使用另外一种操作方式实现。如下:

#define LED0 (1

#define LED1 (1

#define LED0_SET(x) GPIOA->ODR=(GPIOA->ODR&~LED0)|(x ? LED0:0) #define LED1_SET(x) GPIOD->ODR=(GPIOD->ODR&~LED1)|(x ? LED1:0)

后者通过LED0_SET(0)和LED0_SET(1)来控制PA8的输出0和1。而前者的类似操作为:LED0=0和LED0=1。显然前者简单很多,从而可以看出位带操作带来的好处。以后像这样的IO口操作,我们都使用位带操作来实现,而不使用第二种方法。

将led.h也保存一下。接着,我们在Manage Components管理里面新建一个HARDWARE的组,并把led.c加入到这个组里面,如下图所示:

图3.1.3.3 给工程新增HARDWARE组

单击OK,回到工程,然后你会发现在Project Workspace里面多了一个HARDWARE的组,在改组下面有一个led.c的文件。如下图所示:

图3.1.3.4给工程新增HARDWARE组

然后用之前介绍的方法将led.h头文件的路径加入到工程里面。回到主界面,在main函数里面编写如下代码:

#include

#include

//Mini STM32开发板范例代码1 //跑马灯实验

//正点原子@ALIENTEK //2010.5.27 int main(void) {

Stm32_Clock_Init(9); //系统时钟设置 delay_init(72); //延时初始化 LED_Init(); //初始化与LED连接的硬件接口 while(1) {

LED0=0; LED1=1;

delay_ms(300); LED0=1; LED1=0;

delay_ms(300); } }

代码先包含了#include

然后按

,编译工程,得到结果如下图所示:

图3.1.3.5编译结果

可以看到没有错误,也没有警告。接下来,我们就先进行软件仿真,验证一下是否有错误的地方,然后下载到Mini STM32看看实际运行的结果。

3.1.4 仿真与下载

我们可以先用软件仿真,看看结果对不对,根据软件仿真的结果,然后再下载到MINI

STM32板子上面看运行是否正确。

首先,我们进行软件仿真。

先按

开始仿真,接着按

,显示逻辑分析窗口,点击Setup,

新建两个信号PORTA.8和PORTD.2,如下图所示:

图3.1.4.1逻辑分析设置

Display Type选择bit,然后单击Close关闭该对话框,可以看到逻辑分析窗口出来了2个信号,如下图所示:

图3.1.4.2设置后的逻辑分析窗口

,开始运行。运行一段时间之后,按

按钮,暂停仿真回到逻辑分析窗口,

接着,点击

可以看到如下波形:

图3.1.4.3 仿真波形

这里注意Gird要调节到0.25s左右比较合适,可以通过Zoom里面的In按钮来放大波形,通过Out按钮来缩小波形,或者按All显示全部波形。从上图中可以看到PORTD.2和PORTA.8交替输出,周期可以通过中间那根红线来测量。至此,我们的软件仿真已经顺利通过。

在软件仿真没有问题了之后,我们就可以把代码下载到Mini STM32观看运行结果是否与我们仿真的一致。运行结果如下图所示:

图3.1.4.4 执行结果

至此,我们的第一节学习就结束了,这一节,作为STM32的入门第一个例子,详细介绍了STM32的IO口操作,同时巩固了前面的学习,并进一步介绍了MDK的软件仿真功能。希望大


相关内容

  • 基于线性霍尔传感器的磁场检测装置设计
  • 桂林理工大学信息科学与工程学院 感知技术 课程设计(实习)报告 题目: 的磁场检测装置设计 专业(方向):物联网工程 班级:物联网学生: 学号: 组员:覃俊华 指导老师:蒋存波老师.汪彦君老师 2016年1月9日 13-1班 目次 1.1 1.2 1.3 1. 绪论................. ...

  • 基于Cortex_M3的自动气象站设计
  • 电子技术设计与应用 Electronics Design & Application 基于Cortex-M3的自动气象站设计 张惠捷 钟 鼎 (中国地质大学机械与电子信息学院) 摘 要:设计了一种气象数据采集系统,该系统能采集温度.湿度.气压.风速4个气象要素,采集的原始数据保存在本地SD ...

  • 创新项目结题报告
  • 大学生创新创业训练项目 结题报告 项目名称: 远程无线信息发布系统 项目级别:[ ]国家级 [ ]省级 [√]院级 项目负责人: xxx 所在系部: 计算机工程系 专业班级: 计算机科学与技术xxx 联系电话: xxx E - mail:项目组成员: xxx 指导教师: xxx 职称 讲师 填表日期 ...

  • 电机驱动 毕业设计
  • 基于STM32的电机驱动系统的设计 专业:机电工程系 班级: 姓名: 徐斐斐 目 录 引 言 ....................................................................................................... ...

  • [经验]谈下单片机和嵌入式的学习心得,希望对新手能有些帮助.
  • 首先说一下我自己的一个大概情况吧,我是一个二本学校的,现在大四下期了,马上就要毕业了,学习嵌入式这方面的东西也有比较长的一段时间了.对于LINUX方面,由于我以前是做STM32和μC/OS方面的,所以LINUX方面的知识不是很会,还是个菜鸟阶段,今天主要是想跟大家聊聊大学这几年的学习经历. 我在大二 ...

  • 棉花纤维超微结构的扫描隧道显微镜观察
  • 生物化学与生物物理学报 ISSN 058229879 ACTA BIOCHIMICA et BIOPHYSICA SINICA 2000, 32(5) :521-523 CN 3121300/Q 研究简报 棉花纤维超微结构的扫描隧道显微镜观察 张玉忠3 陈秀兰 刘 洁 高培基 (山东大学微生物技术国 ...

  • 自制磁悬浮资料
  • 从朋友那儿知道这个网站开始,每天都来逛好几次.最近? 碌淖柿弦膊欢啵 芯跤械憷洹? 好久没看到老头上来了,不知道最近身体怎么样了?挂念! 咕唧霖那套有没有找到铁芯呢?期待! 我一个看不懂电路,顶多能看个初中电路,动手能力也一般.只是很喜欢这个磁悬,就想搞一个出来. 已经搞了一些构架性的东西,在一位朋 ...

  • STM32--定时器中断程序文档(2)
  • /*********************************************************************** 火牛开发板基础实验 外部中断实验 分别按下S3.S4,在串口1打印出相关信息 ************************************** ...

  • 基于ARM Cortex-M3的无线通信系统电路模块设计
  • 设计一个可以实现短信收发与数据无线传输的模块的要求,本文采用了ARM Cortex-M3内核的主流产品STM32作为主控芯片,采用SIMCom公司的SIM900A作为通信芯片.在查阅大量相关文献以及相关芯片的数据手册之后,本文设计了一个远程无线通信模块.该模块在实验室试运行一周后,没有出现掉线的情况 ...