找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4164|回复: 1
收起左侧

求一个控制LED从上移动到下 再从左移动到右的程序

[复制链接]
ID:268581 发表于 2018-1-3 10:16 | 显示全部楼层 |阅读模式
1、按下启动按钮,机构连续下降、上升2次(上限位SQ1下限位SQ2) 后转右移;至SQ3限位处暂停5秒钟,然后转左移;至SQ4限位处即原点位置完成一次循环。接着连续不断执行上一次的循环重复动作,按停止按钮 继续执行循环到原点停止
2、手动操作设置上下左右按键 分别控制上下左右移动
3、用数字显示运行次数 0-99
4、做急停按钮 按下急停 再按运行
Proteus 89C51

回复

使用道具 举报

ID:270661 发表于 2018-1-3 11:09 | 显示全部楼层
一、课程设计目的和任务 实习目的任务是培养学生运用有关课程的基础理论和技能解决实际问题,进一步提高学生本专业必要的基本技能、方法和创新能力的重要环节之一。通过综合实习要使学生受到设计方法的初步训练,能用文字、图形和现代设计方法简要、系统、正确地表达设计成果。 利用点阵LED屏向右滚动显示“KST”:熟悉Keil软件和STC-ISP-v4.80软件的使用,单片机实验箱及其开发环境;查阅点阵LED屏的工作原理,如何获取图形,结合原理图了解芯片如何驱动点阵LED屏工作,了解LED点阵的基本结构,学习LED点阵的扫描显示方法。 二、分析与设计 1.设计任务分析: 为了吸引观众增强显示效果,可以有多种显示模式,最简单的显示模式是静态显示。这里所说的“静态显示模式”不同于静态驱动方式。与静态显示模式相对应,就有各种动态显示模式,它们所显示的图文都是能够动的。按照图文运动的特点又可以分为闪烁、平移、旋转、缩放等多种显示模式。产生不同显示模式的方法,并不意味着一定要重新编写显示数据,可以通过一定的算法从原来的显示数据直接生成。例如,按顺序调整行号,可以使显示图文产生上下平移;而顺序调整列显示数据的位置,就可以达到左右平移的目的;同时调整行列顺序,就能得到对角线平移的效果。其它模式的数据刷新,也可找到相应的算法。不过当算法太复杂,太浪费时间的话,也可以考虑预先生成刷新数据,存储备用。刷新的时间控制,要考虑运动图形文字的显示效果。刷新太慢,动感不显著;刷新太快了,中间过程看不清。一般刷新周期可控制在几十毫秒范围之内。 而本实验用KST-51开发板的点阵显示KST向右移动的显示设计。由于只控制8*8点阵显示屏,故不需要扩展单片机的I/O接口。考虑到P0口需要接上拉电阻,使得电路较为复杂,因此利用单片机的P1口来控制点阵的行,用P2口控制点阵的列。 2。 设计方案论证: 本次设计向右移动显示需要利用二维数组来实现,算法基本上和上下移动相似。二维数组,他的使用也很简单。它的声明方式是: 数据类型 数组名[数组长度 1][数组长度 2]; 与一维数组类似,数据类型是全体元素的数据类型,数组名是标识符,数组长度 1 和数组长度 2 分别代表数组具有的行数和列数。数组元素的下标一律从 0 开始。 例如:unsigned char a[2][3];声明了一个具有 2 行 3 列的无符号字符型的二维数组 a。 二维数组的数组元素总个数是两个长度的乘积。二维数组在内存中存储的时候,采用行优先的方式来存储,即在内存中先存放第 0 行的元素,再存放第一行的元素......,同一行中再按照列顺序存放,刚才定义的那个 a[2][3]的存放形式就如下表所示。 a[0][0]  a[0][1]  a[0][2]  a[1][0]  a[1][1]  a[1][2] 二维数组的初始化方法分两种情况,数组元素的数量可以小于数组元素个数,没有赋值的会自动给 0。当数组元素的数量等于数组个数的时候, 如下所示: unsigned char a[2][3] = {{1,2,3}, {4,5,6}}; 或者是 unsigned char a[2][3] = {1,2,3,4,5,6}; 当数组元素的数量小于数组个数的时候,如下所示: unsigned char a[2][3] = {{1,2}, {3,4}}; 等价于 unsigned char a[2][3] = {1,2,0,3,4,0}; 而反过来的写法 unsigned char a[2][3] = {1,2,3,4}; 等价于 unsigned char a[2][3] = {{1,2,3}, {4,0,0}}; 此外,二维数组初始化的时候,行数可以省略,编译系统会自动根据列数计算出行数,但是列数不能省略。 要进行横向做KST向右移动的动画,先把需要的图片画出来,再逐一取模,如下图所示,这个图形共有30张图片,通过程序每250ms改变一张图片,就可以做出来动画效果了。因为横向移动的图片切换时的字模数据不是连续的,所以要对30张图片分别取模。                                    3.硬件设计及原理图: (1)LED点阵总体框图:点阵电路大体上可以分成微机本身的硬件、显示驱动电路、控制信号电路三部分。控制电路部分包括一个51CUP和一些外围电路。点阵包括显示屏体、以及它的行和列的各个驱动电路。此显示电路采用扫描方式进行显示时,每行有一个行驱动器,从第一行开始,按顺序依次对各行进行扫描。另一方面,根据各列锁存的数据点亮相应的LED。    (2)电路原理图:点阵显示模块的硬件电路设计如下图所示:   (3)点阵的认识 一个数码管是8个LED组成,同理,一个8*8的点阵就是由64个LED小灯组成。如下图:     在上图中大方框外侧的就是点阵LED的引脚图,左侧的8个引脚是接的内部LED的阳极,上侧的8个引脚接的是内部LED的阴极。那么如果把9引脚置成高电平,13引脚置成低电平的话,左上角的那个LED小灯就会亮了。特别注意,控制点阵左侧引脚的74HC138是原理图上的U4,8个引脚自上而下依次由U4的Y0~Y7输出来控制。 从图中(本图的LED阵列采用共阴的接法)可以看出,8×8点阵共需要64个发光二极管组成,且每个发光二极管是放置在行线和列线的交叉点上。要实现显示图形或字体,只需考虑其显示方式,通过编程控制各显示点对应LED阳极和阴极端的电平,就可以有效的控制各显示点的亮灭。当采用按行扫描按列控制的驱动方式时,LED显示屏8行的同名列共用一套列驱动器。行驱动器一行的行线连接到电源的一端,列驱动器一列的列线连接到电源的另一端。应用时还应在各条行线或列线上接上限流电阻。扫描中控制电路将行线的1到 8轮流接通高电位,使连接到各该行的全部LED器件接通正电源,但具体那一个LED导通,还要看它的负电源是否接通,这就是列控制的任务了。当对应的某一列置0电平,则相应的二极管就亮;反之则不亮。例如:如果想使屏幕左上角LED点亮,左下角LED熄灭的话,在扫描到第一行时,第一列的电位就应该为低,而扫描到第八行时第一列的电位就应该为高。这样行线上只管一行一行的轮流导通,列线上进行通断控制,实现了行扫描列控制的驱动方式。 (4)8X8点阵共由64个发光二极管组成,且每个发光二极管是放置在行线和列线的交叉点上,当对应的某一列置0电平,某一行置1电平,则相应的二极管就亮;8X8点阵的列输入为C0~C7,行输入为R0~R7,它们通过驱动电路74HC138接至发光二极管的阴极和阳极。要显示某一个字母,首先要设计该字母的点阵形状,编好行(或列)点阵码数据,然后在单片机的控制下对点阵进行逐行(或列)扫描。在人眼的暂存效应下我们会看到完整的字形,从而实现了字母在点阵显示屏上的输出。  4.程序流程图和源代码清单: 流程图如下:  源代码: #include <reg52.h>  sbit ADDR0 = P1^0; sbit ADDR1 = P1^1; sbit ADDR2 = P1^2; sbit ADDR3 = P1^3; sbit ENLED = P1^4;  unsigned char code image[30][8] = { {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},    //动画帧1 {0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE},    //动画帧2 {0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,0xFE,0xFD},    //动画帧3 {0xFB,0xFD,0xFE,0xFF,0xFF,0xFE,0xFD,0xFB},    //动画帧4 {0xF7,0xFB,0xFD,0xFE,0xFE,0xFD,0xFB,0xF7},    //动画帧5 {0xEF,0xF7,0xFB,0xFD,0xFC,0xFB,0xF7,0xEF},    //动画帧6         {0xDE,0xEE,0xF6,0xFA,0xF8,0xF6,0xEE,0xDE},            //动画帧7 {0xBD,0xDD,0xED,0xF5,0xF1,0xED,0xDD,0xBD},    //动画帧8 {0x7B,0xBB,0xDB,0xEB,0xE3,0xDB,0xBB,0x7B},            //动画帧9 {0xF7,0x76,0xB7,0xD7,0xC7,0xB6,0x76,0xF7},    //动画帧10 {0xEE,0xED,0x6F,0xAF,0x8F,0x6D,0xED,0xEE},            //动画帧11 {0xDC,0xDB,0xDF,0x5F,0x1C,0xDB,0xDB,0xDC},    //动画帧12 {0xB8,0xB7,0xBF,0xBF,0x38,0xB7,0xB7,0xB8},            //动画帧13 {0x70,0x6F,0x7F,0x7E,0x71,0x6F,0x6F,0x70},    //动画帧14 {0xE1,0xDE,0xFE,0xFD,0xE3,0xDF,0xDE,0xE1},    //动画帧15 {0xC3,0xBD,0xFD,0xFB,0xC7,0xBF,0xBD,0xC3},    //动画帧16         {0x87,0x7B,0xFB,0xF7,0x8F,0x7F,0x7B,0x87},            //动画帧17 {0x0E,0xF7,0xF7,0xEF,0x1F,0xFF,0xF7,0x0F},    //动画帧18         {0x1C,0xEF,0xEF,0xDF,0x3F,0xFF,0xEF,0x1F},    //动画帧19         {0x38,0xDE,0xDE,0xBE,0x7E,0xFE,0xDE,0x3E},    //动画帧20 {0x70,0xBD,0xBD,0x7D,0xFD,0xFD,0xBD,0x7D},    //动画帧21         {0xE0,0x7B,0x7B,0xFB,0xFB,0xFB,0x7B,0xFB},    //动画帧22 {0xC1,0xF7,0xF7,0xF7,0xF7,0xF7,0xF7,0xF7},    //动画帧23         {0x83,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF},    //动画帧24 {0x07,0xDF,0xDF,0xDF,0xDF,0xDF,0xDF,0xDF},    //动画帧25 {0x0F,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF},    //动画帧26 {0x1F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F},    //动画帧27 {0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},    //动画帧28 {0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},    //动画帧29 {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},    //动画帧30 };  void main() {  EA = 1;                              //使能总中断         ENLED = 0;                           //使能U4,选择LED点阵         ADDR3 = 0;         TMOD = 0x01;                         //设置T0为模式1         TH0 = 0xFC;                           //为T0赋初值0xFC67,定时1ms         TL0 = 0x67;         ET0 = 1;                             //使能T0中断         TR0 = 1;                             //启动T0         while (1); } / * 定时器0中断服务函数 * / void InterruptTimer0() interrupt 1 { static unsigned char i = 0;          //动态扫描的索引         static unsigned char tmr = 0;        //250ms软件定时器         static unsigned char index = 0;      //图片刷新索引          TH0 = 0xFC;                          //重新加载初值         TL0 = 0x67; //以下代码完成LED点阵动态扫描刷新         P0 = 0xFF;                           //显示消隐          switch (i) {         case 0 :ADDR2 = 0;ADDR1 = 0;ADDR0 = 0; i++; P0 = image[index][0];break;         case 1 :ADDR2 = 0;ADDR1 = 0;ADDR0 = 1; i++; P0 = image[index][1];break;         case 2 :ADDR2 = 0;ADDR1 = 1;ADDR0 = 0; i++; P0 = image[index][2];break;         case 3 :ADDR2 = 0;ADDR1 = 1;ADDR0 = 1; i++; P0 = image[index][3];break;         case 4 :ADDR2 = 1;ADDR1 = 0;ADDR0 = 0; i++; P0 = image[index][4];break;         case 5 :ADDR2 = 1;ADDR1 = 0;ADDR0 = 1; i++; P0 = image[index][5];break;         case 6 :ADDR2 = 1;ADDR1 = 1;ADDR0 = 0; i++; P0 = image[index][6];break;         case 7 :ADDR2 = 1;ADDR1 = 1;ADDR0 = 1; i=0; P0 = image[index][7];break;         default:break;         } //以下代码完成每250ms改变一帧图像         tmr++;         if(tmr>=250)                      //达到250ms时改变一次图片索引         {         tmr = 0;                 index++;                 if(index >=30)                 //图片索引达到30后归零                 {                 index = 0;                 }         } }
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表