PIC16F1789的C语言For循环迭代器无法正常递增问题求助
迭代器在PIC16F1789的For循环中无法递增,停留在001的问题解决
问题描述
我在PIC16F1789上写了一段C语言代码,想用For循环把迭代器的值输出到16x2 LCD屏幕上。现在代码运行时,先显示“000”,等待500毫秒后显示“001”,之后就一直重复显示“001”——不过RB0引脚的LED是正常闪烁的,说明延迟和IO翻转是正常的,但迭代器i不再继续递增了。我换了另一款PIC芯片测试,问题还是一样。请问怎么解决这个迭代器无法正常递增的问题?
代码如下:
void main(void) { init(); LCD_init(); for(uint8_t i = 0; i <= 255; i++) { char str[3]; sprintf(str, "%03u", i); LCD_cmd(LCD_CLEAR); LCD_string(str); LATB ^= 0x01; __delay_ms(500); } }
问题根源分析
你的代码里有两个关键问题,第一个直接导致了迭代器停在1的现象:
- 数组越界破坏栈内存:你定义的
char str[3]只能容纳3个字符,但sprintf(str, "%03u", i)生成的是4个字节——比如"000"这样的3位数字,再加上C字符串必须的结束符\0。这个越界写入会覆盖栈上相邻的变量,而你的迭代器i正好在栈上,当i=1时,越界的\0把i的值重置成了0,导致循环一直在0→1→0→1的死循环里打转,自然不会继续递增到2及以上。 - 无符号8位整数的循环边界陷阱:
uint8_t是无符号8位类型,最大值是255,当i等于255时执行i++,会溢出变成0,此时i <=255永远为真,循环会变成无限循环——不过这个问题在当前场景里还没暴露,因为第一个问题先触发了。
修复方案
1. 核心修复:修正数组长度
这是解决当前i停止递增的关键,给字符串结束符留足空间:
void main(void) { init(); LCD_init(); for(uint8_t i = 0; i <= 255; i++) { char str[4]; // 改为4个字节,容纳3位数字+结束符 sprintf(str, "%03u", i); LCD_cmd(LCD_CLEAR); LCD_string(str); LATB ^= 0x01; __delay_ms(500); } }
2. 优化循环边界(可选但推荐)
为了避免uint8_t溢出导致的无限循环,你可以二选一:
- 改用
uint16_t类型作为迭代器,扩大范围:for(uint16_t i = 0; i <= 255; i++) { char str[4]; sprintf(str, "%03u", i); // 其余代码不变 } - 保持
uint8_t,调整循环条件为i < 255:for(uint8_t i = 0; i < 255; i++) { // 其余代码不变 }
3. 额外优化:减少屏幕闪烁(可选)
频繁调用LCD_CLEAR会让屏幕频繁闪烁,你可以定位到固定位置后再输出字符串,替代清屏操作:
void main(void) { init(); LCD_init(); LCD_cmd(LCD_CLEAR); // 只初始化清屏一次 for(uint16_t i = 0; i <= 255; i++) { char str[4]; sprintf(str, "%03u", i); LCD_gotoxy(1, 1); // 定位到第一行第一列 LCD_string(str); LATB ^= 0x01; __delay_ms(500); } }
内容的提问来源于stack exchange,提问作者Stonks3141
相关产品推荐
相关产品推荐

