ATMELのAT-Tiny26,ATmega,R8Cなどのワンチップマイコン,C言語,JAVAなどのプログラミング言語の入門のためのページです.サンプルプログラムを中心に紹介します.他にもLinixや数学ソフトなどの紹介も行います.

このブログを検索

あなたは 番目のお客様です.

2008年11月27日木曜日

tiny2313でGPSデータを液晶に表示する


秋月のGPSレシーバモジュールキット(GPS-52)とマイコンATtiny2313,液晶SC1602BSを使い,
約2秒ごとに緯度経度を表示します.
GPS-52から出力されるシリアルデータの文字列の中から"36"の文字列を見つけ,
液晶の上段に緯度を,下段に経度を表示します.時々別な文字データが表示されます.
電源はATtiny2313とSC1602BSに単3×4を使い,GPS-52に3.3Vレギュレータ(TA48M033F)を
使います.またGPS-52でバックアップバッテリーは使わず,BATTピンもレギュレータの
3.3Vに接続しました.
Tiny2313の設定は,外部発振Ext Osc. 8MHz:Start-up time:6CK+64ms,分周なし.
GPS-52は,ビットレートが9600です.

Tiny2313とSC1602BSのピン接続は以下の通り.
PB0--RS
PB1
PB2--E
PB3
PB4--DB4
PB5--DB5
PB6--DB6
PB7--DB7
GND--R/W,Vo,Vss
5V--Vdd

Tiny2313とGPS-52のピン接続

RXD(PD0)--SDO
TXD(PD1)--RDO
GND--GND
3.3V--BATT,VCC
Tiny2313のシリアル入出力とGPS-52のシリアル入出力との間は,直接つなげてしまいました.

GPS-52は標準で測地系がTOKYOになってますが,googleマップなどでは測地系はWGS-84です.
測地系をWGS-84に切り替えるには,コマンドが必要です.
GPS-52は電源投入後、3秒間通信が禁止されるので注意すること.プログラムでは,約3秒
待ってから$PSRF106,21*0F<CR><LF>のコマンドを送っています.


以下Tiny2313のソースプログラム

/* gps2313.c 
Tiny2313,GPS-52,液晶SC1602BSを接続し約2秒ごとに緯度経度を表示する
注意:GPS-52は電源投入後、3秒間通信が禁止される。GPSとマイコンが同時オンの場合,
測地系がWGS-84に変更できない
約3秒待ってから$PSRF106,21*0F<CR><LF>

Tiny2313:外部発振Ext Osc. 8MHz:Start-up time:6CK+64ms
分周なし
ビットレート:9600,U2X=0
Tiny2313--SC1602BSのピン接続
PB0--RS
PB1
PB2--E
PB3
PB4--DB4
PB5--DB5
PB6--DB6
PB7--DB7
GND--R/W,Vo,Vss
5V--Vdd

Tiny2313--GPS-52のピン接続

RXD(PD0)--SDO
TXD(PD1)--RDO
GND--GND
3.3V--BATT,VCC
Tiny2313の電源は単3×4,GPS-52の電源はレギュレータ3.3V(TA48M033F)を使う
*/

#include <avr/io.h>
#include <avr/interrupt.h>
uint16_t a;//aは16ビット整数でマイクロ秒単位のカウントを行うa<65535

ISR(TIMER0_OVF_vect){ //タイマカウンタ0のオーバーフローで呼ばれる
a+=256;
}
//マイクロ秒単位の待ち
void delay(uint16_t t){
TCNT0=0;
a=0;
while(a+TCNT0<t){}
}
void en(void){
PORTB|= 1<<2;
delay(20);
PORTB&=~(1<<2);
delay(20);
}

//SC1602BSへのコマンド
void cmnd(char i){
PORTB=i&(0B11110000);
en();
PORTB=(i<<4)&(0B11110000); //i<<4は4ビット左シフト &はビット間のAND
en();
delay(40);
}

//データの書き込み
void dat(char i){
PORTB=i&(0B11110000);
PORTB|= 1<<0; //RS
en();
PORTB=(i<<4)&(0B11110000);
PORTB|= 1<<0; //RS
en();
delay(40);
}

void Utx(uint8_t data) //マイコンがデータを送信する
{
while ( !(UCSRA & (1<<UDRE)) );
UDR = data;
}

uint8_t Urx(void) //マイコンがデータを受信する
{
while ( !(UCSRA & (1<<RXC)) );
return UDR;
}


int main( void )
{
uint8_t dat1,i,c1,c2;
uint16_t baud;
baud=8000000/16/9600-1;//ボーレートの計算
UBRRH = (uint8_t)(baud>>8);//ボーレート上位
UBRRL = (uint8_t)baud; //ボーレート下位
UCSRC = (1<<USBS)|(3<<UCSZ0);
UCSRB = (1<<RXEN)|(1<<TXEN);//送受信可

DDRB = 0xFF; //PB all output
TCCR0B=0B00000010; //CK/8
TIMSK|= 1<<TOIE0; //T0 Ovf Int Enable
sei(); //All Int Enable
delay(20000); //Wait 20ms
PORTB=0B00110000;
en();
delay(5000); //Wait 5ms
en();
delay(100); //Wait 100Us
en();
delay(50); //Wait 50Us
PORTB=0B00100000; //Function set
en();
delay(50); //Wait 50Us
cmnd(0B00101100); //N=1:2lines F=1:10dots
cmnd(0B00001100); //Display On Off Control
cmnd(0B00000110); //Entry Mode Increment

//測地系をWGS-84に変更 $PSRF106,21*0F<CR><LF>
for(i=0;i<60;i++)delay(50000); //Wait 3s
Utx('$');
Utx('P');
Utx('S');
Utx('R');
Utx('F');
Utx('1');
Utx('0');
Utx('6');
Utx(',');
Utx('2');
Utx('1');
Utx('*');
Utx('0');
Utx('F');
Utx(0X0D);//CR
Utx(0X0A);//LF

while(1){
for(i=0;i<40;i++)delay(50000); //Wait 2s
cmnd(0B00000001); //Clear LCD
while(1){ //"36"の文字列を見つける
c2=Urx();
if(c2=='6' && c1=='3')break;
c1=c2;
}//while()
dat(c1);
dat(c2);
for(i=0;i<10;i++){dat1 = Urx();dat(dat1);}
cmnd(0XC0); //Lower Line
for(i=0;i<12;i++){dat1 = Urx();dat(dat1);}
}//while(1)
}

2008年11月21日金曜日

Tiny2313でカウンタと分周

Tiny2313のint0の割り込みを使いカウントを行い結果をPORTBに表示します
Tiny2313のヒューズの設定は,内蔵RC8MHz,8分周なしとしました.
#include <avr/io.h>
#include <avr/interrupt.h>

uint8_t a;  //カウンタ値を記録
ISR(INT0_vect){ //INT0で呼ばれる割り込み
a++;
PORTB=a;
}


int main( void )
{
DDRB = 0xFF;  //PB all output
DDRD = 0x00;  //PD all input
MCUCR|= 1<<ISC00;
MCUCR|= 1<<ISC01; //Int0 の立ち上がりで割り込み

a=0x00;

GIMSK|= 1<<INT0; //Interrupt 0 enable
sei();   //All Int Enable

while(1){}
}