您的当前位置:首页正文

74HC595与数码管

2022-11-09 来源:化拓教育网
第十九篇 74HC595与数码管 2011-03-08 15:07

第十九篇 74HC595与数

先引用一句官方语:“74HC595是硅结构的CMOS器件, 兼容低电压TTL电路,遵守JEDEC标准。长话短说,它的功能是8位串行输入并行输出移位寄存器,也就是串行转并行。下图是封装图:

74HC595内部有两个寄存器:8位移位寄存器和8为存储寄存器,下面要PROTEUS做下各个引脚的

调试一下可以看出:

DS为串行数据输入口;SH_CP为串行时钟输入口,SH_CP每个上升沿到来时,芯片内部的移位寄存高位移出丢失,次高位成为最高位,并在Q7'体现出来(根据Q7'可以看出,74HC595也有串行输

寄存器的值输出到存储寄存器,存储寄存器直接和引脚Q0~Q7相连,所以存储寄存器的值会直接反行功能;OE是输出使能,高电平时Q0~Q7为高阻态,低电平时Q0~Q7为存储寄存器的值;MR为低时无效;VCC接电源;GND接地。好了,所有引脚介绍完了。有的封装图引脚名字不太一样,功能

下面用两片74HC595(U1和U2)分别控制四位数码管(U1)的显示和选位(U2),为了减少连线U1的DS),这样连续向U2的DS写两个字节(第一个是要显示的数字,第二个是位选),就可以连SH_CP,P0.6连DS,P0.7连P0.7ST_CP)就可以操作此四连共阴数码管(注意是共阴,不是上篇示的数字”和“位选”取反即可)。如下图:

这个实验测试下:

//***********************************************************************************//功能:LPC2103利用两片74HC595操作四位共阴数码管 //说明:

//用两片74HC595(U1和U2)分别控制四位数码管(U1)的显示和选位(U2),

//为了减少连线,两片74HC595串联(U2的Q7'输出到U1的DS),这样连续向U2的DS写 //两个字节(第一个是要显示的数字,第二个是位选),就可以显示了。这样LPC2103 //用三个口(P0.4连SH_CP,P0.6连DS,P0.7连ST_CP)就可以操作此四连共阴数码管。 #include

#define SH_CP 1<<4 //移位时钟 #define DS 1<<6 //数据

#define ST_CP 1<<7 //字节输出时钟 #define u8 unsigned char

void display(u8 data,u8 n); void send(u8 byte);

void delay(unsigned int i);

//注意:这是共阳数码管的码表,但用在共阴数码管上,两者之间转换容易,把数据取反即可 u8 table[16] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1int main() {

PINSEL0=0; //GPIO

IODIR=SH_CP|DS|ST_CP; //三位设定为输出 while(1) {

display(0x5,1); //在1位显示数字5 delay(1000000); display(0xA,2); delay(1000000); display(0xF,3); delay(1000000); display(7,4); delay(1000000); } }

//在“n”位处显示数字“data”,用于共阴数码管 void display(u8 data,u8 n) {

send(~table[data]); //发送数字,若要用于共阳,去掉“~” send( ~(1<<(n-1)) ); //发送 位,若要用于共阳,去掉“~” }

//向74HC595发一个字节 void send(u8 byte) {

u8 i;

IOCLR=ST_CP; //先拉低,为后面的上升沿做准备 for(i=0;i<8;i++) {

IOCLR=SH_CP; //先拉低,为后面的上升沿做准备

if(byte&0x80) IOSET=DS; //将字节最高位 输出 在DS线上 else IOCLR=DS;

byte=byte<<1; //该字节右移一位

IOSET=SH_CP; //使74HC595接收该位(DS) }

IOSET=ST_CP; //使74HC595输出该字节 }

void delay(unsigned int i) {

while(i--); }

//************************************************************************** proteus仿真结果如下图:

硬件测试如下图:

可见,操作四位数码管本来需要12个口,利用74HC595后只要三个口就行了,大大节约了硬件资源

用两片74HC595驱动两个四连体数码管(共阳极,动态扫描) 首先介绍一下74HC595芯片:

74HC595是具有8位移位寄存器和一个存储器,三态输出功能。 移位寄存器和存储器是分别的时钟。

数据在SHcp的上升沿输入,在STcp的上升沿进入的存储寄存器中去。如果两个时钟连在一起,则移位寄存器总是比存储寄存器早一个脉冲。移位寄存器有一个串行移位输入(Ds),和一个串行输出(Q7’),和一个异步的低电平复位,存储寄存器有一个并行8位的,具备三态的总线输出,当使能 OE时(为低电平),存储寄存器的数据输出到总线。

我的硬件连接:

用级联方式连接!他们的工作顺序是这样的:单片机先送1个8位数据到第一个595的内部移位寄存器->然后数据会送到内部的输出寄存器->输出

当MR(10引脚)为高电平,OE(13引脚)为低电平时,数据在SHCP 上升沿

进入移位寄存器,在STCP上升沿输出到并行端口。 请看一个简单的程序:

/*--------------------------------------------*/

sbit SDA1 = P0^0; //串行数据输入,对应595的14脚SER sbit SCL1 = P0^1;//移位寄存器时钟输入,对应595的11脚SCK sbit SCL2 = P0^2;//存储寄存器时钟输入,对应595的12脚RCK /*---------------------------------------------*/ unsigned char code

duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

//0 1 2 3 4 5 6 7 8 9 unsigned char code

wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

void delay2ms(void) {

unsigned char i,j; for(i=133;i>0;i--) for(j=6;j>0;j--); }

/*---------------串行数据输入-----------------------------*/ void 595_in(unsigned char Data) {

unsigned char i;

for(i = 0; i < 8; i++) //循环8次,刚好移完8位 {

SCL1 = 0; //先将移位寄存器控制引脚置为低

SDA1 = Data & 0x80; //取数据的最高位

Data <<= 1; //将数据的次高位移到最高位 SCL1 = 1; //再置为高,产生移位时钟上升沿,上升沿时数据寄存器的数据移位 } }

/*----------------并行数据输出----------------------------*/ void 595_out(void) {

SCL2 = 0; //先将存储寄存器引脚置为低 _nop_();

SCL2 = 1; //再置为高,产生移位时钟上升沿,上升沿时移位寄存器的数据进入数据存储寄存器,更新显示数据。 }

/*---------------------------------------------*/ void main(void) {

unsigned char i;

for(i=0;i<8;i++) //有八位数码管,八位依次扫描 {

595_in(wei[i]); //先传位码 595_in(duan[i]); //再传段码 595_out();

delay2ms(); //延迟时间2ms以内 } }

注:74164和74595功能相仿,都是8位串行输入转并行输出移位寄存器。74164的驱动电流(25mA)比74595(35mA)的要小,14脚封装,体积也小一些。

74595的主要优点是具有数据存储寄存器,在移位的过程中,输出端的数据可以保持不变。这在串行速度慢的场合很有用处,数码管没有闪烁感。

与164只有数据清零端相比,595还多有输出端时能/禁止控制端,可以使输出为高阻态。

51单片机+74hc595锁存器驱动一个静态数码管 收藏

实验开发板HC6800 v2.8 (淘宝可以查到)

将JP2 与JP3相连即可,注意排线要反接

代码如下:

view plaincopy to clipboardprint? ·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······15001./*******************************************************************************

02.* 标题: 试验数码管上如何显示数字(共阳极) *

03.*

* 04.* 连接方法:P2 与P3 用8PIN排线连接 *

05.********************************************************************************

06.* *

07.* *

08.********************************************************************************/ 09. 10.

11.#include 12.#include

13.void delay(unsigned int i); //函数声名 14.

15.// 此表为 LED 的字模,0~F 16.unsigned char code LED7Code[] = {~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,~0x07,~0x7F,~0x6F,~0x77,~0x7C,~0x39,~0x5E,~0x79,~0x71}; 17.

18.sbit lock=P3^5;//12,storage register clock input 19.

20.sbit clk=P3^6;//11,shift register clock input 21.

22.sbit dat=P3^4;//14,serial data input 23./*将显示数据串行发送到74hc595*/ 24.void sendTo(unsigned char k) 25.{

26. unsigned char i; 27. for(i=0;i<8;i++) 28. {

29. dat=k&0x01;

30. clk=0;//移位寄存器移位 31. _nop_(); 32. _nop_(); 33. clk=1;

34. k>>=1;//发送数据右移一位 35. } 36.} 37.

38.void main() 39.{

40. unsigned int LedNumVal=0 ,C ; //定义变量

41.

42. while(1) 43. {

44. if (++C>= 300)

45. { LedNumVal++ ; //每隔300个扫描周期加一次 46. C =0; //每隔300个扫描清零 47. } 48. lock=0;

49. // 将字模送到14,serial data input

50. sendTo(LED7Code[LedNumVal%10]&0x7f);

51. //LED7 0x7f为小数点 共阴和共阳此处也是不一样; 52. _nop_(); 53. _nop_();

54. lock=1;//所存数据 55. delay(300); //调用延时程序 56. 57. } 58. 59. 60.} 61.

62./***************************************************************** 63.* * 64.* 延时程序 * 65.* * 66.*****************************************************************/ 67.void delay(unsigned int i) 68.{

69. char j;

70. for(i; i > 0; i--)

71. for(j = 200; j > 0; j--); 72.}

本文来自CSDN博客,转载请标明出http://blog.csdn.net/rainertop/archive/2010/10/24/5962116.aspx

处:

单片机实验箱扩展LED点阵板实验

一个汇编语言程序编程的优秀范例

1.说明:

在杨建南同学毕业论文的提示下,我要求孟仁周同学制作了这个在单片机实验箱上扩展的LED点阵板实验。扩展板电路中只用了三只元件:一片7×5 LED点阵板CD-2057,一只移位寄存器74HC164和一只带输出锁存的8位移位寄存器74HC595。扩展板与单片机的连接很简单,除了两根正、负电源线外,只有串行数据和时钟共5根线,可用多种形式与单片机连接。

孟仁周同学编写了一个规范的、专业的汇编语言程序,为了同学们学习方便,我将这个程序以及系统的工作原理作了详细的介绍,同学们应以此作为自己学习编程的范本,编写出规范的程序和写出规范的设计论文。

同时,这也是一个LED点阵板上进行帧扫描和行扫描以及字符移动显示的应用实例,它的工作方式是字符逐行向上漂移,我也绘出了程序控制流程图供大家学习,对汇编语言源程序,我作了详细的注释。

聂思敏 记于2005年4月24日星期日

2. 电路简介

VCCU2U3212223242526272810111213141516173029P2.0/A8P2.1/A9P2.2/A10P2.3/A11P2.4/A12P2.5/A13P2.6/A14P2.7/A15P3.0/RXDP3.1/TXDP3.2/INT0P3.3/INT1P3.4/T0P3.5/T1P3.6/WRP3.7/RDALE/PROGPSENP0.0/AD0P0.1/AD1P0.2/AD2P0.3/AD3P0.4/AD4P0.5/AD5P0.6/AD6P0.7/AD7P1.0P1.1P1.2P1.3P1.4P1.5P1.6P1.7XTAL1XTAL2EA/VPPRSTAT89C513938373635343332123456781419183191211VCC1013128VCC9ABCLKCLRQAQBQCQDQEQFQGQH34561011121374HC164U1SDIRCLKSRCLKCLRGSDOQAQBQCQDQEQFQGQH915123456774HC595CD-2057

图1 扩展LED点阵实验板电路图

在扩展LED点阵实验板电路中最主要的是一片7×5 LED点阵板CD-2057(该型号印在器件的背面),它的7根行线是相应行内5只发光二极管的公共负极端,5根列线为相应列内7只发光二极管的公共正极端,当一根列线接正5V,一根行线接地时,两线相交处的发光二极管被点亮。

图2是LED点阵板PLTM2088BS结构图,由于有8×8=64只发光二极管,显然显示效果较好。我们手中除了有PLTM2088BS外,还有若干7×5 LED点阵板CD-2057,是从市场上购得的旧材料,每片的价格不足两元,但未找到其内部结构图。于是参照图2进行实测,很容易找出其逻辑关系,与图2的结构完全相似,只是少了一行三列。

图2 PLTM2088BS结构图

实验板电路中带输出锁存的8位移位寄存器74HC595的低7位输出端与点阵板CD-2057行线连接。74HC595的第14脚SD1是串行数据输入线,11脚SRCLK为串行输入时钟控制线,当SRCLK从低电平跳到高电平时,SD1的一个数据移入输入级移位寄存器。12脚RCLK为输出级锁存器的时钟控制线,当RCLK从低电平跳到高电平时,输入级移位寄存器的数据转移到输出级。

电路中8位串入并出移位寄存器74HC164的高5位输出端与点阵板CD-2057列线连接。若列线也用74HC595连接,效果似乎更好些。由于74HC164的输出端不带锁存,送数时易出现余辉,从而降低对比度。但74HC164是单片机教程中常用的器件,使用它可以让学生熟悉这一

器件的特性。编程中,如果设计成将数据送至列的形式,则每次刷新列数据时只须对8位的串行移位寄存器74HC164移入5位数据即可。

以上三个器件连接好后,除了正5V和对地的电源线外,另外5根线中有一根行数据输入线SD1和一根列数据输入线B,两根时钟控制线74HC595的SRCLK和74HC164的CLK,以及74HC595的输出转移控制线RCLK。

3. 字符移动显示原理及软件设计

图1给出了扩展电路与单片机连接的一个方案。根据这种联接形式,介绍在LED点阵板上实现字符移动显示的原理。该方案是在点阵板CD-2057上显示自下向上漂移的字母或图案。由于只有7×5=35只发光三极管,像素太少,不宜显示汉字,因为显示效果不好看,但工作原理相同。若将点阵板增至4块,显示的汉字就很美观了。

3.1 程序框图

开始 取字表首置循环次数R3=35 置帧扫描次帧扫描子程置表地址偏移指针置行扫描字置扫描行数从表中取一行调列发送子程调帧扫描子N 取行控制字R2次扫Y 调行发送扫调延时子程行扫描字R5取下一个字N Y 所有字显 字表偏移指针N 行扫描Y

子程序返图3 主程序及字扫描子程序

在主程序中,使用DPTR地址寄存器作为地址指针,开始时指向数据表首地址。第一次循环时,DPTR指向第一列,在循环体中DPTR加1,第二次循环时,地址指针后移一列。帧扫描子程序每次扫描LED点阵板7行数据。数据串行送至74HC164输出端连接的5根列线。行线作控制开关使用,由74HC595输出端提供控制信号。第一次送出第一个字符最

上一行5位列数据时,作行扫描开关除了置第一行为低外,其余行置高,即打开第一行,关闭其余行。第二次送出第一个字符第二行5位列数据,行扫描开关置第二行为低,其余行置高,打开第二行,关闭其余行,以后类推。用这样方式完成一帧扫描。

数据表按显示要求编码。每一个字节为LED点阵板一行中5位相应的显示数据。由于只发送5次,所以有效数据只在一个字节的低5位。当列线为0时与行线相交点的发光三极管关,列线为1时开。数据表中一行7列的7个字节数据为一个字符的编码信息。

DPTR在帧扫描子程序外置数据表地址的基值,R1作地址偏移量,以两者之和对数据寻址。R1的初值为0,当DPTR为表首地址时,在子程序的循环中R1从0增加到6,取出第一个显示字符的全部7个字节并与行开关配合依次逐行显示,完成一帧扫描操作。

DPTR在每次循环后加1,使得它所指向的数据表地址前移。此后调用帧扫描子程序时,每帧显示的字符将向后移。例如第二次调用帧扫描子程序,DPTR的值为表首地址加1,此时当R1再从0增加到6时,取出的是第一个显示字符后6个字节和第二个显示字符的第一个字节,并与行开关配合依次逐行显示,完成一帧扫描操作。此时看到的显示效果为第一个显示字符向上移动了一行,其第一行从上端移出了屏幕,而第二个显示字符的第一行从下端进入了屏幕。随着DPTR在每次循环后加一次次地加1,每帧显示都将当前显示字符的一行从上端移出,将后续显示字符的一行从下端移入,形成了所有设置字符的流水显示。

DPTR能增加的最大数是循环计数器R3的初值,因此R3的初值应比数据表中数据总数少7,否则DPTR与R1相加后将指到表外。为了保证最后一个字也能移动显示,DPTR又要能指向最后一个显示字符的最后一个编码字节。因此将数据表最后一行用了全0数据,结果以黑屏显示效果结束全部字符一场移动显示。

每帧反复循环扫描的次数,决定显示移动速度。在主程序中,移动速度由帧扫描次数计数器R2中的初值决定。该值要根据不同晶振的频率和个人的喜好决定。

列发送子程序 置列数R0=5 行发送子程序 输出时钟线置低关输出 列时钟线置低 右移累加器使最低位送至数据输出端口 列时钟线置高 5列送完? N 置行数R0=8 行时钟线置低 右移累加器使最低位送至数据输出端口 行时钟线置高 8行送完? Y Y 子程序返回 N 输出时钟线置高开输出 子程序返回

图4 行、列数据发送子程序

在图4所示的列数据发送子程序中,CPU通过P1.5端口的5次串行移位操作,将数据送到74HC164的输出端及LED点阵板CD-2057的5根列线。

LED点阵板CD-2057按重合法方式显示,可将数据同时送到5条列线,然后开启这5列数据应出现的行线,关闭其它行。由于只有7根行线与74HC595的第0到6位连接,第一次调用字扫描子程序,CPU通过P1.2端口的8次串行移位操作,将控制字#10111111B送到74HC595的输出端及LED点阵板CD-2057的7根列线。控制字#10111111B中的数据0处于输出端第6位,点亮LED点阵板CD-2057顶端第一行,其余行关闭。以后控制字循环经过循环移位后发送出来,依次点亮第二行、第三行等等,其余行关闭。由于LED点阵板只有7位,所以有一次操作将0移出LED点阵板,此时屏幕全关。

3.2 源程序 ; Define I/O for lattice

P_ROW_DATA BIT P1.2 ;行数据发送端口 P_ROW_CLK BIT P1.0 ;行时钟输出端口 P_ROW_CS BIT P1.1 ;行数据输出控制端口

P_COL_DATA BIT P1.5 ;列数据发送端口至74HC164

P_COL_CLR BIT P1.4 ;列线清口,现直接接Vcc

P_COL_CLK BIT P1.3 ;列时钟输出端口 ORG 0000H

START: MOV DPTR, #POINT_TAB ;置表首地址 MOV R3, #35 ;比要显示的总字节数少7。

P_WORD_MOVE: MOV R2, 显示移动速度

P_SCAN_DEGREE: ACALL P_WORD_SCAN DJNZ R2, P_SCAN_DEGREE INC DPTR DJNZ R3, P_WORD_MOVE 符

AJMP START; Scan function

P_WORD_SCAN: MOV R1, #00H 移指针初值

MOV R5, MOV R4, #07 数

P_NEXT_BIT: MOV A, R1 MOVC A, ACALL P_COL_SEND #20 ;每个字符循环扫描次数,决定;调帧扫描程序 ;反复扫描同一帧 ;帧数据地址前移一行 ;扫描一场的全部字 ;置表地址偏#10111111B ;置行扫描字 ;置行扫描次

@A+DPTR ;取一个列数据 ;发送列数据

MOV A,R5 ;取行扫描字 ACALL P_ROW_SEND ;显示一行 ACALL DELAY ;维持点亮一行 MOV A, R5

RR A ;扫描字指向下一行 MOV R5, A

INC R1 ;指向下一行的列数据

DJNZ R4, P_NEXT_BIT ;一帧7行数据扫描完否?未完再扫

RET

; Send data for col display.Use 74HC164 chip

P_COL_SEND: MOV R0,#05H ;置列计数值 P_COL_NEXTBIT: CLR P_COL_CLK ;列时钟线置低 RRC A ;带进位循环移出数据最低位至进位位

MOV P_COL_DATA,C ;送一位数据至列发送端口

SETB P_COL_CLK ;列时钟线置高,串行发送一位列数据

DJNZ R0,P_COL_NEXTBIT ;一列数据发完否?未完再发

RET

; Send data for Row select.Use M74HC595B chip

P_ROW_SEND: CLR P_ROW_CS ;关闭74HC595输出寄存器

MOV R0,#08H ;置行计数值 P_ROW_NEXTBIT: CLR P_ROW_CLK ;行时钟线置低

RRC A ;带进位循环移出控制字最低位至进位位

MOV P_ROW_DATA,C ;送一位数据至行发送端口

SETB P_ROW_CLK ;行时钟线置高,串行发送一位行数据

DJNZ R0,P_ROW_NEXTBIT;一行数据发完否?未完再发

SETB P_ROW_CS ;开启74HC595输出寄存器

RET

DELAY: MOV R7,#30 DELAY_LOOP: MOV R6,#30 DJNZ R6,$

DJNZ R7,DELAY_LOOP RET

; Word model table

POINT_TAB: DB 00H,00H,00H,00H,00H,00H,00H

DB 00H,0AH,0AH,0EH,0AH,0AH,00H ;H DB 00H,0EH,08H,0EH,08H,0EH,00H ;E DB 00H,08H,08H,08H,08H,0EH,00H ;L DB 00H,08H,08H,08H,08H,0EH,00H ;L DB 00H,0AH,15H,11H,0AH,04H,00H ;O DB 00H,00H,00H,00H,00H,00H,00H END 4. 结束语

除了用这里介绍的P1口输出,也可改为P2口输出,还可改为用串行口作同步串行输出。根据上述字符输出的工作原理,可以充分发挥自己的想象力,对这一程序作一些修改,产生各种各样的显示输出效果。例如可以将字符上滚改为下滚,将一行一行地滚动改为一字一字地跳跃。或改为左进右出,右进左出。但有些要求看似简单,实现起来也不是太容易的,这就增加了挑战性。

以上若有问题,可找孟仁周同学咨询,也可直接找我。

另外,吴坤同学在校期间,欢迎各位同学前往探讨学术问题。吴坤同学是本行高手,是你们的大师兄,常日在学生科研室内,请勿错过机会。

ProteuS在ARM系统设计中的应用 引 言

现在,人们生活中的每个角落都有嵌入式设备的存在,比如DVD、移动电话、MP3及掌上电脑等等。这些嵌入式设备多采用32位RISC嵌入式处理器作为核心部件。其中基于ARM核的嵌入式处理器独占鳌头,在32位RISC处理器中占据超过75%的市场份额。因而越来越多的电子爱好者都加入了学习ARM的队伍中。通过和一般单片机系统开发过程的比较不难发现,嵌入式系统的设计包括硬件设计和软件设计两个方面,其调试过程包括软件调试、硬件测试、系统调试3个过程。软件调试一般比较容易进行,但是硬件测试和系统调试则比较麻烦,因为要进行这两个过程必须在 PCB制作、元器件焊接完毕之后才能进行;而PCB的制作、元器件的焊接是非常费时费力的,如果能采用仿真工具ProteuS VSM,则不用制作具体的电路板也能够完成以上工作。毫无疑问,这样可给广大ARM学习者带来很大的方便。 1 Proteus简介

Proteus软件是英国Labcenter electronics公司的EDA工具软件,是一个电子设计的教学平台、实验平台和创新平台,涵盖了电工电子实验室、电子技术实验室、单片机应用实验室等的全部功能。它运行于Windows操作系统上,可以仿真、分析(SPICE)各种模拟器件和集成电路。该软件的特点是: ①实现了单片机仿真和SPICE电路仿真相结合。具有模拟电路仿真、数字电路仿真、单片机及其外围电路组成的系统的仿真、RS232动态仿真、I2C调试器、SPI调试器、键盘和LCD系统仿真的功能;有各种虚拟仪器,如示波器、逻辑分析仪、信号发生器等。

②支持主流单片机系统的仿真。目前支持的单片机类型有:68000系列、8051系列、AVR系列、PIC12系列、PIC16系列、PIC18系列、Z80系列、HC11系列以及Phil-lips公司的ARM(LPC系列)等。 ③提供软件调试功能。在硬件仿真系统中具有全速、单步、设置断点等调试功能,同时可以观察各个变量、寄存器等的当前状态,因此在该软件仿真系统中,也必须具有这些功能;同时支持第三方的软件编译和调试环境,如Keil、ADS等软件。

④具有强大的原理图绘制功能。能够进行SCH(原理图)和PCB(印刷板)电路的设计。 2 Proteus环境下的原理图设计

Proteus和Protel、EWB等软件相似,绘制原理图都要先从器件库里取出所需的元器件符号并在绘图区布局好,同时编辑好元件的参数,接着进行连线,添加必要的网络标号等步骤。下面通过一个简单的实例说明如何使用Proteus软件实现ARM(以LPC2106为例)系统的设计与仿真。实例以 LPC2106控制器为核心,使用硬件SPI接口与74HC595进行连接,添加必要的外围电路,控制74HC595驱动LED数码管显示。

电路原理如图 1所示。LPC2106的P0.4(/SCK/CAP0.1)、P0.6(/MOSI/CAP0.2)和P0.8(/TxD1/PWM4)分别与 74HC595的SH_CP、DS和ST_CP相连来控制74HC595,74HC595的输出Q0~Q6分别与数码管和LED相连,控制它们的实时显示。

3 程序代码的编写

程序代码的编写主要分4个部分进行: ①LPC2106的初始化代码;

②LPC2106异常向量入口及异常向量与C语言代码的接口,包括初始化堆栈的代码; ③LPC2106目标板特殊的代码,包括异常处理程序和目标板初始化程序;

④根据实例要求并结合原理图,编写实现预期功能的代码,即通常的执行代码,代码文件保存为“main.C”。 通常为了节省开发的时间,一般用设计好的工程模板,这里使用LPC2100系列工程模板。模板中包含LPC2100系列ARM7微控制器的启动文件,包括 STACK.S、HEAP.S、STARTUP.S和TARGET.C;模板还包含LPC2100系列ARM7微控制器的头文件,分散加载描述文件(如 mem_a.scf、mem_b.scf和mem_c.scf)等等。这样在以后的程序代码编写时就可以直接使用这些工程模板,而不用再编写初始、启动等程序代码了,只需根据不同的要求编写“main.C”就行了,因而节省了大量时间,大大提高了工作效率。 这里主要说明“main.C”的编写,要实现的功能是使用硬件SPI接口输出0~F的数据,通过74HC595控制LED数码管显示0~F字符,同时控制4个LED显示对应的十六进制数。程序源代码如下:

4 仿 真

用ADS集成开发环境进行程序的编译连接设置,ADS集成开发环境是ARM公司推出的ARM核微控制器集成开发工具,英文全称为ARM Developer Suite,成熟版本为ADS1.2。ADS1.2支持ARM10以前的所有ARM系列微控制器,支持软件调试,支持汇编、C和C++源程序,具有编译效率高、系统库功能强等特点。打开ADS1.2集成开发环境CodeWarrior IDE,使用事先加入的工程模板建立一个新的工程spi.mcp,把以上编好的代码文件main.c添加进工程。进行相关设置后,选择 Projeet→Make命令,编译并连接工程,生成spi.hex文件。

在原理图中双击微控制器LPC2106,出现一属性设置窗口Edit Component,如图2所示。在其中的ProgramFile中添加上面生成的spi.hex文件的路径,单击OK完成设置。

点击原理图左下角的运行按钮即开始仿真运行。数码管显示SPI发送的O~F的数据,LED显示的是相对应的十六进制值。仿真结果完全符合设计要求。

结 语

本文结合一个简单的SPI接口实验详细说明了ProteuS在ARM开发中的应用。可以看出,Proteus功能十分强大,能仿真各种数字模拟电路,且操作简单,使用方便。使用Proteus进行ARM的虚拟开发,不仅可以减少实验硬件资本的投入,还突破了实际开发板中实验内容的局限性,使开发者能够充分发挥自身的主动性。使用Pro—teus仿真进行系统虚拟开发成功之后再进行实际制作,无疑可以提高开发效率、降低开发成本、提升开发速度,具有较高的推广应用价值

4HC595 的实际应用与编程(汇编 C语言)

595具有一个8位串行输入并行输出的移位寄存器和一个8位输出锁存器。

电路图:

595演示电路板:

演示程序:

==================================================

C595 走马灯演示程序

作日期:2006/01/02

作者: gguoqing

==================================================

SDATA_595 EQU P1.0 ;串行数据输入

SCLK_595 EQU P1.1 ;移位时钟脉冲

RCK_595 EQU P1.2 ;输出锁存器控制脉冲

==================================================

ORG 0000H

LJMP MAIN

ORG 0030H

==================================================

IN:

MOV SP,#60H

MOV R0,#0FEH

IN1:

CALL OUT_595

CALL DELAY

MOV A,R0

RL A

MOV R0,A

JMP MAIN1

-------------------------------------------------------------------

出锁存器输出数据子程序

-------------------------------------------------------------------

595:

LCALL WR_595

CLR RCK_595

NOP

NOP

SETB RCK_595 ;上升沿将数据送到输出锁存器

NOP

NOP

NOP

CLR RCK_595

RET

------------------------------------------------------------------

位寄存器接收数据子程序

------------------------------------------------------------------

95:

MOV R4,#08H ;

MOV A,R0

OOP:

RLC A

MOV SDATA_595,C

SETB SCLK_595 ;上升沿发生移位

NOP

NOP

CLR SCLK_595

DJNZ R4,WR_LOOP

RET

-----------------------------------------------------------------

时子程序

-----------------------------------------------------------------

Y:

MOV R5,#03H

:

MOV R6,#0FFH

:

MOV R7,#0FFH

DJNZ R7,$

DJNZ R6,DEL1

DJNZ R5,DEL0

RET

==================================================

END

在一些智能化仪表中,人机接口通常是LED数码管显示器和小型键盘。常见的工作方式有两种:一是直接使用系统中的CPU对显示器进行动态扫描和键盘检测,为保证显示的稳定和键盘的及时响应,CPU需要频繁的执行动态扫描程序,显然在CPU工作比较繁忙的情况下不太适用;二是用专用的显示、键盘芯片如8279、SAA1064等,这些芯片由于种种原因在实际应用中总有不便之处,如可显示的位数均较少,价格较高等。Phlips公司的P87LPC76X系列单片机属51系列,其体积小、功能强、价格低廉,有很高的性价比,本文介绍一种利用该系列单片机构成的具有一定通用性的显示、键盘电路。

图1 硬件电路图 P87LPC76X单片机简介

P87LPC76X单片机共有P87LPC760、P87LPC761、P87LPC762、P87LPC764、P87LPC767、P87LPC768等型号,该芯片采用加速的51内核,在相同的时钟频率下,其速度是标准51的2倍,它们除引脚数目、存储器容量和一些特殊的I/O功能外,其大部分功能均相同。下面以87LPC762为例进行说明。87LPC762为20脚封装,内有2KB的程序存储器,128B的数据存储器,两个16位定时/计数器,有一个标准串行通讯口,一个I2C接口,内部带有振荡器、上电复位和看门狗电路。在使用其内部振荡器和上电复位电路的情况下,可以有多达18根I/O线;特别值得一提的是,它的I/O口都可有上拉,其中P0口还专门设有键盘中断功能,若利用这些口线作为按键,则当有任一键按下时会产生相应的中断。

硬件设计

图2 寄存器的地址安排 D7 D6 D5 D4 D3 D2 D1 D0 D3-D0,显示的LED位数

D4 数据格式,0-ASCII码,1-BCD码 D6 键盘工作方式,0-简易按键,1-扫描键盘 D5,D7 保留

图3 控制寄存器格式

本设计用87LPC762组成一个最小的单片机系统。为使成本最低,结构最简单,再考虑到其可靠性要求不是太高,故使用单片机内部的振荡器、上电复位和看门狗电路,这样可以有18根I/O线可供使用。考虑到驱动的LED数码管的位数和单片机口线的驱动能力,通

过87LPC762的串行接口,使用移位寄存器进行扩展。本应用中,由于显示的总位数为8位LED,故使用了2片移位寄存器74HC595,其中一片用作显示的位控,一片用作段控。根据74HC系列芯片的输出驱动特性,可以不使用限流电阻,直接用74HC595的输出驱动数码管的段和各位。使用结果表明在电源电压为5V,显示的数码管数目不是太多的条件下,有较好的亮度,并可长期稳定工作。按键可直接连接在87LPC762的P0口,这样其电路结构最为简单,工作时可使用87LPC762的按键中断方式,不用附加任何外部元件。但使用87LPC762在不用扫描方式时最多只可以有8个按键,这里利用P0.0~P0.7作为输入,可以有8个按键,这在一般情况下已经够用;如需要的按键数目较多,可以使用扫描式键盘。显示/键盘部分和系统中主CPU之间的数据交换使用I2C接口,87LPC762作为从器件;工作时,系统的主CPU只需将要显示的数据通过I2C接口,以标准的格式发送到87LPC762即可。另外87LPC762使用一根I/O线作为向系统主CPU发送中断申请的信号线,当有按键按下时,87LPC762分析识别后向系统主CPU发出中断申请,系统主CPU响应中断后,通过I2C接口,从87LPC762中读出键值即可。本设计的硬件电路如图1所示。

软件设计

软件设计主要包括显示驱动程序的设计、键盘识别分析程序及I2C接口程序的设计。显示程序设计比较简单,让87LPC762的串行接口工作在方式0,用一个定时/计数器工作在定时方式,按显示的位数和扫描频率确定定时常数,打开定时中断,P87LPC762进入中断后通过串行口送出显示的段控和位控码。键盘可利用P87LPC762的按键中断功能,在有按键按下时,进入中断服务程序进行按键的抗抖、识别等,此处不再赘述。

下面主要介绍I2C接口和驱动软件的接口设计及其考虑。87LPC762内部有完善的I2C接口部件,它可以工作在主方式,也可以工作在从方式,这里工作在从方式即可,其编程也较为简单。在从方式下87LPC762需要有一个从地址,这个地址可以根据我们的需要选择,但要注意不要和系统中其他的I2C器件地址相冲突。软件的接口设计的和标准的I2C器件完全一样,访问时先写入器件地址,然后是片内地址;访问时既可以对某一特定的单元,也可以连续访问若干单元。为方便系统中主CPU对键盘、显示电路的访问,该电路对外提供了一个标准的接口,即可以由主CPU通过I2C访问的10个寄存器,这些寄存器的地址安排如图2所示。注意,这只是通过I2C接口访问时使用的地址,并不是在87LPC762内部RAM中的真正地址。工作时,主CPU只须将要显示的数据按地址通过I2C接口写入,87LPC762即将其显示出来。同样当87LPC762识别到有按键按下,把该键的键码放入寄存器中,然后向主CPU发出中断申请,主CPU响应中断通过I2C接口从87LPC762中指定的地址读出键码即可。由此可见,我们完全可以把87LPC762作为一片专用的键盘、显示芯片来使用。为使该电路使用起来更为方便、灵活,还设置了一个控制寄存器,用来控制显示的位数和方式、键盘工作方式等如图3所示。在此基础上还可以增加一些其他功能,如让指定的位闪烁,长时间无键按下时关闭显示,进入保护模式等。控制寄存器用来控制显示/键盘电路的工作方式,其格式见图3。

系统中的主CPU既可以采用有I2C接口的单片机;也可以使用没有专用I2C接口的单片机,这种情况下可用软件模拟I2C接口。

结语

利用P87LPC762构成的显示、键盘电路具有结构简单、功能强、与系统主CPU的接口简单、使用方便、成本低等特点,在我们所研制的智能化仪表中已成功使用。实际上我们可以将P87LPC762、74HC595等芯片集成在一起做成一个专用的显示和键盘模块。

点阵的显示原理是行扫描列发送字码,或者是列扫描行发送字码。当点阵屏大于16×16时,普通的32个I/O口的单片机是无法直接连接了,必须通过串行输入/输出寄存器或者锁存器等I/O口扩展,例如锁存器:74HC373、74HC273等;串行输入并行输出寄存器:74HC595、74HC164等;I/O口扩展芯片:8255、8155等。

一、74HC273连接的16×16点阵示例

74HC273是8位数据/地址锁存器,D0~D7为数据出入端;Q0~Q7为数据输出端;WR为主清除端,低电平触发,将锁存数据清零;CLK是触发端,上升沿触发,即当CLK从低到高电平时,D0~D7的数据通过芯片输出到Q0~Q7,为0时将数据锁存。

74HC273的测试程序如下: #include sbit CLK=P3^0 ; sbit MR=P3^1;

#define uchar unsigned char #define uint unsigned int

//数码管字型表,对应0,1,2,3,4,5,6,7,8,9//

uchar Table[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; void Delay(uint i )

{

uchar j; for(;i!=0;i--)

{for(j=200;j!=0;j--) ;} }

void main(void) { uchar N; MR=1; while(1) {

for(N=0;N<10;N++) { CLK=0;

Delay(300); // P2=Table[N]; CLK=1; Delay(300); } MR=!MR; } }

测试效果如下

延时为了方便看到管脚电平变化 利用74HC237连接的点阵如下图所示:

显示扫描方式也可以分为行扫描和列扫描,行扫描时,U1先输出行码依次扫描第1至第8行,同时U3输出第1行的左半部分列码,U4再输出第1行右半部分列码;扫描完1至8行后U2扫描8至16行,同时U3、U4输出对应的列码,这样就可以显示了。这仅仅是为了说明74HC273的连接图,不是最好的点阵连接方式,大家可以自己优化电路图。

二、74HC164与8255连接的点阵示例

图中8255的PA、PB输出端应加上拉电阻(300Ω~1KΩ)。ULN2803为增加驱动列能力。

5288的地址:PA口为0000H、PB口为0100H、PK(控制)口为0300H。使用逐列扫描方式。

以显示四个静态的“欠一个吻”为例,参考程序如下: #include #include

#define PA8255 XBYTE[0X0000] #define PB8255 XBYTE[0X0100] #define PK8255 XBYTE[0X0300] #define uhar unsigned char uchar code hzdot[]={

0x80,0x40,0x40,0x40,0x20,0x20,0x18,0x20,0x0F,0x10,0x0A,0x0C,0x08,0x03,0xE8,0x00,

0x08,0x03,0x08,0x0C,0x48,0x10,0x28,0x30,0x18,0x60,0x08,0x20,0x00,0x20,0x00,0x00,/*\"欠\

0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,

0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xC0,0x00,0x80,0x00,0x00,0x00,/*\"一\

0x00,0x00,0x80,0x00,0x80,0x00,0x40,0x00,0x20,0x00,0x10,0x00,0x0C,0x00,0xE3,0x7F,

0x04,0x00,0x08,0x00,0x10,0x00,0x20,0x00,0x60,0x00,0xC0,0x00,0x40,0x00,0x00,0x00,/*\"个\

0x00,0x00,0xFC,0x07,0x04,0x02,0x04,0x02,0xFC,0x03,0x40,0x48,0x30,0x44,0x0F,0x23,

0xCA,0x10,0x38,0x0C,0x08,0x03,0xF8,0x40,0x08,0x80,0x08,0x60,0xF8,0x1F,0x00,0x00/*\"吻\};

uchar a,i,t,x[8]={0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; char b;

void main(void) {

PK8255=0X80; while(1) {

for(a=0;a<64;a++) {

PA8255=0x00; PB8255=0x00; for(b=7;b>=0;b--) {

SBUF=~x[b]; while(!TI) ;TI=0; }

PA8255=hzdot[2*a]; PB8255=hzdot[2*a+1]; for(i=0;i<8;i++) {

if((x[7]&0x01)==0) goto LP; if((~x[i]!=0)&&((x[i]&0x01)!=0)) x[i]=x[i]<<7|x[i]>>1;

else if((~x[i]!=0)&&((x[i]&0x01)==0)) { x[i]=0xff; x[i+1]=0x7f; break; } } }

LP:x[0]=0x7f;x[7]=0xff; } }

三、74HC595连接的点阵示例

很多点阵都是使用74HC595连接的,74HC595是8位串行输入/输出或者并行输出移位寄存器,具有高阻关断三态输出功能。 74HC595的功能表如下:

为了形象的演示74HC595的功能,编写如下测试程序:

#include

#define uint unsigned int #define uchar unsigned char

sbit DS=P3^4; //74HC595的数据串行输入端口 sbit ST=P3^7; //74HC595并行输出使能 sbit SH=P3^6; //74HC595移位寄存器移位使能 //测试串行传输数据:

uchar code Test[]={0xFF,0x00,0xAA,0xCC,0xEE,}; //******延时子程序******// void delay(uint a) {

uint i,j; for(i=0;ivoid SendByte(uchar date) { uchar i;

for(i=0;i<8;i++) { SH=0; ST=0;

if(date&0x80) //将date最高位移到74HC595的移位寄存器 DS=1;

else DS=0;

SH=1; //SH上升沿时移位 ST=1; //ST上升沿时输出数据

date=date<<1; //左移一位,将送出第二位数据 delay(5000); } }

//****主函数****// void main() { uchar i; while(1) {

for(i=0;i<5;i++) SendByte(Test[i]); } }

测试是依次输出0xFF,0x00,0xAA,0xCC,0xEE几个数据,在点阵显示程序中,是将数据全部送到74HC595的移位寄存器,再同时显示出来,并不是像下图所示一个一个流动显示,这个仅仅是测试数据的传输路径。

ORG 0000H LJMP STAR

ORG 0BH LJMP INTT0 STAR: MOV 20H,#00H MOV A,#0FFH MOV R7,#0 MOV P1,A MOV P2,A MOV P3,A MOV P0,A CLR P1.6 MOV TMOD,#01H MOV TH0,#0FEH MOV TL0,#18H MOV SCON,#0 MOV IE,#82H MOV SP,#70H MOV R0,#0 MAIN: LCALL DIS1 MOV DPTR ,#TAB LCALL MOVDISP LJMP MAIN MOVDISP:MOV B,#00H DISLOOP:MOV R3,#07H DISMOV: JNB 02H,AAA

DEC DPH CLR 02 AAA: MOV R2,#0 MOV R1,B SETB TR0

WAITMOV:JBC 00H,DISMOV1 AJMP WAITMOV DISMOV1:DJNZ R3,DISMOV JNB 02H,BBB DEC DPH CLR 02 BBB: INC B MOV A,B CJNE A,#0,CC1 INC DPH INC R7 CC0: INC B MOV A,B CJNE A,#0,CCC INC DPH INC R7 CC1: INC B MOV A,B CJNE A,#0,CCC

INC DPH INC R7 CCC: MOV A,R1

MOVOUT:CJNE R7,#3,DISLOOP MOV A,B

CJNE A,#24,DISLOOP MOV R7,#0 RET

DIS1: MOV R3,#0AH CLR P1.3 CLR P1.4 CLR P1.5 DIS11: MOV R2,#0 MOV DPTR,#TAB MOV R1,#0H SETB TR0

WAIT11:JBC 01H,DIS11 AJMP WAIT11 DIS111:DJNZ R3,DIS11 RET INTT0: INC R0 PUSH ACC MOV TH0,#0FEH MOV TL0,#18H

JBC 00H,GOEND MOV A,R1 MOVC A,@A+DPTR MOV SBUF,A WAIT: JBC TI,GO AJMP WAIT GO: INC R1 CJNE R1,#0,AA INC DPH SETB 02H AA: MOV A,R1 MOVC A,@A+DPTR MOV SBUF,A WAIT1: JBC TI,GO1 AJMP WAIT1 GO1: INC R1 CJNE R1,#0,BB INC DPH SETB 02H BB: MOV A,R1 MOVC A,@A+DPTR MOV SBUF,A WAIT2: JBC TI,GO2 AJMP WAIT2

GO2: CLR P1.3 CLR P1.4 CLR P1.5 NOP SETB P1.6 NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP CLR P1.6 MOV A,R2 ANL A,#7H ANL P1,#0F8H ORL P1,A P122: INC R2

CJNE R2,#8,PAN1 LJMP PAN1A

PAN1: JC PAN1A

CJNE R2,#10H,PAN2 LJMP PAN1B PAN2: JC PAN1B

CJNE R2,#018H,PAN3 LJMP PAN1C PAN3: JC PAN1C AJMP PANT PAN1A: SETB P1.3 AJMP PANT PAN1B: SETB P1.4 AJMP PANT PAN1C: SETB P1.5 PANT: INC R1

CJNE R1,#0,CC INC DPH SETB 02H CC: MOV A,R2 GO3: CJNE R2,#24,GO4 SETB 00H GO4: POP ACC RETI GOEND: CLR TR0 SETB 01H

POP ACC RETI ORG 0A00H TAB:

;-- 逐行 顺向 --

DB

000H,000H,000H,003H,0C0H,000H,004H,030H,000H,004H,010H,000H,008H,03FH,0FCH,008H;

DB

000H,006H,010H,000H,002H,020H,000H,002H,020H,000H,002H,040H,083H,004H,041H,083H;

DB

004H,041H,083H,008H,042H,083H,008H,03FH,001H,0F0H,001H,001H,080H,002H,000H,0C0H;

DB

004H,000H,060H,008H,00CH,018H,030H,008H,004H,040H,01CH,002H,040H,026H,002H,040H;

DB 043H,002H,021H,080H,0C4H,03EH,000H,03CH;\"欠\

DB

000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H;

DB

000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,07FH,0FFH,0FCH,0C0H,000H;

DB

006H,080H,000H,002H,080H,000H,002H,080H,000H,002H,0C0H,000H,006H,07FH,0FFH,0FCH;

DB

000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H;

DB 000H,000H,000H,000H,000H,000H,000H,000H;\"一\

DB

000H,000H,000H,000H,07CH,000H,000H,083H,000H,001H,000H,080H,006H,000H,060H,008H;

DB

000H,030H,030H,000H,00CH,040H,07EH,002H,080H,042H,001H,080H,082H,001H,081H,083H;

DB

081H,046H,082H,0E2H,078H,082H,01CH,000H,082H,000H,000H,082H,000H,000H,082H,000H;

DB

000H,082H,000H,000H,082H,000H,000H,082H,000H,000H,082H,000H,000H,082H,000H,000H;

DB 082H,000H,000H,082H,000H,000H,07CH,000H;\"个\

DB

000H,000H,000H,000H,01CH,000H,000H,022H,000H,07FH,0C1H,000H,0C0H,081H,0F8H,080H;

DB

080H,004H,080H,080H,002H,081H,000H,002H,08BH,000H,002H,08AH,002H,002H,08AH,022H;

DB

042H,089H,044H,042H,088H,0C4H,042H,088H,088H,042H,089H,008H,082H,082H,010H,082H;

DB

084H,020H,082H,084H,040H,082H,0C4H,083H,082H,07FH,084H,002H,001H,004H,004H,000H;

DB 084H,004H,000H,04CH,00CH,000H,033H,0F8H;\"吻\„„ END

参考链接:http://www.picavr.com/news/2009-08/513.htm

LED点阵显示与编程

[日期:2009-06-02 ] [来源:net 作者:佚名] [字体:大 中 小] (投递新闻)

点阵的显示原理是行扫描列发送字码,或者是列扫描行发送字码。当点阵屏大于16×16时,普通的32个I/O口的单片机是无法直接连接了,必须通过串行输入/输出寄存器或者锁存器等I/O口扩展,例如锁存器:74HC373、74HC273等;串行输入并行输出寄存器:74HC595、74HC164等;I/O口扩展芯片:8255、8155等。

一、74HC273连接的16×16点阵示例

74HC273是8位数据/地址锁存器,D0~D7为数据出入端;Q0~Q7为数据输出端;WR为主清除端,低电平触发,将锁存数据清零;CLK是触发端,上升沿触发,即当CLK从低到高电平时,D0~D7的数据通过芯片输出到Q0~Q7,为0时将数据锁存。

74HC273的测试程序如下: #include sbit CLK=P3^0 ; sbit MR=P3^1;

#define uchar unsigned char #define uint unsigned int

//数码管字型表,对应0,1,2,3,4,5,6,7,8,9//

uchar Table[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; void Delay(uint i ) {

uchar j;

for(;i!=0;i--)

{for(j=200;j!=0;j--) ;} }

void main(void) { uchar N; MR=1; while(1) {

for(N=0;N<10;N++) { CLK=0;

Delay(300); //延时为了方便看到管脚电平变化 P2=Table[N]; CLK=1; Delay(300); } MR=!MR; } }

测试效果如下:

利用74HC237连接的点阵如下图所示:

显示扫描方式也可以分为行扫描和列扫描,行扫描时,U1先输出行码依次扫描第1至第8行,同时U3输出第1行的左半部分列码,U4再输出第1行右半部分列码;扫描完1至8行后U2扫描8至16行,同时U3、U4输出对应的列码,这样就可以显示了。这仅仅是为了说明74HC273的连接图,不是最好的点阵连接方式,大家可以自己优化电路图。

二、74HC164与8255连接的点阵示例

图中8255的PA、PB输出端应加上拉电阻(300Ω~1KΩ)。ULN2803为增加驱动列能力。

5288的地址:PA口为0000H、PB口为0100H、PK(控制)口为0300H。使用逐列扫描方式。

以显示四个静态的“欠一个吻”为例,参考程序如下: #include #include

#define PA8255 XBYTE[0X0000] #define PB8255 XBYTE[0X0100] #define PK8255 XBYTE[0X0300] #define uhar unsigned char uchar code hzdot[]={

0x80,0x40,0x40,0x40,0x20,0x20,0x18,0x20,0x0F,0x10,0x0A,0x0C,0x08,0x03,0xE8,0x00,

0x08,0x03,0x08,0x0C,0x48,0x10,0x28,0x30,0x18,0x60,0x08,0x20,0x00,0x20,0x00,0x00,/*\"欠\

0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,

0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xC0,0x00,0x80,0x00,0x00,0x00,/*\"一\

0x00,0x00,0x80,0x00,0x80,0x00,0x40,0x00,0x20,0x00,0x10,0x00,0x0C,0x00,0xE3,0x7F,

0x04,0x00,0x08,0x00,0x10,0x00,0x20,0x00,0x60,0x00,0xC0,0x00,0x40,0x00,0x00,0x00,/*\"个\

0x00,0x00,0xFC,0x07,0x04,0x02,0x04,0x02,0xFC,0x03,0x40,0x48,0x30,0x44,0x0F,0x23,

0xCA,0x10,0x38,0x0C,0x08,0x03,0xF8,0x40,0x08,0x80,0x08,0x60,0xF8,0x1F,0x00,0x00/*\"吻\};

uchar a,i,t,x[8]={0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; char b;

void main(void) {

PK8255=0X80; while(1) {

for(a=0;a<64;a++) {

PA8255=0x00; PB8255=0x00; for(b=7;b>=0;b--) {

SBUF=~x[b]; while(!TI) ;TI=0; }

PA8255=hzdot[2*a]; PB8255=hzdot[2*a+1];

for(i=0;i<8;i++) {

if((x[7]&0x01)==0) goto LP; if((~x[i]!=0)&&((x[i]&0x01)!=0)) x[i]=x[i]<<7|x[i]>>1;

else if((~x[i]!=0)&&((x[i]&0x01)==0)) { x[i]=0xff; x[i+1]=0x7f; break; } } }

LP:x[0]=0x7f;x[7]=0xff; } }

三、74HC595连接的点阵示例

很多点阵都是使用74HC595连接的,74HC595是8位串行输入/输出或者并行输出移位寄存器,具有高阻关断三态输出功能。 74HC595的功能表如下:

为了形象的演示74HC595的功能,编写如下测试程序: #include

#define uint unsigned int

#define uchar unsigned char

sbit DS=P3^4; //74HC595的数据串行输入端口 sbit ST=P3^7; //74HC595并行输出使能 sbit SH=P3^6; //74HC595移位寄存器移位使能 //测试串行传输数据:

uchar code Test[]={0xFF,0x00,0xAA,0xCC,0xEE,}; //******延时子程序******// void delay(uint a) {

uint i,j; for(i=0;ivoid SendByte(uchar date) { uchar i;

for(i=0;i<8;i++) { SH=0; ST=0;

if(date&0x80) //将date最高位移到74HC595的移位寄存器 DS=1; else DS=0;

SH=1; //SH上升沿时移位 ST=1; //ST上升沿时输出数据

date=date<<1; //左移一位,将送出第二位数据 delay(5000); } }

//****主函数****// void main() { uchar i; while(1) {

for(i=0;i<5;i++) SendByte(Test[i]); } }

测试是依次输出0xFF,0x00,0xAA,0xCC,0xEE几个数据,在点阵显示程序中,是将数据全部送到74HC595的移位寄存器,再同时显示出来,并不是像下图所示一个一个流动显示,这个仅仅是测试数据的传输路径。

74HC595仅仅使用3个I/O口就能点亮点阵屏,因此大大减少了I/O口的使用。 例如24×24点阵的连接如下所示(行扫描使用3线-8线译码器74HC138),此图为原理示意图,实际中行扫描需要增加驱动。

根据此上图用汇编编写的静态显示程序如下:

ORG 0000H LJMP STAR ORG 0BH LJMP INTT0 STAR: MOV 20H,#00H MOV A,#0FFH MOV R7,#0 MOV P1,A MOV P2,A MOV P3,A MOV P0,A CLR P1.6 MOV TMOD,#01H MOV TH0,#0FEH MOV TL0,#18H MOV SCON,#0 MOV IE,#82H MOV SP,#70H MOV R0,#0 MAIN: LCALL DIS1 MOV DPTR ,#TAB LCALL MOVDISP LJMP MAIN MOVDISP:MOV B,#00H

DISLOOP:MOV R3,#07H DISMOV: JNB 02H,AAA DEC DPH CLR 02 AAA: MOV R2,#0 MOV R1,B SETB TR0

WAITMOV:JBC 00H,DISMOV1 AJMP WAITMOV DISMOV1:DJNZ R3,DISMOV JNB 02H,BBB DEC DPH CLR 02 BBB: INC B MOV A,B CJNE A,#0,CC1 INC DPH INC R7 CC0: INC B MOV A,B CJNE A,#0,CCC INC DPH INC R7 CC1: INC B

MOV A,B CJNE A,#0,CCC INC DPH INC R7 CCC: MOV A,R1

MOVOUT:CJNE R7,#3,DISLOOP MOV A,B

CJNE A,#24,DISLOOP MOV R7,#0 RET

DIS1: MOV R3,#0AH CLR P1.3 CLR P1.4 CLR P1.5 DIS11: MOV R2,#0 MOV DPTR,#TAB MOV R1,#0H SETB TR0

WAIT11:JBC 01H,DIS11 AJMP WAIT11 DIS111:DJNZ R3,DIS11 RET INTT0: INC R0 PUSH ACC

MOV TH0,#0FEH MOV TL0,#18H JBC 00H,GOEND MOV A,R1 MOVC A,@A+DPTR MOV SBUF,A WAIT: JBC TI,GO AJMP WAIT GO: INC R1 CJNE R1,#0,AA INC DPH SETB 02H AA: MOV A,R1 MOVC A,@A+DPTR MOV SBUF,A WAIT1: JBC TI,GO1 AJMP WAIT1 GO1: INC R1 CJNE R1,#0,BB INC DPH SETB 02H BB: MOV A,R1 MOVC A,@A+DPTR MOV SBUF,A

WAIT2: JBC TI,GO2 AJMP WAIT2 GO2: CLR P1.3 CLR P1.4 CLR P1.5 NOP SETB P1.6 NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP CLR P1.6 MOV A,R2 ANL A,#7H ANL P1,#0F8H ORL P1,A P122: INC R2

CJNE R2,#8,PAN1 LJMP PAN1A PAN1: JC PAN1A

CJNE R2,#10H,PAN2 LJMP PAN1B PAN2: JC PAN1B

CJNE R2,#018H,PAN3 LJMP PAN1C PAN3: JC PAN1C AJMP PANT PAN1A: SETB P1.3 AJMP PANT PAN1B: SETB P1.4 AJMP PANT PAN1C: SETB P1.5 PANT: INC R1

CJNE R1,#0,CC INC DPH SETB 02H CC: MOV A,R2 GO3: CJNE R2,#24,GO4 SETB 00H GO4: POP ACC RETI

GOEND: CLR TR0 SETB 01H POP ACC RETI ORG 0A00H TAB:

;-- 逐行 顺向 --

DB

000H,000H,000H,003H,0C0H,000H,004H,030H,000H,004H,010H,000H,008H,03FH,0FCH,008H;

DB

000H,006H,010H,000H,002H,020H,000H,002H,020H,000H,002H,040H,083H,004H,041H,083H;

DB

004H,041H,083H,008H,042H,083H,008H,03FH,001H,0F0H,001H,001H,080H,002H,000H,0C0H;

DB

004H,000H,060H,008H,00CH,018H,030H,008H,004H,040H,01CH,002H,040H,026H,002H,040H;

DB 043H,002H,021H,080H,0C4H,03EH,000H,03CH;\"欠\

DB

000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H;

DB

000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,07FH,0FFH,0FCH,0C0H,000H;

DB

006H,080H,000H,002H,080H,000H,002H,080H,000H,002H,0C0H,000H,006H,07FH,0FFH,0FCH;

DB

000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H;

DB 000H,000H,000H,000H,000H,000H,000H,000H;\"一\

DB

000H,000H,000H,000H,07CH,000H,000H,083H,000H,001H,000H,080H,006H,000H,060H,008H;

DB

000H,030H,030H,000H,00CH,040H,07EH,002H,080H,042H,001H,080H,082H,001H,081H,083H;

DB

081H,046H,082H,0E2H,078H,082H,01CH,000H,082H,000H,000H,082H,000H,000H,082H,000H;

DB

000H,082H,000H,000H,082H,000H,000H,082H,000H,000H,082H,000H,000H,082H,000H,000H;

DB 082H,000H,000H,082H,000H,000H,07CH,000H;\"个\

DB

000H,000H,000H,000H,01CH,000H,000H,022H,000H,07FH,0C1H,000H,0C0H,081H,0F8H,080H;

DB

080H,004H,080H,080H,002H,081H,000H,002H,08BH,000H,002H,08AH,002H,002H,08AH,022H;

DB

042H,089H,044H,042H,088H,0C4H,042H,088H,088H,042H,089H,008H,082H,082H,010H,082H;

DB

084H,020H,082H,084H,040H,082H,0C4H,083H,082H,07FH,084H,002H,001H,004H,004H,000H;

DB 084H,004H,000H,04CH,00CH,000H,033H,0F8H;\"吻\„„ END

效果图:

四、16×64双色点阵 原理图:

16×64单色点阵参考程序: #include

#define uint unsigned int #define uchar unsigned char uchar code table[]={

0xEF,0xFF,0xCF,0xFF,0xEF,0xFF,0x07,0xC0,0xF7,0xEF,0x7B,0xF7,0x7D,0xFB,0x7E,0xFF,

0xBF,0xFE,0xBF,0xFE,0xDF,0xFD,0xDF,0xFD,0xEF,0xF3,0xF3,0x87,0xFC,0xEF,0xFF,0xFF,//欠0

0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,0x01,0x80,

0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,//一1

0x7F,0xFF,0x7F,0xFF,0xBF,0xFE,0xBF,0xFD,0xDF,0xFB,0x6F,0xE7,0x77,0x8F,0x79,0xDF,

0x7F,0xFF,0x7F,0xFF,0x7F,0xFF,0x7F,0xFF,0x7F,0xFF,0x7F,0xFF,0x7F,0xFF,0xFF,0xFF,//个2

0x7F,0xFF,0x7F,0xFE,0x61,0xFF,0x6D,0x80,0xAD,0xB5,0xAD,0xB5,0xCD,0xB6,0xED,0xB6,

0x6D,0xBB,0x61,0xBB,0xBD,0xBD,0xDF,0xBD,0xFF,0xBE,0x7F,0xDF,0x9F,0xD7,0xFF,0xEF,//吻3

};

sbit DS=P3^0; //74HC595的数据串行输入端口 sbit ST=P3^5; //74HC595并行输出使能 sbit SH=P3^1; //74HC595移位寄存器移位使能 sbit G=P3^6;

//******延时子程序******// void delay(uint a) {

uint i,j; for(i=0;i/*将1个字节数据送到74HC595的移位寄存器,但未输出*/ void SendByte(uchar date) { uchar i;

for(i=0;i<8;i++) { SH=0;

if(date&0x80) //将date最高位移到74HC595的移位寄存器 DS=1; else DS=0;

SH=1; //SH上升沿时移位

date=date<<1; //左移一位,将送出第二位数据 } }

void main(void) {

uchar k,t,j; uchar i; while(1) { G=1;

for(k=0;k<=0;k++) //翻动的屏数 {

for(t=0;t<=200;t++) //翻动速度 {

for(i=0,j=0;i<16;i++,j+=2) //扫描 {

SendByte(table[64*k+j+97]); SendByte(table[64*k+j+96]); SendByte(table[64*k+j+65]); SendByte(table[64*k+j+64]); SendByte(table[64*k+j+33]);

SendByte(table[64*k+j+32]); SendByte(table[64*k+j+1]); SendByte(table[64*k+j]);

ST=0; G=0; P1=i; ST=1;

delay(30); G=1; } } } } }

阅读: 次 录入:petta

参考链接:http://www.picavr.com/news/2009-06/9459.htm

因篇幅问题不能全部显示,请点此查看更多更全内容