备注:本次学习用的是《普中A7开发板》
功能:两个四位一体数码管,可以显示两个浮点数计算的结果。
代码:
#define SMG_A_DP_PORT P0
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
u8 gsmg_code[17]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71
};
//将一个浮点数值,转化位一个unsigned char数组,长度为8,整数4位,小数4位
void floatToCharArray(float A, unsigned char B[]) {
int integerPart = (int)A;
float decimalPart = A - integerPart;
int i= 3;
// Convert integer part to char array
for ( i = 3; i >= 0; i--) {
B[i] = integerPart % 10;
integerPart /= 10;
}
// Convert decimal part to char array
for ( i = 4; i < 8; i++) {
decimalPart *= 10;
B[i] = (int)decimalPart;
decimalPart -= (int)decimalPart;
}
}
void float_display(float A)
{
int i=0;
u8 B[8];
floatToCharArray(A, B);
for(i=0; i<8; i++)
{
switch(7-i)//λѡ
{
case 0:
LSC=1;
LSB=1;
LSA=1;
break;
case 1:
LSC=1;
LSB=1;
LSA=0;
break;
case 2:
LSC=1;
LSB=0;
LSA=1;
break;
case 3:
LSC=1;
LSB=0;
LSA=0;
break;
case 4:
LSC=0;
LSB=1;
LSA=1;
break;
case 5:
LSC=0;
LSB=1;
LSA=0;
break;
case 6:
LSC=0;
LSB=0;
LSA=1;
break;
case 7:
LSC=0;
LSB=0;
LSA=0;
break;
}
SMG_A_DP_PORT=gsmg_code[B[i]];
if (i==3)SMG_A_DP_PORT=gsmg_code[B[i]]|0x80;//将第四位显示小数点
delay_10us(100);
SMG_A_DP_PORT=0x00;//ÏûÒô
}
}
void main()
{
while(1)
{
float A=37.5/13.3;
float_display(A);
}
}
遇到的问题:
1.不用的函数要注释掉,否则会警告:“*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS”。
2.Keil uVision5不支持函数中定义变量,之前用C++和C#习惯了用到变量了再定义。在Keil uVision5中需要避免这种写法。否则会报错:“main.c(51): error C202: 'i': undefined identifier”。
3.子函数的定义要放在使用该函数的函数前,有点绕。真确的写法就是类似变量的定义。定义函数在使用函数之上。否则会报错:
main.c(106): warning C206: 'floatToCharArray': missing function-prototype
main.c(106): error C267: 'floatToCharArray': requires ANSI-style prototype
main.c(159): error C231: 'floatToCharArray': redefinition
main.c(175): error C231: 'floatToCharArray': redefinition
习惯了C++和C#的程序员要特别注意。
另外,作为一个从纯软件开始学习单片机的初学者来说,一些概念要搞清楚:
1.段选和位选:简单来说就是段选是控制具体数字显示几,位选是控制哪个数码管显示。
参考:3分钟带你彻底弄懂数码管的段选与位选_位选和段选分别是什么-CSDN博客
2.OE:英文全称为Output Enable,中文意思为输出使能端、输出允许信号。
3.DIR:Direct的缩写,指驱动芯片引脚。