C语言 C51单片机 双74HC595驱动8*8点阵,为何只有一行延时,其他行一闪而过

________________________________________
双74HC595驱动8*8点阵,为何只有第一行延时,其他行一闪而过
------------------------------------------------------------------
#include "reg51.h"
#include "intrins.h"
//定义变量
unsigned char temp = 0xfe;
unsigned char KEY_NUM = 0;
sbit LEDARRAY_DI=P1^0;
sbit LEDARRAY_CLK=P1^1;
sbit LEDARRAY_LAT=P1^2;
unsigned char code play[4][8] = {0x83,0x80,0x00,0x00,0x00,0x00,0x01,0xC1,
0x0C,0x00,0x80,0x80,0x01,0x01,0x00,0x30,
0x30,0x00,0x01,0x01,0x80,0x80,0x00,0x0C,
0xC1,0x01,0x00,0x00,0x00,0x00,0x80,0x83};
//****************************************************
//发送一个字节数据
//****************************************************
void Send_Byte( unsigned char dat)
{
unsigned char i;
LEDARRAY_CLK = 0;
_nop_();
LEDARRAY_LAT = 0;
_nop_();
for( i = 0 ; i < 8 ; i++ )
{
LEDARRAY_DI =dat&0x01?1:0;
LEDARRAY_CLK = 1; //上升沿发送数据
// _nop_();
LEDARRAY_CLK = 0;
// _nop_();
dat >>= 1;
}
}
void Latch()
{
LEDARRAY_LAT = 1; //锁存数据
_nop_();
LEDARRAY_LAT = 0;
_nop_();
}
//****************************************************
//MS延时函数(12M晶振下测试)
//****************************************************
void Delay_ms(unsigned int n)
{
unsigned int i,j;
for(i=0;i<n;i++)
for(j=0;j<123;j++);
}
void Hc595_led()
{
unsigned char j,k;
static unsigned char i=0;
for(j = 0; j < 4 ;j++) //循环右移
{
temp = 0x7f;
for(k = 0 ; k < 8 ; k++)
{
Send_Byte(temp); //列选择
Send_Byte(play[j][k]); //行数据
Latch(); //锁存数据
temp = (temp>>1)|0x80;
}
Delay_ms(200);
}
}
//****************************************************
//主函数
//****************************************************
void main()
{
while(1)
{
Hc595_led();
}
}
___________________________________________________
双74HC595驱动8*8点阵,为何只有第一行延时,其他行一闪而过
--------------------------------------------------------------------------------------
=================================================
只亮temp = 0x7f; 这一行;而temp = (temp>>1)|0x80的行一闪而过
只亮temp = 0x7f; 这一行;而temp = (temp>>1)|0x80的行一闪而过
只亮temp = 0x7f; 这一行;而temp = (temp>>1)|0x80的行一闪而过
只亮temp = 0x7f; 这一行;而temp = (temp>>1)|0x80的行一闪而过
只亮temp = 0x7f; 这一行;而temp = (temp>>1)|0x80的行一闪而过
只亮temp = 0x7f; 这一行;而temp = (temp>>1)|0x80的行一闪而过
=================================================

你的那个有点混乱,都不知道要干嘛,你看看这个
/******************************************************************
/*                                                                *
/* 单片机开发系统演示程序                                                  *
/*                                                                *
/*                                                                *
/******************************************************************/

#include <reg52.h>                                    //51芯片管脚定义头文件
#include <intrins.h>                                //内部包含延时函数 _nop_();

#define uchar unsigned char
#define uint  unsigned int


sbit  SDATA_595=P1^5;                                 //串行数据输入  ----接板卡上的SPI
sbit  SCLK_595 =P1^6;                               //移位时钟脉冲  ---接板卡上的SPO
sbit  RCK_595  =P1^7;                               //输出锁存器控制脉冲 ----接板卡上SPK
sbit  CS_LED8   =P1^1;                                //数码管片选 --------接板卡上的CS
sbit  CS_1302   =P1^4;                                //ds1302片选

uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,
                    0x6d,0x7d,0x07,0x7f,0x6f,
                    0x77,0x7c,0x39,0x5e,0x79,0x71};    //数码管编码(0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F)(共阴极数码管)
uchar  dis[8];                                        //显示缓冲区

void  delay(uint );
void  display();

/*******************************************************
*                                                      *
* 延时函数                                             *
*                                                      *
*******************************************************/
void  delay(uint dt)
{
   uint i;
   uchar bt;
   for(i=0;i<dt;i++)
   for(bt=0;bt<200;bt++);
 }

/*******************************************************
*                                                      *
*    定时中断函数                                       *
*                                                      *
*******************************************************/

void timer0(void)    interrupt 1
{
    TH0=0XFC;
    TL0=0X66;
    display();
}

/*******************************************************
*                                                      *
* 显示函数                                               *
*                                                      *
*******************************************************/

void display()
{
    uchar num,c,i;
    for(i=0;i<8;i++)
    {
        num=dis[i];
        CS_LED8=0;
        for(c=0;c<8;c++)                            //写入显示数据
        {
            SCLK_595=0;
            num=num<<1;
            SDATA_595=CY;
            SCLK_595=1;
            SCLK_595=0;
        }
        num=~(1<<i);
        for(c=0;c<8;c++)                            //写入数码管序号
        {
            SCLK_595=0;
            num=num<<1;
            SDATA_595=CY;
            SCLK_595=1;
            SCLK_595=0;
        }
        RCK_595=0;
        _nop_();                                    //短延时
        _nop_();
        RCK_595=1; 
        _nop_();
        _nop_();
        RCK_595=0;                                    //显示数据输出
        delay(1);
        CS_LED8=1;
    }
}

/*******************************************************
*                                                      *
* 主函数                                               *
*                                                      *
*******************************************************/
main(void)
{
    uchar k;
    TMOD|=0x01;
    TH0=0XFC;
    TL0=0X66;                                        //定时器初始化
    TR0=1;
    EA=1;
    ET0=1;
//    IP=0X10;
    
    CS_1302=0;                                        //屏蔽1302的信号
    for(k=0;k<8;k++)
    {
        dis[k]=table[k];                            //将显示内容送入显示缓冲区
    }
    
    while(1);
} //end of main()

追问

我是在做8*8点阵仿霓虹灯的四角旋转

————————————

四角达到霓虹灯闪烁的要求

但是只是第一列的灯很亮,

其他列的灯很暗,

而且都是一闪而过

————————————

郁闷

追答 for(k = 0 ; k < 8 ; k++) 
  {   
   Send_Byte(temp);  //列选择
    //这里是不是也该锁存下?
   Send_Byte(play[j][k]);  //行数据
   Latch();   //锁存数据
   temp = (temp>>1)|0x80;     
  }

追问

temp = 0x7f;
for(k = 0;k >1)|0x80;
}
Delay_ms(200);
————
不对啊
————

温馨提示:答案为网友推荐,仅供参考
第1个回答  2015-04-30
修改一下函数 Hc595_led()如下,试试,祝你成功!
void Hc595_led()
{
unsigned char j,k;
//static unsigned char i=0;
unsigned char times;
for(j = 0; j < 4 ;j++) //循环右移
{
for(times=0;times<50;times++) //每帧画面刷50遍,点亮约1秒。目的能看清每个动画。也是循环速度的调节变量。
{
temp = 0x7f;
for(k = 0 ; k < 8 ; k++)
{
Send_Byte(temp); //列选择
Send_Byte(play[j][k]); //行数据
Latch(); //锁存数据
temp = (temp>>1)|0x80;
Delay_ms(3); //假设为1mS定时。此处延时3mS。整屏刷完时间24mS。目的不闪。
}
}
}
}追问

我验证过了,看上去你的这个程序似乎可以通过,等晚点测试,
不知道为什么用 Delay_ms(200)延时1S 秒不能通过,

追答

4次循环,是为了让周围的四组灯连成一个圈的效果,共送4组数据。
8次循环,是为了让每一组8列数据分别送到屏的8列上。(你之前程序,就会使得最后一列送出的数据整整延时200mS,而其他的列没有延时就会一闪而过。)
因此主要问题,就是8次循环的工作要不停的送,连续送足延时时间。然后再切换另外一组数据。

1)每次一组数据保证20mS之内送完,使得频率在50Hz以上,画面不闪。
2)每组数据,保证足够的总点亮时间,使得画面停留时间足够看清。调节时间可改变旋转速度。

本回答被提问者和网友采纳
第2个回答  2015-04-30
你的延时的加错地方了吧!8次,每一次都应该有一定的延时的追问

假如是个数字8,你每一次延时,是不是一横一竖都要延时呢!!!!!!!!!!

追答

看你的电路!
你自己想想数码管吧!这个和数码管的原理的一样的

追问

我要四角的灯一起转,不是一个一个角的转,懂!!!!!!!!!!!!!