码管显示程序设计
1.实验目的
(1)了解数码管的显示原理;
(2)掌握JX44B0中数码显示的编程方法。
2.实验内容
设计LED数码管显示程序,要求六位LED数码管滚动显示0~9数字字符以及两至三个固定的英文单词。
3.实验设备
(1)硬件:JX44B0教学实验箱、PC机;
(2)软件:PC机操作系统Windows 98(2000\XP)+ADT IDE集成开发环境。
4.实验原理
(1)LED显示原理
发光二极管数码显示器简称LED显示器。LED显示器具有耗电省、成本低廉、配置简单灵活、安装方便、耐振动、寿命长等优点,目前广泛应用于嵌入式系统中。
7段LED由7个发光二极管按“日”字形排列,所有发光二极管的阳极连在一起称共阳极接法,阴极连在一起称为共阴极接法。一般共阴极可以不需外接电阻,但共阳极接法中发光二极管必须外接电阻。LED的结构及连接图见图1.1。
图1.1 LED结构及连接图
当选用共阴极的LED显示器时,所有发光二极管的阴极连在一起接地,当某个发光二极管的阳极加入高电平时,对应的二极管点亮。因此要显示某字形就应使此字形的相应段的二极管点亮,也就是送一个用不同电平组合代表的数据字来控制LED的显示,此数据称为字符的段码。字符0、1、2…F与LED码段A、B、C…F以及DP(小数点)的关系如表5-1所示:
表1.1 LED字符与码段对应表
说明:共阴的LED,被选中时的段为高电平有效,熄灭的段码为00H;
共阳的LED,被选中时的段为低电平有效.熄灭的段码为FFH。
本次试验系统中采用的是共阳极接法。
(2)LED显示接口
LED显示器的接口一般有静态显示与动态显示接口两种方式
1) 静态显示
LED数码管采用静态接口时,共阴极或共阳极点连接在一起接地或接高电平。每个显示位的段选线与一个8位并行口线对应相连,只要在显示位上的段选线上保持段码电平不变,则该位就能保持相应的显示字符。这里的8位并行口可以直接采用并行I/O口,也可以采用串入/并出的移位寄存器或是其它具有三态功能的锁存器等。
2) 动态显示
在多位LED显示时,为了简化电路,降低成本,将所有位的段选线并联在一起,由一个8位I/O口控制。而共阴(或共阳)极公共端分别由相应的I/O线控制,实现各位的分时选通。由于各个数码管是共用同一个段码输出口,分时轮流通电的,从而大大简化了硬件线路,降低了成本。不过这种方式的数码管接口电路中数码管不宜太多,一般在8个以内,否则每个数码管所分配的实际导通时间会太少,显得亮度不足。若LED位数较多时应采用增加驱动能力以提高显示亮度。
本实验系统中采用的是动态显示接口,其中数码管扫描控制地址为0x02000006,位0-位5每位分别对应一个数码管,将其中某位清0来选择相应的数码管,地址0x02000004为数码管的数据寄存器。数码管采用共阳方式,向该地址写一个数据就可以控制LED的显示。
图1.2 实验系统LED原理图
5.实验硬件原理框图
实验中将数码管与ARM的相应I/O端口相连,如图1.3。
图1.3 硬件原理框图
6.程序设计流程图
图1.4 程序流程图
7.程序及实验结果
unsigned char seg7table[16] =
{
/* 0 1 2 3 4 5 6 7*/
0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8,
/* 8 9 A B C D E F*/
0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e,
};
unsigned char seg7table2[5] =
{
/*H E L L O */
0x89, 0x86, 0xc7, 0xc7, 0xc0,
};
unsigned char seg7table3[3]=
{0xc7,0x86,0xa1,};
#define U8 unsigned char
static int delayLoopCount=1000;
void Delay(int time);
void display_seg7();
void flash_seg7();
void Test_Seg7(void);
void display_hello(void);
/******************************************************************
函数说明: EB44B0 7段构共阳数码管测试
功能描述: 依次在7段数码管上显示0123456789ABCDEF
返回代码: 无
参数说明: 无
******************************************************************/
void Test_Seg7(void)
{
int i;
/* 设置数码管段选,某位为0时选择,下面同时选中所有数码管 */
*((U8*) 0x02000006) = 0x0f;
for( ; ; )
{
/* 数码管从0到F依次将字符显示出来 */
for(i=0;i<0x10;i++)
{
/* 查表并输出数据 */
*((U8*) 0x02000004) = seg7table[i];
Delay (100);
}
/* 数码管从F到0依次将字符显示出来 */
for(i=0xf;i>=0x0;i--)
{
/* 查表并输出数据 */
*((U8*) 0x02000004) = seg7table[i];
Delay (100);
}
}
}
/******************************************************************
函数说明: EB44B0 7段构共阳数码管测试
功能描述: 依次在不同的段数码管上显示0~9
返回代码: 无
参数说明: 无
******************************************************************/
void flash_seg7(void)
{
int i = 0;
int index = 0;
*((U8*) 0x02000006) = 0x3f; /* 关闭所有数码管 */
for( ; ; )
{
/* 设置数码管段选 */
*((U8*) 0x02000006) = 0x3f & ~(0x01 << index);
/* 查表并输出数据 */
*((U8*) 0x02000004) = seg7table[i];
Delay (800);
i++;
i %= 10;
index ++;
index %= 6;
}
}
/******************************************************************
函数说明: EB44B0 7段构共阳数码管测试
功能描述: 在数码管上显示123456
返回代码: 无
参数说明: 无
******************************************************************/
void display_seg7(void)
{
int index = 0;
int sleep = 0;
for( ; ; )
{
/* 设置数码管段选 */
*((U8*) 0x02000006) = 0x3f & ~(0x01 << 0);
*((U8*) 0x02000004) = seg7table[(index+0)%10];
Delay (100);
/* 设置数码管段选 */
*((U8*) 0x02000006) = 0x3f & ~(0x01 << 1);
*((U8*) 0x02000004) = seg7table[(index+1)%10];
Delay (100);
/* 设置数码管段选 */
*((U8*) 0x02000006) = 0x3f & ~(0x01 << 2);
*((U8*) 0x02000004) = seg7table[(index+2)%10];
Delay (100);
/* 设置数码管段选 */
*((U8*) 0x02000006) = 0x3f & ~(0x01 << 3);
*((U8*) 0x02000004) = seg7table[(index+3)%10];
Delay (100);
/* 设置数码管段选 */
*((U8*) 0x02000006) = 0x3f & ~(0x01 << 4);
*((U8*) 0x02000004) = seg7table[(index+4)%10];
Delay (100);
/* 设置数码管段选 */
*((U8*) 0x02000006) = 0x3f & ~(0x01 << 5);
*((U8*) 0x02000004) = seg7table[(index+5)%10];
Delay (100);
sleep++;
if( (sleep % 5) == 0 )
{
index++;
index %= 10;
}
}
}
/*******************************************************************
函数说明: EB44B0 7段构共阳数码管测试
功能描述: 依次在不同的段数码管上显示Hello
返回代码: 无
参数说明: 无
*******************************************************************/
void display_hello(void)
{
int i=0;
int index=0;
*((U8*) 0x02000006) = 0x3f; /* 关闭所有数码管 */
for( ; ; )
{
/* 设置数码管段选 */
*((U8*) 0x02000006) = 0x3f & ~(0x01 << index);
/* 查表并输出数据 */
*((U8*) 0x02000004) = seg7table2[i];
Delay (100);
i++;
i%=5;
index++;
index%=6;
}
}
/*******************************************************************
Function name : 循环延时子程序
Description : 循环 'time' 次
Return type :void
Argument : 循环延时计数器
*******************************************************************/
void Delay(int time)
{
int i;
for(;time>0;time--)
for(i=0;i<delayLoopCount;i++);
}
void Main()
{
//Test_Seg7();
//flash_seg7();
//display_seg7();
//display_hello();
//display_led();
}
试验结果:
执行display_hello(void)程序,依次在不同的段数码管上显示Hello;执行display_led(void)程序,依次在不同的段数码管上显示led;
8.实验体会
通过实验了解了数码管的显示原理、数码管显示的编程方法,并对JX44B0实验箱也有了具体实际的了解。
试验中遇到的困难是对数码管相应的扫描地址和数据寄存器的地址不熟悉,导致程序编写和理解困难。因此,在以后的学习和实验中还要注意这方面的学习。
第二篇:微机与嵌入式实验实验报告
微机与嵌入式实验
2012-1-1
实验一 ARM linux 系统移植
一、 实验目的
Linux是一个源代码免费公开的操作系统, 有很强的移植性。实验一将Linux移植到ARM 目标板MOTOROLA ADS板上,其MC9328MX1是Motorola公司的龙珠MX1系列微处理器,将Linux内核及文件系统移植到目标板上。
二、 实验原理
嵌入式Linux(Embeded Linux)是指对Linux经过小型化裁剪后,能够固化在容量仅有几十万字节的存储器芯片或单片机中, 应用于特定嵌入式场合的专用Linux操作系统。嵌入式Linux是由很多体积小且性能高的微内核系统组成。在Linux内核与具体的目标平台相关,MC9328MX1是Motorola公司的龙珠MX1系列微处理器,其嵌入了先进的低功耗ARM920T~ ,运行的速度可以达到200MHZ。
三、 实验步骤
嵌入式系统开发通常采用“主机(H o S T)/ 目标机(TARGET) 方式。首先,利用主机上丰富的资源及良好的开发环境开发和仿真调试目标机上的软件, 然后通过串行口或网络将交叉编译生成的目标代码传输和装载到目标机上, 并用交叉调试器在监控程序或实时内核操作系统的支持下进行分析和调度,最后目标机在特定的环境下运行。在基于MC9328MX1开发板上,有三种下载程序的方式:RS232串口Xmodem 方式、以太网方式和USB方式。在此为了方便,我们采用了串口方式。
第一步、在Bootstrap模式下编译Bootloader Image
1、在对芯片第一次擦写时,首先对其寄存器等进行初始化。在PC机上W indows环境下,连接主机RS232串口到目标机(基于MC9328MX1的开发板)的RS232串口,打开超级终端设置RS232串口参数:波特率115200、数据位8位、停止位1位、无奇偶校验、无硬件流控制。RS232串口通信的目的在于发送控制
指令和传输数据, 同时获得反馈信息;
2、在设置中文件/属性菜单中选择ASCII设置,设置行延迟为1并勾选“在
每一行后添加换行符”;
3、将串口线与开发板连接并通过超级终端监听串口数据;
4、将模式开关拨到全ON的模式;
5、给开发板上电;
6、在超级终端中键入‘a’,如果开发板连接正常,开发板回应一个‘:’,
否则重复上面的步骤;
7、按下<ENTER>。光标移到下一行;
8、选择“传送/发送文本文件”并找到添加传送文件:programBoot_b.txt
9、程序会自动启动,出现一行一行的信息来反映程序的进程,例如:"Erasing
flash...", "Blank checking...", "Programming...", "Verifying flash...."最后出现
"Programming finished"。
第二步、利用Bootloader编译文件系统Images
1、将模式开关拨到ON-OFF-ON-ON-ON-ON 模式;
2、将开发板上电;
3、敲击<ENTER>进入bootloader的菜单界面;
4、选择适当的选项(‘0’是编译bootloader,‘1’是编译kernel image,‘2’
是编译rootdisk image)
5、当窗口显示“USB驱动准备好传输”,将USB线连接上;
6、在Windows explorer中一个USB新硬件被找到,将image拷贝到USB
盘符中;
7、拷贝完毕后选择弹出USB设备;
8、在监听窗口中会显示“Press any key to start program ...”按下任意键开
始编译;
9、编译结束后就可以在超级终端中看到烧写好的系统,可以进入系统查看。
四、 实验结果
运行内核即可启动平台上的Linux系统。
实验二:MX1 linux点阵字库的使用
五、 实验目的
实现点阵字库的中文显示。点阵字库结构简单,特别适合于点阵输出。
六、 实验原理
一般我们使用16*16的点阵宋体字库,所谓16*16,是每一个汉字在纵、横各16点的区域内显示的。不过后来又有了HZK12、HZK24、HZK32和HZK48字库及黑体、楷体和隶书字库。虽然汉字库种类繁多,但都是按照区位的顺序排列的。前一个字节为该汉字的区号,后一个字节为该字的位号。每一个区记录94个汉字,位号则为该字在该区中的位置。因此,汉字在汉字库中的具体位置计算公式为:94*(区号-1)+位号-1。减1是因为数组是以0为开始而区号位号是以1为开始的。这仅为以汉字为单位该汉字在汉字库中的位置,那么,如何得到以字节为单位得到该汉字在汉字库中的位置呢?只需乘上一个汉字字模占用的字节数即可,即:(94*(区号-1)+(位号-1))*32。汉字库文该从该位置起的32字节信息即记录了该字的字模信息。
了解点阵汉字及汉字库的构成原理后,显示汉字就变得简单。以16*16点阵字库为例,通常的方法是:将文件工作指针移到需要的汉字字模处、将汉字库文件读入一2*16数组再用for循环一位一位的显示。
七、 实验步骤
首先,设置一个Lunix开发服务器。
1. 将armLinuxXToolChain.tar.gz(arm-linux交叉编译工具)复制到/usr/local
目录
2. “cd”到/usr/local
3. 执行“tar-xzf armLinuxXTollChain.tar.gz”命令解压缩
以上步骤建立交叉编译环境,其目的是在linux系统下编译将在arm-linux系统上执行的应用程序。
然后,进行以下步骤:
1. 对源程序进行必要修改
2. 使用gcc编译、调试代码
例如:gcc –o test test.c
3. 上一步无错误后,使用arm-linux-gcc编译、调试代码
编译之前,需要配置环境变量,其目的为指定所用编译器所在的路径使用如下命令:
Export PATH=$PATH:/usr/local/bin
Export PATH=$PATH:/usr/local/arm/bin
Export PATH=$PATH:/usr/local/gtopia/bin
Export PATH=$PATH:/usr/local/arm/gtopia/bin
编译:arm-linux-goc –o test test.c
完成以上步骤后,以下步骤将生成root文件系统
将root文件系统镜像Mount(挂载)到一个空目录(如disk),使用如下命令:
Mount–t cramfs –o loop root.cramfs
将disk目录内的整个root文件系统复制到一个新文件夹(例如,newdisk) 确定完整无误地复制了root文件系统后,Umount(卸载)disk内的文件系统,使用命令如下:
Umount disk
然后,对newdisk文件系统执行必要修改。例如,对本实验而言,可以在/local文件夹下建立一个文件夹(如tmp),然后将经过交叉编译的目标文件(如上述的test)复制到其中。
使用如下命令生成一个新的root文件系统镜像
Mkcramfs newdisk newroot.cramfs
到实验室按照第一个实验的最后一步,将自己生成的root文件系统下载到实验板上,在LCD上观察是否实现预期结果。
八、 实验结果
Gcc编译后程序运行结果如下图:
九、 实验源代码
#include <sys/types.h>
#include <sys/stat.h>
#include <fentl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define U16 unsigned char
#define FONT COLOR 60
char chr[16][2];
int fd_fb;
U16*fb;
void PrintLCD(int top,int left); int main(){
int i,j,k,strLength;
char teststr[]=”北京邮电大学”; FILE*HzK;
HzK = fopen(“hzk16”,”rb”); strLength=strlen(teststr);
for(k=0;k<strLength;){
/*32个字节记录字模信息*/
}
} i=teststr[k]-0xffffffa(); j=teststr[k+1]-0xffffffa(); fseek(HzK,(94*(i-1)+(j-1))*32L.SEEK_SET); fread(chr.32,1,HzK); PrintLCD(90,(int)(k/2)*16+5); k+=2;
void PrintLCD(int top,int left){ int i,j,k;
U16*p=fb;
for(j=0;j<16;j++){
for(i=0;i<2;i++){ for(k=0;k<8;k++) if(char[j][i]$(0x90>>k)){ //*(p+(j+top)*240+left+i*8+k)=FONT_COLOR; printf(“1”);
}else
}
printf(“\n”);
}
}
printf(“”);