2010年07月18日 RS232Cモニター
_ AVRでRS232Cのmonitor
PS2のマウスをAVRで扱おうと計画しているが、その前段階として、RS232Cのモニターを作ってみた。具体的には、PCからRS232Cで送った数字を、液晶で表示するというものだ。PCからのデータは次のようなスクリプトでrubyから送信できる。s=open("/dev/ttyS0","r+") system("stty raw -echo -crtscts 9600 cs8 -parenb cstopb </dev/ttyS0") # 9600bps 8bit, 2 stop bit, no parity loop{ i=rand(256) puts '%02x'%i s.write(i.chr) s.flush sleep 1 }この信号をMAX232でTTLレベルに変換して、それをtiny2313のUSARTの機能を使って受信する。あとは液晶表示ルーチンを利用して表示するだけだ。あまりきれいではないけれど、そのソースはこんな感じ。
#include次は、PS2のモニターを作ろうと思うが、なかなか時間が取れないので、なかなか進まないかな。#include #define F_CPU 1000000 /* 1MHz */ #include #define BAUD 9600 /* 9600bps */ #define SET_BAUD F_CPU/8/BAUD-1 // U2X=1 #define setbit(PORT,BIT) PORT|=_BV(BIT) #define clearbit(PORT,BIT) PORT&=~_BV(BIT) #define checkbit(PORT,BIT) (PORT&_BV(BIT)) // LCD #define LCD_PORT PORTD #define LCD_DDR DDRD #define LCD_MASK 0x3c // data PD 2-5 #define LCD_RS 1 //PA #define LCD_RS_PORT PORTA //PA #define LCD_RS_DDR DDRA //PA #define LCD_RW 0 //PA #define LCD_RW_PORT PORTA //PA #define LCD_RW_DDR DDRA //PA #define LCD_EN 6 //PD #define LCD_EN_PORT PORTD //PD #define LCD_EN_DDR DDRD //PD static volatile unsigned char lcd_buf[16]="123456789012345"; void lcd_send(unsigned char c){ // c=((c&0x0f)<<4)|((c&0xf0)>>4); //reverse // c=((c&0x33)<<2)|((c&0xcc)>>2); //reverse // c=((c&0x55)<<1)|((c&0xaa)>>1); //reverse c>>=2; c&=LCD_MASK; setbit(LCD_EN_PORT,LCD_EN); LCD_PORT=(LCD_PORT&~LCD_MASK)|c; clearbit(LCD_EN_PORT,LCD_EN); _delay_us(1); } void lcd_command8(unsigned char c){ clearbit(LCD_RS_PORT,LCD_RS); clearbit(LCD_RW_PORT,LCD_RW); lcd_send(c); _delay_us(100); } void lcd_command(unsigned char c){ //while(busy_address()&0x80){_delay_us(1);} clearbit(LCD_RS_PORT,LCD_RS); clearbit(LCD_RW_PORT,LCD_RW); lcd_send(c); lcd_send(c<<4); _delay_us(100); } void lcd_write(unsigned char c){ setbit(LCD_RS_PORT,LCD_RS); clearbit(LCD_RW_PORT,LCD_RW); lcd_send(c); lcd_send(c<<4); } void lcd_display(){ unsigned char i,j; i=0; for(j=0;j<0x48;j++){ if(j==0x08){j=0x40;} lcd_command(0x80+j); // DDRAM lcd_write(lcd_buf[i++]); } lcd_command(0x0f); // display } void lcd_shift(unsigned char s){ unsigned char n; for(n=0;n<15;n++){ lcd_buf[n]=lcd_buf[n+1]; } lcd_buf[15]=s; lcd_display(); } void lcd_init(){ _delay_ms(15); LCD_PORT=0; setbit(LCD_RS_DDR,LCD_RS); setbit(LCD_RW_DDR,LCD_RW); setbit(LCD_EN_DDR,LCD_EN); // LCD_DDR=0x0f|_BV(LCD_RS)|_BV(LCD_RW)|_BV(LCD_EN) ; LCD_DDR|=LCD_MASK; _delay_ms(15); lcd_command8(0x30); _delay_us(4000); lcd_command8(0x30); lcd_command8(0x30); lcd_command8(0x20); // 4bit lcd_command(0x2c); // 4bit //command(0x07); // mode,shift lcd_command(0x06); // mode,no shift lcd_command(0x01); // clear lcd_command(0x02); // home lcd_command(0x0f); // display } void disp_num(unsigned char c){ unsigned char i; // lcd_shift(0x20); i=c>>4; lcd_shift(i+((i<10)?0x30:0x37)); i=c&0x0f; lcd_shift(i+((i<10)?0x30:0x37)); } /* rs232c */ void init_rs232c(){ UBRRH=0; UBRRL=SET_BAUD; _delay_ms(5); setbit(UCSRA,U2X); /* double speed */ setbit(UCSRB,RXEN); /* RXCIE,TXCIE,UDRIE,RXEN,TXEN */ setbit(UCSRB,RXCIE); /* RXCIE,TXCIE,UDRIE,RXEN,TXEN */ setbit(UCSRC,USBS); /* 2 stop bits */ setbit(UCSRC,UCSZ0); /* 8bit*/ setbit(UCSRC,UCSZ1); /* 8bit*/ clearbit(UCSRB,UCSZ2); /* 8bit*/ } char receive_data(){ while(checkbit(UCSRA,RXC)==0){} /* received */ return UDR; } ISR(USART_RX_vect){ /* recieved */ char c; c=receive_data(); disp_num(c); } int main() { unsigned char i,j; _delay_ms(9000); init_rs232c(); lcd_init(); sei(); for(;;); }