51单片机课程设计 您所在的位置:网站首页 led滚动字幕有一半不显示 51单片机课程设计

51单片机课程设计

2023-11-11 09:50| 来源: 网络整理| 查看: 265

上学期期末的课设题目是led点阵广告牌,当时的要求如下: (1)能够显示不同字符的LED点阵广告牌; (2)按键切换不同的显示效果(如闪烁,静止,平移等); (3)按键切换不同的显示内容; (4)能够显示图形或自定义字符; (5)其他功能(创新部分); (6)系统调试、分析、总结与功能实现。 当时用的是我用是的普中科技的STC90C51RD+的单片机,不过只要是51单片机,换哪个51内核的芯片都可以,只要电路和程序匹配就可以。 我用的那款普中科技的51单片机可以直接连线决定线路的布置,不需要自己去重新焊一个电路板。 然后我根据任务要求连接了电路,写了对应的程序,还有proteus仿真。 另外,觉得有趣可以点个赞;有什么有趣的想法可以评论一下,我感兴趣的话会做一下。

一、设计思路

首先是P1连接8个独立按键,P3.4,P3.5,P3.5三个I/O口通过模拟SPI(51单片机没有硬件的SPI总线控制器)控制led点阵。 下面是包含头文件,定义独立键盘,选用模拟SPI的三个I/O口的程序内容,其中也包括重定义函数变量的内容,可以有效地减少编写程序时的负担。

#include #include #define GPIO_KEY P1 //独立键盘用P1口 //--重定义函数变量--// #define uchar unsigned char #define uint unsigned int #define ulong unsigned long //--定义SPI要使用的 IO--// sbit MOSIO = P3^4; sbit R_CLK = P3^5; sbit S_CLK = P3^6;

之后设计显示在led点阵上的文字,符号。(当时设计的是我和组员的名字还有一些自定义的符号)。 要实现的效果是:打开电源后按下K1可以一堆汉字会从上而下移动,按下K2汉字会闪烁显示(闪烁显示就是显示一个字零点几秒钟,然后先后显示其他字),按下K3是我自定义的那些字符闪烁显示,然后进入每个功能后都可以按下K8退出这个功能,之后可以按下K1,K2或K3进入这三个功能。

二、通过I/O口模拟SPI发送数据

(1)传输数据函数与对应模块的仿真

以下是普中科技单片机自带的通过I/O口模拟SPI发送数据的函数,因为有配套的字模生成软件,所以对这个部分我就不写太多东西了,有想要字模软件的可以在文末的百度网盘链接自己下载。

//通过74HC595发送四个字节的数据 void HC595SendData(uchar BT3, uchar BT2,uchar BT1,uchar BT0) { uchar i; //--发送第一个字节--// for(i=0;i MOSIO = BT2 >>7; //从高位到低位 BT2 MOSIO = BT0 >> 7; //从高位到低位 BT0 128,1,191,49,176,49,176,25,176,13,190,7,134, 1,230,255,134,7,190,13,176,13,176,25,176,49,176,103,158,195,140,1}; //--王--// uchar code tab1[] = { 0,0,252,31,128,0,128,0,128,0,128,0,128,0,248, 15,128,0,128,0,128,0,128,0,128,0,254,63,0,0,0,0}; //--李--// uchar code tab2[] = { 128,0,128,0,254,63,160,2,144,4,136,8,6,48,240, 3,0,1,128,0,254,63,128,0,128,0,224,0,0,0,0,0}; //--任--// uchar code tab3[] = { 16,0,16,28,208,3,8,2,8,2,12,2,10,2,232,63,8,2, 8,2,8,2,8,2,8,2,200,31,0,0,0,0}; //--徐-// uchar code tab4[] = { 16,2,16,2,8,5,132,8,82,16,176,47,8,2,12,2,202, 31,8,2,72,18,72,34,40,34,136,3,0,0,0,0}; //--杨--// uchar code tab5[] = { 24,0,152,63,24,24,24,12,127,6,24,3,156,255,60, 219,126,219,126,219,155,217,152,205,216,204,120,198,24,123,152,49}; //--桃心--// uchar code xin[] = { 0,0,28,56,252,63,254,127,255,255,207,243,135, 225,7,224,15,240,30,120,60,60,120,30,240,15,224,7,192,3,128,1}; //--五角星--// uchar code char1[] = { 128,1,128,1,192,3,192,3,192,3,96,6,127,254,6, 96,28,56,48,12,48,12,152,27,248,30,56,28,12,48,0,0}; //--圆--// uchar code char2[] = { 0,0,224,7,120,30,28,56,28,56,14,112,14,112,14, 112,14,112,14,112,28,56,28,56,120,30,224,7,0,0,0,0}; //--三角--// uchar code char3[] = { 0,0,128,1,128,1,192,3,192,3,96,6,96,6,48,12,48, 12,24,24,24,24,12,48,12,48,254,127,0,0,0,0}; //--菱形--// uchar code char4[] = { 128,0,64,1,32,2,16,4,8,8,4,16,2,32,1,64,2,32, 4,16,8,8,16,4,32,2,64,1,128,0,0,0}; //--箭头--// uchar code char5[] = { 0,0,0,0,0,0,0,2,0,4,0,8,0,16,0,32,126,64,0, 32,0,16,0,8,0,4,0,2,0,0,0,0};

之后会将要显示的数组在混合起来成为一个新的指针数组,这个数组是用来直接在点阵显示的函数中使用的,*p的指针数组中多余很多是被我删掉的名字,只留下了姓。

uchar *p[] = {tab1, tab2, tab3, tab4, tab5, tab6, tab7, tab8, tab9, tab10, tab11, tab12, tab13, tab14}; uchar *c[] = {char1, char2, char3, char4,char5}; 三、检测独立按键

主函数中首先是while(1),无限循环,只要没有检测到键值(即独立按键中有任意键被按下),就一直循环,并且执行清屏的程序(即调用标题二中的传输数据功能,分别传输0xff,0xff,0,0四个数据)如果检测到键值就进入对应的功能中,进入每个功能对应的函数。 以下是主函数内容:

void main(void) { while(1) { HC595SendData(0xff,0xff,0,0); //清屏 keyNum=Key_Scan(); //读取键值 switch (keyNum) { case(0xFE) : //返回按键K1的数据 translation();//文字从上到下平移 break; case(0xFD) : //返回按键K2的数据 twinkle1(); //文字闪烁 break; case(0xFB) : //返回按键K3的数据 twinkle2(); //符号闪烁 break; // case(0xF7) : //返回按键K4的数据 // ; // break; // case(0xEF) : //返回按键K5的数据 // ; // break; // case(0xDF) : //返回按键K6的数据 // ; // break; // case(0xBF) : //返回按键K7的数据 // ; // break; case(0x7F) : //返回按键K8的数据 HC595SendData(0xff,0xff,0,0); //清屏 break; default: break; } } } 读取键值

前面有提到定义P1为独立按键,即程序中的GPIO_KEY,当独立按键按下时GPIO_KEY != 0xFF,这时消除抖动(即延时十毫秒)再检测一次,如果检测为按下按键则将键值保存到keyValue中,之后松开按键或500ms后仍未松开按键,都会将读取到的键值返回。

unsigned char Key_Scan() { unsigned char keyValue = 0 , i; //保存键值 //--检测按键1--// if (GPIO_KEY != 0xFF) //检测按键K1是否按下 { Delay10ms(1); //消除抖动 if (GPIO_KEY != 0xFF) //再次检测按键是否按下 { keyValue = GPIO_KEY; i = 0; while ((i j=0; while(keyNum!=0x7F) { for(ms = 10; ms > 0; ms--) //移动定格时间设置 { for(k = 0; k j = 0; } } }

以下是文字移动的效果(这时第一个字已经消失了近一半,下一个字也显示出一小半,分别是“王”字和“李”字): 在这里插入图片描述

(2)文字闪烁显示

i.如何实现随时按下K8退出该功能,重新回到主函数

与文字从上而下移动的功能同理,只不过文字闪烁功能有四个循环,比文字移动多一个,同样是最小循环中检测键值,若检测到keyNum==0x7F,则逐级退出,最后返回主函数。

ii.如何实现文字闪烁显示

与文字移动有些类似的地方,在最小的循环中发送数据从LED点阵第一行显示到最后一行,上一级循环决定最小循环一共运行几次,即显示一个字的时间,再上一级循环中每次i+1决定显示下一个文字,当i=14时回到最外层循环,之后回到刚才的循环重新从第一个文字开始显示。

第二个循环中有多少要显示的文字,就循环多少次,例如我原先共设计了14个文字,则 for(i = 0; i < 14; i++) 中i for(i = 0; i for(k = 0; k while(keyNum!=0x7F) { for(i = 0; i for(k = 0; k



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有