Arduino Uno驱动5个SN74HC595N移位寄存器33位LED输出异常排查
5个SN74HC595N移位寄存器控制LED异常排查
核心问题
你的代码存在两个致命错误,直接导致第16项之后出现异常:
- 数据类型溢出:Arduino Uno的
int是16位(仅能存储0~65535的无符号值),但你的33位二进制数远超这个范围。前15项的数值(2⁰到2¹⁴)还在16位范围内,所以能正常工作;从第16项(2¹⁵)开始,数值超出16位,int无法容纳,数据被截断,出现乱码甚至触发系统重启。 - 移位操作无效:用16位的
int执行>>32移位,结果直接为0,完全无法正确传输高位数据,导致后续寄存器的输出混乱。
修正方案
- 将存储LED数据的数组类型改为
unsigned long long(64位无符号整数),足以容纳33位数据; - 保持5次
shiftOut的调用顺序(对应5个寄存器),确保高位数据先传输; - 移除冗余的全局变量
arrayplace,直接使用循环内的局部变量。
修正后的代码
const int latchpin = 10; const int clockpin = 11; const int datapin = 12; // 使用unsigned long long存储33位数据,末尾加ULL后缀明确类型 unsigned long long ledarray[] = { 0b000000000000000000000000000000001ULL, 0b000000000000000000000000000000010ULL, 0b000000000000000000000000000000100ULL, 0b000000000000000000000000000001000ULL, 0b000000000000000000000000000010000ULL, 0b000000000000000000000000000100000ULL, 0b000000000000000000000000001000000ULL, 0b000000000000000000000000010000000ULL, 0b000000000000000000000000100000000ULL, 0b000000000000000000000001000000000ULL, 0b000000000000000000000010000000000ULL, 0b000000000000000000000100000000000ULL, 0b000000000000000000001000000000000ULL, 0b000000000000000000010000000000000ULL, 0b000000000000000000100000000000000ULL, 0b000000000000000001000000000000000ULL, 0b000000000000000010000000000000000ULL, 0b000000000000000100000000000000000ULL, 0b000000000000001000000000000000000ULL, 0b000000000000010000000000000000000ULL, 0b000000000000100000000000000000000ULL, 0b000000000001000000000000000000000ULL, 0b000000000010000000000000000000000ULL, 0b000000000100000000000000000000000ULL, 0b000000001000000000000000000000000ULL, 0b000000010000000000000000000000000ULL, 0b000000100000000000000000000000000ULL, 0b000001000000000000000000000000000ULL, 0b000010000000000000000000000000000ULL, 0b000100000000000000000000000000000ULL, 0b001000000000000000000000000000000ULL, 0b010000000000000000000000000000000ULL, 0b100000000000000000000000000000000ULL, }; int arraysize = sizeof(ledarray)/sizeof(ledarray[0]); void setup() { pinMode(latchpin, OUTPUT); pinMode(clockpin, OUTPUT); pinMode(datapin, OUTPUT); } void loop() { for (int arrayplace = 0; arrayplace < arraysize; arrayplace ++){ digitalWrite(latchpin, LOW); // 依次发送5个寄存器的8位数据,从最高位到最低位,强制转byte确保只发8位 shiftOut(datapin, clockpin, MSBFIRST, (byte)(ledarray[arrayplace] >> 32)); shiftOut(datapin, clockpin, MSBFIRST, (byte)(ledarray[arrayplace] >> 24)); shiftOut(datapin, clockpin, MSBFIRST, (byte)(ledarray[arrayplace] >> 16)); shiftOut(datapin, clockpin, MSBFIRST, (byte)(ledarray[arrayplace] >> 8)); shiftOut(datapin, clockpin, MSBFIRST, (byte)(ledarray[arrayplace])); digitalWrite(latchpin, HIGH); delay(100); } }
额外说明
- 二进制数末尾加
ULL后缀,明确告知编译器这是unsigned long long类型; - 移位后强制转换为
byte,确保每次shiftOut只发送8位数据; - 5个SN74HC595N级联时,数据从第一个寄存器的串行输入脚进入,最终依次传递到所有寄存器,因此发送顺序必须从最高位(对应最后一个寄存器的输出)开始,保证数据位置正确。
内容的提问来源于stack exchange,提问作者Peter Sikkens
相关产品推荐
相关产品推荐

