天天看點

188數位管驅動案方案

最近做的一個案子,需要用單片機的5個引腳來控制一塊5PIN的188數位管顯示

數位管資料如下:

188數位管驅動案方案
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;
}
           

運作效果如下:

188數位管驅動案方案

好了,大功告成!!!

繼續閱讀