void Hc595(u8 dat0,dat1,dat2) 这个函数可以优化一下。一个发送8bit的函数调用3次就可以了,没必要发3个字节就直接写了3次的8bit发送发代码。 595的10脚可以直接接VDD,没必要接开关来复位。无非就是在第一次发真正数据前,先发送3个空的数据。 |
把void hc595(u8 dat0,dat1,dat2)改成void hc595(u8 dat0,u8 dat1,u8 dat2) 传数据 延时改成_nop_() |
嘻嘻哈哈东 发表于 2023-5-2 21:45 抱歉,看错了,下面是我的做法,参考一下 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; } 两个时钟引脚的操作我和你的不同 |
感觉接线有点问题呀,改成这样试试。
![]() 参考下这个级联驱动程序: 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(); } |
嘻嘻哈哈东 发表于 2023-5-2 12:16 虽然也可以一次性写3个循环语句,不过我喜欢简洁,通常把重复代码写为一个,包括数码管驱动,其他芯片驱动都提炼为模块。 |
嘻嘻哈哈东 发表于 2023-5-2 12:16 OE低电平时,移位后的信号从Q0-Q7八个脚并行输出,同时这八个脚上的信号也以串行的方式从Q7S脚依次输出。该脚输出的信号可作为下一个595的输入信号,理论上讲,可实现无限级联。 |
coody_sz 发表于 2023-5-2 14:29 是的啊,你可以仔细看一下我发出来的仿真图,就是级联的方式啊 |
人中狼 发表于 2023-5-2 15:26 你好,我在protues仿真里用的就是级联方式呀,第一片595的9号脚连接到第二片的14号脚(DS),以此类推。 |
谢谢您,我回去学习一下 |
楼主对595的理解有错误,按楼主的做法应该只有最后一个发送数据的595是正确的,其他两个都是不定的,595要用级联的方法 |
![]() |
楼主你的用法不建议,我们都是串联在一起的,DATA觉第一片14脚(DS),9脚接下一片的14脚,一直级联下去,最经典的就是LED点阵屏,一般一个单元屏(32*16)有8片595串联(或者分2组,每组4片串联)。 |
xianfajushi 发表于 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); } } 前辈你好,我把代码改成您帖子这样单次发送的就可以显示我想要的效果了,但是我还是不理解,为什么不能一次性将数据传到3片级联的595中,它的级联原理不是将新输入的数据代替旧输入数据的595吗?将旧数据向前推送,单次发送的原理和一起发送的原理似乎是一样的吧?但是一次性发送中间那片595就是乱吗了 ![]() |
xianfajushi 发表于 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次发送吗?但是仿真的效果还是一样,我看protues的仿真电路的各个IO电平时发现,只有第一片的595是符合我的数据输入,剩下两片的数据是乱的, |
看我帖子的办法是发送1个芯片数据,3个级联的话分3次发送。 |