利用定时器中断方式控制led灯的闪烁速度_实验四 LED点阵

LED点阵

实验目的和要求

了解LED点阵显示的基本原理和实现方法。掌握点阵汉字库的编码和从标准字库中提取汉字编码的方法。

实验设备

单片机测控实验系统,LED点阵显示器实验模块,Keil开发环境,STC-ISP程序下载工具

实验内容

了解16*16点阵电路的原理,编写汇编语言程序。编写一行汉字字符(至少三个字)的显示程序。能够从左到右(或从右到左)循环显示(要求显示过程中字的大小与屏幕尺寸相适应)。

实验步骤

  1. 掌握点阵式LED显示屏的控制方法;
  2. 使用MCS-51汇编语言,使用LED点阵显示器显示出正确的汉字字符及动态效果;
  3. 将编译后的程序下载到51单片机,观察LED显示屏的显示结果。

实验原理

高亮度LED发光管构成点阵,通过编程控制可以显示中英文字符、图形及视频动态图形。所显示字符的点阵数据可以自行编写(即直接点阵画图),也可从标准字库(如ASC16、HZ16)中提取。后者需要正确掌握字库的编码方法和字符定位的计算

实验用的LED点阵显示屏为16*16点阵。

行和列分别使用两个移位寄存器作为输出。

当移位寄存器输出的第i行为0,第j列为1时点亮点(i,j)。

为了能够显示出一个点阵字型,需要进行循环扫描,也就是每一次只点亮一行, 然后在列上输出该列对应的16个点阵值。

输出一行后暂停一段时间,输出下一行。为了达到较好的显示效果,整屏总的扫描时间不高于40ms。

上述过程中行列可以互换。

实验中使用的移位寄存器是74HC595,它是一个同时具有串行移位和输出锁存驱动功能的器件。

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

数据在SRCK(移位寄存器时钟输入)的上升沿输入到移位寄存器中,在R(存储器时钟输入)的上升沿输入到存储寄存器中去。 移位寄存器有一个串行移位输入(行Dx(P00)、列Dy(P03)),和一个串行输出(QH),和一个异步的低电平复位,存储寄存器有一个并行8位的,具备三态的总线输出,当使能 (P02和P07为低电平)时,存储寄存器的数据输出到总线。

实验代码

;使用中断来同步,摘自程序中断的典型例子
ORG 0000H                   ;复位起始地址
    LJMP START 
ORG 000BH                   ;中间地址保留给中断向量表
    LJMP EINT0              ;定时器0中断程序入口地址
ORG 0040H                   ;程序实际起始地址
​
START: 
OE1 EQU P0.7                ;存储器x方向使能端口
OE2 EQU P0.4                ;存储器y方向使能端口 
SER1 EQU P0.0               ;移位寄存器串行行输入口Dx 
SER2 EQU P0.3               ;移位寄存器串行列输入口Dy 
SRCK1 EQU P0.1              ;移位寄存器x方向时钟输入口
SRCK2 EQU P0.5              ;移位寄存器y方向时钟输入口
RCK1 EQU P0.2               ;存储器x方向时钟输入口 
RCK2 EQU P0.6               ;存储器y方向时钟输入口
MOV DPTR,#TABLE1            ;表首地址 
MOV TMOD,#01H               ;定时器控制字,选择定时器工作方式为定时 
MOV IE,#82H                 ;中断允许屏蔽控制字,中断设置,定时器0允许中断 
​
L0:  
MOV R4,#0                   ; 偏 移 
 
L2: 
MOV R3,#01FH                ;时间控制,一个屏幕的时间<40ms 
​
S0: 
MOV R0,#15                  ;行控制S00: 
CLR SRCK1                   ; 行 清 零 
CLR SER1                    ; 行 数 据 清 零
SETB SRCK1                  ;上升沿读入数据
DJNZ R0,S00                 ;自减一,循环  
​
​
S1:  
MOV R0,#0       
CLR SRCK1   ;从第一开始选中
SETB SER1 
SETB SRCK1 
​
​
S2: 
MOV A,R0 ; 计 数 器ADD A,R4      
MOVC A,@A+DPTR  ;寻址,将R0,R4控制的地址取出MOV R1,#8 ;前8位,循环控制 
​
​
S3: 
CLR SRCK2 
RRC A        ; 向 右 移
MOV SER2,C  ;溢出一位给C 
SETB SRCK2  ;上升沿输出数据 
​
DJNZ R1,S3  ;R1!=0,则跳转S3 
INC R0 
;重复第二组8位
MOV A,R0 
ADD A,R4 
MOVC A,@A+DPTR 
MOV R1,#8 
​
S4: 
CLR SRCK2 
RRC A 
MOV SER2,C 
SETB SRCK2 
DJNZ R1,S4 
INC R0 
​
S5: 
CLR RCK1 
SETB RCK1 
CLR RCK2 
SETB RCK2 
CLR OE1 ;使能段有效
CLR OE2 
LCALL TIME  ;长跳转SETB OE1 
SETB OE2 
CLR SRCK1;下一行
CLR SER1 
SETB SRCK1 
​
​
CJNE R0,#32,S2 ;不相等跳转,一个屏幕的32个8 
DJNZ R3,S0 ;不等于零跳转窗口大小固定  
​
MOV A,R4 
ADD A,#2 
MOV R4,A 
CJNE R4,#128,L2   ;四个字,4×32,32个8位是一个字,结束之后,循环回到开始 。 
LJMP L0 
​
TIME:           ; 延 迟 实 现
MOV TH0,#0FFH 
MOV TL0,#3CH      ;0.2ms 
SETB TR0 
MOV R7,#0H 
​
T11: 
CJNE R7,#1H,T11 
RET 
​
​
;定时器0中断处理程序
EINT0: 
MOV R7,#1H 
RETI 
​
TABLE1: 
DB 20H,00H,24H,00H,24H,0FCH,24H,88H,24H,88H,24H,88H,0FCH,88H; 
DB 24H,88H,24H,88H,24H,88H,24H,0FCH,24H,00H,20H,00H,00H,00H;"?",0 
​
​
DB 10H,40H,11H,80H,16H,00H,0FFH,0FCH,12H,00H,11H,00H,00H,20H; 
DB 10H,0C0H,13H,00H,0FFH,0FCH,13H,00H,10H,0C0H,10H,20H,00H,00H;"?",1 
​
​
DB 08H,04H,08H,04H,08H,08H,08H,10H,08H,60H,0BH,80H,0FCH,00H; 
DB 0BH,80H,08H,60H,08H,10H,08H,08H,08H,04H,08H,04H,00H,00H;"?",2 
​
​
DB 1CH,40H,10H,40H,92H,40H,52H,40H,12H,44H,92H,44H,52H,0FCH; 
DB 12H,0C0H,33H,40H,52H,40H,90H,40H,10H,40H,1CH,40H,00H,00H;"?",3 
END 

流程图

6cc48653b5eeff27a9f093caf54f6410.png

思考题

1. 如何使用软件调整和控制LED点阵的亮度?

对于LED显示屏,点的亮度值对应于有效的显示时间,这是由列的显示时间来实现的,时间越长,亮度越高。

2.如何尽量避免显示过程中的闪烁?

对于用户来说,显示频率越高,屏的视觉稳定性越强;显示频率越低,屏的视觉稳定性越差,即显示屏看起来会有闪烁和抖动的现象。因此为避免显示过程中的闪烁,应提高显示频率。

3.如何将本实验的软硬件推广到多行多列的LED显示屏(如64*1280)?

可以多增加几个控制行列的移位寄存器。

实验过程中的问题和收获

收获:在本次实验中了解到了LED点阵的原理。

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,根据你的要求,我为你编写了一个基本的程序框架。注意,由于不知道你使用的具体硬件,因此一些细节需要你根据自己的硬件环境进行调整和修改。 ```c #include <reg51.h> // 定义LED的引脚号 #define LED_PIN P0 // 定义按键的引脚号 #define BUTTON_PIN P1 // 定义点阵屏的引脚号 #define MATRIX_PIN P2 // 定义LED的状态常量 #define LED_OFF 0 #define LED_ON 1 // 定义点阵屏的显示内容 unsigned char matrix_data[] = { // 在这里添加点阵显示的内容 }; // 定义全局变量 unsigned char led_state = LED_OFF; // LED的状态 unsigned char matrix_index = 0; // 点阵显示的位置 // 定义函数原型 void init_led(); void init_button(); void init_matrix(); void led_blink(); void update_matrix(); void stop_display(); void main() { init_led(); init_button(); init_matrix(); while (1) { // 在主循环中执行LED闪烁 led_blink(); } } // 初始化LED void init_led() { LED_PIN = LED_OFF; // 默认关闭LED // TODO: 初始化定时器中断,实现LED闪烁 } // 初始化按键 void init_button() { BUTTON_PIN = 0xFF; // 默认将按键引脚设置为高电平 // TODO: 初始化中断,检测按键的状态,并在按键被按下时触发中断 } // 初始化点阵屏 void init_matrix() { // TODO: 初始化点阵屏的引脚为输出模式 // TODO: 初始化定时器中断,实现点阵屏的更新 } // LED闪烁函数 void led_blink() { // TODO: 在定时器中断中调用该函数,实现LED闪烁 } // 点阵屏的更新函数 void update_matrix() { // TODO: 在定时器中断中调用该函数,实现点阵屏的更新 } // 按键被按下时触发的函数 void button_pressed() { // TODO: 在中断中调用该函数,实现按键被按下时的操作 } // 停止点阵屏的显示LED的状态设置为闪烁 void stop_display() { // TODO: 停止点阵屏的显示 // TODO: 设置LED的状态为闪烁 } ``` 在以上的程序框架中,我已经为你定义了一些常量和变量,并且编写了对应的函数原型。你需要根据自己的硬件环境,实现这些函数并将它们组合起来,从而完成整个程序的编写。在具体的实现中,你需要注意以下几点: 1. 初始化LED的引脚为输出模式,并将LED的状态设置为闪烁。 2. 初始化按键的引脚为输入模式,并设置中断,检测按键的状态,并在按键被按下时触发中断。 3. 初始化点阵屏的引脚为输出模式,并设置定时器中断,每隔一定的时间更新点阵屏的内容。 4. 在按键被按下时,依次显示指定的内容,并将LED的状态设置为常亮。 5. 再次按下按键时,立即停止点阵屏的显示,并将LED的状态设置为闪烁。 希望这个程序框架能够帮助到你,祝你编写顺利!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值