一乐电子

一乐电子百科

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

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

搜索
查看: 1636|回复: 8
收起左侧

[其他综合] 请指点下max7219的时序问题

[复制链接]
发表于 2014-8-2 16:52 | 显示全部楼层 |阅读模式
本帖最后由 gongzhu 于 2014-8-2 16:58 编辑

最近玩max7219,单个显示是没有问题的,并联也没有问题,现在级联(3块)的时候出现了一个怪问题,发送第一块max7219的数据时,常会传到后级上去。
1、如果第一个max更新的话,后两个也会更新成一样的数据。
2、如果3个同时更新,第二、三个会在更新的时候闪烁下,特难看。
3、如果第一块不更新,第二三块更新是没有任何问题的。

下载了两个案例,因为是静态从前往后显示的,并未更新,所以调试是看不出问题的,一旦动态更新就出现以上问题。
按经验应该是时序上面的问题,最近常加夜班,头昏脑涨,犯迷糊,希望大神给指点指点:


快照1.png




#include<reg52.h>
#include <intrins.h>
#define uchar unsigned char
sbit din = P3 ^ 5;
sbit load = P3 ^ 6;
sbit clk = P3 ^ 7;
uchar number;//初始化单片机,不多说了,number是待会要显示的数

void write(uchar pos, num) //先输出8位地址,再输出8位数据
{
    uchar LEDnum = pos, i;
    clk = 0;
    din = 0;
    load = 1;
    load = 0; //小心的按照时序图来到这一步,要用DIN输出地址了

    for(i = 0; i < 8; i++)
    {
        lednum = lednum << 1; //移位到CY
        din = CY; //输出CY
        clk = 1; //上升沿锁定!

        clk = 0; //恢复0等待下一数据
    }//for
    lednum = num; //把数据准备好写入
    for(i = 0; i < 8; i++) //重复一遍写入数据
    {
        lednum = lednum << 1;
        din = CY;
        clk = 1;

        clk = 0;
    }//for
    load = 1; //最后LOAD上升作为收尾
}

void send(uchar op)//发送语句的for部分,第二、三、四片写入数据专用
{
    uchar lednum = op, i;
    for(i = 0; i < 8; i++) //只完成DIN发送数据部分即可
    {
        clk = 0;
        lednum = lednum << 1;
        din = CY;
        clk = 1;

    }//for
}

write2(uchar pos, num) //第二片7219写入数据函数,原理是LOAD成为低电平16.5 个周期后DOUT从头开始输出地址和数据,而7219会保留收到的最后一组地址和数据(16字节)!
{
    load = 0; //LOAD降低,准备输入地址、数据
    send(pos);//地址
    send(num);//数据

    send(0);//输入空操作
    send(0);//输入空操作
    load = 1; //收尾LOAD升高
}

write3(uchar pos, num) //同理,多输出一对空操作数
{
    load = 0;
    send(pos);
    send(num);

    send(0);
    send(0);
    send(0);
    send(0);
    load = 1;
}


void init()
{
    write(0x0c, 1); //开启正常工作模式 1正常 0关闭芯片
    write(0x0f, 0); //显示测试 正常工作0 全亮1
    write(0x09, 0xff); //解码方式 0xff全译码,全译码就是输出数据0x07就显示7!
    write(0x0b, 0x07); //8只LED全用
    write(0x0a, 2); //亮度为10

    write2(0x0c, 1); //开启正常工作模式 1正常 0关闭芯片
    write2(0x0f, 0); //显示测试 正常工作0 全亮1
    write2(0x09, 0xff); //解码方式 0xff全译码
    write2(0x0b, 0x06); //8只LED全用
    write2(0x0a, 2); //亮度为10

    write3(0x0c, 1); //开启正常工作模式 1正常 0关闭芯片
    write3(0x0f, 0); //显示测试 正常工作0 全亮1
    write3(0x09, 0xff); //解码方式 0xff全译码
    write3(0x0b, 0x07); //8只LED全用
    write3(0x0a, 2); //亮度为10
}

void Delay500ms()                //@12.000MHz
{
        unsigned char i, j, k;

        _nop_();
        i = 4;
        j = 205;
        k = 187;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}

void main()
{
    init();//初始化3片7219,里面的write,write2,write3就是分别向3片7219写入数据的程序!
    for(number = 1; number < 9; number++) //简单的循环,让3片7219都显示出1~8,顺序相反
    {
        write(number, number-1);
        write2(number, 9 - number);
        write3(number, number);        
    }
    while(1)//进入无限循环
    {
                Delay500ms();

                    for(number = 1; number < 9; number++) //简单的循环,让四片7219都显示出1~8,顺序相反
                    {
                        write(number, number-1); // 只循环此句的话,3块max全部更新成一样的数据
                        //write2(number, 9- number);
                        //write3(number, number+1);        
                    }         
        
        };
}

原文章,号称西门子手册:
max7219芯片4片级联C51程序与电路.pdf (882.59 KB, 下载次数: 319)


发表于 2014-8-2 19:06 | 显示全部楼层
不妨看看美信官方的手册

点评

英文、中文都翻N遍了  发表于 2014-8-2 21:56
发表于 2014-8-2 20:43 | 显示全部楼层
適著平常就推 clk 訊號 部要一送完資料就停止 看能不能改善
 楼主| 发表于 2014-8-2 21:58 | 显示全部楼层
skcho 发表于 2014-8-2 20:43
適著平常就推 clk 訊號 部要一送完資料就停止 看能不能改善

数据发送完后clk置零,加一个小延时,对第二块max7219无影响了,还是会影响到第三块7219。有进展!
 楼主| 发表于 2014-8-2 22:34 | 显示全部楼层
从目前下载的几乎所有的max7219的C51程序都没有处理好DOUT的输出问题,绝大多数都是因为未级联所以看不出来问题。
发表于 2014-8-3 06:10 | 显示全部楼层
gongzhu 发表于 2014-8-2 21:58
数据发送完后clk置零,加一个小延时,对第二块max7219无影响了,还是会影响到第三块7219。有进展!

发送完后置1看看,要有16.5个时钟周期数据才开始后传

点评

还是不行,试了多种方法,第一块max无论如何都会影响到后面第3块。  发表于 2014-8-3 09:56
 楼主| 发表于 2014-8-3 10:27 | 显示全部楼层
本帖最后由 gongzhu 于 2014-8-3 10:58 编辑

加大延时仔细观察,发现目前第一块max的更新会影响到第三块的前7位数码管,第三块的第8位数码管是不受影响的(发送一位数码管的地址和数据刚好16个时钟周期,---16.5个周期后dout输出?)。
换了多种方案单独处理第一块max实在是折腾不起,虽然没有彻底搞定,但还是曲线救国了,发出来给以后可能会用到7219级联的坛友。


换一种思路,既然第一块后的max单独更新都没有问题,那就修改第三块的更新程序,将前级一、二块的“放空” 操作  send(0); send(0);    send(0); send(0);    改为前级的更新,这下好了。

//一次同时更新三块max的某一位数据
void write0 (uchar add1, uchar dat1,uchar dat2,uchar dat3)
{
    LOAD = 0;                  // CS置低选通 MAX7219

    send(add1);               // 写register number 到 第三块MAX7219
    send(dat3);               // 写 data 到 第三块MAX7219

    send(add1);               // 写register number 到 第二块MAX7219
    send(dat2);               // 写 data 到 第二块MAX7219

    send(add1);               // 写register number 到 第一块MAX7219
    send(dat1);               // 写 data 到 第一块MAX7219

    LOAD = 1;                  // 利用CS上升沿锁存以上移位进输入的48位数据
}
有了上面的思路,想单独发送第一块max时在前面给后两块max“放空操作”不就行了,按下修改:
void write1 (uchar add1, uchar dat1)  //向第一片MAX7219写数据
{

        LOAD = 0;                  // CS置低选通 MAX7219  
        send(0x00);                 // 放空第三块 MAX7219  
        send(0x00);

        //CLK = 1;                  //此句加不加调试结果都一样
        send(0x00);                 // 放空第二块 MAX7219
        send(0x00);        

        send(add1);               // 写register number 到 第一块MAX7219
        send(dat1);               // 写 data 到 第一块MAX7219


        LOAD = 1;                  // 利用CS上升沿锁存以上移位进输入的48位数据
}

故障依旧。

暂时就用一次同时更新三块max的某一位数据的方案了。

本版积分规则

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

GMT+8, 2024-3-29 08:34 , Processed in 0.065909 second(s), 49 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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