在LED显示汉字,怎么做到可以三个汉字循环显示?怎么添加代码? 100
#include<stdio.h>#include<sys/unistd.h>#include<io.h>#include<string.h>#include"syste...
#include <stdio.h>
#include <sys/unistd.h>
#include <io.h>
#include <string.h>
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "altera_avalon_timer_regs.h"
#include "alt_types.h"
#include "sys/alt_irq.h"
#define TRUE 1
#define FALSE 0
/***********************************************/
static void Timer_ISR_Init(void); //初始化中断
/***********************************************/
int main(void)
{
printf("\n Exp5 - Keyboard & 7Seg LED!\n");
//设置Timer中断
Timer_ISR_Init();
while(1)
{
usleep(10000);
}
return 0;
}
/***********************************************/
alt_u16 DispSegTab[]={0xDFFB,0xE7FB,0xD802,0xBFD9,0xC01B,0xBFEB,0xBFF7,0xC168,
0xFF2B,0x8143,0xFF6B,0xC12B,0xBF6B,0xBEEB,0x8FFF,0xFFFF};/*"旒",0*/
alt_u16 DisplayNum=0;
alt_u16 c=0x0001;
static void Timer_Irq_Handler(void *context, alt_u32 id)
{
IOWR_ALTERA_AVALON_PIO_DATA(PIO2_BASE, DispSegTab[DisplayNum]);
IOWR_ALTERA_AVALON_PIO_DATA(PIO1_BASE,c);
DisplayNum = (DisplayNum + 1) % 16;
c=c<<1;
if (c==0)
c=0x0001;
//清除Timer中断标志寄存器
IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER_BASE, 0);
}
/************************************************/
static void Timer_ISR_Init(void) //初始化中断
{
//清除Timer中断标志寄存器
IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER_BASE, 0);
//注册Timer中断
alt_irq_register(TIMER_IRQ, NULL, Timer_Irq_Handler);
//允许Timer中断
//IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER_BASE, 0x01);
} 展开
#include <sys/unistd.h>
#include <io.h>
#include <string.h>
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "altera_avalon_timer_regs.h"
#include "alt_types.h"
#include "sys/alt_irq.h"
#define TRUE 1
#define FALSE 0
/***********************************************/
static void Timer_ISR_Init(void); //初始化中断
/***********************************************/
int main(void)
{
printf("\n Exp5 - Keyboard & 7Seg LED!\n");
//设置Timer中断
Timer_ISR_Init();
while(1)
{
usleep(10000);
}
return 0;
}
/***********************************************/
alt_u16 DispSegTab[]={0xDFFB,0xE7FB,0xD802,0xBFD9,0xC01B,0xBFEB,0xBFF7,0xC168,
0xFF2B,0x8143,0xFF6B,0xC12B,0xBF6B,0xBEEB,0x8FFF,0xFFFF};/*"旒",0*/
alt_u16 DisplayNum=0;
alt_u16 c=0x0001;
static void Timer_Irq_Handler(void *context, alt_u32 id)
{
IOWR_ALTERA_AVALON_PIO_DATA(PIO2_BASE, DispSegTab[DisplayNum]);
IOWR_ALTERA_AVALON_PIO_DATA(PIO1_BASE,c);
DisplayNum = (DisplayNum + 1) % 16;
c=c<<1;
if (c==0)
c=0x0001;
//清除Timer中断标志寄存器
IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER_BASE, 0);
}
/************************************************/
static void Timer_ISR_Init(void) //初始化中断
{
//清除Timer中断标志寄存器
IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER_BASE, 0);
//注册Timer中断
alt_irq_register(TIMER_IRQ, NULL, Timer_Irq_Handler);
//允许Timer中断
//IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER_BASE, 0x01);
} 展开
2015-12-25
展开全部
一般是要应用软件实现的,有一款show电子资讯发布系统,很强大,可以播室外全彩屏,图文视频都可以,最牛的是它可以多点联网同步实现,而且可以像电视一样编辑节目单什么,很好用!不过是收费的哦!!!
控制系统里面设置,有的有这个选项,勾上就可以循环,没有这个选项的一般都过调整文字的播放时间,使之循环播放,总之,基本上所有的控制系统都有这个功能。建议多多看下你显示屏供应商给你提供的使用说明书。
t;
#include "toppic.h"
unsigned int num=0;
void LED4_display(unsigned int i);
void PIC18F_High_isr(void);/*中断服务函数声明*/
void PIC18F_Low_isr(void);
#pragma code high_vector_section=0x8
/*高优先级中断响应时,会自动跳转到0x8处*/
/*利用预处理器指令#pragma code来指定后面的程序在ROM中的起始地址为0x08,*/
/*它是告诉连接器定位到特定的代码段,HIGH_INTERRUPT_VECTOR 是该特定代码段的段名*/
void high_vector (void)
{
_asm goto PIC18F_High_isr _endasm/*通过一条跳转指令(汇编指令),跳转到中断服务函数(中断服务程序)处*/
}
#pragma code low_vector_section=0x18
/*低优先级中断响应时,会自动跳转到0x18处*/
void low_vector (void)
{
_asm goto PIC18F_Low_isr _endasm
}
#pragma code
/*这条语句不是多余的,它是告诉连接器回到默认的代码段,*/
/*如果不加的话,连接器就会傻傻地把后面的代码紧跟着上面的代码一直放下去。*/
/*而18f4520.lkr文件里定义了向量区地址最多到0x29,所以如果没加此句通常会报错*/
/*---高优先级中断服务程序---*/
#pragma interrupt PIC18F_High_isr
/*利用预处理器指令#pragma interrupt来声明后面的函数是低优先级中断服务函数(中断服务程序),*/
/*注意:关键字是interrupt,和低优先级中断时不同*/
/*一旦指定后面的函数是低优先级中断服务程序,系统在进入该函数时,会自动保护现场,退出前自动恢复现场,*/
/*同时中断服务程序执行完毕后,会自动返回断点,*/
/*中断服务函数前必须加该语句*/
void PIC18F_High_isr (void)
{
TMR0H=0X67;/*TMR0置初值,先写高字节,后写低字节*/
TMR0L=0X69;
num++;
if (num>9999) num=0;
INTCONbits.TMR0IF=0;/*TMR0溢出标志清零*/
}
/*---低优先级中断服务程序---*/
#pragma interruptlow PIC18F_Low_isr
/*注意:关键字是interruptlow,和高优先级中断时不同*/
void PIC18F_Low_isr (void)
{
}
void main(void)/*主函数*/
{
RCONbits.IPEN=1; /*使能中断优先级*/
toppic_init();/*TOPPIC开发板初始化*/
T0CON=0b00000101;/*TMR0设置:停止运行、16位定时,预分频1:64*/
TMR0H=0X67;/*TMR0置初值,先写高字节,后写低字节*/
TMR0L=0X69;
INTCONbits.TMR0IE=1;/*允许Timer0溢出中断*/
T0CONbits.TMR0ON=1;/*启动TMR0*/
INTCONbits.GIE=1;/*开全局中断*/
while(1)
{
LED4_display(num);/*完成4位数码管的一次动态扫描*/
}
}
/*0-F共阴字形码表*/
const rom uchar DB[17]={0x3f , 0x06 , 0x5b , 0x4f , 0x66 ,
0x6d ,0x7d , 0x07 , 0x7f , 0x6f , 0x77 , 0x7c ,
0x39 , 0x5e , 0x79 , 0x71 , 0x00};
void LED4_display(unsigned int i)
{
unsigned int a,bit1000,bit100,bit10,bit1;
a=i;
bit1000=a/1000;//提取千位
a=a%1000;
bit100=a/100;//提取百位
a=a%100;
bit10=a/10;//提取十位
bit1=a%10;//提取个位
COL4=0;
PORTD=DB[bit1];
COL1=1; //个位的位选
delayms(5);/*延时5mS*/
COL1=0;
PORTD=DB[bit10];
COL2=1; //十位的位选
delayms(5);/*延时5mS*/
COL2=0;
PORTD=DB[bit100];
COL3=1; //百位的位选
delayms(5);/*延时5mS*/
COL3=0;
PORTD=DB[bit1000];
COL4=1; //千位的位选
delayms(5);/*延时5mS*/
}
另外,虚机团上产品团购,超级便宜
LED显示屏作为户外大屏的领导者,显示性能以高清,色彩丰富,高亮度,维护简单等特点,受到市场青睐。而汉字是最常用文字之一。下面给大家展示LED显示屏汉字的设计过程及方案。
LED显示屏是利用发光二极管点阵模块或像素单元组成的平面式显示屏幕。它具有发光率高、使用寿命长、组态灵活、色彩丰富以及对室内外环境适应能力强等优点。并广泛的用于公交汽车、商店、体育场馆、车站、学校、银行、高速公路等公共场所的信息发布和广告宣传。LED显示屏发展较快,本文讲述了基于AT89C51单片机16×16LED汉字点阵滚动显示的基本原理、硬件组成与设计、程序编写与调试、Proteus软件仿真等基本环节和相关技术。
1 硬件电路组成及工作原理
本产品采用以AT89C51单片机为核心芯片的电路来实现,主要由AT89C51芯片、时钟电路、复位电路、列扫描驱动电路(74HCl54)、16×16LED点阵5部分组成,如图1所示。其中,AT89C51是一种带4kB闪烁可编程可擦除只读存储器(Falsh Programmable and Erasable Read OnlyMemory,FPEROM)的低电压、高性能CMOS型8位微处理器,俗称单片机。该器件采用ATMEL高密度非易失存储器制造技术制造,工业标准的MCS一5l指令集和输出管脚相兼容。由于将多功能8位CPU和闪烁存储器组合在单个芯片中,能够进行1 000次写/擦循环,数据保留时间为10年。他是一种高效微控制器,为很多嵌人式控制系统提供了一种灵活性高且价廉的方案。因此,在智能化电子设计与制作过程中经常用到AT89C51芯片。时钟电路由AT89C5l的18,19脚的时钟端(XTAI l及XTAL2)以及12 MHz晶振X、电容C2、C3组成,采用片内振荡方式。复位电路采用简易的上电复位电路,主要由电阻R,R2,电容C,开关K组成,分别接至AT89C51的RST复位输入端。LED点阵显示屏采用16×16共256个象素的点阵,可通过万用表检测发光二极管的方法测试判断出该点阵的引脚分布。
我们把行列总线接在单片机的I/0口,然后把上面分析到的扫描代码送入总线,就可以得到显示的汉字了。但是若将LED点阵的行列端口全部直接接入89S5 1单片机,则需要使用32条I/0口,这样会造成I/0口资源的耗尽,系统也再无扩充的余地。因此,我们在实际应用中只是将LED点阵的16条行线直接接在P0口和P2口,至于列选扫描信号则是由4—16线译码器74HCl54来选择控制,这样一来列选控制只使用了单片机的4个I/O口,节约了很多I/O口资源,为单片机系统扩充使用功能提供了条件。考虑到P0口必需设置上拉电阻,我们采用4.7 kΩ排电阻作为上拉电阻。汉字扫描显示的基本过程是这样的:通电后由于电阻R,电容c1的作用,使单片机的RST复位脚电平先高后低,从而达到复位;之后,在C、C3、X以及单片机内部时钟电路的作用下,单片机89C51按照设定的程序在P0和P2接口输出与内部汉字对应的代码电平送至LED点阵的行选线(高电平驱动),同时在P1.1,P1.2,P1.3,P1.4接口输出列选扫描信号(低电平驱动),从而选中相应的象素LED发光,并利用人眼的视觉暂留特性合成整个汉字的显示。再改变取表地址实现汉字的滚动显示。
2 汉字的点阵显示原理及字库代码获取方法
我们以UCDOS中文宋体字库为例,每一个字由16行16列的点阵组成显示。即国标汉字库中的每一个字均由256点阵来表示。我们可以把每一个点理解为一个象素,而把每一个字的字形理解为一幅图像。事实上这个汉字屏不仅可以显示汉字,也可以显示在256象素范围内的任何图形。如查用8位的AT89C51单片机控制,由于单片机的总线由8位,一个字需要拆分为2个部分。
为了弄清楚汉字的点阵组成规律,首先通过列扫描方法获取汉字的代码。汉字可拆分为上部和下部,上部由8×16点阵组成,下部也由8×16点阵组成。本例通过列扫描方法首先显示左上角的第一列的上半部分,即第0列的P00~P07口,方向为P00到P07,显示汉字“我”时,为全灭,第一列的下半部分也为全灭。第二列的上半部分P06、点亮,由上往下排列,为:PO.0灭,PO.1灭,P0.2灭PO.3灭,PO.4灭,P0.5灭,P0.6亮,P0.7灭。即二进制00000010,转换为十六进制为02h。上半部第二列完成后,继续扫描下半部的第二列,为了接线的方便,我们仍设计成由上往下扫描,即从P27向P20方向扫描,从图3可以看到,这一列P23亮,即为00001000,十六进制则为08h。依照这个方法转向第三列、第四列,……,直至第十六列的扫描,一共扫描32个8位,可以得出汉字“我”的扫描代码为:
00H,02H,08H,06H,28H,02H,24H,22H
0FCH,3FH,24H,2 1H,20H,10H,3CH,08H
0E2H,07H,20H,0AH,0E4H,11H,0A8H,20H
20H,30H,00H,00H,00H,00H,00H,00H
由这个原理可以看出,无论LED显示屏显示何种字体或图像,都可以用这个方法来分析出他的扫描代码从而显示在屏幕上。上述方法虽然能够让我们弄清楚汉字点阵代码的获取过程,但是依靠人工方法获取汉字代码是一件非常繁琐的事情。为此,我们经常采用字库软件查找字符代码,软件打开后输入汉字,点“检取”,十六进制数据的汉字代码即可自动生成,把我们所需要的竖排数据复制到程序中即可。
可见,汉字点阵显示一般有点扫描、行扫描和列扫描3种。为了符合视觉暂留要求,点扫描方法的扫描频率必须大于16×64—1 024 Hz,周期小于1 ms即可。行扫描和列扫描方法的扫描频率必须大于16×8一128 Hz,周期小于7.8 ms即可,但是一次驱动一列或一行(8颗LED)时需外加驱动电路提高电流,否则LED亮度会不足。
3 在Keil环境中程序设计与调试
软件程序主要由开始、初始化、主程序、字库组成。
在keil软件中完成程序编写、调试和编译之后,生成能让单片机运行的Hex文件。
4 运用Proteus软件仿真LED汉字显示屏
Proteus与其它单片机仿真软件不同的是,它不仅能仿真单片机外围电路或没有单片机参与的其它电路的工作情况,也能仿真单片机CPU的工作情况。因此在仿真和程序调试时,是从工程的角度直接看程序运行和电路工作的过程和结果。从某种意义上讲Proteus仿真,基本接近与工程应用。本次基于AT89C51单片机16×16LED汉字滚动显示屏的设计已运用Proteus软件仿真实现。
虽然本设计只使用了一块16×16LED点阵,电路简单,但是已经包涵了LED汉字滚动显示屏的电路基本原理、基本程序和Proteus软件仿真,只要扩展单片机的10接口,并增加一些LED点阵和相关芯片,就能设计出更大面积、更多花样的LED显示屏。因此本文对同类设计具有一定的理论和实践参考价值。
国内LED显示屏的汉字滚动是常见的播放方式之一,只要扩展单片机的IO接口,就可以增加LED显示屏的点阵,随着LED点阵的增加,显示屏的面积就可以自动增加。当设计汉字,需要针对显示屏的面积来做最合适的设计。
能把带字库12864液晶显示汉字了,程序如下,以供参考
显示三屏汉字,每屏显示三秒,来回循环显示
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define lcd_data P0
uchar code table1[]="钟山风雨起苍黄毛""百万雄师过大江泽""亦将剩勇追穷寇东""不可沽名学霸王七";
uchar code table2[]="学习技术天天向上""努力学习才有提高""总结经验不断前进""电子设计一路领先";
uchar code table3[]="爱一个人难却还爱""交结朋友可路更宽""诚实守信加油努力""成功做人成功做事";
sbit lcden=P2^7;
sbit rd=P2^6;
sbit wr=P2^5;
sbit psb=P3^2; //并/串方式选择
void delay(uint z) //延迟函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--)
;
}
void write_com(uchar com) //写指令
{
rd=0;
wr=0;
lcden=0;
P0=com;
delay(5); //这个延迟函数必须要有,因为读数据时当E为高时,数据必须保持稳定
lcden=1;
lcden=0;
}
void write_date(uchar date) //写数据
{
rd=1;
wr=0;
lcden=0;
P0=date;
delay(5); //这个延迟必须要有
lcden=1;
lcden=0;;
}
void write_word(uchar *add) //用指针
{
uchar i;
write_com(0x80); //从第一行开始显示
for(i=0;i<64;i++) //一个汉字占两个字节
{
write_date(*add);
add++; //指针加,指向下一个字节
}
}
void init() //初始化
{
psb=1; //设置并口方式
write_com(0x 0c); //显示状态 整体显示开
write_com(0x01); //游标左移
write_com(0x30); //功能设定基本指令操作
write_com(0x10); //游标左移
}
void main()
{
init();
while(1)
{
write_word(table1);
delay(3000); //每一屏显示秒钟
write_word(table2);
delay(3000);
write_word(table3);
delay(3000);
}
}
我那时候用的是吴鉴鹰单片机开发板,各方面还是不错的。
从刚开始接触单片机,到现在已经有4年的时间了,在这期间学习和使用了51单片机、飞思卡尔单片机,LPC2138,PIC16F887等系列的单片机,每接触一款单片机,都会经历熟悉其基本开发,然后将其用于项目中的过程,对于如何学习一款单片机,自己做了如下的总结。
大家都知道,51单片机是最容易入门的,不仅因为其编程简单,更重要的是网上的资料非常丰富。所以一般学习单片机开发的都将51单片机作为入门开发的首选。我学习51单片机的时候是采用这样的一个步骤进行学习的:
第一步(熟悉的过程):买了一款51单片机开发板,然后就开始了我的学习之旅,刚开始的时候没有去看视频教程,而是对着一本实验教材进行学习,那本实验教材的名字记不清楚了,但是其内容就是围绕单片机的LED灯进行控制,将51单片机内部的各个功能部件全部都使用到了,这样就能使我在很短的时间内,通过控制LED灯的亮、灭熟悉了51单片机的内部的各种资源,这时对51单片机也就没有感到陌生了。所以,个人觉得,学习单片机,要从实验入手,先熟悉单片机再说,开发语言开始使用的是C语言。
第二步(进阶的过程):有了第一步的基础之后,接下来的便是进阶的过程,当时,我看的是郭天祥十天学会单片机的视频教程,因为这个教程从基础到复杂的编程慢慢深入,讲的比较的全面,而且也生动,所以那一阶段,也是我学习单片机进步最快的阶段,每次听课的时候,按照上面的实验,以及课堂上面调试程序时出现的一些问题,自己认真的在电脑上进行调试,并分析产生故障的原因,让我有了一定的开发基础。在看完了视频教程之后,后面又对基础的知识进行了下补习,主要是看单片机原理性的教材,因为有些细节性的东西还是要从教材上面获得。
第三步(项目实战的阶段):学习单片机的时候,虽然也编写了一些程序,但是那些都是一些很小的模块程序,并没有起到综合应用的目的,所以在这之后,我和另外一个学习硬件的同学一起组成了一个小的团队,进行项目实践开发,那时候,实验室的条件比价好,有很多的器件可以自己使用。所以,我们就设计了我们的第一个作品,基于单片机的液体点滴监控系统。做这个系统时,就将以前单片机所学的知识,做了一个综合的应用,包括有LCD1602控制,串口的控制等。
经过以上三个步骤的学习之后,对于51单片机的开发基本上就算入门了。而对于其他类型的单片机,如飞思卡尔单片机,LPC2148 ARM7单片机,PIC16F887等,虽然每个系列的功能不一样,但是最基本的编程思想还是一样的,不同的可能就是编译器,程序下载的软件等差别,所以有了51单片机的开发基础之后,学习其他单片机所采用的方法就是一个差异化的学习,学习各种单片机不同的地方,这样,就能很快的熟悉一款新的型号的单片机。
如在学习PIC16F887这个系列的单片机时,我首先做的工作不是去阅读数据手册,而是先拿着DEMO代码,在编译软件中编译、链接、生成HEX文件,然后将其下载到开发板中跑起来,这个过程主要就是学习其软件的基本操作,有了这个基础之后,就能自己进行编程、测试。之后就是熟悉其编程的模式,所谓其编程模式,就是寄存器的控制,中断程序的编写,熟悉了这个操作,也就能控制其他的功能模块了,如串口的控制、I2C硬件控制器的控制。这些基本的开发熟悉了之后,接下来便是学习差异的部分,例如PIC单片机C语言中,其堆栈深度不能超过8级,超过了之后,将会使得程序出现跑飞的现象。而且内存的分配完全要靠自己来控制,分成了4个BANK的数据,BANK0,BANK1,BANK2,BANK3 等。这些就是每个系列单片机所独有的一些东西,这些东西需要详细的了解,因为它们可能为你的编程带来很大的便利。
以上就是我学习单片机的总结,如果大家有更好的学习方法,希望大家能够提出来,一起讨论,共同进步。
控制系统里面设置,有的有这个选项,勾上就可以循环,没有这个选项的一般都过调整文字的播放时间,使之循环播放,总之,基本上所有的控制系统都有这个功能。建议多多看下你显示屏供应商给你提供的使用说明书。
t;
#include "toppic.h"
unsigned int num=0;
void LED4_display(unsigned int i);
void PIC18F_High_isr(void);/*中断服务函数声明*/
void PIC18F_Low_isr(void);
#pragma code high_vector_section=0x8
/*高优先级中断响应时,会自动跳转到0x8处*/
/*利用预处理器指令#pragma code来指定后面的程序在ROM中的起始地址为0x08,*/
/*它是告诉连接器定位到特定的代码段,HIGH_INTERRUPT_VECTOR 是该特定代码段的段名*/
void high_vector (void)
{
_asm goto PIC18F_High_isr _endasm/*通过一条跳转指令(汇编指令),跳转到中断服务函数(中断服务程序)处*/
}
#pragma code low_vector_section=0x18
/*低优先级中断响应时,会自动跳转到0x18处*/
void low_vector (void)
{
_asm goto PIC18F_Low_isr _endasm
}
#pragma code
/*这条语句不是多余的,它是告诉连接器回到默认的代码段,*/
/*如果不加的话,连接器就会傻傻地把后面的代码紧跟着上面的代码一直放下去。*/
/*而18f4520.lkr文件里定义了向量区地址最多到0x29,所以如果没加此句通常会报错*/
/*---高优先级中断服务程序---*/
#pragma interrupt PIC18F_High_isr
/*利用预处理器指令#pragma interrupt来声明后面的函数是低优先级中断服务函数(中断服务程序),*/
/*注意:关键字是interrupt,和低优先级中断时不同*/
/*一旦指定后面的函数是低优先级中断服务程序,系统在进入该函数时,会自动保护现场,退出前自动恢复现场,*/
/*同时中断服务程序执行完毕后,会自动返回断点,*/
/*中断服务函数前必须加该语句*/
void PIC18F_High_isr (void)
{
TMR0H=0X67;/*TMR0置初值,先写高字节,后写低字节*/
TMR0L=0X69;
num++;
if (num>9999) num=0;
INTCONbits.TMR0IF=0;/*TMR0溢出标志清零*/
}
/*---低优先级中断服务程序---*/
#pragma interruptlow PIC18F_Low_isr
/*注意:关键字是interruptlow,和高优先级中断时不同*/
void PIC18F_Low_isr (void)
{
}
void main(void)/*主函数*/
{
RCONbits.IPEN=1; /*使能中断优先级*/
toppic_init();/*TOPPIC开发板初始化*/
T0CON=0b00000101;/*TMR0设置:停止运行、16位定时,预分频1:64*/
TMR0H=0X67;/*TMR0置初值,先写高字节,后写低字节*/
TMR0L=0X69;
INTCONbits.TMR0IE=1;/*允许Timer0溢出中断*/
T0CONbits.TMR0ON=1;/*启动TMR0*/
INTCONbits.GIE=1;/*开全局中断*/
while(1)
{
LED4_display(num);/*完成4位数码管的一次动态扫描*/
}
}
/*0-F共阴字形码表*/
const rom uchar DB[17]={0x3f , 0x06 , 0x5b , 0x4f , 0x66 ,
0x6d ,0x7d , 0x07 , 0x7f , 0x6f , 0x77 , 0x7c ,
0x39 , 0x5e , 0x79 , 0x71 , 0x00};
void LED4_display(unsigned int i)
{
unsigned int a,bit1000,bit100,bit10,bit1;
a=i;
bit1000=a/1000;//提取千位
a=a%1000;
bit100=a/100;//提取百位
a=a%100;
bit10=a/10;//提取十位
bit1=a%10;//提取个位
COL4=0;
PORTD=DB[bit1];
COL1=1; //个位的位选
delayms(5);/*延时5mS*/
COL1=0;
PORTD=DB[bit10];
COL2=1; //十位的位选
delayms(5);/*延时5mS*/
COL2=0;
PORTD=DB[bit100];
COL3=1; //百位的位选
delayms(5);/*延时5mS*/
COL3=0;
PORTD=DB[bit1000];
COL4=1; //千位的位选
delayms(5);/*延时5mS*/
}
另外,虚机团上产品团购,超级便宜
LED显示屏作为户外大屏的领导者,显示性能以高清,色彩丰富,高亮度,维护简单等特点,受到市场青睐。而汉字是最常用文字之一。下面给大家展示LED显示屏汉字的设计过程及方案。
LED显示屏是利用发光二极管点阵模块或像素单元组成的平面式显示屏幕。它具有发光率高、使用寿命长、组态灵活、色彩丰富以及对室内外环境适应能力强等优点。并广泛的用于公交汽车、商店、体育场馆、车站、学校、银行、高速公路等公共场所的信息发布和广告宣传。LED显示屏发展较快,本文讲述了基于AT89C51单片机16×16LED汉字点阵滚动显示的基本原理、硬件组成与设计、程序编写与调试、Proteus软件仿真等基本环节和相关技术。
1 硬件电路组成及工作原理
本产品采用以AT89C51单片机为核心芯片的电路来实现,主要由AT89C51芯片、时钟电路、复位电路、列扫描驱动电路(74HCl54)、16×16LED点阵5部分组成,如图1所示。其中,AT89C51是一种带4kB闪烁可编程可擦除只读存储器(Falsh Programmable and Erasable Read OnlyMemory,FPEROM)的低电压、高性能CMOS型8位微处理器,俗称单片机。该器件采用ATMEL高密度非易失存储器制造技术制造,工业标准的MCS一5l指令集和输出管脚相兼容。由于将多功能8位CPU和闪烁存储器组合在单个芯片中,能够进行1 000次写/擦循环,数据保留时间为10年。他是一种高效微控制器,为很多嵌人式控制系统提供了一种灵活性高且价廉的方案。因此,在智能化电子设计与制作过程中经常用到AT89C51芯片。时钟电路由AT89C5l的18,19脚的时钟端(XTAI l及XTAL2)以及12 MHz晶振X、电容C2、C3组成,采用片内振荡方式。复位电路采用简易的上电复位电路,主要由电阻R,R2,电容C,开关K组成,分别接至AT89C51的RST复位输入端。LED点阵显示屏采用16×16共256个象素的点阵,可通过万用表检测发光二极管的方法测试判断出该点阵的引脚分布。
我们把行列总线接在单片机的I/0口,然后把上面分析到的扫描代码送入总线,就可以得到显示的汉字了。但是若将LED点阵的行列端口全部直接接入89S5 1单片机,则需要使用32条I/0口,这样会造成I/0口资源的耗尽,系统也再无扩充的余地。因此,我们在实际应用中只是将LED点阵的16条行线直接接在P0口和P2口,至于列选扫描信号则是由4—16线译码器74HCl54来选择控制,这样一来列选控制只使用了单片机的4个I/O口,节约了很多I/O口资源,为单片机系统扩充使用功能提供了条件。考虑到P0口必需设置上拉电阻,我们采用4.7 kΩ排电阻作为上拉电阻。汉字扫描显示的基本过程是这样的:通电后由于电阻R,电容c1的作用,使单片机的RST复位脚电平先高后低,从而达到复位;之后,在C、C3、X以及单片机内部时钟电路的作用下,单片机89C51按照设定的程序在P0和P2接口输出与内部汉字对应的代码电平送至LED点阵的行选线(高电平驱动),同时在P1.1,P1.2,P1.3,P1.4接口输出列选扫描信号(低电平驱动),从而选中相应的象素LED发光,并利用人眼的视觉暂留特性合成整个汉字的显示。再改变取表地址实现汉字的滚动显示。
2 汉字的点阵显示原理及字库代码获取方法
我们以UCDOS中文宋体字库为例,每一个字由16行16列的点阵组成显示。即国标汉字库中的每一个字均由256点阵来表示。我们可以把每一个点理解为一个象素,而把每一个字的字形理解为一幅图像。事实上这个汉字屏不仅可以显示汉字,也可以显示在256象素范围内的任何图形。如查用8位的AT89C51单片机控制,由于单片机的总线由8位,一个字需要拆分为2个部分。
为了弄清楚汉字的点阵组成规律,首先通过列扫描方法获取汉字的代码。汉字可拆分为上部和下部,上部由8×16点阵组成,下部也由8×16点阵组成。本例通过列扫描方法首先显示左上角的第一列的上半部分,即第0列的P00~P07口,方向为P00到P07,显示汉字“我”时,为全灭,第一列的下半部分也为全灭。第二列的上半部分P06、点亮,由上往下排列,为:PO.0灭,PO.1灭,P0.2灭PO.3灭,PO.4灭,P0.5灭,P0.6亮,P0.7灭。即二进制00000010,转换为十六进制为02h。上半部第二列完成后,继续扫描下半部的第二列,为了接线的方便,我们仍设计成由上往下扫描,即从P27向P20方向扫描,从图3可以看到,这一列P23亮,即为00001000,十六进制则为08h。依照这个方法转向第三列、第四列,……,直至第十六列的扫描,一共扫描32个8位,可以得出汉字“我”的扫描代码为:
00H,02H,08H,06H,28H,02H,24H,22H
0FCH,3FH,24H,2 1H,20H,10H,3CH,08H
0E2H,07H,20H,0AH,0E4H,11H,0A8H,20H
20H,30H,00H,00H,00H,00H,00H,00H
由这个原理可以看出,无论LED显示屏显示何种字体或图像,都可以用这个方法来分析出他的扫描代码从而显示在屏幕上。上述方法虽然能够让我们弄清楚汉字点阵代码的获取过程,但是依靠人工方法获取汉字代码是一件非常繁琐的事情。为此,我们经常采用字库软件查找字符代码,软件打开后输入汉字,点“检取”,十六进制数据的汉字代码即可自动生成,把我们所需要的竖排数据复制到程序中即可。
可见,汉字点阵显示一般有点扫描、行扫描和列扫描3种。为了符合视觉暂留要求,点扫描方法的扫描频率必须大于16×64—1 024 Hz,周期小于1 ms即可。行扫描和列扫描方法的扫描频率必须大于16×8一128 Hz,周期小于7.8 ms即可,但是一次驱动一列或一行(8颗LED)时需外加驱动电路提高电流,否则LED亮度会不足。
3 在Keil环境中程序设计与调试
软件程序主要由开始、初始化、主程序、字库组成。
在keil软件中完成程序编写、调试和编译之后,生成能让单片机运行的Hex文件。
4 运用Proteus软件仿真LED汉字显示屏
Proteus与其它单片机仿真软件不同的是,它不仅能仿真单片机外围电路或没有单片机参与的其它电路的工作情况,也能仿真单片机CPU的工作情况。因此在仿真和程序调试时,是从工程的角度直接看程序运行和电路工作的过程和结果。从某种意义上讲Proteus仿真,基本接近与工程应用。本次基于AT89C51单片机16×16LED汉字滚动显示屏的设计已运用Proteus软件仿真实现。
虽然本设计只使用了一块16×16LED点阵,电路简单,但是已经包涵了LED汉字滚动显示屏的电路基本原理、基本程序和Proteus软件仿真,只要扩展单片机的10接口,并增加一些LED点阵和相关芯片,就能设计出更大面积、更多花样的LED显示屏。因此本文对同类设计具有一定的理论和实践参考价值。
国内LED显示屏的汉字滚动是常见的播放方式之一,只要扩展单片机的IO接口,就可以增加LED显示屏的点阵,随着LED点阵的增加,显示屏的面积就可以自动增加。当设计汉字,需要针对显示屏的面积来做最合适的设计。
能把带字库12864液晶显示汉字了,程序如下,以供参考
显示三屏汉字,每屏显示三秒,来回循环显示
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define lcd_data P0
uchar code table1[]="钟山风雨起苍黄毛""百万雄师过大江泽""亦将剩勇追穷寇东""不可沽名学霸王七";
uchar code table2[]="学习技术天天向上""努力学习才有提高""总结经验不断前进""电子设计一路领先";
uchar code table3[]="爱一个人难却还爱""交结朋友可路更宽""诚实守信加油努力""成功做人成功做事";
sbit lcden=P2^7;
sbit rd=P2^6;
sbit wr=P2^5;
sbit psb=P3^2; //并/串方式选择
void delay(uint z) //延迟函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--)
;
}
void write_com(uchar com) //写指令
{
rd=0;
wr=0;
lcden=0;
P0=com;
delay(5); //这个延迟函数必须要有,因为读数据时当E为高时,数据必须保持稳定
lcden=1;
lcden=0;
}
void write_date(uchar date) //写数据
{
rd=1;
wr=0;
lcden=0;
P0=date;
delay(5); //这个延迟必须要有
lcden=1;
lcden=0;;
}
void write_word(uchar *add) //用指针
{
uchar i;
write_com(0x80); //从第一行开始显示
for(i=0;i<64;i++) //一个汉字占两个字节
{
write_date(*add);
add++; //指针加,指向下一个字节
}
}
void init() //初始化
{
psb=1; //设置并口方式
write_com(0x 0c); //显示状态 整体显示开
write_com(0x01); //游标左移
write_com(0x30); //功能设定基本指令操作
write_com(0x10); //游标左移
}
void main()
{
init();
while(1)
{
write_word(table1);
delay(3000); //每一屏显示秒钟
write_word(table2);
delay(3000);
write_word(table3);
delay(3000);
}
}
我那时候用的是吴鉴鹰单片机开发板,各方面还是不错的。
从刚开始接触单片机,到现在已经有4年的时间了,在这期间学习和使用了51单片机、飞思卡尔单片机,LPC2138,PIC16F887等系列的单片机,每接触一款单片机,都会经历熟悉其基本开发,然后将其用于项目中的过程,对于如何学习一款单片机,自己做了如下的总结。
大家都知道,51单片机是最容易入门的,不仅因为其编程简单,更重要的是网上的资料非常丰富。所以一般学习单片机开发的都将51单片机作为入门开发的首选。我学习51单片机的时候是采用这样的一个步骤进行学习的:
第一步(熟悉的过程):买了一款51单片机开发板,然后就开始了我的学习之旅,刚开始的时候没有去看视频教程,而是对着一本实验教材进行学习,那本实验教材的名字记不清楚了,但是其内容就是围绕单片机的LED灯进行控制,将51单片机内部的各个功能部件全部都使用到了,这样就能使我在很短的时间内,通过控制LED灯的亮、灭熟悉了51单片机的内部的各种资源,这时对51单片机也就没有感到陌生了。所以,个人觉得,学习单片机,要从实验入手,先熟悉单片机再说,开发语言开始使用的是C语言。
第二步(进阶的过程):有了第一步的基础之后,接下来的便是进阶的过程,当时,我看的是郭天祥十天学会单片机的视频教程,因为这个教程从基础到复杂的编程慢慢深入,讲的比较的全面,而且也生动,所以那一阶段,也是我学习单片机进步最快的阶段,每次听课的时候,按照上面的实验,以及课堂上面调试程序时出现的一些问题,自己认真的在电脑上进行调试,并分析产生故障的原因,让我有了一定的开发基础。在看完了视频教程之后,后面又对基础的知识进行了下补习,主要是看单片机原理性的教材,因为有些细节性的东西还是要从教材上面获得。
第三步(项目实战的阶段):学习单片机的时候,虽然也编写了一些程序,但是那些都是一些很小的模块程序,并没有起到综合应用的目的,所以在这之后,我和另外一个学习硬件的同学一起组成了一个小的团队,进行项目实践开发,那时候,实验室的条件比价好,有很多的器件可以自己使用。所以,我们就设计了我们的第一个作品,基于单片机的液体点滴监控系统。做这个系统时,就将以前单片机所学的知识,做了一个综合的应用,包括有LCD1602控制,串口的控制等。
经过以上三个步骤的学习之后,对于51单片机的开发基本上就算入门了。而对于其他类型的单片机,如飞思卡尔单片机,LPC2148 ARM7单片机,PIC16F887等,虽然每个系列的功能不一样,但是最基本的编程思想还是一样的,不同的可能就是编译器,程序下载的软件等差别,所以有了51单片机的开发基础之后,学习其他单片机所采用的方法就是一个差异化的学习,学习各种单片机不同的地方,这样,就能很快的熟悉一款新的型号的单片机。
如在学习PIC16F887这个系列的单片机时,我首先做的工作不是去阅读数据手册,而是先拿着DEMO代码,在编译软件中编译、链接、生成HEX文件,然后将其下载到开发板中跑起来,这个过程主要就是学习其软件的基本操作,有了这个基础之后,就能自己进行编程、测试。之后就是熟悉其编程的模式,所谓其编程模式,就是寄存器的控制,中断程序的编写,熟悉了这个操作,也就能控制其他的功能模块了,如串口的控制、I2C硬件控制器的控制。这些基本的开发熟悉了之后,接下来便是学习差异的部分,例如PIC单片机C语言中,其堆栈深度不能超过8级,超过了之后,将会使得程序出现跑飞的现象。而且内存的分配完全要靠自己来控制,分成了4个BANK的数据,BANK0,BANK1,BANK2,BANK3 等。这些就是每个系列单片机所独有的一些东西,这些东西需要详细的了解,因为它们可能为你的编程带来很大的便利。
以上就是我学习单片机的总结,如果大家有更好的学习方法,希望大家能够提出来,一起讨论,共同进步。
追问
我晕,你就帮我看看怎么加进去!你写那么多我也看不懂,我学的JAVA跟C++,我能看懂代码意思跟函数等,就是不知道怎么加,这个是基于sopc的点阵啊大哥
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询