文档库 最新最全的文档下载
当前位置:文档库 › 流水灯的前后今生

流水灯的前后今生

流水灯的前后今生
流水灯的前后今生

0、友情提示

《零死角玩转STM32》系列教程由初级篇、中级篇、高级篇、系统篇、四个部分组成,根据野火STM32开发板旧版教程升级而来,且经过重新深入编写,重新排版,更适合初学者,步步为营,从入门到精通,从裸奔到系统,让您零死角玩转STM32。M3的世界,于野火同行,乐意惬无边。

另外,野火团队历时一年精心打造的《STM32库开发实战指南》将于今年10月份由机械工业出版社出版,该书的排版更适于纸质书本阅读以及更有利于查阅资料。内容上会给你带来更多的惊喜。是一本学习STM32必备的工具书。敬请期待!

5、流水灯的前后今生

通过前面的内容,读者对库仅仅是建立了一个非常模糊的印象。

作为大家的第一个STM32例程,野火认为很有必要进行足够深入的分析,才能从根本上扫清读者对使用库函数的困惑。而且,只要读者利用这个LED例程,真正领会了库开发的流程以及原理,再进行其它外设的开发就变得相当简单了。

所以本章的任务是:

●从STM32库的实现原理上解答库到底是什么、为什么要用库、用库与

直接配置寄存器的区别等问题。

●让读者了解具体利用库的开发流程,熟悉库函数的结构,达到举一反三

的效果,这次可就不是喝稀粥了,保证有吃干饭,所学就是所用的效

果。

5.1 STM32的GPIO

想要控制LED灯,当然是通过控制STM32芯片的I/O引脚电平的高低来实现。在STM32芯片上,I/O引脚可以被软件设置成各种不同的功能,如输入或输出,所以被称为GPIO (General-purpose I/O)。而GPIO引脚又被分为GPIOA、GPIOB……GPIOG不同的组,每组端口分为0~15,共16个不同的引脚,对于不同型号的芯片,端口的组和引脚的数量不同,具体请参考相应芯片型号的datasheet。

于是,控制LED的步骤就自然整理出来了:

1.GPIO端口引脚多 --> 就要选定需要控制的特定引脚

2.GPIO功能如此丰富 --> 配置需要的特定功能

3.控制LED的亮和灭--> 设置GPIO输出电压的高低

继续思考,要控制GPIO端口,就要涉及到控制相关的寄存器。这时我们就要查一查与GPIO相关的寄存器了,可以通过《STM32参考手册》来查看,见图 5-1

图 5-1

图中的7个寄存器,相应的功能在文档上有详细的说明。可以分为以下4类,其功能简要概括如下:

1.配置寄存器:选定GPIO的特定功能,最基本的如:选择作为输入还是

输出端口。

2.数据寄存器:保存了GPIO的输入电平或将要输出的电平。

3.位控制寄存器:设置某引脚的数据为1或0,控制输出的电平。

4.锁定寄存器:设置某锁定引脚后,就不能修改其配置。

注:要想知道其功能严谨、详细的描述,请读者养成习惯在正式使用时,要以官方的datasheet为准,在这里只是简单地概括其功能进行说明。

关于寄存器名称上标号x 的意义,如:GPIOx_CRL、GPIOx_CRH ,这个x 的取值可以为图中括号内的值(A……E),表示这些寄存器也跟GPIO一样,也是分组的。也就是说,对于端口GPIOA和GPIOB,它们都有互不相干的一组寄存器,如控制GPIOA的寄存器名为GPIOA_CRL、GPIOA_CRH等,而控制GPIOB的则是不同的、被命名为GPIOB_CRL、GPIOB_CRH等寄存器。

我们的程序代码以野火STM32第二代开发板为例,根据其硬件连接图来分析,见图 5-2及图 5-3错误!未找到引用源。

图 5-2

从这个图我们可以知道STM32的功能,实际上也是通过配置寄存器来实现

的。配置寄存器的具体参数,需要参考《STM32参考手册》的寄存器说明。见图 5-4。

选定GPIO 的

特定功能 控制LED 的亮

输出功能 PC3、PC4、PC5 引脚均在GPIOC 端口上,

选定的寄存器组的标号为

x=C

设置数据寄存器GPIOx_ODR 的值或修改位控制寄存器 向 配置寄存器 GPIOx_CRL (0~7引

脚)写入相关控制参数

要实现的功能

相应的状态 对寄存器的配置 选定与LED 硬件相连的引脚 图 5-3

图 5-4

如图,对于GPIO 端口,每个端口有16个引脚,每个引脚 的模式由寄存器的4个位控制,每四位又分为两位控制引脚配置(CNFy[1:0]),两位控制引脚的 模式及最高速度(MODEy[1:0]),其中y 表示第y 个引脚。这个图是

GPIOx_CRH 寄存器的说明,配置GPIO 引脚模式的一共有两个寄存器,CRH 是高寄存器,用来配置高8位引脚:pin8~pin15。还有一个称为CRL 寄存器,如果我们要配置pin0~pin7引脚,则要在寄存器CRL 中进行配置。

举例说明对CRH 的寄存器的配置:当给GPIOx_CRH 寄存器的第28至29位设置为参数“11”,并在第30至31位 设置为参数“00”,则把x 端口第15个引脚 的模式配置成了“输出的最大速度为50MHz 的 通用推挽输出模式、”,其它引脚可通过其GPIOx_CRH 或GPIOx_CRL 的其它寄存器位来配置。至于x 端口的x 是指端口GPIOA 还是GPIOB 还要具体到不同的寄存器基址,这将在后面分析。

每4个寄存器位配置一个引脚 这4位控制pin12

CNFy:向这两个位写入不同

的值,设置引脚为不同的

功能。y 表示第y 个引脚。

MODEy:向这两个位写入不同的

值,设置引脚为不同的最大输出

速率,或设置为输入模式。

接下来分析要控制引脚电平高低,需要对寄存器进行什么具体的操作。见图 5-5。

图 5-5

由寄存器说明图可知,一个引脚y的输出数据由GPIOx_BSRR寄存器位的2个位来控制分别为BRy (Bit Reset y)和BSy (Bit Set y),BRy位用于写1清零,使引脚输出低电平,BSy位用来写1置1,使引脚输出高电平。而对这两个位进行写零都是无效的。(还可以通过设置寄存器ODR来控制引脚的输出。)

例如:对x端口的寄存器GPIOx_BSRR的第0位(BS0)进行写1,则x端口的第0引脚被设置为1,输出高电平,若要令第0引脚再输出低电平,则需要向GPIOx_BSRR的第16位(BR0) 写1。

5.2 STM32的地址映射

温故而知新——stm32f10x.h文件

首先请大家回顾一下在51单片机上点亮LED是怎样实现的。这太简单了,几行代码就搞定。

1.#include

2.h>

2.int main (void)

3.{

4. P0=0;

5. while (1);

6. }

以上代码就可以点亮P0端口与LED 阴极相连的LED 灯了,当然,这里省略了启动代码。为什么这个P0 =0; 句子就能控制P0端口为低电平?很多刚入门51单片机的同学还真解释不来,关键之处在于这个代码所包含的头文件

在这个文件下有以下的定义: 1. /* BYTE Registers */

2. sfr P0 = 0x80;

3. sfr P1 = 0x90;

4. sfr P2 = 0xA0;

5. sfr P3 = 0xB0;

6. sfr PSW = 0xD0;

7. sfr ACC = 0xE0;

8. sfr B = 0xF0; 9. sfr SP = 0x81;

10. sfr DPL = 0x82;

11. sfr DPH = 0x83; 12. sfr PCON = 0x87;

13. sfr TCON = 0x88; 14. sfr TMOD = 0x89;

15. sfr TL0 = 0x8A ; 16. sfr TL1 = 0x8B ;

17. sfr TH0 = 0x8C ;

18. sfr TH1 = 0x8D ;

19. sfr IE = 0xA8;

20. sfr IP = 0xB8;

21. sfr SCON = 0x98;

22. sfr SBUF = 0x99; 这些定义被称为地址映射。

所谓地址映射,就是将芯片上的存储器 甚至I/O 等资源与地址建立一一对应的关系。如果某地址对应着某寄存器,我们就可以运用c 语言的指针来寻址并修改这个地址上的内容,从而实现修改该寄存器的内容。

正是因为头文件中有了对于各种寄存器和I/O 端口的地址映射,我们才可以在51单片机程序中方便地使用P0 =0xFF; TMOD =0xFF

等赋值句子对寄存器进行配置,从而控制单片机。 Cortex-M3的地址映射也是类似的。Cortex-M3有32根地址线,所以它的寻址空间大小为2^32 bit=4GB 。ARM 公司设计时,预先把这4GB 的寻址空间大致地分配好了。它把地址从0x4000 0000至0x5FFF FFFF( 512MB )的地址分配给片上外设。通过把片上外设的寄存器映射到这个地址区,就可以简单地以访

寄存器(I/O) P0端口

地址 0x80 TMOD 寄存器 0x89 映射至地址 图 5-6

问内存的方式,访问这些外设的寄存器,从而控制外设的工作。结果,片上外设可以使用 C 语言来操作。M3存储器映射见图 5-7

图 5-7

stm32f10x.h 这个文件中重要的内容就是把STM32的所有寄存器进行地址映射。如同51单片机的头文件一样,stm32f10x.h 像一个大表格,我们在使用的时候就是通过宏定义进行类似查表的操作,大家想像一下没有这个文件的话,我们要怎样访问STM32的寄存器?有什么缺点?

不进行这些宏定义的缺点有:

1、地址容易写错

2、我们需要查大量的手册来确定哪个地址对应哪个寄存器

预留给芯片生产厂商进

行具体的寄存器至地址

的映射

3、看起来还不好看,且容易造成编程的错误,效率低,影响开发进度。

当然,这些工作都是由ST的固件工程师来完成的,只有设计M3的人才是最了解M3的,才能写出完美的库。

在这里我们以外接了LED灯的外设GPIOC为例,在这个文件中有这样的一系列宏定义:

1.#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)

2.#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)

3.#define PERIPH_BASE ((uint32_t)0x40000000)

这几个宏定义是从文件中的几个部分抽离出来的,具体的读者可参考

stm32f10x.h源码。

外设基地址

首先看到PERIPH_BASE这个宏,宏展开为0x4000 0000,并把它强制转换为uint32_t的32位类型数据,这是因为地STM32的地址是32位的,是不是觉得0x4000 0000这个地址很熟?是的,这个是Cortex-M3核分配给片上外设的从0x4000 0000至0x5FFF FFFF的512MB寻址空间中的第一个地址,我们把0x4000 0000称为外设基地址。

总线基地址

接下来是宏APB2PERIPH_BASE,宏展开为PERIPH_BASE(外设基地址)加上偏移地址0x1 0000,即指向的地址为0x4001 0000。这个

APB2PERIPH_BASE宏是什么地址呢?STM32不同的外设是挂载在不同的总线上的,见图 5-8。有AHB总线、APB2总线、APB1总线,挂载在这些总线上

的外设有特定的地址范围。

外设总线

图 5-8

其中像GPIO、串口1、ADC及部分定时器是挂载这个被称为APB2的总线上,挂载到APB2总线上的外设地址空间是从0x4001 0000至地址0x4001

3FFF。这里的第一个地址,也就是0x4001 0000,被称为APB2PERIPH_BASE (APB2总线外设的基地址)。

而APB2总线基地址相对于外设基地址的偏移量为0x1 0000个地址,即为APB2相对外设基地址的偏移地址。

见表:

地址范围总线总线基地址总线基地址相

对外设基地址

(0x4000

000)的偏移

0x4001 8000 -0x5003 FFFF AHB 0x4001 8000 0x1 8000

0x4001 0000 - 0x4001 7FFF APB2 0x4001 0000 0x1 0000

0x4000 0000 - 0x4000FFFF APB1 0x4000 0000 0x0 0000 由这个表我们可以知道,stm32f10x.h这个文件中必然还有以下的宏:

1.#define APB1PERIPH_BASE PERIPH_BASE

因为偏移量为零,所以APB1的地址直接就等于外设基地址

寄存器组基地址

最后到了宏GPIOC_BASE,宏展开为APB2PERIPH_BASE (APB2总线外设的基地址)加上相对APB2总线基地址的偏移量0x1000得到了GPIOC端口的寄存器组的基地址。这个所谓的寄存器组又是什么呢?它包括什么寄存器?

细看stm32f10x.h文件,我们还可以发现以下类似的宏:

1.#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)

2.#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)

3.#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)

4.#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400)

除了GPIOC寄存器组的地址,还有GPIOA、GPIOB、GPIOD的地址,并且这些地址是不一样的。

前面提到,每组GPIO都对应着独立的一组寄存器,查看stm32的datasheet,看到寄存器说明如下图:

图 5-9

注意到这个说明中有一个偏移地址:0x04,这里的偏移地址的是相对哪个

地址的偏移呢?下面进行举例说明。

对于GPIOC组的寄存器,GPIOC含有的端口配置高寄存器(GPIOC_CRH) 寄存器地址为:GPIOC_BASE +0x04。

假如是GPIOA组的寄存器,则GPIOA含有的端口配置高寄存器(GPIOA_CRH)寄存器地址为:GPIOA_BASE+0x04。

也就是说,这个偏移地址,就是该寄存器相对所在寄存器组基地址的偏移量。

于是,读者可能会想,大概这个文件含有一个类似如下的宏( 当初野火也

是这么想的 ):

1.#define GPIOC_CRH (GPIOC_BASE + 0x04)

这个宏,定义了GPIOC_CRH寄存器的具体地址,然而,在stm32f10x.h

文件中并没有这样的宏。ST公司的工程师采用了更巧妙的方式来确定这些地址,请看下一小节——STM32库对寄存器的封装。

5.3 STM32库对寄存器的封装

ST的工程师用结构体的形式,封装了寄存器组,c语言结构体学的不好的

同学,可以在这里补补课了。在stm32f10x.h文件中,有以下代码:

1.#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)

2.#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)

3.#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE)

有了这些宏,我们就可以定位到具体的寄存器地址,在这里发现了一个陌

生的类型GPIO_TypeDef ,追踪它的定义,可以在stm32f10x.h 文件中找

到如下代码:

1.typedef struct

2.{

3. __IO uint32_t CRL;

4. __IO uint32_t CRH;

5. __IO uint32_t IDR;

6. __IO uint32_t ODR;

7. __IO uint32_t BSRR;

8. __IO uint32_t BRR;

9. __IO uint32_t LCKR;

10.} GPIO_TypeDef;

其中 __IO 也是一个ST库定义的宏,宏定义如下:

1.#define __O volatile /*!< defines 'write only' permissions */

2.#define __IO volatile /*!< defines 'read / write' permissions */

volatitle 是c语言的一个关键字,有关volatitle的用法可查阅相关的C语

言书籍。

回到GPIO_TypeDef 这段代码,这个代码用typedef 关键字声明了名为GPIO_TypeDef的结构体类型,结构体内又定义了7个 __IO uint32_t 类型的变量。这些变量每个都为32位,也就是每个变量占内存空间4个字节。在c语言中,结构体内变量的存储空间是连续的,也就是说假如我们定义了一个GPIO_TypeDef ,这个结构体的首地址(变量CRL的地址)若为0x4001 1000,那么结构体中第二个变量(CRH)的地址即为0x4001 1000 +0x04 ,加上的这个0x04 ,正是代表4个字节地址的偏移量。

细心的读者会发现,这个0x04偏移量,正是GPIOx_CRH寄存器相对于所在寄存器组的偏移地址,见图 5-9。同理,GPIO_TypeDef 结构体内其它变

量的偏移量,也和相应的寄存器偏移地址相符。于是,只要我们匹配了结构体的首地址,就可以确定各寄存器的具体地址了。

有了这些准备,就可以分析本小节的第一段代码了: 4. #define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)

5. #define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)

6. #define GPIOC ((GPIO_TypeDef *) GPIOC_BASE)

GPIOA_BASE 在上一小节已解析,是一个代表GPIOA 组寄存器的基地址。(GPIO_TypeDef *) 在这里的作用则是把GPIOA_BASE 地址转换为GPIO_TypeDef 结构体指针类型。

有了这样的宏,以后我们写代码的时候,如果要修改GPIO 的寄存器,就可以用以下的方式来实现。代码分析见注释。 1. GPIO_TypeDef * GPIOx; //定义一个GPIO_TypeDef 型结构体指针GPIOx

2. GPIOx = GPIOA; //把指针地址设置为宏GPIOA 地址

3. GPIOx->CRL = 0xffffffff; //通过指针访问并修改GPIOA_CRL 寄存器

CRL (32位) CRH (32

位)

ODR (32

位) IDR (32位) BRR (32位) LCKR (32

位) BSRR (32位) GPIO_TypeDe f 结构体

寄存器(变量)

偏移量 0x00

0x04

0x0c 0x08

0x14

0x18

0x10

图 0-10

通过类似的方式,我们就可以给具体的寄存器写上适当的参数,控制STM32了。是不是觉得很巧妙?但这只是库开发的皮毛,而且实际上我们并不是这样使用库的,库为我们提供了更简单的开发方式。M3的库可谓尽情绽放了c的魅力,如果你是单片机初学者,c语言初学者,那么请你不要放弃与M3库邂逅的机会。是否选择库,就差你一个闪亮的回眸。

5.4 STM32的时钟系统

STM32芯片为了实现低功耗,设计了一个功能完善但却非常复杂的时钟系统。普通的MCU,一般只要配置好GPIO的寄存器,就可以使用了,但STM32还有一个步骤,就是开启外设时钟。

5.4.1时钟树&时钟源

首先,从整体上了解STM32的时钟系统。见图 0-11

图 0-11

这个图说明了STM32的时钟走向,从图的左边开始,从时钟源一步步分配到外设时钟。

从时钟频率来说,又分为高速时钟和低速时钟,高速时钟是提供给芯片主体的主时钟,而低速时钟只是提供给芯片中的RTC (实时时钟)及独立看门狗使用。

从芯片角度来说,时钟源分为内部时钟与外部时钟源 ,内部时钟是在芯片内部RC 振荡器产生的,起振较快,所以时钟在芯片刚上电的时候,默认使用内部高速时钟。而外部时钟信号是由外部的晶振输入的,在精度和稳定性上都有很大优势,所以上电之后我们再通过软件配置,转而采用外部时钟信号。

1 ○

2 ○

3 ○

4 ○

5 ○

6

所以,STM32有以下4个时钟源:

高速外部时钟(HSE):以外部晶振作时钟源,晶振频率可取范围为

4~16MHz,我们一般采用8MHz的晶振。

高速内部时钟(HSI):由内部RC振荡器产生,频率为8MHz,但不稳定。

低速外部时钟(LSE):以外部晶振作时钟源,主要提供给实时时钟模块,所以一般采用32.768KHz。野火M3实验板上用的是32.768KHz,6p负载规格的晶振。

低速内部时钟(LSI):由内部RC振荡器产生,也主要提供给实时时钟模块,频率大约为40KHz。

5.4.2高速外部时钟(HSE)

我们以最常用的高速外部时钟为例分析,首先假定我们在外部提供的晶振的频率为8MHz的。

1、从左端的OSC_OUT和OSC_IN开始,这两个引脚分别接到外部晶振的

两端。

2、8MHz的时钟遇到了第一个分频器PLLXTPRE(HSE divider for PLL

entry),在这个分频器中,可以通过寄存器配置,选择它的输出。它的输出时钟可以是对输入时钟的二分频或不分频。本例子中,我们选择不分频,所以经过PLLXTPRE后,还是8MHz的时钟。

3、8MHz的时钟遇到开关PLLSRC(PLL entry clock source),我们可

以选择其输出,输出为外部高速时钟(HSE)或是内部高速时钟

(HSI)。这里选择输出为HSE,接着遇到锁相环PLL,具有倍频作

用,在这里我们可以输入倍频因子PLLMUL(PLL multiplication

factor),哥们,你要是想超频,就得在这个寄存器上做手脚啦。经过PLL的时钟称为PLLCLK。倍频因子我们设定为9倍频,也就是说,经

过PLL之后,我们的时钟从原来8MHz的 HSE变为72MHz的PLLCLK。

4、紧接着又遇到了一个开关SW,经过这个开关之后就是STM32的系统时

钟(SYSCLK)了。通过这个开关,可以切换SYSCLK的时钟源,可以

选择为HSI、PLLCLK、HSE。我们选择为PLLCLK时钟,所以SYSCLK就为72MHz了。

5、PLLCLK在输入到SW前,还流向了USB预分频器,这个分频器输出为

USB外设的时钟(USBCLK)。

6、回到SYSCLK,SYSCLK经过AHB预分频器,分频后再输入到其它外

设。如输出到称为HCLK、FCLK的时钟,还直接输出到SDIO外设的

SDIOCLK时钟、存储器控制器FSMC的FSMCCLK时钟,和作为APB1、APB2的预分频器的输入端。本例子设置AHB预分频器不分频,即输出

的频率为72MHz。

7、GPIO外设是挂载在APB2总线上的, APB2的时钟是APB2预分频器

的输出,而APB2预分频器的时钟来源是AHB预分频器。因此,把

APB2预分频器设置为不分频,那么我们就可以得到GPIO外设的时钟也等于HCLK,为72MHz了。

5.4.3 HCLK、FCLK、PCLK1、PCLK2

从时钟树的分析,看到经过一系列的倍频、分频后得到了几个与我们开发密切相关的时钟。

SYSCLK:系统时钟,STM32大部分器件的时钟来源。主要由AHB预分频器分配到各个部件。

HCLK:由AHB预分频器直接输出得到,它是高速总线AHB的时钟信号,提供给存储器,DMA及cortex内核,是cortex内核运行的时钟,cpu主频就是这个信号,它的大小与STM32运算速度,数据存取速度密切相关。

FCLK:同样由AHB预分频器输出得到,是内核的“自由运行时钟”。“自由”表现在它不来自时钟 HCLK,因此在HCLK时钟停止时 FCLK 也继续运行。它的存在,可以保证在处理器休眠时,也能够采样和到中断和跟踪休眠事件,它与HCLK互相同步。

PCLK1:外设时钟,由APB1预分频器输出得到,最大频率为36MHz,提供给挂载在APB1总线上的外设。

PCLK2:外设时钟,由APB2预分频器输出得到,最大频率可为

72MHz,提供给挂载在APB2总线上的外设。

为什么STM32的时钟系统如此复杂,有倍频、分频及一系列的外设时钟的开关。需要倍频是考虑到电磁兼容性,如外部直接提供一个72MHz的晶振,太高的振荡频率可能会给制作电路板带来一定的难度。分频是因为STM32既有高速外设又有低速外设,各种外设的工作频率不尽相同,如同pc机上的南北桥,把高速的和低速的设备分开来管理。最后,每个外设都配备了外设时钟的开关,当我们不使用某个外设时,可以把这个外设时钟关闭,从而降低STM32的整体功耗。所以,当我们使用外设时,一定要记得开启外设的时钟啊,亲。

5.5 LED具体代码分析

有了以上对STM32存储器映像,时钟系统,以及基本的库函数知识,我们就可以分析LED例程的代码了,不知现在你有没饱饱的感觉了,如果还饿,那继续。

5.5.1实验描述及工程文件清单

实验描述该实验讲解了如何运用ST的库来操作I/O口,使I/O口产

生置位(1)和复位(0)信号,从而来控制LED的亮灭。

硬件连接PC3 – LED1、PC4 – LED2、PC5 – LED3

用到的库文件startup/start_stm32f10x_hd.c

CMSIS/core_cm3.c

CMSIS/system_stm32f10x.c

FWlib/stm32f10x_gpio.c

FWlib/stm32f10x_rcc.c

用户编写的文件USER/main.c

心型流水灯制作教程

作为一个电子技术爱好者,先就做一个最简单的心形流水灯玩玩吧。 本教程主要特点就是简单,不要你懂原理,不要你懂编程,只要最基本的元件和材料就可以完成。 首先我们来准备和认识元件。 1、最大的一个部件,洞洞板也叫万能板,9*15cm的刚刚好。便宜的万能板1元一块,你也可以用双面喷锡的质量好的玻纤板,4元一块。 2、主角单片机。要求用40脚的,刚好驱动32个led。建议用STC89C52RC,最常见便宜而且不用复位电路。 3、led,5mm的颜色随你喜欢,32个,注意长脚为正极。我用的是白发蓝,你也可以用不同的颜色组合各种效果。 4、电阻,限制led的工作电流,这个严格讲要经过计算,咱们随便作就不管了,200欧姆到1K欧姆的都可以,只是led的亮度有点区别。贴片电阻和直插的都可以,建议用贴片美观,熟练了焊起来更快,只要稍加练习就可以,实在没信心直插的也可以,反正在背面也没用什么影响。 5、镊子,焊接贴片电阻要用到。 6、晶振和瓷片电容。 晶振采用12MHz的,电容15pF-33pF都可以。 7、导线几根,连接电源和飞线用,当然飞线越少越好,一是美观,二是飞线容易出问题。 8、焊接工具。烙铁、焊锡、烙铁架、海绵、斜口钳等等,大家自己有啥样就用什么。我的是坏烙铁拼凑的白菜白光,看着烂用着还可以。 9、还有最好用IC座,一是保护单片机二是方便拆卸和烧录。第一个是固定式IC座,元,第二个是活体的,用的更方便,4元一个。 10、电源部分。这里可以废物利用,用废弃的手机电池,在正负极接上导线,安装XH插头,插座焊在洞洞板上。不必在意电压,只是点亮led,手机电池标准电压,充满这里用没问题。可以加一个拨动开关控制电源。 接下来开始焊接,注意元件的位置和极性。 先焊最小系统,ic座,晶振、电容这些,然后是led,注意正极(长脚)朝外,负极(断脚)朝向单片机。接着是led的负极用锡接过线接到单片机的io口,注意中间接电阻。最后连

流水灯小程序

流水灯小程序 #include void delay() //延时函数,这里延时100ms { int i,j; for(i=0;i<100;i++) { for(j=0;j<2242;j++){} //j循环一次大概1ms } } void main() { //这里看LED原理图LPC_IOCON->JTAG_TMS_PIO1_0=0x01;//定义p1.0引脚为输出 LPC_IOCON->JTAG_TDO_PIO1_1=0x01;//定义p1.1引脚为输出 LPC_IOCON->JTAG_nTRST_PIO1_2=0x01;//定义p1.2引脚为输出 //p1.9引脚默认为输出,不用写 LPC_GPIO1->DIR=(1<<0)+(1<<1)+(1<<2)+(1<<9); LPC_GPIO1->DA TA=(1<<0)|(1<<1)|(1<<2)|(1<<9); //D1、D2、D3、D4灯全灭 while(1) { LPC_GPIO1->DA TA&=~(1<<0);//D1灯亮 delay(); //调用延时函数 LPC_GPIO1->DA TA|=(1<<0);//D1灯灭 delay(); LPC_GPIO1->DA TA&=~(1<<1);//D2灯亮 delay(); LPC_GPIO1->DA TA|=(1<<1);//D2灯灭 delay(); LPC_GPIO1->DA TA&=~(1<<2);//D3灯亮 delay(); LPC_GPIO1->DA TA|=(1<<2);//D3灯灭 delay(); LPC_GPIO1->DA TA&=~(1<<9);//D4灯亮 delay(); LPC_GPIO1->DA TA|=(1<<9);//D4灯灭 delay(); } } 显示1234 # include int main(void) { const int table[4]={0x06,0x5b,0x4f,0x66,};//定义一个数组 LPC_IOCON->JTAG_TDI_PIO0_11=0x01;//定义p1.1为输出 //LPC_IOCON->PIO3_4=0x01; //默认为输出 //LPC_IOCON->PIO3_5=0x01; //默认为输出 LPC_GPIO3->DIR|=(1<<4)|(1<<5);//P3.4与P3.5输出 LPC_GPIO0->DIR|=(1<<3)|(1<<11); //定义P0.3与P0.11为输 出 LPC_GPIO2->DIR|=0XFF+(1<<11); //定义P2.0~P2.7和 P2.11为输出 //这是将四个数码管的引脚都设置为输出 LPC_GPIO2->DA TA|=0xff; //定义P2.0~P2.7输出高电平 LPC_GPIO0->DA TA|=1<<3; //定义P0.3输出为高电平 LPC_GPIO2->DA TA|=(1<<11); //定义P2.11输出高电平 LPC_GPIO3->DA TA|=(1<<4); //定义P3.4输出高电平 LPC_GPIO3->DA TA|=(1<<5); //定义P3.5输出高电平 while(1) { LPC_GPIO0->DA TA&=~(1<<11); //定义P0.11输出 低电平,导通 LPC_GPIO2->DA TA&=~table[0];//调用一个数组,因为为 公共用到的引脚,所以要设置它为一开一关的形式 LPC_GPIO0->DA TA|=(1<<11); //定义P0.11输出高电 平,息灭 LPC_GPIO2->DA TA|=0xff; //定义P2.0~2.7输出高电 平,截止 LPC_GPIO2->DA TA&=~(1<<11); LPC_GPIO2->DA TA&=~table[1]; LPC_GPIO2->DA TA|=(1<<11); LPC_GPIO2->DA TA|=0xff; LPC_GPIO3->DA TA&=~(1<<4); LPC_GPIO2->DA TA&=~table[2]; LPC_GPIO3->DA TA|=(1<<4); LPC_GPIO2->DA TA|=0xff; LPC_GPIO3->DA TA&=~(1<<5); LPC_GPIO2->DA TA&=~table[3]; LPC_GPIO3->DA TA|=(1<<5); LPC_GPIO2->DA TA|=0xff; } }

三极管流水灯电路设计

三极管流水灯电路设计 王雅 20111041105;韦梦娜 20111041107 摘要:3组12只LED流水灯是特别针对电子装配与调试技能设计出来的,值得学习和电路分析。本文分析了该流水灯电路的特点及其电路工作原理的说明。 关键字:3组12只LED流水灯;电路设计;循环。 1 引言 随着科学技术的发展,电力电子设备与人们的工作、生活的关系日益密切。各种小套件层出不穷,功能多样。本文所设计的电子制作可以说是电子初学者学习电子的最佳入门制作!其制作方式容易,趣味横生,更能提高初学者的动手能力!让初学者在制作学习中感受电子技术带来的乐趣! 2 系统的功能描述 这款3组12只LED流水灯具有制作容易、有趣易学的特点,电路焊接成功后,装入电池,即可正常工作,3组12只发光二极管便会被轮流点亮,不断的循环发光,达到流动的效果。 3 设计原理 3.1 电路工作原理说明: 本电路是由3只三极管组成的循环驱动电路。每当电源接通时,3只三极管会争先导通,但由于元器件存在差异,只会有1只三极管最先导通。这里假设V1最先导通,则V1集电极电压下降,使得电容C2的左端下降,接近0V。由于电容两端的电压不能突变,因此此时V2的基极也被拉到近似0V,V2截止,V2的集电极为高电压,故接在它上面的发光二极管LED5-LED8被点亮。此时V2的高电压通过电容C3使V3基极电压升高,V3也将迅速导通,因此在这段时间里,V1、V3的集电极均为低电压,因此只有LED5-LED8被点亮,LED1-LED4、LED9-LED12熄灭。但随着电源通过电阻R3对C2的充电,V2的基极电压逐渐升高,当超过0.7V时,V2由截止状态变为导通状态,集电极电压下降,LED5-LED8熄灭。与此同时,V2的集电极下降的电压通过电容C3使V3的基极电压也降低,V3由导通变为截止,V3的集电极电压升高,LED9-LED12被点亮。接下来,电路按照上面叙述的过程循环,3组12只发光二极管便会被轮流点亮,不断的循环发光,达到流动的效果。改变电容C1、C2、C3的容量可以改变循环速度,容量越小,循环速度越快。电源使用2节5号干电池即可。 3.2元件清单: 3.3 电路图

流水灯灯的制作流程

流水灯的制作流程 201400800657 唐宁 1·根据系统的需求设计需求设计单片机电路,本实验的目的是制一个流水灯,编写的程序使用中断电路和直接控制电路,下图为流水灯的电路: 2. 对单片机闪光电路的程序设计,本次编程采用了定时器来控制闪光灯,设计的周期为50ms,采用51单片机学习板为例(P1控制闪光灯),使用keil-c对单片机进行编程。keil-c的安装使用如下:(1)点击keil-c软件,按默认位置安装,这是为使得程序中的头文件 reg51.h能够在默认位置调用,安装完成后运行软件。

(2)新建一个工程,保存在计算机的某一个文件夹下;在新建一个空 白文档,将所写的程序写完后,保存为c文件,关闭程序。(3)找到所建工程的文件夹,打开project文件,将c文件添加到所在的工程中,对工程右键选中生成hex文件,然后对c文件进行编译,不断调试,然后选择重编译,直至编译通过。表明所写的程序没有语法上的错误。接下来就可以对程序进行模拟,在这里我们可以先利用软件自带的调试程序来查看运行是否正确,最终是下载到单片机上进行测试。 程序见下图: #include main() { TMOD=0x01; /*初始化定时器,按方式一工作*/ TH0=0x3c; TL0=0xb0; /*定时为50ms*/ ET0=1; /*开定时器的中断允许*/ EA=1; /*开CPU中断允许*/ TR0=1; /*打开定时器中断开关*/ TF0=0; /*溢出置为零*/ P1=0xfe; /*第一个灯亮*/ while(1); /*死循环,等待中断发生*/ }

流水灯电路的制作

流水灯电路的制作 一、概述: 随着电子技术的快速发展尤其是数字技术的突飞猛进,多功能流水灯凭着简易,高效,稳定等特点得到普遍的应用。在各种娱乐场所、店铺门面装饰、家居装潢、城市墙壁更是随处可见,与此同时,还有一些城市采用不同的流水灯打造属于自己的城市文明,塑造自己的城市魅力。目前,多功能流水灯的种类已有数十种,如家居装饰灯、店铺招牌灯等等。所以,多功能流水灯的设计具有相当的代表性。 多功能流水灯,就是要具有一定的变化各种图案的功能,主要考察了数字电路中一些编码译码、计数器原理,555定时器构成时基电路,给其他的电路提供时序脉冲,制作过程中需要了解相关芯片(NE555、CD4017)的具体功能,引脚图,真值表,认真布局,在连接过程中更要细致耐心。 二、电路原理图 三、电路工作原理 多功能流水灯原理电路图如上图所示。原理电路图由振荡电路、译码电路和光源电路三部分组成。本文选用的脉冲发生器是由NE555与R2、R3及C1组成的多谐振荡器组成。主要是为灯光流动控制器提供流动控制的脉冲,灯光的流动速度可以通过电位器R3进行调节。由于R3的阻值较大,所以有较大的速度调节范围。灯光流动控制器由一个十进制计数脉冲分配器CD4017和若干电阻组成。 CD4017的CP端受脉冲发生器输出脉冲的控制,其输出端(Q0~Q9)将输入脉冲按输入顺序依次分配。输出控制的脉冲,其输出控制脉冲的速度由脉冲发生器输出的脉冲频率决定。10

个电阻与CD4017的10个输出端Q0~Q9相连,当Q0~Q9依次输出控制脉冲时10个发光二极管按照接通回路的顺序依次发光,形成流动发光状态,即实现正向流水和逆向流水的功能。电源电路所采用的电源为。 四、板的设计 五、元器件清单 六、电路的组装与调试 1、电路的组装方法和步骤 (1)筛选元器件。对所有购置的元器件进行检测,注意它们的型号、规格、极性,应该保质量。 (2)按草图在PCB板上组装并焊接。 要求:①元器件布局整齐、美观,同类型元器件高度一致;

用单片机控制的LED流水灯设计(电路、程序全部给出)

1.引言 当今时代是一个新技术层出不穷的时代,在电子领域尤其是自动化智能控制领域,传统的分立元件或数字逻辑电路构成的控制系统,正以前所未见的速度被单片机智能控制系统所取代。单片机具有体积小、功能强、成本低、应用面广等优点,可以说,智能控制与自动控制的核心就是单片机。目前,一个学习与应用单片机的高潮正在工厂、学校及企事业单位大规模地兴起。学习单片机的最有效方法就是理论与实践并重,本文笔者用AT89C51单片机自制了一款简易的流水灯,重点介绍了其软件编程方法,以期给单片机初学者以启发,更快地成为单片机领域的优秀人才。 2.硬件组成 按照单片机系统扩展与系统配置状况,单片机应用系统可分为最小系统、最小功耗系统及典型系统等。AT89C51单片机是美国ATM EL公司生产的低电压、高性能CMOS 8位单片机,具有丰富的内部资源:4kB闪存、128BRAM、32根I/O口线、2个16位定时/计数器、5个向量两级中断结构、2个全双工的串行口,具有4.25~5.50V的电压工作范围和0~24MHz 工作频率,使用AT89C51单片机时无须外扩存储器。因此,本流水灯实际上就是一个带有八个发光二极管的单片机最小应用系统,即为由发光二极管、晶振、复位、电源等电路和必要的软件组成的单个单片机。其具体硬件组成如图1所示。 图1 流水灯硬件原理图 从原理图中可以看出,如果要让接在P1.0口的LED1亮起来,那么只要把P1.0口的电平变为低电平就可以了;相反,如果要接在P1.0口的LED1熄灭,就要把P1.0口的电平变为高电平;同理,接在P1.1~P1.7口的其他7个LED的点亮和熄灭的方法同LED1。因此,要

花样流水灯设计

单片机课程设计 2014年 6月 15日 课 程 单片机课程设计 题 目 花样流水灯 院 系 电气工程及其自动化系 专业班级 1112班 学生姓名 温亿锋 学生学号 201111631227 指导教师 张瑛

一丶任务 设计一款以AT89C51单片机作为主控核心,按键控制电路、流水灯显示电路以及单片机最小系统等模块组成的核心主控制电路。 二丶设计要求 通过发光二极管显示不同的花样(至少有六种花样),并且可以通过按键来控制流水灯的速度。 三丶设计方案 本方案主要是通过对基于单片机的多控制、多闪烁方式的LED流水灯循环系统的设计,来达到本设计的要求。其硬件构成框图如下图所示,以单片机为核心控制,由单片机最小系统(时钟电路、复位电路、电源)、按键控制电路、LED 发光二极管和5V直流电源组成。 单片机流水灯循环控制系统硬件框图 此设计方案中单片机的P1口接5路按键控制电路,实现流水灯花型的切换功能;单片机的P3.7引脚接上一个按钮开关以实现对流水灯闪烁频率的控制,即实现了快慢两种节拍实现花型的变换;单片机上的P2口接八路LED发光二极管组成流水灯电路,显示流水灯循环情况。 四丶系统硬件设计 4.1 直流稳压电源电路

对于一个完整的电子设计来讲,首要问题就是为整个系统提供电源供电模块,电源电路的稳定可靠是系统平稳运行的前提和基础。电子设备除用电池供电外,还采用市电(交流电网)供电。通过变压、整流、滤波和稳压后,得到稳定的直流电。直流稳压电源是电子设备的重要组成部分。本项目直流稳压电源为+5V。 直流稳压电源的制作一般有3种制作形式,分别是分立元件构成的稳压电源、线性集成稳压电源和开关稳压电源。下图为稳压电源采用的是三端集成稳压器7805构成的正5V直流电源。 三端固定式集成稳压电源电路图 AT89C51单片机的工作电压范围:4.0V---5.5V,所以通常给单片机外接5V 直流电源。此处用3节1.5V的干电池供电。 4.2 单片机最小系统 要使单片机工作起来,最基本的电路的构成由单片机、时钟电路、复位电路等组成,单片机最小系统如图所示。 时钟电路:本系统采用单片机内部方式产生时钟信号,用于外接一个12MHz 石英晶体振荡器和2个30pF微调电容,构成稳定的的自激振荡器,其发出的脉冲直接送入内部的时钟电路。 复位电路:确定单片机工作的起始状态,完成单片机的启动过程。单片机系统的复位方式有上电自动复位和手动按键复位。本设计采用手动按键复位,该复位方式同样具有上电自动复位功能。

流水灯电路

流水灯电路的制作与测试 【知识目标】 ●理解时序逻辑电路的基本概念及分类。 ●掌握同步和异步时序逻辑电路的分析方法。 ●理解计数器的逻辑功能及原理。 ●掌握寄存器电路的基本工作原理,理解移位寄存器的逻辑功能。 【技能目标】 ●能用触发器制作与调试各种同步计数器。 ●能用集成计数器制作任意进制的计数器。 ●熟悉集成移位寄存器逻辑功能和各控制端的作用,能构成实用电路。 ●多种方法实现流水灯电路,且进一步完善流水灯功能。 任务一用移位寄存器构成流水灯电路 一、分析任务 在一些数字系统中,有时需要系统按照事先规定的顺序进行一系列的操作。这就要求系统的控制部分能给出一组在时间上有一定先后顺序的脉冲,再用这组脉冲形成所需要的各种控制信号。 二、相关知识 在数字系统中,常常需要将一些数码、运算结果和指令等暂时存放起来,然后在需要的时候再取出来进行处理或运算。这种能够用于存储少量二进制代码或数据的时序逻辑电路,称为寄存器。 寄存器用于暂时存放二进制代码,它是数字系统中重要的部件之一。寄存器的主要组成部分是具有记忆功能的双稳态触发器。一个触发器可以存储一位二进制代码,所以要存放n位二进制代码,就需要n个触发器。 按照功能的不同,可将寄存器分为数码寄存器和移位寄存器两大类。 1. 数码寄存器 数码寄存器具有寄存数据和清除原有数据的功能。现以集成四位数据寄存器74LSl75来说明数据寄存器的电路结构和功能。74LSl75是用D触发器组成的四

位数据寄存器。它的逻辑图和管脚排列图如图7-11所示。 (a)逻辑图 (b)管脚排列图 图7-11 四位集成数码寄存器74LS175 74LS175的功能表见表7-11,CP 是时钟端,CR 是异步清零端,D 0~D 3是数据输入端,Q 0~Q 3是数据输出端。其功能如下。 表7-11 74LS175的功能表 ①异步清零。只要CR =0,就可使输出端清零,而与时钟无关。清零后,将 CR 接高电平,数据才能正常存人。 ②并行输入/输出。在CR =1的前提下,(将需要存人的四位二进制数据送到数据输入端D 0~D 3),在CP 脉冲上升沿的作用下,将D 0~D 3的数据并行存入Q 0~Q 3,同时也可取出存人的数码的反码。 ③记忆保持。当只CR =1且CP =0时,各触发器保持原状态不变,数据寄存器处于保持状态。 无论寄存器中原来的内容是什么,只要送数控制时钟脉冲CP 上升沿到来,加在并行数据输入端的数据D 0~D 3将立即被送入寄存器中,有 32103210Q Q Q Q D D D D

用8255做流水灯(汇编)

ORG 000H MOV DPTR,#7FFFH ; 功能设置 begin: JB P1.0,ZX01; 01 JB P1.1,ZX10 ; 10 JMP begin1 ZX01:JB P1.1,ZX11 JMP begin2 ZX10: JMP begin3 ZX11: JMP begin begin1: MOV A,#0FEH MOV R4,#8 again1: MOV DPTR,#7CFFH;输出端口选择A 7CFFH,B 7DFFH ,C 7EFFH MOVX @DPTR,A ACALL DELAY RL A DJNZ R4,again1 AJMP begin begin2: MOV A,#0FEH MOV R4,#8 again2: MOV DPTR,#7DFFH;输出端口选择A 7CFFH,B 7DFFH ,C 7EFFH MOVX @DPTR,A ACALL DELAY RR A DJNZ R4,again2 AJMP begin begin3: MOV R4,#8 MOV A,#0FEH again3: MOV DPTR,#7EFFH;输出端口选择A 7CFFH,B 7DFFH ,C 7EFFH MOVX @DPTR,A ACALL DELAY rl a DJNZ R4,again3 MOV R4,#8 rr1: MOV DPTR,#7EFFH;输出端口选择A 7CFFH,B 7DFFH ,C 7EFFH rr a MOVX @DPTR,A ACALL DELAY DJNZ R4,rr1 AJMP begin DELAY: MOV R1,#0H

L1: MOV R2,#0H L2: DJNZ R2,L2 L3: DJNZ R2,L3 DJNZ R1,L1 RET END

心形LED流水灯制作方法

LED心形流水灯加程序 1.原件清单:一个万能板,一个底座,一个STC89C52芯片,32个LED 灯,32个贴片电阻,两个30uf电容,一个晶振。 2.原理图: 注:电源处的复位可以不用;就是上面红框里的内容 3.正面图

背面图: 亮灯图: 4. 程序代码: #include #include #define uint unsigned int #define uchar unsigned char uchar code table[]={0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00}; // 逐个点亮0~7 uchar code table1[]={0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01,0x00}; // 逐个点亮7~0 uchar code table2[]={0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff}; // 逐个灭0~7 uchar code table3[]={0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff}; // 逐个灭7~0

/***********************************************************/ void delay(uint t); //延时 void zg(uint t,uchar a);//两边逐个亮 void qs(uint t,uchar a);//全部闪烁 void zgxh(uint t,uchar a); // 逆时针逐个点亮 //void zgxh1(uint t,uchar a); // 顺时针逐个点亮 void djs(uint t,uchar a); //对角闪 void lbzgm(uint t,uchar a);//两边逐个灭 //void sszgm(uint t,uchar a); // 顺时针逐个灭 void nszgm(uint t,uchar a); // 逆时针逐个灭 void sztl(uint t,uchar a);//顺时逐个同步亮 void nztl(uint t,uchar a);//逆时逐个同步亮 void sztm(uint t,uchar a);//顺时逐个同步灭 void nztm(uint t,uchar a);//逆时逐个同步灭 void hwzjl(uint t,uchar a); //横往中间亮 void hwzjm(uint t,uchar a); //横往中间灭 //void swzjl(uint t,uchar a); //竖往中间亮 //void swzjm(uint t,uchar a); //竖往中间灭 void nzdl(uint t,uchar a); //逆时逐段亮 void nzdgl(uint t,uchar a); //逆时逐段一个点亮 void jgs(uint t,uchar a); //间隔闪 /**********************************************************/ void zg(uint t,uchar a)//两边逐个亮 { uchar i,j; for(j=0;j

单片机流水灯所有程序

单片机流水灯所有程序 SANY GROUP system office room 【SANYUA16H-SANYHUASANYUA8Q8-

#include #define uchar unsigned char //char是字符数组 #define unit unsigned int uchar num; sbit led1=P1^0; void main() { TMOD=0x01; // 打开工作方式寄存器,选择工作方式1(0000 0001) TH0=(65536-45872)/256; TL0=(65536-45872)%6; EA=1; //开总中断 ET0=1; //开定时器0中断 TR0=1; //启动定时器0 while(1); //程序停止在这里等待中断发生 } void T0_time()interrupt 1 { TH1=(65536-45872)/256; //装初值50ms TL1=(65536-45872)%6; num ; //num每加一次判断是否到了20次 if(num==20) // 20*50ms=1000ms=1s,间隔1s { num=0; //然后把num清0重新再计20次 led1=~led1; //让发光管状态取反 } } 用定时器使1灯间隔1s闪烁 #include #define uchar unsigned char #define unit unsigned int unit num ; #define ucha unsigned char #define uni unsigned int uni a ; uchar table[]={0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00}; //????

用单片机控制LED流水灯方案(电路程序全部给出)开关电源方案制作

用单片机控制的LED流水灯设计<电路、程序全部给出)开关电源设计制作学习园地 »。您尚未登录注册 | 社区服务 | 勋章中心 | 帮助 | 首页 | 无图版 社区服务 银行 朋友圈 开关电源设计制作学习园地 -> 好好学习-天天向上 -> 用单片机控制的LED流水灯设计<电路、程序全部给出) XML RSS 2.0 WAP --> 本页主题: 用单片机控制的LED流水灯设计<电路、程序全部给出)加为IE收藏 | 收藏主题 | 上一主题 | 下一主题 pwmdy 级别: 电源-1级工程师 精华: 0 发帖: 212 威望: 126 点 金钱: 212 RMB 贡献值: 0 点 注册时间:2009-05-21 最后登录:2009-11-22 用单片机控制的LED流水灯设计<电路、程序全部给出) 1.引言 当今时代是一个新技术层出不穷的时代,在电子领域尤其是自动化智能控制领域,传统的分立元件或数字逻辑电路构成的控制系统,正以前所未见的速度被单片机智能控制系统所取代。单片机具有体积小、功能强、成本低、应用面广等优点,可以说,智能控制与自动控制的核心就是单片机。目前,一个学习与应用单片机的高潮正在工厂、学校及企事业单位大规模地兴起。学习单片机的最有效方法就是理论与实践并重,本文笔者用AT89C51单片机自制了一款简易的流水灯,重点介绍了其软件编程方法,以期给单片机初学者以启发,更快地成为单片机领域的优秀人才。 2.硬件组成 按照单片机系统扩展与系统配置状况,单片机应用系统可分为最小系统、最小功耗系统及典型系统等。AT89C51单片机是美国ATMEL公司生产的低电压、高性能CMOS 8位单片机,具有丰富的内部资源:4kB闪存、128BRAM、32根I/O口线、2个

流水灯的设计与制作

2010—2011学年第二学期控制系统实训 设 计 报 告 设计题目:流水灯的设计与制作 小组成员:陈琳(11097241108) 孙钢干(11097242041) 指导老师:王永祥 所在班级:09电子信息工程技术(1)班 二〇一一年六月三十日

流水灯的设计与制作 摘要:当今时代是一个新技术层出不穷的时代,在电子领域尤其是自动化智能控制领域,传统的分立元件或数字逻辑电路构成的控制系统,正以前所未见的速度被单片机智能控制系统所取代。单片机具有体积小、功能强、成本低、应用面广等优点,可以说,智能控制与自动控制的核心就是单片机。 关键词:LED 单片机控制系统流水灯

1.引言 (4) 2.任务描述及设计方案 (4) 2.1 任务描述 (4) 2.2 设计方案 (4) 3.硬件设计方案 (4) 3.1 设计思路 (4) 3.2 流水灯电路原理图 (5) 3.3 主要原件功能说明 (5) 4.软件方案 (9) 4.1 程序流程图 (9) 4.2 元件清单 (9) 4.3 参考程序 (9) 4.4 Proteus 仿真软件 (10) 5.结论 (10) 6.设计总结 (10) 7.参考文献 (11)

学习单片机的最有效方法就是理论与实践并重,用单片机设计与制作流水灯,需要更深的去了解单片机的很多功能,努力的去查找资料,当今时代是一个新技术层出不穷的时代,在电子领域尤其是自动化智能控制领域,传统的分立元件或数字逻辑电路构成的控制系统,正以前所未见的速度被单片机智能控制系统所取代。单片机具有体积小、功能强、成本低、应用面广等优点,可以说,智能控制与自动控制的核心就是单片机。 2.任务描述及设计方案 2.1 任务描述 设计流水灯控制电路,使连接在该电路上的8个发光二极管按顺序依次闪烁;将按键K1按下,8个发光二极管全部处于点亮状态,按下按键K2后,8个发光二极管全灭。 2.2设计方案 为实现此功能,选择用单片机控制的电路。其中系统工作原理为: 我们利用循环移位指令,采用循环程序结构进行编程。我们在程序一开始就给P1口送一个数,这个数本身就让P1.0先低,其他位为高,然后延时一段时间,再让这个数据向高位移动,然后再输出至P1口,这样就实现“流水”效果啦。 3.硬件设计方案 3.1 设计思路 如果要让接在P1.0口的LED1亮起来,那么只要把P1.0口的电平变为低电平就可以了;相反,如果要接在P1.0口的LED1熄灭,就要把P1.0口的电平变为高电平;同理,接在P1.1~P1.7口的其他7个LED的点亮和熄灭的方法同LED1。因此,要实现流水灯功能,我们只要将发光二极管LED1~LED8依次点亮、熄灭,8只LED灯便会一亮一暗的做流水灯了。在此我们还应注意一点,由于人眼的视觉暂留效应以及单片机执行每条指令的时间很短,我们在控制二极管亮灭的时候应该延时一段时间,否则我们就看不到“流水”效果了。

单片机流水灯多种程序方法

一、傻瓜式编程 #include<> #define uint unsigned int #define uchar unsigned char void delay(uint z); //延时子函数的声明main () { P0=0xfe;//第一个灯亮 delay(500); P0=0xfd;//第二个灯亮 delay(500); P0=0xfb; delay(500); P0=0xf7; delay(500); P0=0xef; delay(500); P0=0xdf; delay(500); P0=0xbf; delay(500); P0=0x7f; delay(500); } void delay(uint z) //延时子函数 { uint x,y; for(x=0;x

二、用移位符号“<<”或“>>” void main() //主函数 { a=0xfe; //给a赋值 while(1) { P0=a; //给P0口赋值,第一个等亮 a为1111 1110 a=~a; //求反 a为0000 0001 a=a<<1;//移位 a为0000 0010 a=~a; //求反还原a。第二个灯亮 a为1111 1101 delay(500); if(a==0x7f) { P0=0x7f;//第八个灯亮一次 delay(500); a=0xfe;//让第一个灯亮,然后无限循环 } } } 三、用移位函数_crol_( )和_cror_( ) main() { a=0xfe; while(1) { P0=a; delay(500); a=_crol_(a,1); //a每次左移一位 } } 四、使用数组 uchar code table[ ]={0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf,0x7f}; main() { whlie(1) { for(a=0;a<8;a++) { P0=table[a]; delay(500); } } }

多变流水灯控制电路.doc

(1)电路结构与特点 多变流水灯控制电路如图2S所示。图中的多谐振荡器由非门U5;A、U5:B及R1、R2、C1组成,其振荡频率为2H2。三极管开关电路由R3、v1组成,它并联在R2(决定频率的元件之一)的两端。当v1饱和时,相当于R2两端并联一电阻,多谐振荡器的频率将 变为原来的3倍。多谐振荡器产生的方波由两路输出,其中b4日1u5:A输出的一路输入U4的12级串行二进制计数分频器。该计数分频器将输入端信号输出,分频作用于v1。在U4的13脚输出的一个方波的前半段,其输出电平为“o”,v1截止,振荡器频率保持2H2;在后半段v1饱和,使振荡频率变为6Hz。非门U5:B输出至U1的BCD可预置数同步可逆计数器。其4、12、13、3脚为BCD码数据预置端,6、11、14、2脚为BCD码数据输出端。9脚为清零端,当其为高电平时,输出的数据为咖零数。l脚为置数允许端,当其为 高电平而9脚为低电平时,输出的数据与4、12、13、3脚预置数相同。I o脚为加、减计数

控制端,高电平为加计数,低电乎为减计数。5脚为进位输入端,无进位时,固定为低电乎。15脚为时钟脉冲输入端,脉冲上升沿有效。U1输出直接至U2的咖十进制译码器,将BcD码数据译为十进制码,从相应的十进制码数输出端输出。电路中Ul的4、12脚接高电乎,13、3脚接低电乎,故预置数为o011,即十进制数的3。u1的10脚由U4的输出端提供控制信号,当U1的15脚连续不断地输入时钟脉冲时,如果u1的10脚为高电平,则U1输出的比D码数据经U2译码,U2的3、14、2、15脚依次输出高电平。当U2的1 脚输出高电平时,经R5、C2稍加延时输入非门U5:D、U5lc整形,将经RC延时使前 沿变得较平滑的波形重新整形为方波,以避免ul同步计数器产生信号丢失。整形后的高 电乎至U1的9脚时,U2的3脚迅速变为高电乎输出。于是开始了3、14、2、15脚依次输出高电乎的重复过程。当u1的10脚为低电平时,计数器按逆向过程15、2、14、3脚顺序输出高电乎,原理同前所述。由u2输出的信号分成两路,其中一路输入u3四双向开关,其任一组开头在控制端为高电平时呈低阻通态,而在控制端为低电平时为高阻断态。由 U4的12、14脚输出端经V3、V4、R15组成“或”门电路,同时控制U3四组开关的通、断。 当开关通时,u2的一个输出端的高电乎可以使两个三极管饱和,而开关为断态时,此高电乎只能使一个三极管饱和。三极管由集电极反相输出,控制双向可控硅vsl—vs4的通、断,从而实现对彩灯的控制。 (2)无路件选择 在图23中,U1选用CD45lo,U2选用凹4028,U3选用CD4066,U4选用CD4040,

51单片机经典流水灯汇编程序

单片机流水灯汇编程序设计 流水灯汇编程序 8只LED为共阳极连接,即单片机输出端为低电平时即可点亮LED。 ;用最直接的方式实现流水灯 ORG 0000H START:MOV P1,#01111111B ;最下面的LED点亮 LCALL DELAY ;延时1秒 MOV P1,#10111111B ;最下面第二个的LED点亮 LCALL DELAY ;延时1秒 MOV P1,#11011111B ;最下面第三个的LED点亮(以下省略) LCALL DELAY MOV P1,#11101111B LCALL DELAY MOV P1,#11110111B LCALL DELAY MOV P1,#11111011B LCALL DELAY MOV P1,#11111101B LCALL DELAY MOV P1,#11111110B LCALL DELAY MOV P1,#11111111B ;完成第一次循环点亮,延时约0.25秒 AJMP START ;反复循环 ;延时子程序,12M晶振延时约250毫秒 DELAY: ;大约值:2us*256*256*2=260ms,也可以认为为250ms PUSH PSW ;现场保护指令(有时可以不加) MOV R4,#2 L3: MOV R2 ,#00H L1: MOV R3 ,#00H L2: DJNZ R3 ,L2 ;最内层循环:(256次)2个周期指令(R3减一,如果比1大,则转向L2) DJNZ R2 ,L1 ; 中层循环:256次 DJNZ R4 ,L3 ;外层循环:2次 POP PSW RET END

51单片机汇编程序集(二) 2008年12月12日星期五 10:27 辛普生积分程序 内部RAM数据排序程序(升序) 外部RAM数据排序程序(升序) 外部RAM浮点数排序程序(升序) BCD小数转换为二进制小数(2位) BCD小数转换为二进制小数(N位) BCD整数转换为二进制整数(1位) BCD整数转换为二进制整数(2位) BCD整数转换为二进制整数(3位) BCD整数转换为二进制整数(N位) 二进制小数(2位)转换为十进制小数(分离BCD码) 二进制小数(M位)转换为十进制小数(分离BCD码) 二进制整数(2位)转换为十进制整数(分离BCD码) 二进制整数(2位)转换为十进制整数(组合BCD码) 二进制整数(3位)转换为十进制整数(分离BCD码) 二进制整数(3位)转换为十进制整数(组合BCD码) 二进制整数(M位)转换为十进制整数(组合BCD码) 三字节无符号除法程序(R2R3R4/R7)=(R2)R3R4 余数R7 ;二进制整数(2位)转换为十进制整数(分离BCD码) ;入口: R3,R4 ;占用资源: ACC,R2,NDIV31 ;堆栈需求: 5字节 ;出口: R0,NCNT IBTD21 : MOV NCNT,#00H MOV R2,#00H IBD211 : MOV R7,#0AH LCALL NDIV31 MOV A,R7 MOV @R0,A INC R0 INC NCNT MOV A,R3 ORL A,R4 JNZ IBD211 MOV A,R0 CLR C SUBB A,NCNT MOV R0,A RET ;二进制整数(2位)转换为十进制整数(组合BCD码) ;入口: R3,R4 ;占用资源: ACC,B,R7 ;堆栈需求: 3字节 ;出口: R0

流水灯(电路和汇编)-Proteus和Keil仿真演示实例

示例要求: 在80C51单片机的P2口连接8个发光二极管指示灯,编程实现流水灯的控制,轮流点亮指示灯。 在KEIL 51中编程序,形成HEX文件;在PROTEUS中设计硬件,下载HEX文件,运行看结果。 第1篇:PROTEUS电路设计 1、打开PROTEUS的ISIS软件,如图1所示。新建电路图文件,将文件保存到E:\projectio(新建文件夹projectio)下面,文件基本名为io,扩展名默认。 选择元件 图1 ISIS窗口图 2、在component mode模式下单击选择元件按钮P,打开元件选择对话框,如图2所示。

在元件选择对话框的keywords窗口中输入元件关键字可换搜索元件,找到元件后,双击元件则可选中元件,添加元件到图3的device列表栏。在这里依次添加元件单片机80C51、电阻RES、电容CAP、按键BUTTON、晶振CRYSTAL、发光二极管LED-RED,如图3所示。 图3 添加元件的device列表栏 3、选择devices元件列表中的元件放到工作窗口,注意放置在工作窗口合适的位置,在元件放置时可对元件进行移动、旋转等操作;如图4所示。电源(POWER)与地(GROUND):(右键-放置-终端里选)。 图4 放置元件图

4、连接导线,如图5所示。连接后存盘。 图5 连接元件图 5、在Keil 软件中设计软件程序,形成HEX 文件(具体过程见第2篇Keil 软件编程)。保存软件项目到电路文件相同的文件夹E :\projectio 下。 6、在PROTEUS 电路图中,单击单片机80C51芯片,选中,再次单击打开单片机 80C51的属性对话框,在属性对话框中的program file 框中选择下载到80C51芯片中的程序。这里是同一个文件夹下面的shili.hex 文件。如图6所示。 图6 下载程序到单片机

51单片机爱心流水灯原理及制作

电路原理图:

原件清单: 1、51单片机x1、40Pin 座x1 2、LED x32(建议用5mm 七彩的) 3、电阻470Ωx33 4、晶振12MHz x1 5、10uf 电解电容x1、谐振瓷片电容30pf x2 6·其他的可以看自己的爱好去加 7、其实也可以不用那么多的电阻,用几个排阻就OK了。~ 效果展示:

作品程序: #include<> #define uchar unsigned char ; uchar flag=200; /////////////////////////////////////////////////////////////////////// uchar code Tab1[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,0xFF};//暗中左移向下uchar code Tab2[]={0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE,0xFF};//暗中右移向上uchar code Tab3[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x00};//亮中左移向下uchar code Tab4[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x00};//亮中右移向上uchar code Tab11[]={0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0xff};//暗中左移向下uchar code Tab22[]={0x7F,0x3F,0x1F,0x0F,0x07,0x03,0x01,0x00,0xff}; //////////////////////////////////////////////////////////////////// uchar code Tab33[]={0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFF}; ; uchar code Tab44[]={0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF}; uchar code Tab55[]={0x08,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xff}; uchar code Tab5[]={0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xff};

相关文档
相关文档 最新文档