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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

2個74HC595控制2個8x8點陣,顯示3位數字

[復制鏈接]
跳轉到指定樓層
樓主
想用2個74HC595控制2個8x8點陣,顯示3位數字,但這3個數字要互不干擾,如圖,顯示2位數字會做,但是顯示3位的就不知道怎么下手了,沒有思路,就像控制8位數碼管的小數點亮一下滅一下,而不影響其數字的顯示一樣,這個問題我也不知道怎么解決,求各位大佬給點思路,怎么寫這個驅動程序,小弟不勝感激,謝謝各位。

屏幕截圖 2020-12-30 232758.png (17.6 KB, 下載次數: 87)

屏幕截圖 2020-12-30 232758.png
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

來自 2#
ID:517466 發表于 2021-1-3 14:17 | 只看該作者
如果每個數字字符使用5*8的點陣表達(有一個空白列作為間隔),三個數字占用15列像素。兩個595可以表達兩個字節計16位,絕對是夠用了。但這就要求你自己重新設計所有數字、字母的點陣數據了,以適應5*8的方式。你給的圖片中1、2、3,使用了5*8的點陣方式.
我個人建議你建立4*7點陣模式,因為要考慮數字中間的空白間隔。使用5*8導致太緊湊,不好看。

5x7點陣數字.jpg (209.23 KB, 下載次數: 94)

5x7點陣數字.jpg

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

板凳
ID:566214 發表于 2020-12-30 23:37 | 只看該作者
3位數字可自由控制
回復

使用道具 舉報

地板
ID:390416 發表于 2020-12-31 11:35 | 只看該作者
我很想知道,你兩個595怎么驅動16*8點的?正反都驅動?
說說你的問題,你可以開辟一個16字節的數組,分別對應每一列。595就負責把每一列的字節顯示到16*8點LED上去,這樣,至于你顯示什么圖案,那就跟595無關了。你只需要往數組里面填充字節值就行了。
具體操作,建議你學習《人人學會單片機》視頻教程,第13、14、15、16課程,就是這樣操作的。
回復

使用道具 舉報

5#
ID:566214 發表于 2020-12-31 20:39 | 只看該作者
人人學會單片機 發表于 2020-12-31 11:35
我很想知道,你兩個595怎么驅動16*8點的?正反都驅動?
說說你的問題,你可以開辟一個16字節的數組,分別 ...

行掃描我沒有寫出來,兩個595是列掃描,如果2個595只顯示2個數字,我會寫驅動,但是2個595要顯示3個數字,我沒不知道怎么寫了,請賜教
回復

使用道具 舉報

6#
ID:566214 發表于 2021-1-3 20:32 | 只看該作者
suncat0504 發表于 2021-1-3 14:17
如果每個數字字符使用5*8的點陣表達(有一個空白列作為間隔),三個數字占用15列像素。兩個595可以表達兩個 ...

2個595是16位,每次發8位,如果只顯示2位數字,那好辦,我不明白的是如何把16位原本顯示兩位數字的拆成顯示3位數字,就是說我只能用一個595來控制顯示1位數字,如果要讓2個595來顯示3位數,這個就不懂了,不知道怎么寫這個驅動程序
回復

使用道具 舉報

7#
ID:517466 發表于 2021-1-4 22:04 | 只看該作者
本帖最后由 suncat0504 于 2021-1-5 18:41 編輯
dcjdcj 發表于 2021-1-3 20:32
2個595是16位,每次發8位,如果只顯示2位數字,那好辦,我不明白的是如何把16位原本顯示兩位數字的拆成顯 ...

原理我已經和你說了。點陣顯示數字字符,無非就是逐行逐列把像素點的數據傳遞給顯示部件。
一個595對應一個字節,就是8個bit位。兩個對應16個Bit位。當每個字符、數字占用一個字節8Bit位的時候,每個595一次只能顯示一個一行8列的像素點,逐行掃描,視覺暫留現象,呈現出一個完整的字符。
當一個字符使用4x8方式顯示的的時候。這個字符每一行占用4個像素點,共8行就能完整顯示一個字符。那么兩個595,就能同時顯示4個字符了。實際使用,為了避免太緊湊,我加了一行空白行,就是全0的那行。數字之間間隔一個空白列,數字最后還有一個空白咧,就是在垂直方向上全都為0的那些列。
比如,使用我提供的點陣組合,對234這個數值的組合,我只用0和1來表達, 0表示不亮,1表示亮:
0 1234 5 6789 A BCDE F    // 這行是以16進制表示Bit位的編號
------------------------------
0 0000 0 0000 0 0000 0    // 第0行 從這行開始,表示的是像素數據,0-不亮;1-亮;這樣是空白行。
0 0110 0 0110 0 0110 0    // 第1行
0 1001 0 1001 0 1010 0    // 第2行
0 0001 0 0001 0 1010 0    // 第3行
0 0010 0 0010 0 1010 0    // 第4行
0 0100 0 0001 0 1110 0    // 第5行
0 1000 0 1001 0 0010 0    // 第6行
0 1111 0 0110 0 0010 0    // 第7行
你注意看由1組成的圖形是不是2、3、4?
按照這個點陣數據,你只需要把每行的數據拆分為兩個字節,分別提供給595即可。
這樣。為了顯示234,把以下數據逐行提供給兩個595
0x00 0x00    // 第0行,,對應000000000000
0x31 0x8C    // 第1行,對應0 0110 0 011 0 0 0110 0
0x4A 0x54    // 第2行 對應0 1001 0 1001 0 1010 0
0x08 0x54    // 第3行 對應0 0001 0 0001 0 1010 0
0x10 0x94    // 第4行 0 0010 0 0010 0 1010 0
0x20 0x5E    // 第5行 0 0100 0 0001 0 1110 0
0x42 0x44    // 第6行 0 1000 0 1001 0 0010 0
0x79 0x84    // 第7行 0 1111 0 0110 0 0010 0
那么,在16*8的點陣LED上現實的就是234數字了。其中第0、5、A、F列是空白列。

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

8#
ID:517466 發表于 2021-1-4 22:20 | 只看該作者
dcjdcj 發表于 2021-1-3 20:32
2個595是16位,每次發8位,如果只顯示2位數字,那好辦,我不明白的是如何把16位原本顯示兩位數字的拆成顯 ...

自己組織點陣數據對應數字,需要預先把每個數字的點陣數據以0和1的方式建立出數組,對4列8行,每個數字張勇一個二維數組,比如對于數字2的點陣數據:
pix[2]={{0,0,0,0},
          {0,1,1,0},
          {1,0,0,1},
          {0,0,0,1},
          {0,0,1,0},
          {0,1,0,0},
          {1,0,0,0},
          {1,1,1,1}
         }
把所有數字弄到一起,組成一個三維數組,方便按照下標定位數字所在元素,組成字節數據。
當需要顯示234時,
先取第一行像素數據,依次把0、pix[2]的第0行像素的四列,0,pix[3]的第0行像素的前兩列,0,共計8Bit位,放到第一個595
再取pix[3]的第0行像素的后兩列,0,pix[4]的第0行像素的四列,0,共計8Bit位,放到第二個595中,
這樣234的第一行就都被設置好了;接著是其他各行的像素數據,也按照這種方式組織并顯示,最終,“234”就被顯示出來了。
回復

使用道具 舉報

9#
ID:517466 發表于 2021-1-4 22:24 | 只看該作者
實際上,pix也可以被定義為一位數組,而一位數組的每個元素是另一個二維數組(對應4 x 8的點陣數據)。這樣處理,可能更容易一些。
回復

使用道具 舉報

10#
ID:517466 發表于 2021-1-4 22:43 | 只看該作者
本帖最后由 suncat0504 于 2021-1-5 18:42 編輯

圖片說明更容易理解,第五行16進制數錯了,是0x20, 0x5E

4x8點陣數字的掃描.jpg (191.17 KB, 下載次數: 81)

4x8點陣數字的掃描.jpg
回復

使用道具 舉報

11#
ID:517466 發表于 2021-1-4 23:20 | 只看該作者
本帖最后由 suncat0504 于 2021-1-4 23:26 編輯

如果不想用點陣模式保存,也可以用字節數據保存,比如
數字2的各行數值 pix[2] = {0, 6,9, 1, 2, 4, 8, 15}
數字3的各行數值 pix[3] = {0  6 , 9, 1, 2, 1, 9, 6 }
數字4的各行數值 pix[4] = {0, 6, 10, 10, 10, 15, 2, 2}
顯示234的時候,第二行的點陣數據:
        第一個595 = (pix[2][1]<<3) | (pix[3][1]>>2) ;    // 6<<3 | 6>>2=49=0x31;
        第一個595 = (pix[3][1]<<6) | (pix[4][1]<<1);; // 6<<6 | 6<<1=140=0x8c
這樣的效果是一樣的。(注意,移位操作,是不帶進位的移位)
回復

使用道具 舉報

12#
ID:566214 發表于 2021-1-5 22:00 | 只看該作者
suncat0504 發表于 2021-1-4 23:20
如果不想用點陣模式保存,也可以用字節數據保存,比如
數字2的各行數值 pix[2] = {0, 6,9, 1, 2, 4, 8, 1 ...

#include<reg52.h>
#include<intrins.h>
#define LED_HX P2
typedef unsigned int u16;        
typedef unsigned char u8;
bit Dis_Flag=0;                                    //掃描時間標志位
u8 DATA1,DATA2;                                //   595數據
u8 Duan_Xuan[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//行掃描
u8 code Num_Table[3][8]=
{
        {0x00,0x0E,0x11,0x11,0x11,0x11,0x11,0x0E},        //     0
        {0x00,0x04,0x0C,0x04,0x04,0x04,0x04,0x0E},        //        1
//        {},        //  2
//        {},        //        3
//        {},        //        4
//        {},        //        5
//        {},        //        6
        {0x00,0x1F,0x01,0x02,0x04,0x04,0x04,0x04},        //        7
//        {},        //        8
//        {},        //        9
};

sbit SRCLK=P1^0;
sbit R_CLK=P1^1;
sbit SER=P1^2;

void Hc595SendByte()
{
        u8 i;
        SER=1;
        SRCLK=0;
        R_CLK=0;
                for(i=0;i<8;i++)
                {
                        SER=DATA1&0x80;
                        DATA1<<=1;
                        SRCLK=1;
                        _nop_();
                        _nop_();
                        SRCLK=0;        
                }

                for(i=0;i<8;i++)
                {
                        SER=DATA2&0x80;
                        DATA2<<=1;
                        SRCLK=1;
                        _nop_();
                        _nop_();
                        SRCLK=0;        
                }

                R_CLK=1;
                _nop_();
                _nop_();
                R_CLK=0;
}

void Duan_Dis()                //顯示
{
        static u8 i=0;
        if(Dis_Flag)
        {
                Dis_Flag=0;
                LED_HX=Duan_Xuan[ i];     
                DATA1=Num_Table[0][ i];
                DATA2=Num_Table[2][ i];
                i++;
                i%=8;
        }
}

void Timer0Init(void)                //100us 22.1184.000MHz
{        
        TMOD &= 0xF0;               
        TMOD |= 0x02;               
        TL0 = 0x48;               
        TH0 = 0x48;               
        TF0 = 0;               
        TR0 = 1;               
        ET0=1;
        EA=1;
}

void main(void)
{
        Timer0Init();
        while(1)                        
        {
                Hc595SendByte();
                Duan_Dis();
        }
}

void Timer_Ser(void) interrupt 1
{
        static u8 i;
        i++;
        if(i>=5)
        {
                i=0;
                Dis_Flag=1;
        }
}


屏幕截圖 2021-01-05 195407.png (59.34 KB, 下載次數: 82)

屏幕截圖 2021-01-05 195407.png
回復

使用道具 舉報

13#
ID:566214 發表于 2021-1-5 22:12 | 只看該作者
suncat0504 發表于 2021-1-4 23:20
如果不想用點陣模式保存,也可以用字節數據保存,比如
數字2的各行數值 pix[2] = {0, 6,9, 1, 2, 4, 8, 1 ...

比如5*7的字體,16列可顯示3個數字,這3個數字用變量去控制其顯示的內容
回復

使用道具 舉報

14#
ID:517466 發表于 2021-1-6 10:06 | 只看該作者
dcjdcj 發表于 2021-1-5 22:12
比如5*7的字體,16列可顯示3個數字,這3個數字用變量去控制其顯示的內容

是啊,你想要的這個變量,不就是數組pix的以為元素的下標嗎?
變量num1=2; 那么pix[num1]不就是pix[2]嗎?編程要靈活一些。
回復

使用道具 舉報

15#
ID:566214 發表于 2021-1-6 22:18 | 只看該作者
suncat0504 發表于 2021-1-6 10:06
是啊,你想要的這個變量,不就是數組pix的以為元素的下標嗎?
變量num1=2; 那么pix[num1]不就是pix[2]嗎 ...

看了一些教程,說是可以開一個16字節緩存,再映射到每一列上,但是我這個是發一個字節是橫向排列的,不改電路的情況下可以實現一列一列的掃描嗎?如果這樣,就可以控制每一列顯示的內容了,就可以顯示任意的內容了
回復

使用道具 舉報

16#
ID:566214 發表于 2021-1-6 23:57 | 只看該作者
suncat0504 發表于 2021-1-4 23:20
如果不想用點陣模式保存,也可以用字節數據保存,比如
數字2的各行數值 pix[2] = {0, 6,9, 1, 2, 4, 8, 1 ...

非常感謝您的耐心解答,這樣是可以一個595顯示兩個字了,但是不能把1號595的數據移到2號上面,不能實現自由顯示的目的

  1. u8 code Table1[10][8]=
  2. {
  3.         {0,6,9,9,9,9,9,6},                //0
  4.         {0,2,6,2,2,2,2,7},                //1        
  5.         {0,6,9,1,2,4,8,15},                //2
  6.         {0,6,9,1,6,1,9,6},                //3
  7.         {0,2,6,10,10,15,2,2},        //4
  8.         {0,15,8,14,1,1,9,6},        //5
  9.         {0,6,9,8,14,9,9,6},                //6
  10.         {0,15,9,1,2,2,4,4},                //7
  11.         {0,6,9,9,6,9,9,6},                //8
  12.         {0,6,9,9,7,1,2,4},                //9
  13. };
  14. void Duan_Dis()                //ÏÔê¾
  15. {
  16.         static u8 i=0;
  17.         if(Dis_Flag)
  18.         {
  19.                 Dis_Flag=0;
  20.                 LED_HX=Duan_Xuan[i];     
  21.                 DATA1=Table1[5][i]<<4|Table1[2][i];
  22.                 DATA2=Table1[9][i]<<4|Table1[0][i];
  23.                 i++;
  24.                 i%=8;
  25.         }
  26. }
復制代碼
回復

使用道具 舉報

17#
ID:517466 發表于 2021-1-7 14:40 | 只看該作者
dcjdcj 發表于 2021-1-6 23:57
非常感謝您的耐心解答,這樣是可以一個595顯示兩個字了,但是不能把1號595的數據移到2號上面,不能實現自 ...

顯示原理通了,下一步就是怎么用程序用合理的邏輯實現的問題了,對嗎?這不就是程序員要做到的事情嗎?
回復

使用道具 舉報

18#
ID:566214 發表于 2021-1-7 18:44 | 只看該作者
suncat0504 發表于 2021-1-7 14:40
顯示原理通了,下一步就是怎么用程序用合理的邏輯實現的問題了,對嗎?這不就是程序員要做到的事情嗎?

唉,剛入坑小白一枚,理論經驗都不足
回復

使用道具 舉報

19#
ID:517466 發表于 2021-1-7 20:23 | 只看該作者
dcjdcj 發表于 2021-1-7 18:44
唉,剛入坑小白一枚,理論經驗都不足

這是我剛剛測試過的程序,已經用proteus模擬過了。你可以試試。

595顯示數字.zip

66.68 KB, 下載次數: 11

2個595顯示3位數字

回復

使用道具 舉報

20#
ID:517466 發表于 2021-1-7 20:41 | 只看該作者
dcjdcj 發表于 2021-1-7 18:44
唉,剛入坑小白一枚,理論經驗都不足

程序稍加改動,就可以變成驅動四位數字的。// 保存四位數字的數組變量
u8 v[4]={2,3,4,5};


void getValue(void) {
        v[0]=val/1000;
        v[1]=(val%1000)/100;
        v[2]=(val%100)/10;
    v[3]=val%10;
}

void main() {
    // 初始化595控制管腳
        DATA=0;
        CLK=0;
        LOCK=0;
        getValue(); // 獲得顯示數值
        while(1) {
                // 按鍵按下,累加數據
                if (Key==0) {
                        delayms(5); // 防抖
                        if (Key==0) {
                            while(Key==0); // 等待按鍵松開
                                val++; // 累加1
                                getValue(); // 獲得顯示數值
                        }
                }
                disp();
        }
}


disp函數中,計算行顯示數據的地方:
        // 循環行
        for (row=0; row<8; row++) {
                // 根據顯示數值,計算每行的點陣數據。一行兩個字節,16Bit位對應16列
                // col_data[row][0]對應第一個595,col_data[row][1]對應第二個595.
                // 因為是級聯,所以從col_data[row][1]到col_data[row][0],從Bit0到Bit7串行輸出
                //col_data[row][0]=(Table[v[0]][row]<<3) | (Table[v[1]][row]>>2);
                //col_data[row][1]=(Table[v[1]][row]<<6) | (Table[v[2]][row]<<1);
                col_data[row][0]=(Table[v[0]][row]<<4) | (Table[v[1]][row]);
                col_data[row][1]=(Table[v[2]][row]<<4) | (Table[v[3]][row]);
        }

編譯、執行proteus模擬后,就會看到顯示結果。每按動一次按鈕,顯示數據+1.
回復

使用道具 舉報

21#
ID:517466 發表于 2021-1-7 20:45 | 只看該作者
把顯示延時3毫秒改成1毫秒,proteus顯示更穩定,不閃爍。

截圖.jpg (330.89 KB, 下載次數: 86)

proteus模擬的截圖

proteus模擬的截圖
回復

使用道具 舉報

22#
ID:566214 發表于 2021-1-7 21:49 | 只看該作者
suncat0504 發表于 2021-1-7 20:41
程序稍加改動,就可以變成驅動四位數字的。// 保存四位數字的數組變量
u8 v[4]={2,3,4,5};

顯示4位數字的已經實現了,但是太緊湊了,顯示3位的問題是:如何將1號595的數據移一點在2號595上,這樣就可以顯示3位了,還可以每位數字之間間隔一列空的,但只能右移4次,超過的就移出去了,預想的是移到2號595上

屏幕截圖 2021-01-07 213236.png (21.47 KB, 下載次數: 78)

屏幕截圖 2021-01-07 213236.png
回復

使用道具 舉報

23#
ID:566214 發表于 2021-1-7 22:14 | 只看該作者
suncat0504 發表于 2021-1-7 20:41
程序稍加改動,就可以變成驅動四位數字的。// 保存四位數字的數組變量
u8 v[4]={2,3,4,5};

3位的我也懂了,非常謝謝你,還想請教一個問題:就有源蜂鳴器怎么實現檢查到按鍵按下響,長按就一直響直到松手為止,這個問題也困擾了我好久,網上也沒有找到解決的方法,有一個多月了,現在也沒有想出怎么驅動,難道是我不適合這條路嗎
回復

使用道具 舉報

24#
ID:517466 發表于 2021-1-8 09:03 | 只看該作者
dcjdcj 發表于 2021-1-7 22:14
3位的我也懂了,非常謝謝你,還想請教一個問題:就有源蜂鳴器怎么實現檢查到按鍵按下響,長按就一直響直 ...

你下載的程序里,在主函數中不是有按鍵的監察處理嗎?從按下到松開的整個過程,都有代碼。你只要在防抖動檢查的Key==0的判斷之后,開啟聲音;在確認松開之后(while(Key==0);)架上停止聲音的代碼不就可以了嗎?
if  (Key==0) {      // 檢查按鍵是否按下
    delayms(20);    // 防抖的延時,防止因為異常干擾引起的誤觸發動作
    if  (Key==0) {  // 在防抖之后,再次確認按鍵是否真的被按下
        打開聲音();         // 按鍵被按下,開始播放聲音
        while(Kewy==0); // 直到按鍵松開后,才執行“關閉聲音();”開始處的代碼
        關閉聲音();         // 按鍵已經被松開,停止i播放聲音
        ...                      // 按鍵被按下后,執行對應的處理機能
    }
}
回復

使用道具 舉報

25#
ID:566214 發表于 2021-1-8 19:01 | 只看該作者
suncat0504 發表于 2021-1-8 09:03
你下載的程序里,在主函數中不是有按鍵的監察處理嗎?從按下到松開的整個過程,都有代碼。你只要在防抖動 ...

我學的按鍵檢測是用狀態機的方式實現的,網上說判斷按鍵按下后,給一個標志位,蜂鳴器用npn管驅動,給高就響,低就不響,又不能像LED燈一樣io口取反,給了1以后,多久給0,還是在按鍵松手后也給個標志位?
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 草久久| 国产精品二区三区 | 日韩精品一区二区三区视频播放 | 国产精品a久久久久 | 午夜免费在线观看 | 精品99久久久久久 | 激情欧美日韩一区二区 | 成人精品一区二区 | 91亚洲精品国偷拍自产在线观看 | 欧美a v在线 | 亚洲婷婷一区 | 在线观看国产精品视频 | 久热国产精品视频 | 岛国av免费观看 | 国产综合精品 | 欧美国产91 | 日韩久久久久 | 欧美久久视频 | 欧美老妇交乱视频 | 国产大片一区 | 在线播放国产一区二区三区 | 中文字幕亚洲一区 | 精品免费视频一区二区 | 亚洲一区 中文字幕 | 免费视频一区 | 麻豆va | 免费一看一级毛片 | 久草视频网站 | 国内毛片毛片毛片毛片 | 午夜影院 | 成人在线国产 | 成人免费淫片aa视频免费 | 国产精品1区2区3区 国产在线观看一区 | 日韩中文字幕一区 | 国产女人与拘做受免费视频 | 91视频大全| 国产精品国产精品国产专区不卡 | 欧美激情综合色综合啪啪五月 | 日韩一区二区成人 | 国产精品一区二区三区久久 | 国产精彩视频 |