// 该程序控制2个74HC595操作4个数码管进行显示
// LED_BUFFER_LENGTH为数码管显示缓冲区,长度应为数码管个数得两倍(因为有小数点)
// 可显示内容:数字0-9、小数点、负号、字母A-F、字母H、字母L、字母O、字母P、字母R、字母U
// 应在循环中调用refresh函数刷新数码管显示
#include <string.h>
sbit DIO = P1^1; // 串行数据输入
sbit RCLK = P1^2; // 时钟脉冲信号————上升沿有效
sbit SCLK = P1^3; // 打入信号————上升沿有效
// 共阳
unsigned char code LED_0F[] =
{// 0 1 2 3 4 5 6 7 8 9 A b C d E F - H L O P R U
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xBF,0x89,0xC7,0xA3,0x8C,0xAF,0xC1
};
#define LED_BUFFER_LENGTH 8
uchar led_buf[LED_BUFFER_LENGTH];
void refresh();
void show(uchar* str);
uint floatToString(float n, ubyte a, uchar* str);
void main()
{
show("HELP");
while (true)
{
refresh();
}
}
void led_out(uchar x)
{
uchar i;
for(i = 8;i >= 1;i--)
{
if (x & 0x80)
DIO = 1;
else
DIO = 0;
x <<= 1;
SCLK = 0;
SCLK = 1;
}
}
void refresh()
{
uchar code *led_table;
ubyte tableIndex;
byte i, j;
ubyte outIndex = 1;
bool radixPoint = false;
for (i = LED_BUFFER_LENGTH - 1, j = i; i >= 0; i--, j++)
{
if (led_buf[i] == '.')
{
radixPoint = true;
}
else
{
led_table = LED_0F + led_buf[i];
tableIndex = *led_table;
if (radixPoint == true) tableIndex -= 0x80;
radixPoint = false;
led_out(tableIndex);
led_out(outIndex);
RCLK = 0;
RCLK = 1;
outIndex *= 2;
}
}
}
void show(uchar* str)
{
ubyte i, j;
memset(led_buf, 0xff, LED_BUFFER_LENGTH);
i = LED_BUFFER_LENGTH - strlen(str);
for (j = 0; i < LED_BUFFER_LENGTH; i++, j++)
{
if (str[j] >= '0' && str[j] <= '9') // 0 - 9
led_buf[i] = str[j] - 48;
else if (str[j] == '.') // 小数点
led_buf[i] = '.';
else if (str[j] == '-') // 负号
led_buf[i] = 16;
else if (str[j] >= 'A' && str[j] < 'Z') // A - F
led_buf[i] = str[j] - 55;
else if (str[j] >= 'a' && str[j] < 'z') // a - f
led_buf[i] = str[j] - 87;
if (str[j] == 'H' || str[j] == 'h') // H, h
led_buf[i] = 17;
else if (str[j] == 'L' || str[j] == 'l') // L, l
led_buf[i] = 18;
else if (str[j] == 'O' || str[j] == 'o') // U, u
led_buf[i] = 19;
else if (str[j] == 'P' || str[j] == 'p') // P, p
led_buf[i] = 20;
else if (str[j] == 'R' || str[j] == 'r') // U, u
led_buf[i] = 21;
else if (str[j] == 'U' || str[j] == 'u') // U, u
led_buf[i] = 22;
}
refresh();
}
uint floatToString(float n, ubyte a, uchar* str)
{
uint length = 0;
uint i, j;
if (n == 0)
{
str[0] = '0';
if (a > 0) str[1] = '.';
memset(str + 2, '0', a);
length = 2 + a;
}
else
{
int num;
for (i = 0; i < a; i++) n *= 10;
num = (uint)n;
if (num < 0) num *= -1;
i = 0;
while (num > 0)
{
str[i] = num % 10 + 48;
num /= 10;
i++;
length++;
}
if (n < 0)
{
str[i] = '-';
length++;
}
i = 0; j = length - 1;
while (i < j)
{
uchar c = str[i];
str[i] = str[j];
str[j] = c;
i++; j--;
}
if (a > 0)
{
for (i = 0, j = length; i < a; i++, j--) str[j] = str[j - 1];
str[length - a] = '.';
length++;
}
}
return length;
}