前言
本文主要讲述使用指针及结构体实现三位数码管的显示。
一、引入数码管数组
提示:具体数值需要根据实际数码管共阴/共阳情况进行更改。
const uint8_t Table[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 32-41
// ' ',
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xFC, 0x60, 0xDA, 0xF2, // 42-51
// - 0 1 2 3
0x66, 0xB6, 0xBE, 0xE0, 0xFE, 0xF6, 0x00, 0x00, 0x00, 0x00, // 52-61
// 4, 5, 6, 7, 8, 9,
0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x00, 0x9E, 0x8E, 0x00, // 62-71
// A, B, C, D, E, F, G,
0x6E, 0x0c, 0x00, 0x00, 0x1C, 0x00, 0x00, 0xFC, 0xce, 0x00, // 72-81
// H, I, J, K, L, M, N, O, P Q,
0xEE, 0xB6, 0x8C, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 82-91
// R, S, T, U, V, W, X, Y, Z,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x7a, 0x00, // 92-101
// a, b, c, d, e,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x3A, // 102-111
// f, g, h, i, j, k, l, m, n, o,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 112-121
// p, q, r, s, t, u, v, w, x, y,
0x00 };
// z,
二、设计结构体
typedef struct
{
uint8_t DispH;
uint8_t DispM;
uint8_t DispL;
uint8_t DispDP;
_Bool DispCtrl; // 开关控制
}DISP_SET;
DISP_SET S_DISPINFO = {' ', ' ', ' '};
三、数据存储
/**************************************************
*函数名称:DISP_SET* disp_Set(void)
*函数功能:数码管显示
*入口参数:void
*出口参数:void
**************************************************/
DISP_SET* disp_Set(void)
{
return &S_DISPINFO;
}
/************************************
* 功能:数码管显示数据,显示小数点
* 参数:无
* 返回值:无
************************************/
void ShowData(uint16_t data)
{
uint8_t* p_Disp = (uint8_t*)disp_Set();
if(data< 1000)
{
p_Disp->DispH = data/100;
p_Disp->DispM = (data/10)%10;
p_Disp->DispDP = 1;
p_Disp->DispL = data%10;
}
else
{
p_Disp->DispH = data/1000;
p_Disp->DispM = (data/100)%10;
p_Disp->DispDP = 0;
p_Disp->DispL = (data/10)%10;
}
}
/************************************
* 功能:数码管显示数据,不显示小数点
* 参数:无
* 返回值:无
************************************/
void ShowOtherData(char* str)
{
uint8_t* p_Disp = (uint8_t*)disp_Set();
for(char* p = str; p < str+3; p++, p_Disp++)
{
*p_Disp = *p;
}
disp_Set()->DispDP = 0;
}
四、显示处理
uint8_t GPIO[8] = {LED_A_GPIO_Port, LED_B_GPIO_Port, LED_C_GPIO_Port, LED_D_GPIO_Port, LED_E_GPIO_Port, LED_F_GPIO_Port, LED_G_GPIO_Port, LED_H_GPIO_Port};
uint8_t Pin[8] = {LED_A_Pin , LED_B_Pin, LED_C_Pin, LED_D_Pin, LED_E_Pin, LED_F_Pin, LED_G_Pin, LED_H_Pin};
/**************************************************
*函数名称:void Display_Bit(void)
*函数功能:数码管位选显示:把代码发送到移位寄存器
*入口参数:udata
*出口参数:void
**************************************************/
void Display_Bit(uint8_t udata)
{
uint8_t Code;
uint8_t n = 0;
if(udata < 10)
{
Code = Table['0' - ' ' + udata];
}
else
{
Code = Table[udata - ' '];
}
// 移位寄存器的处理
for(n = 0; n < 8; n++)
{
if(Code & 0x80)
{
Gpio_WriteOutputIO(GPIO[n], Pin[n], TRUE);
}
else
{
Gpio_WriteOutputIO(GPIO[n], Pin[n], FALSE);
}
Code <<= 1;
}
}
/**************************************************
*函数名称:void Display(void)
*函数功能:显示处理
*入口参数:void
*出口参数:void
**************************************************/
void Display(void)
{
static uint8_t s_Bit = 0;
if(S_DISPINFO.DispCtrl == DISP_OFF)
{
COM0(FALSE); // 位选
COM1(FALSE);
COM2(FALSE);
}
else
{
if(s_Bit == 0)
{
COM0(FALSE);
COM1(FALSE);
COM2(FALSE);
Display_Bit(_DISPINFO.DispH);
COM0(TRUE);
s_Bit = 1;
}
else if(s_Bit == 1)
{
COM0(FALSE);
COM1(FALSE);
COM2(FALSE);
Display_Bit(S_DISPINFO.DispM);
if(S_DISPINFO.DispDP)
{
DISP_H(TRUE); // 小数点显示
}
else
{
DISP_H(FALSE); // 小数点不显示
}
COM1(TRUE);
s_Bit = 2;
}
else if(s_Bit == 2)
{
COM0(FALSE);
COM1(FALSE);
COM2(FALSE);
Display_Bit(S_DISPINFO.DispL);
COM2(TRUE);
s_Bit = 0;
}
else{}
}
}
五、函数的使用
void Timer_1ms(void) //定时器中的定时参数处理
{
if(++display_time >= 5)
{
display_time = 0;
//ShowData(650); //数值显示65.0
//ShowData(1250); //数值显示125
ShowOtherData("LOC"); // 显示LOC
Display();
}
}
总结
以上仅为作者实际使用的函数整理,如有错误,欢迎批评指正;若有更好的想法,欢迎留言评论。