本帖最后由 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.以上是数码管显示,主要是尝试动态刷新数码管.
|