一乐电子

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

微信扫码登录

手机号码,快捷登录

手机号码,快捷登录

搜索
楼主: leozzd

请教74HC595多片级联数据溢出的问题

[复制链接]
 楼主| 发表于 2017-7-20 10:49 | 显示全部楼层
snoopy8008 发表于 2017-7-18 06:54
所有595的数据都传输完,再显示。
void Show_Time(unsigned char i)
{

哈哈哈,这个和我现在弄的一模一样,但是这样的程序好累赘,不太现实呀
回复

使用道具 举报

 楼主| 发表于 2017-7-20 11:00 | 显示全部楼层
snoopy8008 发表于 2017-7-18 07:00
原来的问题是:刷新第二行的时候,原来第1、2、3、4个595的数据被挤到第5、6、7、8个595里,结果第二行显示 ...

那这个挤位,你有什么好的建议或方法,我现在又遇到一个大问题了。
三块单板拼成一行,即16*96,也是和你想法一样,全部传给595后再显示,能实现左移,时钟跳显。但是,扩展成48*96的时候,9块屏的EN、ALine、BLine、SCK、STB都是共用的,第一行由R1,第二行由R2,第三行由R3分别控制。结果显示起来的时候,只能第一大行显示,即第一大行显示的时候,第二、三行全亮(R2/R3没输出,为低电平),或者第一大行在左显示,而二三行无法显示其他信息,相当于只能第一大行显示完才轮到其他大行来显示。
回复

使用道具 举报

 楼主| 发表于 2017-7-20 11:12 | 显示全部楼层
leozzd 发表于 2017-7-20 11:00
那这个挤位,你有什么好的建议或方法,我现在又遇到一个大问题了。
三块单板拼成一行,即16*96,也是和 ...

void SerialPut(unsigned char dat, u8 Px)
{
        u16 m;
        switch(Px)
        {
                case 1:                                                        //第一大行
                {
                        for(m=0;m<8;m++)
                        {
                             if(dat & 0x80) R1=1;        //串行数据输入
                             else R1=0;                               
                             CLK=0;      
                             CLK=1;
                                delay_us(1);
                                CLK=0;                  
                                dat=dat<<1;                                //数据左移                                     
                        }
                }
                break;
                case 2:                                                    //第二大行
                {
                        for(m=0;m<8;m++)
                        {
                             if(dat & 0x80) R2=1;        //串行数据输入
                             else R2=0;                               
                             CLK=0;      
                             CLK=1;
                                delay_us(1);
                                CLK=0;                  
                                dat=dat<<1;                                 //数据左移                                     
                        }
                }
                break;
                case 3:                                                         //第三大行
                {
                        for(m=0;m<8;m++)
                        {
                             if(dat & 0x80) R3=1;        //串行数据输入
                             else R3=0;                               
                             CLK=0;      
                             CLK=1;
                                delay_us(1);
                                CLK=0;                  
                                dat=dat<<1;                                 //数据左移                                     
                        }
                }
                break;
                default:  
                break;
        }
}
//行显控制
//入口参数:扫描行数
//入口参数0/1/2/3 代表行扫描13,9,5,1/14,10,6,2/15,11,7,3/16,12,8,4的1/4行
void Scan(u8 temp)
{                          
        EN=0;                                         //关闭显示
        STB=1;                                             //更新595输出
           ALine=0x01 & temp;                         
           BLine=0x01 &(temp>>1);
        STB=0;  
        EN=1;                                         //使能输出
}
void Show_Time(u8 Px)
{
        u8 l,j;
        for(l=0;l<4;l++)                //循环扫描1/4行
    {   
                for(j=0;j<12;j++)                 
            {       
                        SerialPut(Num[(calendar.hour/10)%10][3*4+l],Px);      
                        SerialPut(Num[(calendar.hour/10)%10][2*4+l],Px);
                        SerialPut(Num[(calendar.hour/10)%10][1*4+l],Px);
                        SerialPut(Num[(calendar.hour/10)%10][0*4+l],Px);      //小时十位

                        SerialPut(Num[(calendar.hour/1)%10][3*4+l],Px);
                        SerialPut(Num[(calendar.hour/1)%10][2*4+l],Px);
                        SerialPut(Num[(calendar.hour/1)%10][1*4+l],Px);
                        SerialPut(Num[(calendar.hour/1)%10][0*4+l],Px);      //小时个位

                        SerialPut(Num[11][3*4+l],Px);
                        SerialPut(Num[11][2*4+l],Px);
                        SerialPut(Num[11][1*4+l],Px);
                        SerialPut(Num[11][0*4+l],Px);                                    //:

                        SerialPut(Num[(calendar.min/10)%10][3*4+l],Px);
                        SerialPut(Num[(calendar.min/10)%10][2*4+l],Px);
                        SerialPut(Num[(calendar.min/10)%10][1*4+l],Px);
                        SerialPut(Num[(calendar.min/10)%10][0*4+l],Px);    //分钟十位

                        SerialPut(Num[(calendar.min/1)%10][3*4+l],Px);
                        SerialPut(Num[(calendar.min/1)%10][2*4+l],Px);
                        SerialPut(Num[(calendar.min/1)%10][1*4+l],Px);
                        SerialPut(Num[(calendar.min/1)%10][0*4+l],Px);    //分钟个位

                        SerialPut(Num[11][3*4+l],Px);
                        SerialPut(Num[11][2*4+l],Px);
                        SerialPut(Num[11][1*4+l],Px);
                        SerialPut(Num[11][0*4+l],Px);                                 //:

                        SerialPut(Num[(calendar.sec/10)%10][3*4+l],Px);
                        SerialPut(Num[(calendar.sec/10)%10][2*4+l],Px);
                        SerialPut(Num[(calendar.sec/10)%10][1*4+l],Px);
                        SerialPut(Num[(calendar.sec/10)%10][0*4+l],Px);  //秒钟十位

                        SerialPut(Num[(calendar.sec/1)%10][3*4+l],Px);
                        SerialPut(Num[(calendar.sec/1)%10][2*4+l],Px);
                        SerialPut(Num[(calendar.sec/1)%10][1*4+l],Px);
                        SerialPut(Num[(calendar.sec/1)%10][0*4+l],Px);   //秒钟个位

                        SerialPut(Num[50][3*4+l],Px);
                        SerialPut(Num[50][2*4+l],Px);
                        SerialPut(Num[50][1*4+l],Px);
                        SerialPut(Num[50][0*4+l],Px);                              //空白

                        SerialPut(Num[50][3*4+l],Px);
                        SerialPut(Num[50][2*4+l],Px);
                        SerialPut(Num[50][1*4+l],Px);
                        SerialPut(Num[50][0*4+l],Px);                              //空白
                }                        
                Scan(l);
        }                                
}
像串口扫描的话,通过传递Px给switch选择显示哪行(R1、2、3)来显示,一个Show_Time函数的话就这么多了,好累赘~~~

回复

使用道具 举报

发表于 2017-7-20 12:13 | 显示全部楼层
leozzd 发表于 2017-7-20 10:49
哈哈哈,这个和我现在弄的一模一样,但是这样的程序好累赘,不太现实呀

程序累赘,是因为SerialPut读取的显示内容是直接给定的。
可以把全部屏幕的显示程序再做一个子程序,采用间接寻址的方式从一片指定的区域(显示缓冲区)读取显示内容,并显示;
别的程序只负责改动显示缓冲区的内容,比如跳秒就只改秒的数据,跳分就改分的数据,不参与屏幕的扫描。

回复

使用道具 举报

发表于 2017-7-20 12:19 | 显示全部楼层
leozzd 发表于 2017-7-20 11:00
那这个挤位,你有什么好的建议或方法,我现在又遇到一个大问题了。
三块单板拼成一行,即16*96,也是和 ...

595的级联本来就是正常的功能,是用的方法不对。
只要CLK有上升沿,595的串行数据就会移位;只要STB有上升沿,595的并行输出就会更新。
为什么要把R分成三个传送呢?这样做并不能减轻程序上的负担,硬件上还要多占用两个脚。

方案1,所有595全部级联,从1个R输出所有数据,建议采用这种方案,缺点是中间坏一个595的话,后边的也都不正常了,DIY产品应该不用考虑这个吧?
方案2,将STB分作3个,传输完哪个R的数据,就对应的将哪个STB出一次上升沿。
方案3,将CLK分做3个,传输哪个R的数据,就给哪个CLK上升沿。
方案4,三个R的数据同步变化,再出CLK上升沿。


回复

使用道具 举报

发表于 2017-7-20 12:39 | 显示全部楼层
按照现在的写法,每4*8个点,程序中就会出现一次SerialPut,16*96就要出现48次,要改变显示内容,就得出现更多次。
如果显示内容放在连续的区域里,就可以用for指令循环调用SerialPut,程序就简洁了。
回复

使用道具 举报

 楼主| 发表于 2017-7-20 12:44 | 显示全部楼层
snoopy8008 发表于 2017-7-20 12:19
595的级联本来就是正常的功能,是用的方法不对。
只要CLK有上升沿,595的串行数据就会移位;只要STB有上 ...

方案一:这个是一个项目,而且是一个产品,但是你说的9块屏级联让我眼前一亮,就是真的怕有一个坏了。而且左移和静态这样好像无法结合方案二和三:这就是我在考虑的,把每一大行(三块屏)的EN/ALine/BLine/SCK/STB/R分别单独开,一大行配套6根线,当然这会很耗IO
方案四:这应该是现在led控制卡的驱动方式,即EN/ALine/BLine/SCK/STB共用,每一大行靠所在的R线控制,同一时刻各条R线统一输出。然而……这个程序上好像得大改了,一头雾水无从下手。
回复

使用道具 举报

发表于 2017-7-20 12:48 | 显示全部楼层
本帖最后由 snoopy8008 于 2017-7-20 14:05 编辑
leozzd 发表于 2017-7-20 12:44
方案一:这个是一个项目,而且是一个产品,但是你说的9块屏级联让我眼前一亮,就是真的怕有一个 ...

方案1,我觉得坏一行的一半和坏一大片都是坏,应该对产品没太大影响吧?但原来的控制卡采用那种方式,应该有他的理由,我不好妄加猜测;
方案2和3,只需要将SCK或者STB分开就可以,也不用所有的都分开,如果这就已经是最大的结构了,也就再多用两个IO而已;
方案4,我对C语言不熟,不知道该如何写出来,等有时间的时候研究下结构再来探讨。

回复

使用道具 举报

发表于 2017-7-20 12:56 | 显示全部楼层
leozzd 发表于 2017-7-20 10:48
这个非常好,也顺带解决了左移后的残留,太感谢你了!

不是顺带,就是解决这个问题,虽然照片上看不出来。
回复

使用道具 举报

发表于 2017-7-20 14:22 | 显示全部楼层
“左移和静态”是怎么个要求?
回复

使用道具 举报

本版积分规则

QQ|一淘宝店|手机版|商店|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2025-8-22 00:17 , Processed in 0.043479 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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