目次
前
次
7セグメントLED表示器
7セグメントLEDには、1パッケージに個別LEDを8本封入されています。
電源の高い方を共通にするか、低い方を共通にするかで
アノードコモン、カソードコモンに分けられます。
教材用に入っていた7セグメントLEDは、カソードコモンでした。
点灯は正論理で考えればよく、'1'で点灯、'0'で消灯になります。
7セグメントLEDの点灯実験回路は、以下。
スイッチを押すたびに、表示される数字が変化していきます。
7セグメントLEDの点灯パターンは、switch文を利用して
関数で定義します。
typedef unsigned char UBYTE ;
UBYTE conv7segment(UBYTE x)
{
UBYTE result ;
switch ( number ) {
case 1 : result = 0x06 ; break;
case 2 : result = 0x5b ; break;
case 3 : result = 0x4f ; break;
case 4 : result = 0x66 ; break;
case 5 : result = 0x6d ; break;
case 6 : result = 0x7d ; break;
case 7 : result = 0x07 ; break;
case 8 : result = 0x7f ; break;
case 9 : result = 0x6f ; break;
default : result = 0x3f ; break;
}
return result ;
}
定義した関数の動作を調べるコードは、時間をおいて
点灯パターンを変更していきます。
#define OFF 0
#define ON OFF+1
#define FIVE 500
typedef unsigned char UBYTE ;
/* prototype */
void usr_init(void);
UBYTE conv7segment(UBYTE x);
void main(void)
{
UBYTE tmp;
/* initialize PORT */
usr_init();
/* endless loop */
tmp = 0 ;
while (ON) {
/* impress */
PORTB = conv7segment( tmp );
/* delay */
Delay_ms(FIVE);
/* update */
tmp++ ;
if ( tmp == 10 ) { tmp = 0 ; }
}
}
void usr_init(void)
{
/* disable analog comparator */
CMCON = 0x07 ;
/* initial value */
PORTB = OFF ;
/* direction */
TRISB = 0x00 ;
}
UBYTE conv7segment(UBYTE x)
{
UBYTE result ;
switch ( number ) {
case 1 : result = 0x06 ; break;
case 2 : result = 0x5b ; break;
case 3 : result = 0x4f ; break;
case 4 : result = 0x66 ; break;
case 5 : result = 0x6d ; break;
case 6 : result = 0x7d ; break;
case 7 : result = 0x07 ; break;
case 8 : result = 0x7f ; break;
case 9 : result = 0x6f ; break;
default : result = 0x3f ; break;
}
return result ;
}
スイッチを押すたびに、表示数字が変化するコードは以下。
#define OFF 0
#define ON OFF+1
#define FIVE 500
#define LAST 10
typedef unsigned char UBYTE ;
/* prototype */
void usr_init(void);
UBYTE conv7segment(UBYTE x);
void main(void)
{
UBYTE tmp;
/* initialize PORT */
usr_init();
/* endless loop */
tmp = 0 ;
while (ON) {
/* impress */
PORTB = conv7segment( tmp );
/* delay */
Delay_ms(FIVE);
/* increment*/
if ( PORTA.F0 == OFF ) { tmp++ ; }
/* judge */
if ( tmp == LAST ) { tmp = 0 ; }
}
}
void usr_init(void)
{
/* disable analog comparator */
CMCON = 0x07 ;
/* initial value */
PORTA = 0xff ;
PORTB = OFF ;
/* direction */
TRISA = 0xff ;
TRISB = 0x00 ;
}
UBYTE conv7segment(UBYTE x)
{
UBYTE result ;
switch ( number ) {
case 1 : result = 0x06 ; break;
case 2 : result = 0x5b ; break;
case 3 : result = 0x4f ; break;
case 4 : result = 0x66 ; break;
case 5 : result = 0x6d ; break;
case 6 : result = 0x7d ; break;
case 7 : result = 0x07 ; break;
case 8 : result = 0x7f ; break;
case 9 : result = 0x6f ; break;
default : result = 0x3f ; break;
}
return result ;
}
7セグメントLED点灯パターンを、配列に格納する方法もあります。
UBYTE segment_pat[10];
*(segment_pat+0) = 0x3f ;
*(segment_pat+1) = 0x06 ;
*(segment_pat+2) = 0x5b ;
*(segment_pat+3) = 0x4f ;
*(segment_pat+4) = 0x66 ;
*(segment_pat+5) = 0x6d ;
*(segment_pat+6) = 0x7d ;
*(segment_pat+7) = 0x07 ;
*(segment_pat+8) = 0x7f ;
*(segment_pat+9) = 0x6f ;
この場合、初期化関数usr_initの中に、上のコードを含めます。
#define OFF 0
#define ON OFF+1
#define FIVE 500
#define LAST 10
typedef unsigned char UBYTE ;
volatile UBYTE segment_pat[10];
/* prototype */
void usr_init(void);
void main(void)
{
UBYTE tmp;
/* initialize PORT */
usr_init();
/* endless loop */
tmp = 0 ;
while (ON) {
/* impress */
PORTB = *(segment_pat+tmp);
/* delay */
Delay_ms(FIVE);
/* increment*/
if ( PORTA.F0 == OFF ) { tmp++ ; }
/* judge */
if ( tmp == LAST ) { tmp = 0 ; }
}
}
void usr_init(void)
{
/* disable analog comparator */
CMCON = 0x07 ;
/* initial value */
PORTA = 0xff ;
PORTB = OFF ;
/* direction */
TRISA = 0xff ;
TRISB = 0x00 ;
/* set bit pattern */
*(segment_pat+0) = 0x3f ;
*(segment_pat+1) = 0x06 ;
*(segment_pat+2) = 0x5b ;
*(segment_pat+3) = 0x4f ;
*(segment_pat+4) = 0x66 ;
*(segment_pat+5) = 0x6d ;
*(segment_pat+6) = 0x7d ;
*(segment_pat+7) = 0x07 ;
*(segment_pat+8) = 0x7f ;
*(segment_pat+9) = 0x6f ;
}
配列の利用で、関数内部にある判定を省けるため
動作は少し高速になります。
利用する7セグメントLEDが、アノードコモンに変更に
なったときは、論理演算を応用して正論理から負論理に
変更します。
関数の場合は、次のように1行で対応できます。
UBYTE conv7segment(UBYTE x)
{
UBYTE result ;
switch ( number ) {
case 1 : result = 0x06 ; break;
case 2 : result = 0x5b ; break;
case 3 : result = 0x4f ; break;
case 4 : result = 0x66 ; break;
case 5 : result = 0x6d ; break;
case 6 : result = 0x7d ; break;
case 7 : result = 0x07 ; break;
case 8 : result = 0x7f ; break;
case 9 : result = 0x6f ; break;
default : result = 0x3f ; break;
}
return( result ^ 0xff );
}
排他的論理和を利用して、1と0を反転します。
配列の場合は、「~」を利用して「1の補数」で対応できます。
/* set bit pattern */
*(segment_pat+0) = ~0x3f ;
*(segment_pat+1) = ~0x06 ;
*(segment_pat+2) = ~0x5b ;
*(segment_pat+3) = ~0x4f ;
*(segment_pat+4) = ~0x66 ;
*(segment_pat+5) = ~0x6d ;
*(segment_pat+6) = ~0x7d ;
*(segment_pat+7) = ~0x07 ;
*(segment_pat+8) = ~0x7f ;
*(segment_pat+9) = ~0x6f ;
どちらの場合でも、ポートBへの出力や数字を更新する
処理に手を加えていない点に注意します。
値を増やすことから、減らすように変更してみます。
#define OFF 0
#define ON OFF+1
#define FIVE 500
#define LAST 10
typedef unsigned char UBYTE ;
volatile UBYTE segment_pat[10];
/* prototype */
void usr_init(void);
void main(void)
{
int tmp;
/* initialize PORT */
usr_init();
/* endless loop */
tmp = LAST-1 ;
while (ON) {
/* impress */
PORTB = *(segment_pat+tmp);
/* delay */
Delay_ms(FIVE);
/* increment*/
if ( PORTA.F0 == OFF ) { tmp-- ; }
/* judge */
if ( tmp < 0 ) { tmp = LAST-1 ; }
}
}
void usr_init(void)
{
/* disable analog comparator */
CMCON = 0x07 ;
/* initial value */
PORTA = 0xff ;
PORTB = OFF ;
/* direction */
TRISA = 0xff ;
TRISB = 0x00 ;
/* set bit pattern */
*(segment_pat+0) = 0x3f ;
*(segment_pat+1) = 0x06 ;
*(segment_pat+2) = 0x5b ;
*(segment_pat+3) = 0x4f ;
*(segment_pat+4) = 0x66 ;
*(segment_pat+5) = 0x6d ;
*(segment_pat+6) = 0x7d ;
*(segment_pat+7) = 0x07 ;
*(segment_pat+8) = 0x7f ;
*(segment_pat+9) = 0x6f ;
}
初期値と状態値の更新が−1になるようにしています。
さらに、境界値を判定して範囲外になったとき、範囲内
に戻す操作を加えます。
目次
前
次