最近做的一个案子,需要用单片机的5个引脚来控制一块5PIN的188数码管显示
数码管资料如下:
数字1到5表示对应的数码管引脚,利用二极管的单向导通性来点亮单独的LED
驱动程序如下:
__sbit PIN1 = PORTA:7;
__sbit PIN2 = PORTA:6;
__sbit PIN3 = PORTA:4;
__sbit PIN4 = PORTA:3;
__sbit PIN5 = PORTA:2;
uint8_t SEG;
uint8_t Data[3]={ 0,0,0};
uint8_t ch[11]={ 0X3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0};//显示数字0~9
void Display(uint8_t data0,uint8_t data1,uint8_t data2);
void LED_Scan(void);
void isr(void) __interrupt(0)//中断服务函数
{
if(INTFbits.T0IF)//1.02ms
{
LED_Scan();
INTF= (unsigned char)~(C_INT_TMR0); // Clear T0IF flag bit
}
}
void main(void)
{
//略······
while(1)
{
Display(1,0,0);
}
}
//数码管对应位置显示数字
void Display(uint8_t data0,uint8_t data1,uint8_t data2)
{
Data[0]=ch[data0];
Data[1]=ch[data1];
Data[2]=ch[data2];
}
//16颗LED逐一扫描
//当用到其中任意两个IO口的时候,需要将剩余三个IO口设置为输入模式,防止互相干扰
void LED_Scan(void)
{
SEG++;if(SEG>16)SEG=1;
PIN1=PIN2=PIN3=PIN4=PIN5=0;
if(SEG== 1){IOSTA=0XE5;if(Data[0]&0x02)PIN3=1;else PIN3=0;PIN4=0;}//B1
if(SEG== 2){IOSTA=0X75;if(Data[0]&0x04)PIN2=1;else PIN2=0;PIN4=0;}//C1
if(SEG== 3){IOSTA=0X6D;if(Data[1]&0x01)PIN2=1;else PIN2=0;PIN3=0;}//A2
if(SEG== 4){IOSTA=0X6D;if(Data[1]&0x02)PIN3=1;else PIN3=0;PIN2=0;}//B2
if(SEG== 5){IOSTA=0XE5;if(Data[1]&0x04)PIN4=1;else PIN4=0;PIN3=0;}//C2
if(SEG== 6){IOSTA=0X75;if(Data[1]&0x08)PIN4=1;else PIN4=0;PIN2=0;}//D2
if(SEG== 7){IOSTA=0X79;if(Data[1]&0x10)PIN5=1;else PIN5=0;PIN2=0;}//E2
if(SEG== 8){IOSTA=0XE9;if(Data[1]&0x20)PIN5=1;else PIN5=0;PIN3=0;}//F2
if(SEG== 9){IOSTA=0XF1;if(Data[1]&0x40)PIN5=1;else PIN5=0;PIN4=0;}//G2
if(SEG==10){IOSTA=0X3D;if(Data[2]&0x01)PIN1=1;else PIN1=0;PIN2=0;}//A3
if(SEG==11){IOSTA=0X3D;if(Data[2]&0x02)PIN2=1;else PIN2=0;PIN1=0;}//B3
if(SEG==12){IOSTA=0XAD;if(Data[2]&0x04)PIN1=1;else PIN1=0;PIN3=0;}//C3
if(SEG==13){IOSTA=0XAD;if(Data[2]&0x08)PIN3=1;else PIN3=0;PIN1=0;}//D3
if(SEG==14){IOSTA=0XB5;if(Data[2]&0x10)PIN1=1;else PIN1=0;PIN4=0;}//E3
if(SEG==15){IOSTA=0XB5;if(Data[2]&0x20)PIN4=1;else PIN4=0;PIN1=0;}//F3
if(SEG==16){IOSTA=0XB9;if(Data[2]&0x40)PIN5=1;else PIN5=0;PIN1=0;}//G3
}
补更新另一种:
//-------------------------------------------------------------------
#define SEG1_IN IOSTA |= C_PA7_Input
#define SEG1_H IOSTA &= ~C_PA7_Input; PORTAbits.PA7 = 1
#define SEG1_L IOSTA &= ~C_PA7_Input; PORTAbits.PA7 = 0
#define SEG2_IN IOSTA |= C_PA6_Input
#define SEG2_H IOSTA &= ~C_PA6_Input; PORTAbits.PA6 = 1
#define SEG2_L IOSTA &= ~C_PA6_Input; PORTAbits.PA6 = 0
#define SEG3_IN IOSTA |= C_PA4_Input
#define SEG3_H IOSTA &= ~C_PA4_Input; PORTAbits.PA4 = 1
#define SEG3_L IOSTA &= ~C_PA4_Input; PORTAbits.PA4 = 0
#define SEG4_IN IOSTA |= C_PA3_Input
#define SEG4_H IOSTA &= ~C_PA3_Input; PORTAbits.PA3 = 1
#define SEG4_L IOSTA &= ~C_PA3_Input; PORTAbits.PA3 = 0
#define SEG5_IN IOSTA |= C_PA2_Input
#define SEG5_H IOSTA &= ~C_PA2_Input; PORTAbits.PA2 = 1
#define SEG5_L IOSTA &= ~C_PA2_Input; PORTAbits.PA2 = 0
#define SEG_A 0X01
#define SEG_B 0X02
#define SEG_C 0X04
#define SEG_D 0X08
#define SEG_E 0X10
#define SEG_F 0X20
#define SEG_G 0X40
typedef struct
{
unsigned char flag;
unsigned char tab[4];
}seg_t;
//-------------------------------------------------------------------
//清除显示
void SEG_Clear(void)
{
SEG1_IN; SEG2_IN; SEG3_IN;
SEG4_IN; SEG5_IN;
}
//led正极为1脚~5脚
void San_SEG1(void)
{
if(seg.tab[2] & SEG_B) SEG2_L;
if(seg.tab[2] & SEG_D) SEG3_L;
if(seg.tab[2] & SEG_F) SEG4_L;
if(seg.tab[2] & SEG_G) SEG5_L;
}
void San_SEG2(void)
{
if(seg.tab[1] & SEG_B) SEG3_L;
if(seg.tab[1] & SEG_D) SEG4_L;
if(seg.tab[1] & SEG_E) SEG5_L;
if(seg.tab[2] & SEG_A) SEG1_L;
}
void San_SEG3(void)
{
if(seg.tab[1] & SEG_A) SEG2_L;
if(seg.tab[1] & SEG_C) SEG4_L;
if(seg.tab[1] & SEG_F) SEG5_L;
if(seg.tab[2] & SEG_C) SEG1_L;
}
void San_SEG4(void)
{
if(seg.tab[0] & SEG_B) SEG3_L;
if(seg.tab[0] & SEG_C) SEG2_L;
if(seg.tab[1] & SEG_G) SEG5_L;
if(seg.tab[2] & SEG_E) SEG1_L;
}
void San_SEG5(void)
{
if(seg.tab[3] & SEG_A) SEG2_L;
}
void Seg_Num_Cal(void) // 1ms扫描
{
static uint16_t cntt = 0;
cntt ++;
if(cntt >= 250) //250 ms刷新一次数据
{
cntt = 0;
seg.tab[0] = seg_table[hec];
seg.tab[1] = seg_table[dec];
seg.tab[2] = seg_table[sec];
seg.tab[3] = seg_table[0];
}
}
//显示函数
void Display_Decode(void)
{
static uint8_t cnt = 1;
SEG_Clear();
Seg_Num_Cal();
switch(cnt)
{
case 1: SEG1_H;San_SEG1();break;
case 2: SEG2_H;San_SEG2();break;
case 3: SEG3_H;San_SEG3();break;
case 4: SEG4_H;San_SEG4();break;
case 5: SEG5_H;San_SEG5();break;
default: break;
}
cnt = (cnt >= 6) ? 0 : cnt + 1;
}
运行效果如下:
好了,大功告成!!!