久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4732|回復: 52
打印 上一主題 下一主題
收起左側

用5個74hc595芯片級聯,控制27位數碼管,數碼管顯示閃爍問題

  [復制鏈接]
回帖獎勵 10 黑幣 回復本帖可獲得 10 黑幣獎勵! 每人限 1 次(中獎概率 50%)
跳轉到指定樓層
樓主
用了5個74hc595芯片級聯,控制27位數碼管,數碼管閃爍,懷疑是寫入74HC595數據的時間太長導致的,現在很怕是本來硬件設計的缺陷。
  我的程序大概是這樣的,先用定時器0來計時,再用定時器1來刷新數碼管的刷新,因為用到5塊595芯片,所以寫了一個函數來寫入595的數據,高32位是位選,低八位是段選。
  數碼管顯示單片機程序:
#include "display.h"unsigned char code leddata[]={
        0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x40
};/*數碼管顯示數字0,1,2,3,4,5,6,7,8,9,-*/

unsigned char LEDBuf[] = {0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7};//數據顯示緩沖區
unsigned long code PLACE_CODE[] =
{0xFFFFFFFE,0xFFFFFFFD,0xFFFFFFFB,0xFFFFFFF7,0xFFFFFFEF,0xFFFFFFDF,0xFFFFFFBF,0xFFFFFF7F,0xFFFFFEFF,0xFFFFFDFF,0xFFFFFBFF,0xFFFFF7FF,0xFFFFEFFF,0xFFFFDFFF,0xFFFFBFFF,0xFFFF7FFF,0xFFFEFFFF,0xFFFDFFFF,0xFFFBFFFF,0xFFF7FFFF,0xFFEFFFFF,0xFFDFFFFF,0xFFBFFFFF,0xFF7FFFFF,0xFEFFFFFF,0xFDFFFFFF,0xFBFFFFFF}
;//  1           2         3           4          5          6           7         8          9          10         11         12         13         14         15         16          17          18         19        20          21         22         23        24           25         26       27  位選信號1-27位數碼管
unsigned char digdot0 = 0,digdot1 = 0,digdot2 = 0,digdot3 = 0;//小數點控制變量
unsigned char digdot4 = 0,digdot5 = 0,digdot6 = 0,digdot7 = 0;

void Display()
{
        static unsigned char i = 0;//靜態變量,只會賦值一次
        unsigned char temp;


        switch(i) //逐位輸入數據
        {
        case 0:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[0]];
                if(digdot0 == 1)
                {
                        temp = leddata[LEDBuf[0]] | 0x80;        //控制小數點閃爍
                }
                led_hc595_drive(PLACE_CODE[0],temp);//高位字節是位選 低位字節是斷碼
                                led_hc595_off(0x00);

                i++;        
                break;
        case 1:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[1]];
                if(digdot1 == 1)
                {
                        temp = leddata[LEDBuf[1]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[1],temp);//高位字節是位選 低位字節是斷碼
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                i++;
                break;
        case 2:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[2]];
                if(digdot2 == 1)
                {
                        temp = leddata[LEDBuf[2]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[2],temp);//高位字節是位選 低位字節是斷碼
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                i++;
                break;
        case 3:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[3]];
                if(digdot3 == 1)
                {
                        temp = leddata[LEDBuf[3]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[3],temp);//高位字節是位選 低位字節是斷碼
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                i++;
                break;
        case 4:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[4]];
                if(digdot4 == 1)
                {
                        temp = leddata[LEDBuf[4]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[4],temp);//高位字節是位選 低位字節是斷碼
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                i++;
                break;
        case 5:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[5]];
                if(digdot5 == 1)
                {
                        temp = leddata[LEDBuf[5]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[5],temp);//高位字節是位選 低位字節是斷碼   
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                i++;
                break;
        case 6:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[6]];
                if(digdot6 == 1)
                {
                        temp = leddata[LEDBuf[6]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[6],temp);//高位字節是位選 低位字節是斷碼
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                i++;
                break;
        case 7:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[7]];
                if(digdot7 == 1)
                {
                        temp = leddata[LEDBuf[7]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[7],temp);//高位字節是位選 低位字節是斷碼  
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                i++;
                break;
        case 8:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[8]];
                if(digdot6 == 1)
                {
                        temp = leddata[LEDBuf[8]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[8],temp);//高位字節是位選 低位字節是斷碼
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                i++;
                break;
        case 9:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[9]];
                if(digdot6 == 1)
                {
                        temp = leddata[LEDBuf[9]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[9],temp);//高位字節是位選 低位字節是斷碼
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                i++;
                break;
        case 10:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[10]];
                if(digdot6 == 1)
                {
                        temp = leddata[LEDBuf[10]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[10],temp);//高位字節是位選 低位字節是斷碼  
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                i++;
                break;
        case 11:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[11]];
                if(digdot6 == 1)
                {
                        temp = leddata[LEDBuf[11]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[11],temp);//高位字節是位選 低位字節是斷碼
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                i++;
                break;
        case 12:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[12]];
                if(digdot6 == 1)
                {
                        temp = leddata[LEDBuf[12]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[12],temp);//高位字節是位選 低位字節是斷碼
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                i++;
                break;
        case 13:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[13]];
                if(digdot6 == 1)
                {
                        temp = leddata[LEDBuf[13]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[13],temp);//高位字節是位選 低位字節是斷碼
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試     
                i++;
                break;
        case 14:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[14]];
                if(digdot6 == 1)
                {
                        temp = leddata[LEDBuf[14]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[14],temp);//高位字節是位選 低位字節是斷碼
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                i++;
                break;
        case 15:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[15]];
                if(digdot6 == 1)
                {
                        temp = leddata[LEDBuf[15]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[15],temp);//高位字節是位選 低位字節是斷碼
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                i++;
                break;
        case 16:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[16]];
                if(digdot6 == 1)
                {
                        temp = leddata[LEDBuf[16]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[16],temp);//高位字節是位選 低位字節是斷碼
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                i++;
                break;
        case 17:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[17]];
                if(digdot6 == 1)
                {
                        temp = leddata[LEDBuf[17]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[17],temp);//高位字節是位選 低位字節是斷碼
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                i++;
                break;
        case 18:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[18]];
                if(digdot6 == 1)
                {
                        temp = leddata[LEDBuf[18]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[18],temp);//高位字節是位選 低位字節是斷碼
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                i++;
                break;
        case 19:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[19]];
                if(digdot6 == 1)
                {
                        temp = leddata[LEDBuf[19]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[19],temp);//高位字節是位選 低位字節是斷碼
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                i++;
                break;
        case 20:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[20]];
                if(digdot6 == 1)
                {
                        temp = leddata[LEDBuf[20]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[20],temp);//高位字節是位選 低位字節是斷碼
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                i++;
                break;
        case 21:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[21]];
                if(digdot6 == 1)
                {
                        temp = leddata[LEDBuf[21]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[21],temp);//高位字節是位選 低位字節是斷碼
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                i++;
                break;
        case 22:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[22]];
                if(digdot6 == 1)
                {
                        temp = leddata[LEDBuf[22]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[22],temp);//高位字節是位選 低位字節是斷碼
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                i++;
                break;
        case 23:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[23]];
                if(digdot6 == 1)
                {
                        temp = leddata[LEDBuf[23]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[23],temp);//高位字節是位選 低位字節是斷碼
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試   
                i++;
                break;
        case 24:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[24]];
                if(digdot6 == 1)
                {
                        temp = leddata[LEDBuf[24]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[24],temp);//高位字節是位選 低位字節是斷碼
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                i++;
                break;
        case 25:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[25]];
                if(digdot6 == 1)
                {
                        temp = leddata[LEDBuf[25]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[25],temp);//高位字節是位選 低位字節是斷碼
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                i++;
                break;
        case 26:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[26]];
                if(digdot6 == 1)
                {
                        temp = leddata[LEDBuf[26]] | 0x80;
                }
                led_hc595_drive(PLACE_CODE[26],temp);//高位字節是位選 低位字節是斷碼  
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                i=0;
                break;



                default:break;
        }
        
}

5塊595級聯寫入程序:
  #include "hc595.h"
#include "reg51.h"

void hc_595_init()
{
        //HC595_OE = 1;
        HC595_SH_CP = 0;
        HC595_ST_CP = 0;
        HC595_DS = 0;
        //HC595_OE = 0;
}






void led_hc595_drive(unsigned long datH,unsigned char datL)
{
        unsigned char i;
        unsigned long temp;
        unsigned char temp2;
        temp = datH;
        for(i = 0;i<32;i++)
        {
                //第一步準備數據,放到數據IO上
                if(temp >= 0x80000000)   //大概是比較這部分錯了
                {
                        HC595_DS = 1;
                }
                else
                {
                        HC595_DS = 0;
                }
                HC595_SH_CP = 0;//上升沿 移位寄存器的數據移到存儲寄存器
                HC595_SH_CP = 1;
                temp  <<=1;
        }
        temp2 = datL;
        for(i = 0;i<8;i++)
        {
                //第一步準備數據,放到數據IO上
                if(temp2 >= 0x80)
                {
                        HC595_DS = 1;
                }
                else
                {
                        HC595_DS = 0;
                }
                HC595_SH_CP = 0;//上升沿 移位寄存器的數據移到存儲寄存器
                HC595_SH_CP = 1;
                temp2  <<=1;
        }
        HC595_ST_CP = 0;//上升沿 移位寄存器的數據移到存儲寄存器
        HC595_ST_CP = 1;

        HC595_SH_CP = 0;//拉低,提高抗干擾
        HC595_ST_CP = 0;
        HC595_DS = 0;

}
void led_hc595_off(unsigned char dat1)
{
        unsigned char temp3;
        unsigned char i;
        temp3 = dat1;
        for(i = 0;i<8;i++)
        {
                //第一步準備數據,放到數據IO上
                if(temp3 >= 0x80)
                {
                        HC595_DS = 1;
                }
                else
                {
                        HC595_DS = 0;
                }
                HC595_SH_CP = 0;//上升沿 移位寄存器的數據移到存儲寄存器
                HC595_SH_CP = 1;
                temp3  <<=1;
        }
        HC595_ST_CP = 0;//上升沿 移位寄存器的數據移到存儲寄存器
        HC595_ST_CP = 1;

        HC595_SH_CP = 0;//拉低,提高抗干擾
        HC595_ST_CP = 0;
        HC595_DS = 0;

}

主函數程序:
  #include "reg51.h"
#include "hc595.h"
#include "display.h"
#include "key.h"

void Timer0Init(void);
void Timer1Init(void);
void showNormal();



unsigned char timerCnt;
unsigned char sec;
unsigned char min;
unsigned char hour;


void main()
{
        hc_595_init();
        Timer0Init();
        Timer1Init();
        EA=1;
        while(1)
        {
                TR0=1;
                showNormal();

        }


}

void showNormal()
{
        LEDBuf[0] = min/10;
        LEDBuf[1] = min%10;
        LEDBuf[2] = sec/10;
        LEDBuf[3] = sec%10;

        LEDBuf[4] = min/10;
        LEDBuf[5] = min%10;
        LEDBuf[6] = sec/10;
        LEDBuf[7] = sec%10;

        LEDBuf[8] = min/10;
        LEDBuf[9] = min%10;
        LEDBuf[10] = sec/10;
        LEDBuf[11] = sec%10;

        LEDBuf[12] = min/10;
        LEDBuf[13] = min%10;
        LEDBuf[14] = sec/10;
        LEDBuf[15] = sec%10;

        LEDBuf[16] = min/10;
        LEDBuf[17] = min%10;
        LEDBuf[18] = sec/10;
        LEDBuf[19] = sec%10;

        LEDBuf[20] = min/10;
        LEDBuf[21] = min%10;
        LEDBuf[22] = sec/10;
        LEDBuf[23] = sec%10;

        LEDBuf[24] = 0;
        LEDBuf[25] = 1;
        LEDBuf[26] = 2;


}


void Timer0Init(void)        //50微秒@12.000MHz
{
        // AUXR &=0x7F;  //定時器時鐘12T模式
        TMOD &= 0xF0;    //設置定時器模式
        TMOD |= 0x01;        //設置定時器模式
        TL0 = 0xB0;        //設置定時器初始值
        TH0 = 0x3C;        //設置定時器初始值
        TF0 = 0;        //清除TF0標志
        ET0 = 1;
        EA = 1;
}

void Timer1Init(void)        //300微秒@12.000MHz
{
        // AUXR &=0xBF;  //定時器時鐘12T模式
        //AUXR &= 0xBF;  //定時器時鐘12T模式
        TMOD &= 0x0F;    //設置定時器模式
        TMOD |=0x10;        //設置定時器模式
        TL1 = 0xFF;        //設置定時器初始值
        TH1 = 0xFF;        //設置定時器初始值
        TF1 = 0;        //清除TF1標志
        ET1 = 1;
        TR1 = 1;
}

void timer0_ISR(void)interrupt 1
{
        timerCnt++;
        if(timerCnt >= 20)//20次1ms中斷,即1S時間到
        {
                timerCnt = 0;
                sec++;
                if(sec >= 60)
                {
                        sec = 0;
                        min++;
                        if(min >=60)
                        {
                                min = 0;
                                hour++;
                                if(hour >=24)
                                {
                                        hour = 0;
                                }
                        }
                }
        }

        TL0 = 0xB0;        //設置定時器初始值
        TH0 = 0x3C;        //設置定時器初始值
}                 


void timer1_ISR(void)interrupt 3
{
        TR1 =0;
        Display();
        TL1 = 0xFF;        //設置定時器初始值
        TH1 = 0xFF;        //設置定時器初始值
        TR1 = 1;
}                 

圖片1.png (26.58 KB, 下載次數: 76)

圖片1.png

27位數碼管.rar

52.79 KB, 下載次數: 7

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:298743 發表于 2024-4-12 17:10 | 只看該作者
基本確認是寫入595芯片的程序運行時間長導致的,要判斷40次來寫入一次數據,我在proteus仿真,程序不變每次寫入數據也是判斷40次,只改顯示數碼管的數目,只顯示9位數碼管的時候程序穩定,一超過9位數碼管就開始閃爍了
回復

使用道具 舉報

板凳
ID:298743 發表于 2024-4-12 21:07 | 只看該作者
可以補償
回復

使用道具 舉報

地板
ID:79094 發表于 2024-4-12 22:00 | 只看該作者
小白一個 高手勿噴     增加時鐘頻率 可以嗎
回復

使用道具 舉報

5#
ID:1109793 發表于 2024-4-13 07:12 | 只看該作者
595不是有控制端嗎?怎么還消隱?164才需要消隱吧。我用2片595級聯輸出,發現市場上大部分595都不能用,只有第一片的輸出邏輯正常,后面的就會比較亂。換了好幾種包括安森美原裝都不好使。軟件無論怎樣調都不行。只有一種能用的。
回復

使用道具 舉報

6#
ID:69038 發表于 2024-4-13 09:23 | 只看該作者
switch(i) //逐位輸入數據
        {
        case 0:
                led_hc595_drive(0xffffffff,0x00);//消影 放前還是放后 要試
                temp = leddata[LEDBuf[0]];
                if(digdot0 == 1)
                {
                        temp = leddata[LEDBuf[0]] | 0x80;        //控制小數點閃爍
                }
                led_hc595_drive(PLACE_CODE[0],temp);//高位字節是位選 低位字節是斷碼
                                led_hc595_off(0x00);

                i++;      
                break;
====這里要以優化一下代碼,找出規律,可以不用這么多的case..
回復

使用道具 舉報

7#
ID:876947 發表于 2024-4-13 13:01 | 只看該作者
xiaoyao166ny 發表于 2024-4-12 22:00
小白一個 高手勿噴     增加時鐘頻率 可以嗎

我也是這樣想的40M和20M 的速度肯定不同
回復

使用道具 舉報

8#
ID:105534 發表于 2024-4-13 13:40 | 只看該作者
xiaobendan001 發表于 2024-4-13 07:12
595不是有控制端嗎?怎么還消隱?164才需要消隱吧。我用2片595級聯輸出,發現市場上大部分595都不能用,只 ...

那些做16*16*16光立方的是怎么用的595,參考一下
回復

使用道具 舉報

9#
ID:883242 發表于 2024-4-13 21:26 | 只看該作者
xiaobendan001 發表于 2024-4-13 07:12
595不是有控制端嗎?怎么還消隱?164才需要消隱吧。我用2片595級聯輸出,發現市場上大部分595都不能用,只 ...

那就是硬件有問題,多個595地線電平不一樣。
回復

使用道具 舉報

10#
ID:1110945 發表于 2024-4-13 22:07 | 只看該作者
想要不閃爍,得每秒刷新20次以上,也就是27個數碼管在不
到50毫秒的時間里都要顯示一次,每一個數碼管的顯示時間
不到2毫秒,5個595的數據打進去(軟件法)也是要花時間的,
用硬件SPI數據傳輸能快一些,估計也還是會有困難。
加一片595可以讓兩個數碼管同時顯示或許會好一些。
也可以加兩片595,把27個數碼管分成三組,每組九個,
就很容易做了。
回復

使用道具 舉報

11#
ID:161164 發表于 2024-4-13 23:28 | 只看該作者
1. 不要用Long, 51算Long很耗時間的,拆開4個uchar吧
2. display里的switch太累贅了,如6樓所說的,簡化一下
回復

使用道具 舉報

12#
ID:1109793 發表于 2024-4-14 07:08 | 只看該作者
Hephaestus 發表于 2024-4-13 21:26
那就是硬件有問題,多個595地線電平不一樣。


麻煩幫我看看這個要怎么改才能正常使用其他品牌的595.
回復

使用道具 舉報

13#
ID:795427 發表于 2024-4-14 10:17 | 只看該作者
74hc595也是分型號的,例如74HC595A和75HC595D,它們使用都是存在差異,外部的硬件電路可能都不同,具體參考對應的手冊。
回復

使用道具 舉報

14#
ID:883242 發表于 2024-4-14 10:25 | 只看該作者
xiaobendan001 發表于 2024-4-14 07:08
麻煩幫我看看這個要怎么改才能正常使用其他品牌的595.

大面積敷地可以改善問題。
回復

使用道具 舉報

15#
ID:1109793 發表于 2024-4-14 10:32 | 只看該作者
perseverance51 發表于 2024-4-14 10:17
74hc595也是分型號的,例如74HC595A和75HC595D,它們使用都是存在差異,外部的硬件電路可能都不同,具體參 ...

百度了一下,只是封裝不一樣而已。而且幾個品牌如果只用一片都好使,其中最差的一個大概在幾個月后會壞掉。較好的則針對自己同品牌可以用級聯,但是也不穩定,偶爾出現意外的跳動,時間短的只能在LED上看到,但是繼電器沒有動作,長的就能聽到繼電器有聲音,雖然強電輸出也看不到,但是我認為這會影響繼電器的壽命。只有一個牌子的可以,級聯信號送個其他品牌都能正常穩定的輸出。用示波器看了,實在看不出來問題。但是就是不好使,軟件上面調整了各種順序和延時,會略有改善,無法根除。
回復

使用道具 舉報

16#
ID:1109793 發表于 2024-4-14 10:33 | 只看該作者
Hephaestus 發表于 2024-4-14 10:25
大面積敷地可以改善問題。

截圖里面藍色就是鋪地啊,實際上之前的板子是沒有的,就是因為芯片問題才鋪了,結果沒什么卵用
回復

使用道具 舉報

17#
ID:619259 發表于 2024-4-14 17:19 | 只看該作者
27個數碼管采用動態掃描,理論上是可以實現無閃顯示。動態掃描刷新頻率理論上不低于50Hz,能達到100Hz為最佳,掃描周期即為20-10ms。若取中間值15ms,每個數碼管刷新時間為0.56ms,經仿真可以成功穩定顯示,因多位數碼管共用段端口,程序必須加上消隱。
回復

使用道具 舉報

18#
ID:619259 發表于 2024-4-14 22:27 | 只看該作者
xiaobendan001 發表于 2024-4-13 07:12
595不是有控制端嗎?怎么還消隱?164才需要消隱吧。我用2片595級聯輸出,發現市場上大部分595都不能用,只 ...

不能怪595不好,是你沒消隱造成
回復

使用道具 舉報

19#
ID:1109793 發表于 2024-4-15 07:30 | 只看該作者
cy009 發表于 2024-4-14 22:27
不能怪595不好,是你沒消隱造成

大哥,我不是用來顯示的,我是用來擴展輸出的,2片級聯16個輸出推動三極管+繼電器。這個有使能端,還有RCK,就算顯示也沒必要消隱吧,把數據更新到芯片,然后RCK給個上升沿,把每個芯片的數據更新到輸出腳上去,這樣不行嗎?消隱我覺得是比如164沒有RCK這種功能,在更新數據過程中每個腳都被實時更新,狀態不是想要的,此時先關閉顯示,等更新完成再打開,這樣顯示比較干凈。
回復

使用道具 舉報

20#
ID:298743 發表于 2024-4-15 08:38 | 只看該作者
xiaobendan001 發表于 2024-4-13 07:12
595不是有控制端嗎?怎么還消隱?164才需要消隱吧。我用2片595級聯輸出,發現市場上大部分595都不能用,只 ...

我在仿真上面的結果595級聯是可以正常輸出,有異常的話,你可以用keil單步調試,查看各個變量的值是怎么變化的,來查出原因
回復

使用道具 舉報

21#
ID:619259 發表于 2024-4-15 08:47 | 只看該作者
xiaobendan001 發表于 2024-4-15 07:30
大哥,我不是用來顯示的,我是用來擴展輸出的,2片級聯16個輸出推動三極管+繼電器。這個有使能端,還有RC ...

1.595兩片聯級,一片傳段碼,一片傳位碼,可以不用消隱。樓主的案例是5個595,段碼共用,不消隱不行呵。
2.你用595擴展輸出驅動三極管+繼電器,繼電器電路有反峰保護嗎?
回復

使用道具 舉報

22#
ID:1109793 發表于 2024-4-15 09:16 | 只看該作者
asdadqw2 發表于 2024-4-15 08:38
我在仿真上面的結果595級聯是可以正常輸出,有異常的話,你可以用keil單步調試,查看各個變量的值是怎么 ...

都說了,好的芯片是沒問題的,板子不是很多,10多年前一次性買了一整盤,用了10多年,一直正常的。好不容易用完了,再買就出問題了,后級某個輸出會偶爾跳動。并且幾個月后會完全損壞。于是重新購買,包括在立創商城也買過,結果都不行,有的甚至直接錯位輸出,最后買到一種,上面的LOGO類似><的。就沒問題了。我也是納悶,這樣古老的一個東西,而且大量被使用在LED點陣上面,居然還有問題。
回復

使用道具 舉報

23#
ID:1109793 發表于 2024-4-15 09:19 | 只看該作者
cy009 發表于 2024-4-15 08:47
1.595兩片聯級,一片傳段碼,一片傳位碼,可以不用消隱。樓主的案例是5個595,段碼共用,不消隱不行呵。
...

1,兩片顯示8位和5片顯示32位難道不一樣嗎?為啥2片不用消隱,5片就要?
2,你說的是那個二極管嗎?當然有啊
回復

使用道具 舉報

24#
ID:1109793 發表于 2024-4-15 09:27 | 只看該作者
剛軟件模擬了一下,連續輸出5片的數據時間小于250us,完全可以用的。
回復

使用道具 舉報

25#
ID:1109793 發表于 2024-4-15 09:32 | 只看該作者
這是另外一個用了3片,一片顯示數據,2片輸出驅動。但是這個顯示的位選是用IO的。為了配合,還是加了消隱的,先關了COM,更新數據后再打開。
  1. OP = 0;                                        //鎖定輸入輸出
  2. dqd(OUT[0]);                //顯示
  3. dqd(OUT[1]);                //OUT_1-8=>7-0
  4. dqd(OUT[2]);                //OUT_9-16=>7-0
  5. OP = 1;                                //更新輸出,上升沿有效
復制代碼
  1. void dqd(uchar da){
  2. //SBUF = da;
  3. //while(!TI){};
  4. //TI = 0;
  5. uchar i = 8;
  6. while(i){
  7.         MC = 0;
  8.         if(da&0x01 == 1){
  9.                 MD = 1;
  10.                 }else{
  11.                 MD = 0;
  12.                 }
  13.         da>>=1;
  14.         _nop_();_nop_();
  15.         _nop_();_nop_();
  16.         MC = 1;
  17.         _nop_();_nop_();
  18.         _nop_();_nop_();
  19.         i--;
  20.         }
  21. }
復制代碼
回復

使用道具 舉報

26#
ID:298743 發表于 2024-4-15 11:26 | 只看該作者

能說一下怎么補償的思路嗎,我在網上找不到相關資料
回復

使用道具 舉報

27#
ID:298743 發表于 2024-4-15 11:27 | 只看該作者
xiaoyao166ny 發表于 2024-4-12 22:00
小白一個 高手勿噴     增加時鐘頻率 可以嗎

我也是小白,剛剛試過改了一下long的數據分成四個,再把頻率改為33.1776 就顯示正常了
回復

使用道具 舉報

28#
ID:298743 發表于 2024-4-15 11:31 | 只看該作者
xiaobendan001 發表于 2024-4-15 09:27
剛軟件模擬了一下,連續輸出5片的數據時間小于250us,完全可以用的。

難道是仿真軟件的問題?我在仿真軟件運行這個就有閃爍
回復

使用道具 舉報

29#
ID:298743 發表于 2024-4-15 11:40 | 只看該作者
xiaobendan001 發表于 2024-4-15 09:32
這是另外一個用了3片,一片顯示數據,2片輸出驅動。但是這個顯示的位選是用IO的。為了配合,還是加了消隱的 ...

這個的寫法,跟我的差不多一樣把,我沒看出什么區別,原諒我新手不太懂
回復

使用道具 舉報

30#
ID:298743 發表于 2024-4-15 11:49 | 只看該作者
zhuls 發表于 2024-4-13 09:23
switch(i) //逐位輸入數據
        {
        case 0:

我的想法 是switch的執行效率應該不低吧,只是占用的代碼位置多而已,執行起來應該直接到相應的case里,效率來說應該還行吧。(純新手,剛接觸,希望大佬能解答一下)
回復

使用道具 舉報

31#
ID:161164 發表于 2024-4-15 13:20 | 只看該作者
asdadqw2 發表于 2024-4-15 11:27
我也是小白,剛剛試過改了一下long的數據分成四個,再把頻率改為33.1776 就顯示正常了

貼上來看看
回復

使用道具 舉報

32#
ID:1109793 發表于 2024-4-15 13:22 | 只看該作者
asdadqw2 發表于 2024-4-15 11:40
這個的寫法,跟我的差不多一樣把,我沒看出什么區別,原諒我新手不太懂

應該是可以的,我這用22.1184的晶振
回復

使用道具 舉報

33#
ID:298743 發表于 2024-4-15 13:27 | 只看該作者
  1. void led_hc595_drive(unsigned char dat1,unsigned char dat2,unsigned char dat3,unsigned char dat4,unsigned char datL)
  2. {
  3.         unsigned char i;
  4.         unsigned char temp;
  5.         unsigned char temp2;
  6.         temp = dat1;
  7.         for(i = 0;i<8;i++)
  8.         {
  9.                 if(temp >= 0x80)   
  10.                 {
  11.                         HC595_DS = 1;
  12.                 }
  13.                 else
  14.                 {
  15.                         HC595_DS = 0;
  16.                 }
  17.                 HC595_SH_CP = 0;
  18.                 HC595_SH_CP = 1;
  19.                 temp  <<=1;
  20.         }
  21.         temp = dat2;
  22.         for(i = 0;i<8;i++)
  23.         {
  24.       
  25.                 if(temp >= 0x80)   
  26.                 {
  27.                         HC595_DS = 1;
  28.                 }
  29.                 else
  30.                 {
  31.                         HC595_DS = 0;
  32.                 }
  33.                 HC595_SH_CP = 0;
  34.                 HC595_SH_CP = 1;
  35.                 temp  <<=1;
  36.         }
  37.         temp = dat3;
  38.         for(i = 0;i<8;i++)
  39.         {
  40.          
  41.                 if(temp >= 0x80)   
  42.                 {
  43.                         HC595_DS = 1;
  44.                 }
  45.                 else
  46.                 {
  47.                         HC595_DS = 0;
  48.                 }
  49.                 HC595_SH_CP = 0;
  50.                 HC595_SH_CP = 1;
  51.                 temp  <<=1;
  52.         }
  53.         temp = dat4;
  54.         for(i = 0;i<8;i++)
  55.         {
  56.      
  57.                 if(temp >= 0x80)   
  58.                 {
  59.                         HC595_DS = 1;
  60.                 }
  61.                 else
  62.                 {
  63.                         HC595_DS = 0;
  64.                 }
  65.                 HC595_SH_CP = 0;
  66.                 HC595_SH_CP = 1;
  67.                 temp  <<=1;
  68.         }
  69.         temp2 = datL;
  70.         for(i = 0;i<8;i++)
  71.         {
  72.   
  73.                 if(temp2 >= 0x80)
  74.                 {
  75.                         HC595_DS = 1;
  76.                 }
  77.                 else
  78.                 {
  79.                         HC595_DS = 0;
  80.                 }
  81.                 HC595_SH_CP = 0;
  82.                 HC595_SH_CP = 1;
  83.                 temp2  <<=1;
  84.         }
  85.         HC595_ST_CP = 0;
  86.         HC595_ST_CP = 1;

  87.         HC595_SH_CP = 0;
  88.         HC595_ST_CP = 0;
  89.         HC595_DS = 0;

復制代碼
回復

使用道具 舉報

34#
ID:298743 發表于 2024-4-15 13:37 | 只看該作者
xiaobendan001 發表于 2024-4-15 09:27
剛軟件模擬了一下,連續輸出5片的數據時間小于250us,完全可以用的。

怎么用軟件模擬,我也去試下,能說一下怎么模擬的嗎
回復

使用道具 舉報

35#
ID:1109793 發表于 2024-4-15 14:22 | 只看該作者
asdadqw2 發表于 2024-4-15 13:37
怎么用軟件模擬,我也去試下,能說一下怎么模擬的嗎

就是在keil里面進入調試狀態,設好斷點,記錄時間。
回復

使用道具 舉報

36#
ID:33145 發表于 2024-4-15 15:16 | 只看該作者
可以嘗試提高程序的效率,我用仿真24個數碼管,沒問題。
回復

使用道具 舉報

37#
ID:33145 發表于 2024-4-15 15:21 | 只看該作者
24個共陰數碼管+5個74HC595,仿真軟件為Proteus8.11版本,,,可以正常顯示。

24位數碼管顯示_74HC595X5.rar

93.32 KB, 下載次數: 10

回復

使用道具 舉報

38#
ID:298743 發表于 2024-4-15 15:22 | 只看該作者
yqs138168 發表于 2024-4-15 15:16
可以嘗試提高程序的效率,我用仿真24個數碼管,沒問題。

大佬能不能指點一下想法嗎,我覺得我的switch雖然累贅,但是應該不影響程序執行效率,然后就到消隱和寫入595的程序了,寫入595的程序,我在網上找資料也只找到我這種寫法,實在沒什么頭緒了
回復

使用道具 舉報

39#
ID:33145 發表于 2024-4-15 15:26 | 只看該作者
asdadqw2 發表于 2024-4-15 15:22
大佬能不能指點一下想法嗎,我覺得我的switch雖然累贅,但是應該不影響程序執行效率,然后就到消隱和寫入 ...

看看我的程序,新思路,與你的寫法不一樣,效率高很多
回復

使用道具 舉報

40#
ID:33145 發表于 2024-4-15 15:28 | 只看該作者
asdadqw2 發表于 2024-4-15 15:22
大佬能不能指點一下想法嗎,我覺得我的switch雖然累贅,但是應該不影響程序執行效率,然后就到消隱和寫入 ...

51單片機處理大的數值(特別是32位)或浮點數,效率都很低,盡可能使用char數據或位數據,提高效率,,,
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 99精品免费视频 | 成人久久久 | 中文字幕一区二区三 | 国产精品久久久久无码av | 国产精品1区2区 | 影视先锋av资源噜噜 | 亚洲免费一区二区 | 亚洲 欧美 日韩 在线 | 欧美国产精品 | 亚洲精品一区二三区不卡 | 中文字幕在线观看一区二区 | 精品av天堂毛片久久久借种 | 日韩免费av | 伊人免费观看视频 | 亚洲视频一区 | 黄网址在线观看 | 国产91精品网站 | 欧美九九| 国产精品视频一区二区三区四区国 | 6996成人影院网在线播放 | 久久免费小视频 | 99精品一区二区三区 | 欧美精品1区2区3区 免费黄篇 | 日日夜夜影院 | 亚洲精品66 | 中文字幕在线观看一区二区 | 亚洲va在线va天堂va狼色在线 | 亚洲一级视频在线 | 成人a网| 黄色成人在线观看 | 手机av在线 | xxxxxx国产| 日韩黄色小视频 | 日本精品视频在线观看 | 区一区二区三在线观看 | 日韩三级电影在线看 | 中文天堂在线一区 | 亚洲免费精品一区 | 久99久视频 | 免费a v网站| 99国产视频|