LCDのSD1602HULBをpic18F45K20で制御
参考文献
普通最後に書くところだけどほとんどここを参考にしたので、最初に書く。 PICで遊ぶ電子工作 - 液晶ディスプレイを使う
ハードウェア部
すでに資料があるのに自分で新たにつくるのは正直面倒。
ソフトウェア部
仕組みはともかく、作ったソースコードのみを公開することにする。 上のサイトを参考にすれば似たようなものができるだろう。
#include <xc.h> //コンフィギュレーションビット(内部オシレータを使用) #pragma config BOREN = ON, CPD = OFF, DEBUG = OFF, WRT = OFF, FOSC = HS, WDTE = OFF, CP = OFF, LVP = OFF, PWRTE = ON //クロック周波数の指定(10MHz) #define _XTAL_FREQ 10000000 //各種ポート名 #define EN PORTBbits.RB3 #define RS PORTBbits.RB1 #define RW PORTBbits.RB2 #define DB4 PORTBbits.RB4 #define DB5 PORTBbits.RB5 #define DB6 PORTBbits.RB6 #define DB7 PORTBbits.RB7 //プロトタイプ宣言 void write4bit(unsigned char); void picInit(); void lcdInit(); void lcdTest(); void lcd_data(unsigned char); void lcd_cmd(unsigned char); void write4bit(unsigned char); //メイン関数 void main() { //PICマイコンの初期化 __delay_ms(49); picInit(); //ディスレイ初期化開始 lcdInit(); //テスト用(LEDを点滅させながらLCDに文字を表示) while(1) { __delay_ms(49); PORTAbits.RA0 = 1; __delay_ms(49); PORTAbits.RA0 = 0; lcdTest(); } } void picInit() { OSCCON = 0b00000000 ; //クロック周波数の指定 ANSEL = 0b00000000 ; //デジタルで出力 ANSELH = 0b00001000 ; // デジタルで出力 TRISA = 0b00000000 ; //すべてのピンを出力にする TRISB = 0b00000000 ; TRISC = 0b00000000 ; TRISD = 0b00000000 ; PORTA = 0b00000000 ; //すべてのピンをLowにする PORTB = 0b00000000 ; PORTC = 0b00000000 ; PORTD = 0b00000000 ; PORTAbits.RA2 = 1; } void lcdInit() { EN = 0; RS = 0; RW = 0; //8ビットモードへ __delay_ms(20); write4bit(0x3); __delay_ms(10); write4bit(0x3); __delay_ms(5); write4bit(0x3); //4ビットモードへ __delay_ms(5); write4bit(0x2); __delay_ms(5); //2桁表示 lcd_cmd(0x28); __delay_ms(5); //LCD ON lcd_cmd(0x08); __delay_ms(5); //ディスプレイオン lcd_cmd(0x0D); __delay_ms(5); //エントリーモードセット lcd_cmd(0x06); __delay_ms(5); } void lcdTest()//0x44を出力し続ける。 { lcd_cmd(0x80); __delay_ms(20); lcd_cmd(0x80); __delay_ms(20); lcd_cmd(0x80); __delay_ms(20); lcd_data(0x44); } void write4bit(unsigned char data) { PORTB = (data << 4); EN = 1; __delay_us(20); EN = 0; __delay_us(20); } void lcd_data(unsigned char data) { RS = 1; PORTB = (data & 0xF0); EN = 1; __delay_us(20); EN = 0; __delay_us(20); PORTB = (data & 0x0F) << 4; EN = 1; __delay_us(20); EN = 0; __delay_us(20); } void lcd_cmd(unsigned char data) { RS = 0; PORTB = (data & 0xF0); EN = 1; __delay_us(20); EN = 0; __delay_us(20); PORTB = (data & 0x0F) << 4; EN = 1; __delay_us(20); EN = 0; __delay_us(20); }
PICでTIMER0を使う(PIC18F25K22 , XC8)
基本的にどのPICでも使用方法は同じであるが、変数名が若干違ったりするので、注意が必要。 結局頑張って使うPICのデータシートを読むしか無いのかな。英語わからないけど……
具体的手順
- TIMERの設定レジスタに値を代入(TMR0CON)
- タイマー割り込みを許可
- 割り込み発生時の関数を定義
以上の順序で設定をしていこう。
TIMERの設定レジスタに値を代入
代入する値の詳細は↓のデータ参照
[cpp] T0CON = 0bxxxxxxxx; [/cpp]
タイマー割り込みを許可
[cpp] TMR0IF = 0; //TIMER0のフラグをリセット TMR0IE = 1; //TIMER0による割り込みを許可 PEIE = 1; //割り込みを許可 GIE = 1; //全体の割り込みを許可 [/cpp]
割り込み発生時の関数を定義
割り込みにはタイマー割り込みだけでなく、SPIやUSARTの送受信等さまざまな割り込みが存在しているが、すべての割り込み時に この関数が呼び出されることになる。 今回は他の割り込みを使用しないのでそのまま処理を書き始めても問題ないが、他に割り込みさせる場合はTMR0IFが 1になっていることを確認するなどの方法で場合分けする必要がある。
[cpp] void interrupt isr(void) { TMR0IF = 0; //TIMER0のフラグをリセット
/* 処理 */
} [/cpp]
その他関係するレジスタ
TMR0レジスタ…このレジスタをサイクルごとにインクメントして、オーバーフローして値が0に戻った時に割り込み が発生している模様。だいたいのPICでは8ビットである(0~255) もし16bitモードにしているのであれば、TMR0HレジスタとTMR0Lレジスタを使用する。 INTCON…割り込みを制御している。PEIEやGIE、TMR0IFで直接ビット指定できるので気にするな。
データ
TMR0CON
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
---|---|---|---|---|---|---|---|
TMR0ON | T08BIT | T0CS | T0SE | PSA | T0PS2 | T0PS1 | T0PS0 |
- TMR0ON…タイマーを有効/無効(有効:1 , 無効:0)
- T08BIT…1:カウンターの桁数を指定(16bit : 0 , 8bit :1) 8bitだと0~255、16bitだと0~65535までクロックごとにインクリメント
- T0CS…TIMER0のクロックセレクト。(T0CKI pinを使用:1 , 内部クロックを使用:0) T0CKI pinはRA4です。(PIC18F25K22)
- T0SE…T0CKIpinにおけるTIMER0の検出方法(立ち下がりエッジ:1 , 立ち上がりエッジ:0) 検出時にカウンターをインクリメントする。立ち上がりエッジはLOWからHIGHに電圧が変化したときにインクリメント。 立ち下がりはその逆。
- PSA…TIMER0のプリスケーラアサインメントビット プリスケーラとは分周のこと、1/2に分周するなら2回に一度だけエッジを取り出す。 分周することによってより長い時間間隔で割り込みを行えるってはっきり分かんだね。 1 : プリスケーラを使用しない。 0 : プリスケーラを使用する。
- T0PS…プリスケーラをどの割合で行うか 111:クロックの1/256の周波数。つまり周期が256倍。 110:1/128 101:1/64 100:1/32 011:1/16 010:1/8 001:1/4 000:1/2
追記:任意の秒数で割り込み
8bitなら
16bitなら
この式で割り込む周期を求められるが、右辺の2のn乗の部分をTMR0レジスタの初期値を変更することで変えられる。 この数字は0からスタートして256でオーバーフローして割り込みするわけだから、初期化時と割り込みフラグをリセットする前に TMR0レジスタに何か値をいれれば任意にできる。未知数Xとして方程式とけばいいだけ。
せっかくHTMLで書いたのに間違えてビジュアルモードに書いてたからulタグとかめちゃくちゃだよ
Androidのxml編集中にUnexpected namespace prefix "xmlns" found for tag LinearLayout とかいうエラーを吐く
TeXをWindows7にインストール&TeXStudio
Windows7にTeXをインストールするのは非常に簡単になった。
TeXのインストール
『あべのりページ』
http://www.math.sci.hokudai.ac.jp/~abenori/soft/index.html
ここからTeXインストーラをダウンロードし、実行すればコンパイラであるplatexやその他必要なビュアなどを
ダウンロードからインストールまですべてしてくれるので、困ることがない。
TeXStudioのインストール
TeXStudioは1画面でプレビューと編集ができるので、便利(fullHDくらいないと厳しいが)
インストールは楽だが、このままだと日本語対応していないので、いくつか設定事項。
2.LaTeXのコマンドのlatex部分をplatex-utf8に置き換える。
3.スペルチェックが英語になっているので、日本語に赤い下線が入ってしまう。
OptionのTeXStudioの設定から構文の強調表示でスペルチェックのチェックを外せばおk
MacでもMacTexというインストーラが存在する。エディタも同時にインストールされ設定もプロファイル変更のみで済むので楽であったが。TeXStudioで文字化けが発生して挫折したorz
プロキシを通してgemのインストール【proxy】【gem】
学内LANからインストールするときプロキシを通るので
sudo gem install em-websocket
だとインストールできない。
プロキシを通す場合は
sudo gem install -p http://ip:port em-websocket
と-pオプションをつける必要がある。