PIC单片机SPI控制两个74HC595控制四位数码管?

四位数码管动态显示数字是正确的,但为什么会出现有几个二极管闪有几个二极管不闪,若缩短延迟时间闪的那几个二极管就灭了,是什么原因
2026年09月22日 01:42
有1个网友回答
网友(1):

#include "reg52.h"    //  这是51的仿真实例可以参考一下

#define MAIN_Fosc 11059200UL //定义主时钟

#define Timer0_Reload (MAIN_Fosc / 12000)

unsigned char code t_display[]={

// 0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F   消隐

0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00}; //段码

unsigned char code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //位码

/************* 本地变量声明 **************/

sbit P_HC595_SER   = P1^5; //pin 14 SER data input

sbit P_HC595_RCLK  = P1^4; //pin 12 RCLk store (latch) clock

sbit P_HC595_SRCLK = P1^7; //pin 11 SRCLK Shift data clock


unsigned char LED8[8]; //显示缓冲

unsigned char display_index; //显示位索引

bit B_1ms; //1ms标志

/**********************************************/

void main(void)

  {

  unsigned char i,k;

  unsigned int j;

  TMOD = 0x01; //Timer 0 config as 16bit timer, 12T

  TH0  = (65536 - Timer0_Reload) / 256;

  TL0  = (65536 - Timer0_Reload) % 256;

  ET0 = 1;

  TR0 = 1;

  EA  = 1;


j = 0;

k = 0;

//for(i=0; i<8; i++) LED8[i] = 0x10; //上电消隐

  for(i=0; i<8; i++) LED8[i] = i;

while(1)

{

while(!B_1ms) ; //等待1ms到

B_1ms = 0;

if(++j >= 500) //500ms到

{

j = 0;

for(i=0; i<16; i++) LED8[i] = (k+i)%16; //刷新显示

if(++k > 0x10) k = 0; //8个数码管循环显示0,1,2...,A,B..F,消隐.

}

       }

  } 


/**********************************************/

void Send_595(unsigned char dat) //发送一个字节

  {

  unsigned char i;

  for(i=0; i<8; i++)

    {

    if(dat & 0x80) P_HC595_SER = 1;

    else P_HC595_SER = 0;

    P_HC595_SRCLK = 1;

    P_HC595_SRCLK = 0;

    dat = dat << 1;

    }

  }


/**********************************************/

void DisplayScan(void) //显示扫描函数

{

Send_595(T_COM[display_index]); //共阳 输出位码

Send_595(~t_display[LED8[display_index]]); //共阳 输出段码

Send_595(T_COM[display_index]); //共阳 输出位码

Send_595(~t_display[LED8[display_index+8]]); //共阳 输出段码

P_HC595_RCLK = 1;

P_HC595_RCLK = 0; //锁存输出数据

}


/**********************************************/

void timer0 (void) interrupt 1 //Timer0 1ms中断函数

{

TH0  = (65536 - Timer0_Reload) / 256; //重装定时值

TL0  = (65536 - Timer0_Reload) % 256;


DisplayScan(); //1ms扫描显示一位

B_1ms = 1; //1ms标志

if(++display_index >= 8) display_index = 0; //8位结束回0

}