OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 19463|回复: 26

【Alientek STM32实例 1】--跑马灯

[复制链接]

230

主题

1950

帖子

10

精华

论坛元老

Rank: 8Rank: 8

积分
4562
金钱
4562
注册时间
2010-12-14
在线时间
32 小时
发表于 2010-12-14 22:46:15 | 显示全部楼层 |阅读模式
Alientek SMT32开发板   跑马灯实验

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

     3.1.1 STM32 IO口简介

     3.1.2 硬件设计

     3.1.3 软件设计

     3.1.4 仿真与下载

3.1.1 STM32 IO简介

 

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

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

STM32IO口可以由软件配置成8种模式:

1、输入浮空

2、输入上拉

3、输入下拉

4、模拟输入

5、开漏输出

6、推挽输出

7、推挽式复用功能

8、开漏复用功能

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

STM32的每个IO端口都有7个寄存器来控制。他们分别是:配置模式的232位的端口配置寄存器CRLCRH232位的数据寄存器IDRODR132位的置位/复位寄存器BSRR;一个16位的复位寄存器BRR132位的锁存寄存器LCKR;这里我们仅介绍常用 的几个寄存器,我们常用的IO端口寄存器只有4个:CRLCRHIDRODR

CRLCRH控制着每个IO口的模式及输出速率。

STM32IO口位配置表如表3.1.1.1所示:


                          3.1.1.1 STM32IO口位配置表

STM32输出模式配置如表3.1.1.2所示:

                                                                             3.1.1.2 STM32输出模式配置表

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


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

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

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

给个实例,比如我们要设置PORTC11位为上拉输入,12位为推挽输出。代码如下:

GPIOC->CRH&=0XFFF00FFF;//清掉这2个位原来的设置,同时也不影响其他位的设置

GPIOC->CRH|=0X00038000;  //PC11输入,PC12输出

GPIOC->ODR=1<<11;//PC11上拉

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

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


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

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

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


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

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

在此,我们可以总结一下,对于学过AVR的人来说,我们都知道AVRIO口由3个寄存器控制:DDR PORTPIN。这里我们可以拿STM32IO控制寄存器和AVR的来个类比:

1,            STM32CRLCRH就相当于AVRDDR寄存器,用来控制IO口的方向,只不过STM32CRLCRH功能更强大一点罢了。

2,            STM32ODR就相当于AVRPORT,都是用来控制IO口的输出电平或者上下拉电阻的。

3,            STM32IDR就相当于AVRPIN,都是用来存储IO口当前的输入状态(高低电平)的。

除此之外,STM32还有BSRRBRRLCKR等几个寄存器用于控制IO口,这点是AVR所没有的。

 

3.1.2 硬件设计

 

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


                   3.1.2.1 LEDSTM32连接原理图

3.1.3 软件设计

 

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

然后我们打开USER文件夹下的TEST.Uv2工程,按按钮新建一个文件,然后保存在HARDWARE->LED文件夹下面,保存为led.c。在该文件中输入如下代码:

#include <stm32f10x_lib.h>   

#include "led.h"

//Mini STM32开发板

//LED驱动代码                             

//正点原子@ALIENTEK

//2010/5/27

 

// V1.0

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

      

//LED IO初始化

void LED_Init(void)

{

     RCC->APB2ENR|=1<<2;    //使能PORTA时钟                

     RCC->APB2ENR|=1<<5;    //使能PORTD时钟                            

     GPIOA->CRH&=0XFFFFFFF0;

     GPIOA->CRH|=0X00000003;//PA8推挽输出       

   GPIOA->ODR|=1<<8;     //PA8 输出高                                                                                                                

     GPIOD->CRL&=0XFFFFF0FF;

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

     GPIOD->ODR|=1<<2;      //PD.2输出高

}

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

                   3.1.3.2寄存器APB2ENR各位描述

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

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

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

#ifndef __LED_H

#define __LED_H  

#include "sys.h"

//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<<8)  //led0 PA8

#define       LED1 (1<<2)  //led1       PD2

#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的输出01。而前者的类似操作为:LED0=0LED0=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头文件的路径加入到工程里面(参照本文第36页)。回到主界面,在main函数里面编写如下代码:

#include <stm32f10x_lib.h>

#include "sys.h"

#include "usart.h"               

#include "delay.h"  

#include "led.h"                   

//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 "led.h"这句,使得LED0LED1LED_Init等能在main函数里被调用。接下来,main函数先配置系统时钟为72M,然后把延时函数初始化一下。接着就是调用LED_Init来初始化PA8PD2为输出。最后在死循环里面实现LED0LED1交替闪烁,间隔为300ms

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

                               3.1.3.5编译结果

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



ALIENTEK MINISTM32 实验1 跑马灯.rar

13.82 KB, 下载次数: 954

跑马灯.pdf

786.94 KB, 下载次数: 1788

我是开源电子网?网站管理员,对网站有任何问题,请与我联系!QQ:389063473Email:389063473@qq.com
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

102

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
205
金钱
205
注册时间
2011-1-20
在线时间
7 小时
发表于 2011-1-20 22:30:53 | 显示全部楼层
以上教程中有这么一句:“这里我们可以记住几个常用的配置,比如“0X4”表示模拟输入模式(ADC用)”。请问,其中为什么是“0x4”表示模拟输入模式(ADC用)”,而不是“0x0”呢?
回复 支持 反对

使用道具 举报

39

主题

597

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
2116
金钱
2116
注册时间
2011-9-3
在线时间
121 小时
发表于 2011-9-3 00:20:33 | 显示全部楼层
LZ你好。上面兄弟说的我也有同样的疑问?可否解答一下。谢谢。主要是看STM32的资料上来说应该是0X0才是模拟输入,而0X4应该是浮空输入才对啊?请教,谢谢!
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-9-3 00:58:19 | 显示全部楼层
回复【3楼】螃蟹爱虫:
---------------------------------
是的,这里有误.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

1

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
142
金钱
142
注册时间
2011-6-17
在线时间
15 小时
发表于 2011-9-3 15:54:17 | 显示全部楼层
STM32输出模式配置有 3 個選擇: - 2 MHz, 10MHz, 50MHz. 請問實際使用時有什麼不同?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-9-3 23:23:37 | 显示全部楼层
回复【5楼】Cho:
---------------------------------
速度不同
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

1

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
142
金钱
142
注册时间
2011-6-17
在线时间
15 小时
发表于 2011-9-4 16:50:44 | 显示全部楼层
如果我用50MHz 输出模式配置的端口输出 2MHz 有什麼結果?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-9-4 16:52:19 | 显示全部楼层
自己试试不就知道了.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

1

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
142
金钱
142
注册时间
2011-6-17
在线时间
15 小时
发表于 2011-9-4 16:55:44 | 显示全部楼层
早知你會給這個答案啦
回复 支持 反对

使用道具 举报

1

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
142
金钱
142
注册时间
2011-6-17
在线时间
15 小时
发表于 2011-9-4 17:05:38 | 显示全部楼层
我沒有示波器, 它出什麼我都不會知道
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-9-4 17:13:16 | 显示全部楼层
回复【10楼】Cho:
---------------------------------
那等你有示波器的时候在试验.
50Mhz表示你的输出IO速度可以到50Mhz
你输出2Mhz的方波,表示无压力.

但是你设置为2Mhz模式,输出10M的方波,估计就不行了,不过,我也没试验过.
所以,我一般都是设置为最快的模式.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

1

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
142
金钱
142
注册时间
2011-6-17
在线时间
15 小时
发表于 2011-9-4 17:27:28 | 显示全部楼层
回复【11楼】正点原子:
---------------------------------
明白, 謝回應
回复 支持 反对

使用道具 举报

20

主题

71

帖子

0

精华

初级会员

Rank: 2

积分
171
金钱
171
注册时间
2011-11-6
在线时间
0 小时
发表于 2011-12-20 21:40:32 | 显示全部楼层

问一个小白问题,在跑马灯进行单步调试的时候,在某一时刻红灯和绿灯会一起亮,求解T_T"

原子哥,求交往~(*^__^*) 
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-12-21 00:52:23 | 显示全部楼层
是这样的
回复 支持 反对

使用道具 举报

20

主题

71

帖子

0

精华

初级会员

Rank: 2

积分
171
金钱
171
注册时间
2011-11-6
在线时间
0 小时
发表于 2011-12-21 14:28:30 | 显示全部楼层
回复【14楼】正点原子:
---------------------------------
那为什么啊....
原子哥,求交往~(*^__^*) 
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-12-21 16:37:42 | 显示全部楼层
因为代码就是这么写的。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

2

主题

26

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
225
金钱
225
注册时间
2011-12-28
在线时间
60 小时
发表于 2011-12-28 20:57:57 | 显示全部楼层
学习了,谢谢!
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
21
金钱
21
注册时间
2012-4-5
在线时间
0 小时
发表于 2012-4-5 12:01:07 | 显示全部楼层
楼主,问下,第一个实验,用编译器通过后,在查看logic Anlay中,只可以看到PORTA.8 波形正确。但PORTD.2 无波形输出。



请赐教
回复 支持 反对

使用道具 举报

7

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
82
金钱
82
注册时间
2012-4-7
在线时间
0 小时
发表于 2012-4-7 18:17:13 | 显示全部楼层
回复【2楼】master001:
---------------------------------
这个跟这些寄存器有关即CNYx【1:0】Modex【1:0】,具体看相关寄存器资料
回复 支持 反对

使用道具 举报

6

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2012-7-26
在线时间
1 小时
发表于 2012-7-27 12:01:22 | 显示全部楼层
你好,我直接用原子大哥写的程序打开怎么就编译不过呢,说没有这个头文件<stm32f10x_lib.h>.
有想法没行动等于白日梦。
回复 支持 反对

使用道具 举报

6

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2012-7-26
在线时间
1 小时
发表于 2012-7-27 12:28:41 | 显示全部楼层
回复【20楼】mosquito:

---------------------------------
不用了,我找到原因了,原来装的keil里缺失了这些头文件
有想法没行动等于白日梦。
回复 支持 反对

使用道具 举报

12

主题

55

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
419
金钱
419
注册时间
2015-4-14
在线时间
53 小时
发表于 2015-4-21 21:50:06 | 显示全部楼层
太傻了。。。。。。。。
回复 支持 反对

使用道具 举报

2

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
58
金钱
58
注册时间
2014-11-30
在线时间
7 小时
发表于 2015-7-11 22:41:53 | 显示全部楼层
回复【18楼】bjcxb:
---------------------------------
你好,我 现在刚学 STM32,跑马灯试验这块,遇到了和你相似的问题。我是PA8一直低电平,PD2正常变化。程序是从不完全手册上输入的,编译也没有问题。请教下,最后你怎么处理的。
回复 支持 反对

使用道具 举报

2

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
58
金钱
58
注册时间
2014-11-30
在线时间
7 小时
发表于 2015-7-11 22:44:39 | 显示全部楼层
回复【6楼】正点原子:
---------------------------------
你好,17楼的问题有关注吗?我现在刚学STM32,遇到了和他类是的问题,查过一些资料了,还是没搞清楚什么原因,能不能帮忙解答下?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-7-11 22:56:31 | 显示全部楼层
回复【24楼】笨笨狼:
---------------------------------
直接用我们例程试试
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

2

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
58
金钱
58
注册时间
2014-11-30
在线时间
7 小时
发表于 2015-7-12 10:06:19 | 显示全部楼层
回复【25楼】正点原子:
---------------------------------
你好,你们的例程没有问题。我是按照不完全手册输入的,照理不应该有问题吧?我查看了一下运行过程中寄存器的变化,发现GPIOA->ODR值得变化是0-1,但是PORTA的值一直为0不变。
回复 支持 反对

使用道具 举报

2

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
58
金钱
58
注册时间
2014-11-30
在线时间
7 小时
发表于 2015-7-12 10:32:25 | 显示全部楼层
回复【25楼】正点原子:
---------------------------------
你好,我找到问题所在了。是PA8口配置模式初始化时把一个|符号,输成&了。现在解决了,麻烦了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-20 05:17

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表