程序特点:
1.运用查理复用大法,用最少的管脚点最多的指示灯,N个管脚可以点亮N*(N-1)个灯
2.使用表驱动设计模式,可移植性和扩展性极佳,只需要在数组末端增加元素。
3.演示程序是四格电量灯,实现开机跑马灯自检,放电常亮,充电闪灯,充满全亮。
#include "LED188.c"
cpp
#include "LED188.h"
void LED1_IN(void) { LED1_GPORT->MODER &= ~(0x03 << 2); }
void LED2_IN(void) { LED2_GPORT->MODER &= ~(0x03 << 0); }
void LED3_IN(void) { LED3_GPORT->MODER &= ~(0x03 << 8); }
void LED1_OUT(void) { LED1_GPORT->MODER |= (0x01 << 2); }
void LED2_OUT(void) { LED2_GPORT->MODER |= (0x01 << 0); }
void LED3_OUT(void) { LED3_GPORT->MODER |= (0x01 << 8); }
void LED1_H(void) {LED1_GPORT->BSRR = LED1_GPIN;}
void LED2_H(void) {LED2_GPORT->BSRR = LED2_GPIN;}
void LED3_H(void) {LED3_GPORT->BSRR = LED3_GPIN;}
void LED1_L(void) {LED1_GPORT->BRR = LED1_GPIN;}
void LED2_L(void) {LED2_GPORT->BRR = LED2_GPIN;}
void LED3_L(void) {LED3_GPORT->BRR = LED3_GPIN;}
typedef void (*gpio_func_t)(void);
static const gpio_func_t pin_set_input[] = {LED1_IN, LED2_IN, LED3_IN};
static const gpio_func_t pin_set_output[] = {LED1_OUT,LED2_OUT,LED3_OUT};
static const gpio_func_t pin_set_high[] = {LED1_H, LED2_H, LED3_H};
static const gpio_func_t pin_set_low[] = {LED1_L, LED2_L, LED3_L};
static inline void pin_output_h(u8 pin){pin_set_high[pin-1]();pin_set_output[pin-1]();}
static inline void pin_output_l(u8 pin){pin_set_low[pin-1]();pin_set_output[pin-1]();}
static inline void pin_input(u8 pin) {pin_set_input[pin-1]();}
uc8 bit_mask[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
static void set_all_pins_low(void)
{
for(u8 i=1;i<(LED_PIN_NUM+1);i++)
pin_output_l(i);
}
static void set_all_pins_in(void)
{
for(u8 i=1;i<(LED_PIN_NUM+1);i++)
pin_input(i);
}
const LED_SCANTABLE_t LED_ScanTable[]=
{
{2,1},//2=pin2低电平,1=pin1高电平
{3,1},
{1,2},
{3,2},
};
union uint8_uo dp_scan_led;
void Display_Tube(void)
{
static u8 slot = 0;
if (!Disp_data.B_EN)
{
set_all_pins_low();
return;
}
set_all_pins_in();
const LED_SCANTABLE_t *pslot=&LED_ScanTable[slot];
if(dp_scan_led.byte & bit_mask[slot])
{
pin_output_l(pslot->Lpin);
pin_output_h(pslot->Hpin);
}
if (++slot >= LED_SEG_NUM) slot = 0;
}
uc8 led_paoma_table[9]={
0x00,//0
0x01,//1
0x03,//2
0x07,//3
0x0F,//4
0x1F,//5
0x3F,//5
0x7F,//6
0xFF,//5
};
uc8 led_flow_table[9]={
0x00,//0
0x01,//1
0x02,//2
0x04,//3
0x08,//4
0x10,//5
0x20,//6
0x40,//7
0x80 //8
};
DisplayData Disp_data;
void LED_DCHG_Display(u8 soc)
{
dp_scan_led.byte&=0x01;
if(led_paoma_table[soc])
dp_scan_led.byte=led_paoma_table[soc];
else
dp_scan_led.Bit.b0=!dp_scan_led.Bit.b0;
}
void LED_CHG_Display(u8 soc)
{
static bool B_TOG=0;
static union uint8_uo dp_scan_led_Q;
dp_scan_led.byte&=0x00;
B_TOG=!B_TOG;
dp_scan_led.byte=led_paoma_table[soc];
if(soc>0)
dp_scan_led_Q.byte=led_paoma_table[soc-1];
else
dp_scan_led_Q.byte=led_paoma_table[1];
dp_scan_led.byte=(B_TOG>0)? dp_scan_led.byte:dp_scan_led_Q.byte;
}
bool LED_FLOW_Display(void)
{
static u8 i=0;
if(i++>=LED_SEG_NUM)
{
dp_scan_led.byte=0;
return 1;
}
else
{
dp_scan_led.byte=led_flow_table[i];
return 0;
}
}
u8 soc_grade[6]={10,25,50,75,99,100};
u8 SocGrade_calculate(u8 soc)
{
u8 i=0;
for(i=0;i<6;i++)
if(soc<soc_grade[i])
break;
return i;
}
void Dispdata_Init(void)
{
Disp_data.B_JC =1;
Disp_data.init_cnt=1;
Disp_data.B_EN =1;
Disp_data.B_CHGING=0;
Disp_data.B_ERROR =0;
}
void Refresh_188Data(void)
{
static u8 B_end;
if(!Disp_data.B_JC)
return;
Disp_data.B_JC=0;
Disp_data.B_FCHG =0;
Disp_data.B_CHGING=1;
Disp_data.SOC=SocGrade_calculate(R_bat_data.SOC);
if(Disp_data.B_ERROR)
return;
if(Disp_data.init_cnt)
{
B_end=LED_FLOW_Display();
if(B_end)
Disp_data.init_cnt=0;
}
else
{
if(Disp_data.B_CHGING)
LED_CHG_Display(Disp_data.SOC);
else
LED_DCHG_Display(Disp_data.SOC);
}
}
#include "LED188.h"
cpp
#ifndef LED188_H
#define LED188_H
#include "user_define.h"
#include "gpio.h"
#define LED_PIN_NUM (sizeof(pin_set_input) / sizeof(pin_set_input[0]))
#define LED_SEG_NUM (sizeof(LED_ScanTable) / sizeof(LED_ScanTable[0]))
typedef struct LED_SCANTABLE_t
{
u8 Lpin;
u8 Hpin;
} LED_SCANTABLE_t;
struct bit8_t
{
u8 b0 :1;
u8 b1 :1;
u8 b2 :1;
u8 b3 :1;
u8 b4 :1;
u8 b5 :1;
u8 b6 :1;
u8 b7 :1;
};
union uint8_uo
{
u8 byte;
struct bit8_t Bit;
};
typedef struct DisplayData
{
u8 B_JC :1;
u8 B_EN :1;
u8 B_FCHG :1;
u8 B_CHGING :1;
u8 B_TOG :1;
u8 B_ERROR :1;
u8 LowC_cnt;
u8 LowC_mask_cnt;
u8 SOC;
u8 init_cnt;
u8 display_tim;
}DisplayData;
extern DisplayData Disp_data;
extern void Refresh_188Data(void);
extern void Dispdata_Init(void);
extern void Display_Tube(void);
#endif