当前位置:   article > 正文

arduino(esp8266)驱动74hc595进行流水灯异常一例_arduino esp8266 驱动 74hc595

arduino esp8266 驱动 74hc595

这两天重新来玩74HC595,因为前一段时间为了点亮led 像素屏用了查理复用,但是查理复用的GPIO占用实在太高,而且接线其实也非常不方便;因此打算重新用74HC595来点灯,毕竟595的价格喜人啊。

之前一直不愿意用595的原因是它的文档实在看起来头疼的很,什么sclk,rclk,sclr,stcp ,shcp,ds,si 等等,同样是595 芯片,不同文档介绍的时候,pin的名称是两套,不论是那一套都让人容易晕头转向。

同时为了更深入理解595的运行机制,加上前端时间用了tm1637,学习了异或和对应的二进制转换,所以打算手工来驱动595 ,不使用shiftout函数。

布线如下:

代码如下:

  1. int latchPin = D8; //Pin connected to ST_CP(pin 12) of 74HC595 //ST
  2. int clockPin = D6; //Pin connected to SH_CP(pin 11) of 74HC595 //这个pin居然可以没有 SH
  3. int dataPin = D7; //Pin connected to DS(pin 14) of 74HC595
  4. int r = 8;
  5. unsigned char sequence[8] = {B00000001, B00000010, B00000100, B00001000, B00010000, B00100000, B01000000, B10000000,};
  6. void setup() {
  7. Serial.begin(115200);
  8. pinMode(latchPin, OUTPUT);
  9. pinMode(clockPin, OUTPUT);
  10. pinMode(dataPin, OUTPUT);
  11. }
  12. uint8_t cur = 0;
  13. void loop() {
  14. for (int a = 0; a < 8; a++) {
  15. cur = sequence[a];
  16. digitalWrite(latchPin, LOW);
  17. for (int c = 0; c < 8; c++) {
  18. digitalWrite(clockPin, LOW);
  19. if (cur & 0x01)digitalWrite(dataPin, HIGH);
  20. else digitalWrite(dataPin, LOW);
  21. digitalWrite(clockPin, HIGH);
  22. cur >>= 1;
  23. }
  24. digitalWrite(latchPin, HIGH);
  25. delay(800);
  26. }
  27. delay(2000);
  28. }

这样的代码就是从8->1输出流水灯,结果8->2都运行起来正常,但是2->1的时候出了问题,本来应该是2灭1亮,结果2和1 一期亮了,如下图:

 代码问题找了无数遍找不出原因,各种测试和尝试,找不出原因。

按照595的手册:

1、SI(DS)输入数据;

2、CLK(SHCP)上升沿,输入数据到移位寄存器;

3、重复上面过程到数据输入结v束;

4、RCLK(STCP) 上升沿,移入数据到锁存器并行输出Q0-Q8并行输出;

所以上面的代码是没有错的,网上搜到过由于电压不对,导致输出不对的情况,595 的电压是5V,SI(DS)的电压是3.3V这种情况导致输出不对,于是就试了一下,结果在3.3V 的情况下,8->1确实输出正常。

由于3.3V 下,LED不够亮,重新回到了5V折腾,于是开始怀疑是不是各种接线不对,于是把MR接到了GND,之前没有接,如下图

这次调整后,MR接了GND, 5.5V下8-1输出正常,这其实已经是最标准的做法,因为之前没有接MR.

然而这件事并没有完,后来在MR没有接入GND的情况下,为了对比一下效果,使用了shiftout函数,发觉MR没有接入GND,同样意图8->1输出,我自己的代码2->1 同时亮,而shiftout函数又是完全正常的,代码如下:

  1. int latchPin = D8; //Pin connected to ST_CP(pin 12) of 74HC595 //ST
  2. int clockPin = D6; //Pin connected to SH_CP(pin 11) of 74HC595 //这个pin居然可以没有 SH
  3. int dataPin = D7; //Pin connected to DS(pin 14) of 74HC595
  4. int r = 8;
  5. unsigned char sequence[8] = {B00000001, B00000010, B00000100, B00001000, B00010000, B00100000, B01000000, B10000000,};
  6. void setup() {
  7. Serial.begin(115200);
  8. pinMode(latchPin, OUTPUT);
  9. pinMode(clockPin, OUTPUT);
  10. pinMode(dataPin, OUTPUT);
  11. }
  12. uint8_t cur = 0;
  13. void loop() {
  14. for (int a = 0; a < 8; a++) {
  15. cur = sequence[a];
  16. digitalWrite(latchPin, LOW);
  17. for (int c = 0; c < 8; c++) {
  18. digitalWrite(clockPin, LOW);
  19. if (cur & 0x01)digitalWrite(dataPin, HIGH);
  20. else digitalWrite(dataPin, LOW);
  21. digitalWrite(clockPin, HIGH);
  22. cur >>= 1;
  23. }
  24. digitalWrite(latchPin, HIGH);
  25. delay(800);
  26. }
  27. for (int m = r - 1; m >= 0; m--) {
  28. digitalWrite(latchPin, LOW);
  29. shiftOut(dataPin, clockPin, MSBFIRST, sequence[m]);
  30. digitalWrite(latchPin, HIGH); delay(800);
  31. }
  32. delay(2000);
  33. }

视频对比如下:

WeChat_20221108223820

于是又各种找原因,怀疑是不是各种上升沿出了问题,各种怀疑,各种调试,反正就是觉得奇怪:

1、在MR接入GND的情况下,都正常;

2、在MR没有GND的情况下,3.3V电压 一切正常;5V电压,为啥shiftout函数亮灯正常,而我自己的函数亮灯前面正常,最后两位出了问题,如果说我的代码有问题,那么为啥有的情况下工作正常,有的不正常?

一直到最后实在不行,祭出了终极大法,查看shiftout的源代码:

  1. void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val) {
  2. uint8_t i;
  3. for(i = 0; i < 8; i++) {
  4. if(bitOrder == LSBFIRST)
  5. digitalWrite(dataPin, !!(val & (1 << i)));
  6. else
  7. digitalWrite(dataPin, !!(val & (1 << (7 - i))));
  8. digitalWrite(clockPin, HIGH);
  9. digitalWrite(clockPin, LOW);
  10. }
  11. }

这一下就对比出来了,shiftout对于时钟线的上升沿用的是:

  1. digitalWrite(clockPin, HIGH);
  2. digitalWrite(clockPin, LOW);

而我自己用的是:

  1. digitalWrite(clockPin, LOW);
  2. digitalWrite(clockPin, HIGH);

当把代码重新修改后,在MR不接GND的情况下,5V电压,从8->1 shiftout和我自己的代码都工作正常。

在网上其他人的代码也是同我最初的情况一样:

 应该说很多人都是这么写的,先low后high.

一般情况下,MR接入GND,这段代码都会工作正常,但是我上面的经历说明了某些情况下如果不按照shiftout所示的先high后low,会存在难以找到原因的异常,包括网上流传的5V电压74HC595不稳定要用到3.3V电压的谣传大概也是因为这个原因。

不过最后还是没有搞明白为啥是先high后low,而不是先low和high呢?

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/211509
推荐阅读
相关标签
  

闽ICP备14008679号