前言
前段时间利用TMS320F2335实现了对四位共阳数码管的控制(链接在这),不过当时只实现了利用数码管显示整数,对于含有纯小数部分的小数无法处理,因此打算对之前的代码进行完善,使得数码管能够显示小数。
实现过程
思路
小数和整数的区别在于小数除了整数部分之后还有纯小数部分,这一方面要求我们需要对纯小数部分进行处理;另一方面也要求我们对小数点进行处理。下面我们分别解决这两个问题。
首先解决小数点的问题,小数点这一块主要是小数点位置的问题,也就是说应该在哪一位上显示小数点。为此,我们先确立优先显示整数部分的规则,也就是说小数点的位置会随着整数部分的变化而变化。具体来说就是:如果整数部分在0到9,那么用一位显示整数部分,后面三位显示小数部分,而小数点就显示在第一位的位置上,如此类推。
接着,我们需要对纯小数部分进行处理,也就是将纯小数部分显示出来,这需要我们将纯小数部分各位上的数字提取出来。这里我们采用“乘10变整”的思想,也就是将纯小数部分不断乘以10来将各位上的数字移到整数部分。比如对于纯小数0.234,我们先乘以10得到2.34,就可以将十分位上的2移到个位上,然后就可以利用处理整数的方法来处理这一个2。接着不断乘10,就可以将纯小数部分上的各位依次移到整数部分来。
具体方法
根据上述思路,我们首先要将小数拆分为整数部分和纯小数部分。整数部分的提取可以通过强制类型转换实现,而将小数减去整数部分就可得到纯小数部分,代码如下:
Uint16 int_part;
float dec_part;
int_part = (Uint16)num;
dec_part = num - int_part;
其中,int_part和dec_part分别为整数部分和纯小数部分,而num为待显示的小数。
拆分之后,我们就可以对整数部分进行初步判断并对表征小数点位置的变量进行赋值,代码如下:
if (int_part <= 9)
{
Point_Pos = 1;
}
else if (int_part >= 10 && int_part <= 99)
{
Point_Pos = 2;
}
else if (int_part >= 100 && int_part <= 999)
{
Point_Pos = 3;
}
else if (int_part >= 1000 && int_part <= 9999)
{
Point_Pos = 4;
}
其中,Point_Pos为存储小数点位置信息的变量,如Point_Pos = 1则表示小数点在第1位。
解决完小数点位置的问题之后,我们接着解决纯小数部分的显示问题。同样根据上一节所说的思路,我们可以将纯小数部分数字提取的代码加入上述if-else if语句中并写成一个新的函数 DT_Show_Float :
void DT_Show_Float(float num)
{
Uint16 int_part;
float dec_part;
int_part = (Uint16)num;
dec_part = num - int_part;
if (int_part <= 9)
{
Bits[0] = int_part;
Bits[1] = (Uint16)(dec_part * 10);
Bits[2] = (Uint16)(dec_part * 100 - Bits[1] * 10);
Bits[3] = (Uint16)(dec_part * 1000 - Bits[1] * 100 - Bits[2] * 10);
Point_Pos = 1;
}
else if (int_part >= 10 && int_part <= 99)
{
Bits[0] = int_part / 10;
Bits[1] = int_part - Bits[0] * 10;
Bits[2] = (Uint16)(dec_part * 10);
Bits[3] = (Uint16)(dec_part * 100 - Bits[2] * 10);
Point_Pos = 2;
}
else if (int_part >= 100 && int_part <= 999)
{
Bits[0] = int_part / 100;
Bits[1] = (int_part - Bits[0] * 100) / 10;
Bits[2] = int_part - Bits[0] * 100 - Bits[1] * 10;
Bits[3] = (Uint16)(dec_part * 10);
Point_Pos = 3;
}
else if (int_part >= 1000 && int_part <= 9999)
{
DT_Show(int_part);
Point_Pos = 4;
}
}
最后一个分支中,由于此时整数部分有4位数,所以不显示小数部分,因此直接调用之前处理整数的函数 DT_Show 。
其他代码
首先是单个数字显示代码,也就是之前所写的 Output 函数,之前由于处理的是整数,所以并没有考虑小数点的显示。因此对 Output 函数进行修改,增加对小数点的处理,代码如下:
void Output(Uint16 bit, Uint16 num, Uint16 point_pos)
{
Sel_Num(num);
Sel_Bit(bit);
if (bit == point_pos)
DT_DP_ON;
DELAY_US(10);
}
修改之后,主要是增加了一个形参 point_pos 用来向函数传递小数点的位置,如果小数点位置和当前要显示的位数 bit 相同,则将对应的小数点点亮。
其次是测试代码,声明一个浮点数变量并在定时器中断函数中递增它的值,然后利用数码管进行显示以检验显示效果,代码如下:
DT_Show_Float(test_float);
test_float += 0.1;
其中 test_float 即测试用的浮点数变量。
效果
数码管显示小数效果
利用数码管显示舵机的实际转速
至此,我们就可以利用数码管显示多级的实际转速了。很简单,直接把计算出来的浮点数实际转速传递给 DT_Show_Float 函数即可,效果如下:
使用数码管显示舵机的非整数转速效果
总结
至此,我们就成功利用数码管实现了对小数的显示。如果大家有什么意见和建议,欢迎大家批评指正。