找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1367|回复: 5
收起左侧

求大神帮忙指导改改单片机74hc595按键程序

[复制链接]
回帖奖励 250 黑币 回复本帖可获得 50 黑币奖励! 每人限 1 次
ID:837877 发表于 2020-11-19 10:53 | 显示全部楼层 |阅读模式
需要s1按键为按一下正向移动在按一下暂停,s2为按一下反向移动在按一下暂停,找不到问题在哪里,暂停也不会在当前进度暂停而是回到开始了。
#include<reg51.h>


sbit shcp=P1^2;//数据输入时钟线 595的11脚
sbit stcp=P1^1;//输出存储器锁存时钟线 595的12脚
sbit ds=P1^0;//数据线  595的14脚


sbit s1=P3^1;//按下后会暂停,再按就会继续
sbit s2=P3^2;//按下后显示数字的传送方向取反
bit fx;//方向切换
unsigned char TIME1;//设置数据移动定时时间
unsigned int ABC;//设置控制显示的字符
unsigned char DD=4;
unsigned int ZZ;//总字符
unsigned char code tab[]={




0x02,0x04,0x22,0x48,0x2A,0x52,0xA6,0x41,0x63,0xFE,0x26,0x40,0x2A,0x50,0x22,0x49,
0x00,0x06,0x3F,0xF8,0x22,0x00,0x22,0x00,0x23,0xFF,0x42,0x00,0x02,0x00,0x00,0x00,//显示’新’字


0x04,0x20,0x08,0x20,0x10,0x20,0x3F,0xA0,0xC0,0x20,0x04,0x20,0x04,0x20,0x08,0xFF,
0xFE,0x20,0x11,0x20,0x11,0x20,0x21,0x20,0x41,0x20,0x07,0x20,0x00,0x20,0x00,0x00,//显示‘华’字


0x02,0x20,0x0C,0x20,0x88,0x20,0x69,0x20,0x09,0x20,0x09,0x22,0x89,0x21,0x69,0x7E,
0x09,0x60,0x09,0xA0,0x19,0x20,0x28,0x20,0xC8,0x20,0x0A,0x20,0x0C,0x20,0x00,0x00,//显示’学‘字


0x00,0x00,0x7F,0xFF,0x44,0x20,0x5A,0x10,0x61,0xE0,0x08,0x01,0x30,0x82,0x24,0x8C,
0x24,0xF0,0xA4,0x80,0x64,0x80,0x24,0xFC,0x24,0x82,0x28,0x82,0x30,0x8E,0x00,0x00,//显示‘院‘字


0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};


unsigned char code tab1[]={

0x00,0x00,0x7F,0xFF,0x44,0x20,0x5A,0x10,0x61,0xE0,0x08,0x01,0x30,0x82,0x24,0x8C,
0x24,0xF0,0xA4,0x80,0x64,0x80,0x24,0xFC,0x24,0x82,0x28,0x82,0x30,0x8E,0x00,0x00,//显示’院‘字


0x02,0x20,0x0C,0x20,0x88,0x20,0x69,0x20,0x09,0x20,0x09,0x22,0x89,0x21,0x69,0x7E,
0x09,0x60,0x09,0xA0,0x19,0x20,0x28,0x20,0xC8,0x20,0x0A,0x20,0x0C,0x20,0x00,0x00,//显示‘学’字


0x04,0x20,0x08,0x20,0x10,0x20,0x3F,0xA0,0xC0,0x20,0x04,0x20,0x04,0x20,0x08,0xFF,
0xFE,0x20,0x11,0x20,0x11,0x20,0x21,0x20,0x41,0x20,0x07,0x20,0x00,0x20,0x00,0x00,//显示‘华’字


0x02,0x04,0x22,0x48,0x2A,0x52,0xA6,0x41,0x63,0xFE,0x26,0x40,0x2A,0x50,0x22,0x49,
0x00,0x06,0x3F,0xF8,0x22,0x00,0x22,0x00,0x23,0xFF,0x42,0x00,0x02,0x00,0x00,0x00,//显示‘新’字

};
void delay(unsigned int dz)//设置延时子函数
{
   unsigned char x1;
   for(;dz>0;dz--)
   for(x1=999;x1>0;x1--);
}
void writedata(unsigned char d1,unsigned char d2)         //设置595显示子函数
{
        unsigned char i;
        //设置CY存储移位之后的数据  设置CY进位标志位,单片机内部的寄存器,移位之后的数据保存在CY
        for(i=0;i<8;i++)//设置八次循环
        {
                d1=d1<<1;//令数据左移11110001
                ds=CY;//设置发送数据
                shcp=1;//上升沿发生移位,数据寄存器的数据锁存。
                shcp=0;
        }
        for(i=0;i<8;i++)//同样设置八次循环
        {
                d2=d2<<1;//令数据左移
                ds=CY;//设置发送数据
                shcp=1;//上升沿发生移位,数据寄存器的数据锁存 。
                shcp=0;
        }
        stcp=0;      
        stcp=1;//上升沿将数据送到输出锁存器   
        stcp=0;
}


void main()
{
        char i,aa;
        TMOD=0x01;//设置定时器0与模式1与16位定时模式
        TH0=(65536-10000)/256;//定时10.000ms
        TL0=(65536-10000)%256;
        ET0=1;//使能定时器0
        EA=1;//设置开启总中断
    TR0=1;//开始计数
        ZZ=(DD+1)*32;
        while(1)         //设置无限循环
        {
                if(s1==0)//用于检测按键
                {
                        delay(30);//设置延时消除,按键抖动
                        if(s1==0)
                        {
                               fx=0;
                                aa=0;ABC=0;
                                 if(fx==0)ABC=0;
                                TR0=0;
                                while(s1==0);
                        }
                }
                if(s2==0)//用于检测按键
                {
                        delay(30);//设置延时消除,按键抖动
                        if(s2==0)
                        {
                                fx=~fx;//设置取反方向
                                TR0=0;
                                aa=0;
                                //使显示的数据正向移动
                                if(fx==1)ABC=ZZ;//使显示的数据反向移动
                                while(s2==0);//等待按键松手
                        }
                }
                for(i=0;i<16;i++)//设置循环移位
                {         
                        //两片138组成4-16线译码器
                        P2=i;//设置列数据驱动,138的驱动端口
                        if(fx==0)writedata(tab[ABC+aa],tab[ABC+aa+1]);//设置想要显示的数据
                        if(fx==1)writedata(tab1[ABC+aa],tab1[ABC+aa+1]);//设置想要显示的数据
                        delay(3);//延时
                        writedata(0,0);//清屏
                        aa+=2;//数据加 实现扫描
                        if(aa>30)aa=0;//循环16次 清零
                }
        }
}

void timer0() interrupt 3
{
        TH0=(65536-10000)/256;//10.000ms   设置进入一次中断
        TL0=(65536-10000)%256;
        TIME1++;
        if(TIME1==10)//设置到100.000ms时间加以实现移动,控制移动速度
        {
                TIME1=0;
                if(fx==0)//设置正向移动
                {
                        ABC=ABC+2;        //每次送两个编码数据
                        if(ABC>ZZ)//达到总字符
                        ABC=0;//数据清零
                }
                else//否则反向移动
                {
                        ABC=ABC-2;//设置每次送两个编码数据
                        if(ABC<2)//数据完毕
                        ABC=ZZ;//回到总字符
                }
        }
}


回复

使用道具 举报

ID:837877 发表于 2020-11-19 13:04 | 显示全部楼层
还有一个问题。如何让正反在一组汉字中显示,而不是分正反两组
回复

使用道具 举报

ID:267719 发表于 2020-11-20 14:18 | 显示全部楼层
#include <reg51.h>
#include <string.h>
#include <intrins.h>



sbit shcp=P1^2;//数据输入时钟线 595的11脚
sbit stcp=P1^1;//输出存储器锁存时钟线 595的12脚
sbit ds=P1^0;//数据线  595的14脚


sbit s1=P3^1;//按下后会暂停,再按就会继续
sbit s2=P3^2;//按下后显示数字的传送方向取反
unsigned char fx;//方向切换  0:停止 1:正向 2:反向
unsigned char TIME1;//设置数据移动定时时间
unsigned int ABC;//设置控制显示的字符
unsigned char DD=0;//当前开始显示的位置
unsigned int ZZ=4;//总字符
unsigned char displaybuf[32];//显示缓存(1个中文字),和硬件对应
unsigned char code tab[]={
0x02,0x04,0x22,0x48,0x2A,0x52,0xA6,0x41,0x63,0xFE,0x26,0x40,0x2A,0x50,0x22,0x49,
0x00,0x06,0x3F,0xF8,0x22,0x00,0x22,0x00,0x23,0xFF,0x42,0x00,0x02,0x00,0x00,0x00,//显示’新’字


0x04,0x20,0x08,0x20,0x10,0x20,0x3F,0xA0,0xC0,0x20,0x04,0x20,0x04,0x20,0x08,0xFF,
0xFE,0x20,0x11,0x20,0x11,0x20,0x21,0x20,0x41,0x20,0x07,0x20,0x00,0x20,0x00,0x00,//显示‘华’字


0x02,0x20,0x0C,0x20,0x88,0x20,0x69,0x20,0x09,0x20,0x09,0x22,0x89,0x21,0x69,0x7E,
0x09,0x60,0x09,0xA0,0x19,0x20,0x28,0x20,0xC8,0x20,0x0A,0x20,0x0C,0x20,0x00,0x00,//显示’学‘字


0x00,0x00,0x7F,0xFF,0x44,0x20,0x5A,0x10,0x61,0xE0,0x08,0x01,0x30,0x82,0x24,0x8C,
0x24,0xF0,0xA4,0x80,0x64,0x80,0x24,0xFC,0x24,0x82,0x28,0x82,0x30,0x8E,0x00,0x00,//显示‘院‘字


0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};

void delay(unsigned int dz)//设置延时子函数
{
   unsigned char x1;
   for(;dz>0;dz--)
   for(x1=231;x1>0;x1--);//for(x1=999;x1>0;x1--);        x1 为unsigned char 不能大于255         999实际等于231
}

/*此函数未修改*/
void writedata(unsigned char d1,unsigned char d2)         //设置595显示子函数
{
        unsigned char i;
        //设置CY存储移位之后的数据  设置CY进位标志位,单片机内部的寄存器,移位之后的数据保存在CY
        for(i=0;i<8;i++)//设置八次循环
        {
                d1=d1<<1;//令数据左移11110001
                                ds=CY;//设置发送数据
                shcp=1;//上升沿发生移位,数据寄存器的数据锁存。
                shcp=0;
        }
        for(i=0;i<8;i++)//同样设置八次循环
        {
                d2=d2<<1;//令数据左移
                                ds=CY;//设置发送数据
                shcp=1;//上升沿发生移位,数据寄存器的数据锁存 。
                shcp=0;
        }
        stcp=0;      
        stcp=1;//上升沿将数据送到输出锁存器   
        stcp=0;
}


void main()
{
        char i;

                memcpy(displaybuf,tab,32);
        TMOD=0x01;//设置定时器0与模式1与16位定时模式
        TH0=(65536-10000)/256;//定时10.000ms
        TL0=(65536-10000)%256;
        ET0=1;//使能定时器0
        EA=1;//设置开启总中断
            TR0=1;//开始计数
        while(1)         //设置无限循环
        {
                if(s1==0)//用于检测按键
                {
                        delay(30);//设置延时消除,按键抖动
                        if(s1==0)
                        {//按键被按下
                                                  if(fx==0) fx=1; else fx=0;
                          while(s1==0);
                        }
                }
                if(s2==0)//用于检测按键
                {
                        delay(30);//设置延时消除,按键抖动
                        if(s2==0)
                        {
                                                  if(fx==0) fx=2; else fx=0;
                          while(s2==0);//等待按键松手
                        }
                }
                for(i=0;i<16;i++)//设置循环移位
                {         
                        //两片138组成4-16线译码器
                        P2=i;//设置列数据驱动,138的驱动端口
                                                writedata(displaybuf[i*2],displaybuf[i*2+1]);//显示缓存中内容
                        delay(3);//延时
                        writedata(0,0);//清屏
                }
        }
}


/*
void timer0() interrupt 1
{
        TH0=(65536-10000)/256;//10.000ms   设置进入一次中断
        TL0=(65536-10000)%256;
        TIME1++;
        if(TIME1==10)//设置到100.000ms时间加以实现移动,控制移动速度
        {
                TIME1=0;
                                if (DD<=(ZZ-1)*16)
                                {        //未越界
                                        memcpy(displaybuf,&tab[DD*2],32);//将第n列开始搬入显示缓存
                                }
                                else
                                {        //已越界
                                        memcpy(displaybuf,&tab[DD*2],(ZZ*16-DD)*2);//将全部字 尾部部分移入缓存前部
                                        memcpy(&displaybuf[(ZZ*16-DD)*2],tab,(16-(ZZ*16-DD))*2);//将全部字 头部部分移入缓存后部
                                }               
                if(fx==1)//设置正向移动
                {
                                        DD++;//下一开始显示列
                                        if (DD>=ZZ*16) DD=0; //越界,从头开始显示
                }
                else if(fx==2)//否则反向移动
                {
                                    if (DD==0) DD=ZZ*16-1; else DD--; //下一开始显示列         越界,从尾开始显示
                }
        }
}
*/

void timer0() interrupt 1
{
unsigned char j;
unsigned char k;
        TH0=(65536-10000)/256;//10.000ms   设置进入一次中断
        TL0=(65536-10000)%256;
        TIME1++;
        if(TIME1==10)//设置到100.000ms时间加以实现移动,控制移动速度
        {
                TIME1=0;
                if(fx==1)//设置正向移动
                {
                                        if (DD<=(ZZ-1)*16)
                                        {
                                                memcpy(displaybuf,&tab[DD*2],32); //未越界,
                                        }
                                        else
                                        {
                                                memcpy(displaybuf,&tab[DD*2],(ZZ*16-DD)*2);
                                                memcpy(&displaybuf[(ZZ*16-DD)*2],tab,(16-(ZZ*16-DD))*2);
                                        }
                                        DD++;
                                        if (DD>=ZZ*16) DD=0;  //越界:超过总字数从0开始  超过15个中文请定义DD为unsigned int         因16*16=256 超出 unsigned char
                }
                else if(fx==2)//否则反向移动
                {
                                        j=DD%16;//倒数第几列  0-15->15-0
                                        k=DD/16;//第几个字          0..ZZ-1
                                        memcpy(displaybuf,&tab[(k*16+15-j)*2],j*2);
                                        if (k==0)
                                          {
                                             k=ZZ-1;
                                          }
                                          else
                                          {
                                             k--;
                                          }
                                        memcpy(&displaybuf[j*2],&tab[(k*16)*2],(16-j)*2);
                                        DD++;
                                        if (DD>=ZZ*16) DD=0;  //超过总字数从0开始  超过15个中文请定义DD为unsigned int
                }
        }
}

回复

使用道具 举报

ID:837877 发表于 2020-11-21 13:03 | 显示全部楼层
carpcarey 发表于 2020-11-20 14:18
#include
#include
#include

谢谢大哥!!!!但是,如何让显示的数变多
回复

使用道具 举报

ID:367460 发表于 2020-11-21 16:34 | 显示全部楼层
你可以说设置下字体大小,在取模软件里
回复

使用道具 举报

ID:267719 发表于 2020-11-23 11:23 | 显示全部楼层
花开彼岸鍙哦 发表于 2020-11-21 13:03
谢谢大哥!!!!但是,如何让显示的数变多

缓存开大啊。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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