ポート制御にビットフィールドを使う(ATtiny2313,TC1602E-13A)

bitfield-001

前回「AVRからPORT制御のLCDを使う(ATtiny2313,TC1602E-13A)」で、8BITモードで使用したキャラクタLCDですが、今回は4BITモードで使います。

いつものごとく、横着な接続図。

                                  ATtiny2313
                                 +-----------+
                                -|1        20|- VCC
                                -|2        19|- 
                                -|3        18|- 
                                -|4        17|- PB5 ---> E
                                -|5        16|- PB4 ---> RS
                                -|6        15|- PB3 ---> DB3
                                -|7        14|- PB2 ---> DB2
                                -|8        13|- PB1 ---> DB1
                                -|9        12|- PB0 ---> DB0
                            GND -|10       11|- 
                                 +-----------+

                                  TC1602E-13A
                                  (Connector)
                                 +-----------+
                   PB7 <--- DB7 -|14       13|- DB5 ---> PB5
                   PB5 <--- DB5 -|12       11|- DB4 ---> PB4
                    nc <--- DB3 -|10        9|- DB2 ---> nc
                    nc <--- DB1 -|8         7|- DB0 ---> nc
                   PD2 <---   E -|6         5|- R/W ---> GND
                   PD0 <---  RS -|4         3|- Vo
                            VSS -|2         1|- VDD
                                 +-----------+

TC1602E-13Aの必要なピンとしては、
DB7〜4、E、RS、R/W
ですが、R/Wは、ライトしか使わないので、GNDに落としました。

前回使った時は、PORTDの2番ピンをEに割り当てており、Eのパルスを作るのに、このようにやっていました。

        PORTD = 0b00000100;     //E(PD2)=H
        _delay_us(1);
        PORTD = 0b00000000;     //E(PD2)=L

本来はこうでしょうか。

        PORTD |= 0b00000100;     //E(PD2)=H
        _delay_us(1);
        PORTD &= ~0b00000100;     //E(PD2)=L

今回、EをPORTDの2番からPORTBの5番へ移動させたのですが、上のようなプログラムでは、ピン配が変わる度に修正が大変です。
カスタマイズしやすいように、下の様に作り変えました。

マクロ

#define L 0
#define H 1
#define	E(hl)		((struct bf*)&PORTB)->b5 = hl

本体

	E(H);
        _delay_us(1);
	E(L);

マクロで使っている構造体は、ビットフィールドです。

struct bf{
	int b0:	1;
	int b1:	1;
	int b2:	1;
	int b3:	1;
	int b4:	1;
	int b5:	1;
	int b6:	1;
	int b7:	1;
};

ポート制御は、ビットフィールドを使わないとプログラミングが辛いですね。
エンディアン変換にも使えます。

~$ cat -n my_htonl.c
     1	#include "stdio.h"
     2	#include "stdint.h"
     3	
     4	int main()
     5	{
     6		struct bf{
     7			int b1:	8;
     8			int b2:	8;
     9			int b3:	8;
    10			int b4:	8;
    11		};
    12	
    13		int32_t a;
    14		int32_t b;
    15	
    16		a = 0x12345678;
    17	
    18		((struct bf*)&b)->b1 = ((struct bf*)&a)->b4;
    19		((struct bf*)&b)->b2 = ((struct bf*)&a)->b3;
    20		((struct bf*)&b)->b3 = ((struct bf*)&a)->b2;
    21		((struct bf*)&b)->b4 = ((struct bf*)&a)->b1;
    22	
    23		printf("a=%08x\n",a);
    24		printf("b=%08x\n",b);
    25	}
~$ gcc my_htonl.c
~$ ./a.out
a=12345678
b=78563412
~$ 

レポジトリはこちら

~$ git clone https://github.com/takkete/bread.git
~$ cd bread/mcu/avr/attiny2313/device/clcd

コメント

  1. […] キャラクタLCDに時計を表示します。 「ポート制御にビットフィールドを使う」で作ったプログラムを改造します。今回は時計とまではいかなくて、時を刻むだけのものです。 […]

タイトルとURLをコピーしました