本帖最后由 rclong 于 2018-7-13 09:00 编辑  
 
问题:数组越界,如3楼所说 
解决方法:将数组SMG[7]定义为SMG[8]. 
感谢诸位. 
==================================================== 
最近买了块TM1638方案的数码管+矩阵键盘,写了写代码准备搞和C51联调的培训. 
结果在keil C51 uv5里遇到一个怪问题. 
代码功能很简单,就是在数码管上显示0~99999999. 
把这个整数存在变量number里,一开始用unsigned int型,OK没问题,到65535溢出归0, 
改成unsigned long之后,编译也没有错误也没有警告,但是烧进去数码管就始终黑屏. 
百思不得其解,还得请各位多多指点. 
 
- //part04.以下是数码管显示,主要是尝试动态刷新数码管.
 
 - //存在问题:number为unsigned long 型数据时代码不工作,调试后发现void number_display(unsigned int number)这一函数不工作,具体原因未知.2018年7月11日 15:04:36
 
  
 
- #include <reg52.h>
 
  
- //变量与表
 
 - unsigned char code tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x40,0xef,0x00};//共阴极数码管译码表.[18]为全熄灭.
 
 - unsigned int number; //数字
 
 - unsigned int timer_counter;        //时间计数标记.
 
  
- //引脚定义
 
 - sbit        DIO=P2^0;
 
 - sbit        CLK=P2^1;
 
 - sbit        STB=P2^2;
 
  
- //函数声明
 
 - void number_add(void);
 
 - void number_display(unsigned int number);
 
 - void led_segment_display(unsigned char ddata0,unsigned char ddata1,unsigned char ddata2,unsigned char ddata3,unsigned char ddata4,unsigned char ddata5,unsigned char ddata6,unsigned char ddata7);
 
 - void Write_COM(unsigned char cmd);
 
 - void TM1638_Write(unsigned char        DATA);
 
  
- //主函数
 
 - void main(){
 
 -         number = 0;
 
 -         while(1){        
 
 -                 number_add();
 
 -                 number_display(number);
 
 -         }
 
 - }
 
  
- void number_add(void){
 
 -         timer_counter = timer_counter + 1;        //通过引入timer_counter避免使用delay,从而对数码管动态扫描不构成影响.
 
 -         if(timer_counter >= 50){         //调整该常量值可以调整number自加的速度.
 
 -                 number = number + 199;
 
 -                 if(number > 99999999)
 
 -                         number = 0;
 
 -                 timer_counter = 0;
 
 -         }
 
 -         else
 
 -                 timer_counter = timer_counter + 1;
 
 -         //P1 = 0xf0;
 
 - }
 
  
- void number_display(unsigned int number)
 
 - {
 
 -         unsigned int temp_number;
 
 -         unsigned char SMG[7],i;
 
 -         char j;
 
 -         unsigned int lowest_digit;        //最低位
 
 -         temp_number = number; //整数拆分成各位
 
 -         for(i=0;i<8;i++){
 
 -                 lowest_digit = temp_number%10;//从低位往高位取
 
 -                 temp_number = temp_number/10;
 
 -                 SMG[i] = lowest_digit;
 
 -         }
 
 -         for(j=7;j>-1;j--){
 
 -                 if(SMG[j]==0){
 
 -                         SMG[j] = 18;
 
 -                 }//从高位往低位看,高位为0的就赋18,只到第一个不为零的数出现.
 
 -                 else 
 
 -                         j = -1;
 
 -         }
 
 -         led_segment_display(SMG[7],SMG[6],SMG[5],SMG[4],SMG[3],SMG[2],SMG[1],SMG[0]);
 
 -         //P1 = 0x0f;
 
 - }
 
  
 
- void led_segment_display(unsigned char ddata0,unsigned char ddata1,unsigned char ddata2,unsigned char ddata3,unsigned char ddata4,unsigned char ddata5,unsigned char ddata6,unsigned char ddata7){
 
  
-         unsigned char  writedata0,writedata1,writedata2,writedata3,writedata4,writedata5,writedata6,writedata7;
 
 -         unsigned char  data0,data1,data2,data3,data4,data5,data6,data7;
 
 -         
 
 -         data0=ddata7;        //通过调整该部分代码即可调整数据对应数码管位置.
 
 -         data1=ddata6;
 
 -         data2=ddata5;
 
 -         data3=ddata4;
 
 -         data4=ddata3;
 
 -         data5=ddata2;
 
 -         data6=ddata1;
 
 -         data7=ddata0;
 
  
-         writedata0=(tab[data0]&0x01)+((tab[data1]&0x01)<<1)+((tab[data2]&0x01)<<2)+((tab[data3]&0x01)<<3)+((tab[data4]&0x01)<<4)
 
 -                 +((tab[data5]&0x01)<<5)+((tab[data6]&0x01)<<6)+((tab[data7]&0x01)<<7);
 
  
-         writedata1=((tab[data0]&0x02)>>1)+((tab[data1]&0x02))+((tab[data2]&0x02)<<1)+((tab[data3]&0x02)<<2)+((tab[data4]&0x02)<<3)
 
 -                 +((tab[data5]&0x02)<<4)+((tab[data6]&0x02)<<5)+((tab[data7]&0x02)<<6);
 
  
-         writedata2=((tab[data0]&0x04)>>2)+((tab[data1]&0x04)>>1)+((tab[data2]&0x04))+((tab[data3]&0x04)<<1)+((tab[data4]&0x04)<<2)
 
 -                 +((tab[data5]&0x04)<<3)+((tab[data6]&0x04)<<4)+((tab[data7]&0x04)<<5);
 
  
-         writedata3=((tab[data0]&0x08)>>3)+((tab[data1]&0x08)>>2)+((tab[data2]&0x08)>>1)+((tab[data3]&0x08))+((tab[data4]&0x08)<<1)
 
 -                 +((tab[data5]&0x08)<<2)+((tab[data6]&0x08)<<3)+((tab[data7]&0x08)<<4);
 
  
-         writedata4=((tab[data0]&0x10)>>4)+((tab[data1]&0x10)>>3)+((tab[data2]&0x10)>>2)+((tab[data3]&0x10)>>1)+((tab[data4]&0x10))
 
 -                 +((tab[data5]&0x10)<<1)+((tab[data6]&0x10)<<2)+((tab[data7]&0x10)<<3);
 
  
-         writedata5=((tab[data0]&0x20)>>5)+((tab[data1]&0x20)>>4)+((tab[data2]&0x20)>>3)+((tab[data3]&0x20)>>2)+((tab[data4]&0x20)>>1)
 
 -                 +((tab[data5]&0x20))+((tab[data6]&0x20)<<1)+((tab[data7]&0x20)<<2);
 
  
-         writedata6=((tab[data0]&0x40)>>6)+((tab[data1]&0x40)>>5)+((tab[data2]&0x40)>>4)+((tab[data3]&0x40)>>3)+((tab[data4]&0x40)>>2)
 
 -                 +((tab[data5]&0x40)>>1)+((tab[data6]&0x40))+((tab[data7]&0x40)<<1);
 
  
-         writedata7=((tab[data0]&0x80)>>7)+((tab[data1]&0x80)>>6)+((tab[data2]&0x80)>>5)+((tab[data3]&0x80)>>4)+((tab[data4]&0x80)>>3)
 
 -                 +((tab[data5]&0x80)>>2)+((tab[data6]&0x80)>>1)+((tab[data7]&0x80));
 
  
-         Write_COM(0x8a);//亮度
 
 -         Write_COM(0x40); //写 数据命令
 
 -         STB=0;
 
 -         TM1638_Write(0xc0);                //写地址命令
 
 -         
 
 -         TM1638_Write(writedata0);
 
 -         TM1638_Write(0x80);
 
 -         TM1638_Write(writedata1);
 
 -         TM1638_Write(0x00);
 
 -         TM1638_Write(writedata2);
 
 -         TM1638_Write(0x00);
 
 -         TM1638_Write(writedata3);
 
 -         TM1638_Write(0x00);
 
 -         TM1638_Write(writedata4);
 
 -         TM1638_Write(0x00);
 
 -         TM1638_Write(writedata5);
 
 -         TM1638_Write(0x00);
 
 -         TM1638_Write(writedata6);
 
 -         TM1638_Write(0x00);
 
 -         TM1638_Write(writedata7);
 
 -         TM1638_Write(0x00);
 
  
-         STB=1;
 
  
- }
 
  
- void Write_COM(unsigned char cmd){                //发送命令字
 
  
-         STB=0;
 
 -         TM1638_Write(cmd);
 
 -         STB=1;
 
 - }
 
  
- void TM1638_Write(unsigned char        DATA){                        //写数据函数
 
 -         unsigned char i;
 
 -         for(i=0;i<8;i++){
 
 -                 CLK=0;
 
 -                 if(DATA&0X01)
 
 -                         DIO=1;
 
 -                 else
 
 -                         DIO=0;
 
 -                 DATA>>=1;
 
 -                 CLK=1;
 
 -         }
 
 - }
 
  
 
 
- //存在问题:number为unsigned long 型数据时代码不工作,调试后发现void number_display(unsigned int number)这一函数不工作,具体原因未知.2018年7月11日 15:04:29
 
 - //part04.以上是数码管显示,主要是尝试动态刷新数码管.
 
 
  |