熱門: 51單片機(jī) | 24小時(shí)必答區(qū) | 單片機(jī)教程 | 單片機(jī)DIY制作 | STM32 | Cortex M3 | 模數(shù)電子 | 電子DIY制作 | 音響/功放 | 拆機(jī)樂園 | Arduino | 嵌入式OS | 程序設(shè)計(jì)
![]() |
發(fā)布時(shí)間: 2023-5-2 03:36
正文摘要:代碼如下: #include "reg51.h" #include "intrins.h" typedef unsigned int u16; typ ... |
void Hc595(u8 dat0,dat1,dat2) 這個(gè)函數(shù)可以優(yōu)化一下。一個(gè)發(fā)送8bit的函數(shù)調(diào)用3次就可以了,沒必要發(fā)3個(gè)字節(jié)就直接寫了3次的8bit發(fā)送發(fā)代碼。 595的10腳可以直接接VDD,沒必要接開關(guān)來復(fù)位。無非就是在第一次發(fā)真正數(shù)據(jù)前,先發(fā)送3個(gè)空的數(shù)據(jù)。 |
把void hc595(u8 dat0,dat1,dat2)改成void hc595(u8 dat0,u8 dat1,u8 dat2) 傳數(shù)據(jù) 延時(shí)改成_nop_() |
嘻嘻哈哈東 發(fā)表于 2023-5-2 21:45 抱歉,看錯(cuò)了,下面是我的做法,參考一下 void HC595_SEND_DATA(void) { u8 i, j, row_value; // HC595_OUTPUT_ENABLE = 1; HC595_STORAGE_CLOCK = 0; HC595_SHIFT_CLOCK = 0; for(j=0; j<8; j++) { row_value = ~row_data[j]; for(i=0;i<8;i++) { if(row_value & 0X80) HC595_SERIAL_DATA = 1; //ROW_HC595_SERIAL_DATA_ON(); else HC595_SERIAL_DATA = 0; //ROW_HC595_SERIAL_DATA_OFF(); row_value = row_value << 1; HC595_SHIFT_CLOCK = 1; HC595_SHIFT_CLOCK = 0; } } HC595_STORAGE_CLOCK = 1; HC595_STORAGE_CLOCK = 0; HC595_OUTPUT_ENABLE = 0; } 兩個(gè)時(shí)鐘引腳的操作我和你的不同 |
感覺接線有點(diǎn)問題呀,改成這樣試試。
![]() 參考下這個(gè)級(jí)聯(lián)驅(qū)動(dòng)程序: void HC595_Master_COM1_WR_NByte(uint8_t Len, uint8_t *GPIOValue) { uint8_t i=0,Byte=0; HC595_Master_COM1_STCP_RESET(); while(Len--) { Byte=*GPIOValue; for(i=0;i<8;i++) { HC595_Master_COM1_SHCP_RESET(); if(Byte & 0x80) { HC595_Master_COM1_DS_SET(); } else { HC595_Master_COM1_DS_RESET(); } HC595_Master_COM1_SHCP_SET(); Byte <<= 1; } GPIOValue++; } HC595_Master_COM1_STCP_SET(); } |
嘻嘻哈哈東 發(fā)表于 2023-5-2 12:16 雖然也可以一次性寫3個(gè)循環(huán)語(yǔ)句,不過我喜歡簡(jiǎn)潔,通常把重復(fù)代碼寫為一個(gè),包括數(shù)碼管驅(qū)動(dòng),其他芯片驅(qū)動(dòng)都提煉為模塊。 |
嘻嘻哈哈東 發(fā)表于 2023-5-2 12:16 OE低電平時(shí),移位后的信號(hào)從Q0-Q7八個(gè)腳并行輸出,同時(shí)這八個(gè)腳上的信號(hào)也以串行的方式從Q7S腳依次輸出。該腳輸出的信號(hào)可作為下一個(gè)595的輸入信號(hào),理論上講,可實(shí)現(xiàn)無限級(jí)聯(lián)。 |
coody_sz 發(fā)表于 2023-5-2 14:29 是的啊,你可以仔細(xì)看一下我發(fā)出來的仿真圖,就是級(jí)聯(lián)的方式啊 |
人中狼 發(fā)表于 2023-5-2 15:26 你好,我在protues仿真里用的就是級(jí)聯(lián)方式呀,第一片595的9號(hào)腳連接到第二片的14號(hào)腳(DS),以此類推。 |
謝謝您,我回去學(xué)習(xí)一下 |
樓主對(duì)595的理解有錯(cuò)誤,按樓主的做法應(yīng)該只有最后一個(gè)發(fā)送數(shù)據(jù)的595是正確的,其他兩個(gè)都是不定的,595要用級(jí)聯(lián)的方法 |
![]() |
樓主你的用法不建議,我們都是串聯(lián)在一起的,DATA覺第一片14腳(DS),9腳接下一片的14腳,一直級(jí)聯(lián)下去,最經(jīng)典的就是LED點(diǎn)陣屏,一般一個(gè)單元屏(32*16)有8片595串聯(lián)(或者分2組,每組4片串聯(lián))。 |
xianfajushi 發(fā)表于 2023-5-2 10:03 #include "reg51.h" #include "intrins.h" typedef unsigned int u16; typedef unsigned char u8; sbit sRCLK=P3^6; sbit rCLK=P3^5; sbit sER=P3^4; void delay_10us(u16 ten_us) { while(ten_us--); } void delay_ms(u16 ms) { u16 i,j; for(i=ms;i>0;i--) for(j=110;j>0;j--); } void Hc595(u8 dat) { u8 a; for(a=0;a<8;a++) { sER = dat >> 7; dat <<= 1; sRCLK = 0; delay_10us(1); sRCLK = 1; delay_10us(1); } rCLK = 0; delay_10us(1); rCLK = 1; delay_10us(1); } void main() { while(1) { Hc595(0); Hc595(0x0f); Hc595(0xff); Hc595(0xfe); delay_ms(500); Hc595(0); Hc595(0x00); Hc595(0xdb); Hc595(0x6d); delay_ms(500); } } 前輩你好,我把代碼改成您帖子這樣單次發(fā)送的就可以顯示我想要的效果了,但是我還是不理解,為什么不能一次性將數(shù)據(jù)傳到3片級(jí)聯(lián)的595中,它的級(jí)聯(lián)原理不是將新輸入的數(shù)據(jù)代替舊輸入數(shù)據(jù)的595嗎?將舊數(shù)據(jù)向前推送,單次發(fā)送的原理和一起發(fā)送的原理似乎是一樣的吧?但是一次性發(fā)送中間那片595就是亂嗎了 ![]() |
xianfajushi 發(fā)表于 2023-5-2 10:03 void main() { while(1) { Hc595(0,0,0); Hc595(0x6d,0x00,0x00); Hc595(0x00,0xdb,0x00); Hc595(0x00,0x00,0x00); delay_ms(500); } } 前輩你好,是這樣分成3次發(fā)送嗎?但是仿真的效果還是一樣,我看protues的仿真電路的各個(gè)IO電平時(shí)發(fā)現(xiàn),只有第一片的595是符合我的數(shù)據(jù)輸入,剩下兩片的數(shù)據(jù)是亂的, |
看我帖子的辦法是發(fā)送1個(gè)芯片數(shù)據(jù),3個(gè)級(jí)聯(lián)的話分3次發(fā)送。 |
Powered by 單片機(jī)教程網(wǎng)