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

このブログを検索

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

2008年9月16日火曜日

Tiny2313を使ってシリアル通信とEEP-ROMリーダ









Tiny2313を使ってシリアル通信でPCと接続するサンプルプログラムです.
PC側からaを入力すればPB0に接続したLEDが点灯し,
bを入力すればLEDが消灯し,
c-zを入力すればPC側に大文字を返します.
Tiny2313は8MHzの外部発振で,分周なしの設定にしておきます.
PC側の設定は,ボーレート19200,データ8ビット,
パリティnone,ストップ1bitフロー制御noneにしておきます.
/*シリアル通信でPCとTiny2313を接続する
comtn2313b.c(通信の初期設定をmainに入れた)
Ext8MHz,分周なし,ビットレート:19200,U2X=0
a:LED on b:LED off c-z:大文字を返す
*/

#include <avr/io.h>

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

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

int main(void){
unsigned char dat;
unsigned int baud;
baud=8000000/16/19200-1;//ボーレートの計算
UBRRH = (unsigned char)(baud>>8);//ボーレート上位
UBRRL = (unsigned char)baud; //ボーレート下位
UCSRC = (1<<USBS)|(3<<UCSZ0);
UCSRB = (1<<RXEN)|(1<<TXEN);//送受信可

DDRB=0B00000001; //PD0(Output)
while(1){
dat = Urx();
if(dat=='a')PORTB=0B00000001; //PD0 H(LED:on)
if(dat=='b')PORTB=0B00000000; //PD0 L(LED:off)
if(dat>'b'){ //c-zは大文字を返す
dat=dat-'a'+'A';
Utx(dat);
Utx(0x0a); //LF
Utx(0x0d); //CR
}
}//while(1)
}


続いて以下は,Tiny2313とEEP-ROM(ATMEL24C256)をつないだROMリーダです.
パソコンで数値,sと入力するとEEP-ROMの先頭からn個のデータを
RS-232Cを通してPCに出力します.
/*
EEP-ROM リーダーTiny2313(ExtOsc8MHz,クロックを8分周しない)
ATMEL24C256の場合8ビット×32K,32K=2^15=32768
次のように最初のアドレス:データを続けて表示する
0000:000102030405060708090A0B0C0D0E0F
0010:101112131415161718191AFFFFFFFFFF
0020:FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
ボーレートは19200
マイコンとADM3202,24C256の接続は以下の通り
(Tiny2313)RXD--(ADM3202)R1OUT
(Tiny2313)TXD--(ADM3202)R1IN
(Tiny2313)PB0--(24C256)SCL(1kΩでプルアップ)
(Tiny2313)PB1--(24C256)SDA(1kΩでプルアップ)
*/

#include <avr/io.h>

//マイクロ秒単位の待ち(t<256)
void delay(int8_t t){
TCCR0B=0B00000010; //タイマカウンタ0の分周をセットCK/8
TCNT0=0;
while(TCNT0<t){}
}

void start(void){
PORTB|= 1<<1;// set PB1
PORTB|= 1<<0; // set CLK
delay(5);
PORTB&=~(1<<1); // clear PB1
PORTB&=~(1<<0); // clear CLK
delay(5);
}
void stop(void){
PORTB&=~(1<<1); // clear PB1
PORTB|= 1<<0; // set CLK
delay(5);
PORTB|= 1<<1;// set PB1
PORTB&=~(1<<0); // clear CLK
delay(5);
}
void Hclk(void){//SDAがhighで1クロック
PORTB|= 1<<1;// set PB1
PORTB|= 1<<0; // set CLK
delay(5);
PORTB&=~(1<<0); // clear CLK
delay(5);
}
void Lclk(void){//SDAがlowで1クロック
PORTB&=~(1<<1); // clear PB1
PORTB|= 1<<0; // set CLK
delay(5);
PORTB&=~(1<<0); // clear CLK
delay(5);
}

//データ読み込み
uint8_t read(uint16_t add){
uint8_t i;
uint16_t k;
start();
for(k=0B100000000;k>0;k=k>>1)if(k & 0B101000000)Hclk();
else Lclk();
i=add/256; //上位アドレス
for(k=0B10000000;k>0;k=k>>1)if(k & i)Hclk();
else Lclk();
Lclk();//ACK

i=add%256; //下位アドレス
for(k=0B10000000;k>0;k=k>>1)if(k & i)Hclk();
else Lclk();
Lclk();//ACK
start();
for(k=0B100000000;k>0;k=k>>1)if(k & 0B101000010)Hclk();
else Lclk();
DDRB&=~(1<<1); //PB1を入力に変更
i=0;
for(k=0B10000000;k>0;k=k>>1){
PORTB|= 1<<0; // set CLK
delay(5);
if(PINB & (1<<1))i+=k;
PORTB&=~(1<<0); // clear CLK
delay(5);
}
DDRB|= 1<<1; //PB1を出力に変更
Hclk();//NO ACK
stop();//Stop
return i;
}

void Utx(unsigned char data) //マイコンからデータを送信する
{
while ( !(UCSRA & (1<<UDRE)) );
UDR = data;
}
unsigned char Urx(void) //マイコンがデータを受信する
{
while ( !(UCSRA & (1<<RXC)) );
return UDR;
}

int main(void)
{
uint8_t x,y,dat;
uint16_t i,j,k=0,baud=25; //ボーレートの計算=8000000/16/19200-1
UBRRH = (unsigned char)(baud>>8);//ボーレート上位
UBRRL = (unsigned char)baud; //ボーレート下位
UCSRC = (1<<USBS)|(3<<UCSZ0);
UCSRB = (1<<RXEN)|(1<<TXEN);//送受信可

DDRB=0B00000011; //PB0,PB1:OUT
TIMSK|= 1<<TOIE0; //タイマカウンタ0のオーバーフロー割り込みを許可する
//sei(); //All Int Enable 割り込みを可能にする

while((dat = Urx())!='s')k=k*10+dat-'0';//'s'が入力されるまで待つ

for(i=0;i<k/16;i++){
//最初のアドレス(i*16)を表示
//16進のiと0を表示するのはi*16を表示するのと同じである
y=i/256;
if(y>9)Utx('A'+y-10);
else Utx('0'+y);
y=(i%256)/16;
if(y>9)Utx('A'+y-10);
else Utx('0'+y);
y=i%16;
if(y>9)Utx('A'+y-10);
else Utx('0'+y);
Utx('0');
Utx(':');
for(j=0;j<16;j++){

x=read(i*16+j); //Read EEP
y=x/16;
if(y>9)Utx('A'+y-10);
else Utx('0'+y);
y=x%16;
if(y>9)Utx('A'+y-10);
else Utx('0'+y);
}//for i
Utx(0x0a); //LF
Utx(0x0d); //CR
}//for i
while(1){}
}