//****************************************************************************************** // AVR Sample Program // Project : // Program Name : // Programer : // Create date : Version 1.0 H23.09.25 // History : // Laungage : WinAVR GCC //****************************************************************************************** // Description // (1)I/O PORT // PB(2) : PWM OC0A // PD(5) : PWM OC0B // PB(3) : PWM OC1A // PB(4) : PWM OC1B // PD(0) : Sereal Comunication RX // PD(1) : Sereal Comunication TX //****************************************************************************************** #include #include #include #include #include #include void Int_PWM0(void); void Int_PWM1(void); void Int_uart(void); void Put_uart(char); void Put_uarts(char *); void Get_uart(char *); void Get_dec(void); void Itoa(char *,unsigned int); #define PI_DEF_DUTY 23 //50Hz=>19 / 61Hz=>23 int main (void) { // ******************** // 1.初期化 // ******************** // (0)システムクロックの設定(8MHzの1/2分周[4MHz]にする) CLKPR = 0b10000000; CLKPR = 0b00000001; // (1)ポートの初期化 DDRB=0; DDRD=0; // (2)PWM0の初期化(PWM0のポートも含む) Int_PWM0(); // (3)PWM1の初期化(PWM1のポートも含む) Int_PWM1(); // (4)UARTの初期化 Int_uart(); // (5)Start Message Put_uarts(" ATTINY2313 connected OK > "); // ******************** // 2.メイン // ******************** // (1)メイン処理 Get_dec(); while(1); } //****************************************************************************************** // Function Name : Get_dec // Title : UARTから角度データを入力し、デューティーを変更する // Input : // Output : // Description : //****************************************************************************************** void Get_dec(void) { #define PI_S0 0 #define PI_S1 1 #define PI_S2 2 #define PI_S3 3 #define PI_S4 4 #define PI_SEND 9 char tmp_c = 0x00; char STS_flg = 0x00; char Drive = 0x00; char Sgn = 0x00; int deg = 0; long duty = 0; char tmp_line[5]; STS_flg = PI_S0 ; while(1){ // ************************************* // 1.Set Command // ************************************* // (1)Get UART Get_uart(&tmp_c); tmp_c = toupper(tmp_c); Put_uart(tmp_c); // (2)Set command switch(STS_flg){ case PI_S0 : if(tmp_c =='A'||tmp_c =='B'||tmp_c =='C'||tmp_c =='D'){ STS_flg = PI_S1 ; Drive = tmp_c ; }else{ Put_uarts("[A-D]?"); } break; case PI_S1 : if(tmp_c =='+'||tmp_c =='-'){ STS_flg = PI_S2 ; Sgn = tmp_c ; }else if(tmp_c =='0'){ STS_flg = PI_SEND ; Sgn = '+' ; deg = 0; }else{ Put_uarts("[+/-/0]?"); } break; case PI_S2 : if('0' <= tmp_c && tmp_c <= '6'){ STS_flg = PI_S3 ; deg = (tmp_c & 0b00001111)*10; }else{ Put_uarts("[0-6]?"); } break; case PI_S3 : if('0' <= tmp_c && tmp_c <= '9'){ STS_flg = PI_SEND ; deg = deg + (tmp_c & 0b00001111); }else{ Put_uarts("[0-9]?"); } break; default: Put_uarts("[ERR-001]"); STS_flg = PI_S0 ; break; } // ************************************* // 2.Do Command // ************************************* if( STS_flg == PI_SEND ){ // (1)Put command image Put_uarts(" ["); Put_uart(Drive); Put_uart(Sgn); Itoa(tmp_line,(unsigned int)deg); Put_uarts(tmp_line); Put_uarts("] "); STS_flg = PI_S0 ; // (2)Do command // 2-1)Calc duty : (1.5[mS]*1000/20[mS]+DEG/2)/1000*256 :Feq 50Hz(20mS) Standard type // (1.5[mS]*1000/20[mS]+DEG/2)/1000*256*20/16.384 :Feq 61Hz(16.384mS) // if(Sgn == '-') deg=deg*-1 ; duty = (long)(1500/20+deg/2)*256/1000 *20/16.384; if(Drive=='A') OCR0A =(unsigned char)duty; else if(Drive=='B') OCR0B =(unsigned char)duty; else if(Drive=='C') OCR1AL=(unsigned char)duty; else if(Drive=='D') OCR1BL=(unsigned char)duty; } } } //**************************************************************************** // Function Name : Itoa // Title : // Input : // Output : // Description : 00 <= in_i < 100 //**************************************************************************** void Itoa(char out_s[],unsigned int in_i) { unsigned int tmp_i; if(in_i > 99){ out_s[0]='*'; out_s[1]='*'; out_s[2]=0x00; }else{ tmp_i = in_i % 10; out_s[1] = (char)tmp_i | 0x30 ; out_s[0] = (char)((in_i - tmp_i)/10) | 0x30 ; out_s[2]=0x00; } } //****************************************************************************************** // Function Name : Int_PWM0 // Title : タイマー0の8ビットPWM初期化 // Input : // Output : // Description : 8ビット高速PWMモードを使用 //****************************************************************************************** void Int_PWM0(void) { // ********************************************************* // 0.ポート(DDR)のOC0A,OC0Bを出力に設定 // ********************************************************* DDRB=DDRB|(1<8ビット高速PWM動作 // WGM00 :Waveform Generation Mode bit 1 and 0 // ********************************************************* TCCR0A=(1<8ビット高速PWM動作 // CS02 :Clock Select0, bit 2,1 and 0 001(分周なし)〜101(1024分周) // CS01 :Clock Select0, bit 2,1 and 0 OSC=8MHzの時、001なら 8MHz(OSC)/0xFF/1 => 31.250KHz // CS00 :Clock Select0, bit 2,1 and 0 101なら 8MHz(OSC)/0xFF/1024=> 30.6Hz // ********************************************************* // TCCR0B=(0<8ビット高速PWM動作 // WGM10 :Waveform Generation Mode bit 1 and 0 // ********************************************************* TCCR1A=(1<8ビット高速PWM動作 // WGM12:Waveform Generation Mode bit 3 and 2 // CS12 :Clock Select1, bit 2,1 and 0 001(分周なし)〜101(1024分周) // CS11 :Clock Select1, bit 2,1 and 0 OSC=8MHzの時、001なら 8MHz(OSC)/0xFF/1 => 31.250KHz // CS10 :Clock Select1, bit 2,1 and 0 101なら 8MHz(OSC)/0xFF/1024=> 30.6Hz // ********************************************************* // TCCR1B=(0< UBRR=Fck/(16*BAUD) - 1 // 10MHz,9600BAUDの時, UBRR=10M/(16*9600)-1=>64.10(Dec) // 8MHz,9600BAUDの時, UBRR= 8M/(16*9600)-1=>51.08(Dec) // 4MHz,9600BAUDの時, UBRR= 4M/(16*9600)-1=>25.04(Dec) UBRRL = 25; UBRRH = 0; } //**************************************************************************** // Function Name : Put_uarts // Title : Put Strings // Input : // Output : // Description : //**************************************************************************** void Put_uarts(char in_str[0] ) { unsigned int lp=0; unsigned int lp1; while(in_str[lp]!=0x00){ Put_uart(in_str[lp]); for(lp1=0;lp1<1000;lp1++) asm("NOP"); lp++; } } //****************************************************************************************** // Function Name : Put_uart // Title : Put UART // Input : // Output : // Description : //****************************************************************************************** void Put_uart(char io_char) { // (1)送信バッファ空き待機 while(!(UCSRA & (1<