AVRマイコン UART動作異常

このQ&Aのポイント
  • AVRマイコンのATmega168にてPCとRS-232Cにてシリアル通信(UART)を行うと最初のスタートビットが正常に出ない現象が発生しています。
  • 最初のスタートビットが正常に出ない原因がわかりません。解決方法を教えてください。
  • システムクロックは1MHz(内部発振器のみ)、ボーレートは4800bps、データビット数は8bit、ストップビット数は1bit、パリティビット数はなしです。
回答を見る
  • ベストアンサー

AVRマイコン UART動作異常

AVRマイコンのATmega168にてPCとRS-232Cにてシリアル通信(UART)を行うと最初のスタートビット'L'が正常に出ず、スタートビット'L'の後すぐに'H'に戻ってその後データビットを送っています。2回目以降のスタートビットは正常に'L'が指定したボーレートの時間幅で出ており、問題はありません。最初のスタートビットが正常に出ない原因がわかりませんので教えてください。 システムクロック:1MHz(内部発振器のみ) ボーレート:4800bps データビット数:8bit ストップビット数:1bit パリティビット数:なし -------------------------------------------- #include <avr/io.h> #include <util/delay.h> #include <avr/pgmspace.h> #define sbi(addr,bit) addr |= (1<<bit) #define cbi(addr,bit) addr &= ~(1<<bit) void port_init(void){ PORTB = 0xFE; DDRB = 0xFF; asm("NOP"); } void uart_init(void){ sbi(DDRD,1); cbi(DDRD,0); asm("NOP"); } void uart_putchar(unsigned char c){ loop_until_bit_is_set(UCSR0A,UDRE0); // asm("NOP"); UDR0 = c; } void _delay_1s(void){ int i; for(i=0;i<100;i++){ _delay_ms(10); } } int main(void) { port_init(); uart_init(); UCSR0B = _BV(TXEN0); UCSR0C = 0b00000110; UBRR0H = (uint8_t)0; UBRR0L = (uint8_t)12; while(1) { uart_putchar(0b01011010); _delay_1s(); } return 0; } -----------------------------------------------

noname#230358
noname#230358

質問者が選んだベストアンサー

  • ベストアンサー
noname#230359
noname#230359
回答No.1

多分 UBRRnH と UBRRnL へのセッティング時期が問題だと思うよ。

noname#230358
質問者

お礼

早速の回答大変ありがたいです。 セッティングの順番を変えるとうまくいきました。

関連するQ&A

  • マイコン(AVR)で、ある式を記述すると hex データが跳ね上がってしまう

    サインカーブを算出するために以下の質問をし、計算式を回答していただきました http://okwave.jp/qa4751105.html ですが、別の問題にあたってしまいました 上記回答の計算式をプログラムに書き込むと、コンパイル後の容量が跳ね上がってしまいます 同様の計算式で、x y に直接数字を指定すると容量が跳ね上がることはなさそうです ですが、変数を指定できなければ意味がありません なぜこのようなことが起こるのでしょうか? また、解決方法はありますか? #define F_CPU 800000UL #include <avr/io.h> #define sbi(BYTE,BIT) BYTE|=_BV(BIT) #define cbi(BYTE,BIT) BYTE&=~_BV(BIT) #include <math.h> const int sin_max1 = 127, sin_max2 = 255; int main(void) { DDRA = 0b111; DDRB = 0b11111111; DDRD = 0b1111100; PORTA = 0; PORTB = 0; cbi(PORTD, PD2); cbi(PORTD, PD3); cbi(PORTD, PD4); cbi(PORTD, PD5); cbi(PORTD, PD6); int i = 0; while (1) { sin_get(sin_max1, i); i++; if (i > sin_max1) i = 0; } } void sin_get(const int x, const int y) { int z; z = 127.5 * sin(2 * M_PI * y / x) + 127.5; // y x を直接数字に置き換えると容量は跳ね上がらない PORTB = z; }

  • AVRプログラム 関数から戻ってこない

    AtmelStudio6 で、ATmega64A向けにプログラム行なっているのですが、 すごく、単純なところで困っています。 ICEは、AVR JTAGICE です。 main() のみで処理をさせると普通に動くのですが、関数に飛ばすと飛んだ先の 関数から戻ってこなくなるのです。 ツールかレジスタの設定が不十分なのかもしれません。 -- 問題のプログラム -- #include <avr/io.h> #include <avr/iom64a.h> #include <avr/interrupt.h> #include <util/delay.h> void test(void){ DDRA = 0xC0;//<ここは、実行される }//デバッガで見ると、ここで止まっている。 int main(void) { cli();//この関数はライブラリにあるので戻ってくる test();//この関数から帰ってこない // DDRA = 0xC0; //test();の内容をここに書くと、正常に処理して通過する。 PORTB = 0xFF; //B出力レジスタ DDRB = 0xF7; //B方向レジスタ PORTC = 0xFF; DDRC = 0xDB; while(1) { //TODO:: Please write your application code LEDを点滅させるプログラム <略> } } ------------------------------------------------------- 何方か心当たりのある方は居ないでしょうか?

  • AVRマイコン開発

    #include <avr/io.h> int main(void) { volatile long i; PORTB = 0xff; DDRB = 0xff; while(1) { P1NB |= _BV(PB0); for (i = 5000; i > 0; i--); } return 0; } Build failed... No build tools defined. こんなエラーがでたのですがどこが間違っているのでしょうか?

  • AVRマイコン ビルドエラー

    AVRマイコンを #include <avr/io.h> int main(void) { DDRD =0b11111111; PORTD=0b11111111; } で、ビルドしようとしているのですが、 ../test3.c:0: error: MCU `atmega88p' supported for assembler only と、その後に ../test3.c:5: error: `DDRD' undeclared (first use in this function) 等と、エラーが出てビルド出来ません。 どうすればいいのでしょうか? 回答お願いします。

  • トランジスタ技術8月号:UARTについて

    こんにちは。 トランジスタ技術2007年8月号付録のdsPIC30Fを使って色々といじっているのですが、UARTのところで問題が現れてしまいました。 付録基盤の23・24ピン(dsPIC30F2012の16・17ピン)のURx/UTxを使って、他の組み込みチップと20~30バイトのパケットを通信したいのですが、ボーレートやパリティの設定を正しく行っても送受信ができません。 PCのRS232-Cと組み込みチップを繋げて通信はできているのですが、付録基盤から同じパケットを送信すると不定値が現れてしまいます。 電圧や配線は確かめましたが、特に問題がありそうな場所はありませんでした。 ソースは次のような感じです。助けていただけないでしょうか。 #include <uart.h> #include <p30f2012.h> void init() { unsigned int _U1BRG; // U1BRG register config unsigned int _U1MODE; // U1MODE register config unsigned int _U1STA; // U1STA register config CloseUART1(); ConfigIntUART1( UART_RX_INT_DIS & UART_TX_INT_DIS ); // U1BRG register _U1BRG= ( (7370000*4/19200)/16); // Fcy / BaudRate / 16 // U1MODE register, I/O (U1TX/U1RX), N81 _U1MODE = UART_EN & UART_IDLE_CON & UART_RX_TX & UART_DIS_WAKE & UART_DIS_LOOPBACK & UART_EN_ABAUD & UART_NO_PAR_8BIT & UART_1STOPBIT; // U1STA register _U1STA = UART_INT_TX_BUF_EMPTY & UART_TX_PIN_NORMAL & UART_TX_ENABLE & UART_INT_RX_CHAR & UART_ADR_DETECT_DIS & UART_RX_OVERRUN_CLEAR; // Open UART1 OpenUART1(_U1MODE, _U1STA, _U1BRG); } // end of init() int main(void){ unsigned int packet[] = {パケットデータ} unsigned int result[30]; unsigned int i; // write process for(i=0; i<PACKET_LENGTH; i++) { while(U1STAbits.UTXBF != 0) { ; } U1TXREG = packet[i] & 0xFF; } while(!U1STAbits.TRMT) {;} // read process for(i=0; i<PACKET_LENGTH; i++) { while(U1STAbits.URXDA != 0) {;} result[i] = U1RXREG & 0xFF; } // for(i) while(1) {;} } // end of main()

  • H8マイコンのシリアル通信について。

    H8マイコンでのシリアル通信についてお聞きしたいことがあります。 現在PCとマイコン(H8/3052F)をRS32Cでシリアル通信ができています。 今回は有線ではなく無線(Bluetooth)を利用してシリアル通信が行いたく、RBT-001というものを購入しました。 そのマニュアルには一番簡単に通信する方法としてPICマイコンとの例が挙げられており、要するに初期設定さえすれば無線を意識せずに使えるとの事だったのですが、どうも出来ていないみたいです。 --------------------私のプログラム---------------------- #include<3052.h> void initSCI1 (void){ int i; SCI1.SCR.BYTE = SCI1.SMR.BYTE = 0;//初期値は0、本文参照 SCI1.BRR = 80; //ビットレート for (i = 0; i <4000; i++) ; //待つ SCI1.SCR.BYTE = 0x30; //受信割り込み許可、送受信許可 SCI1.SSR.BYTE; //ダミーリード SCI1.SSR.BYTE = 0x80; //エラーフラグクリア } //1文字受信 char SCI1_IN_d(void){ //受信文字を返す。 unsigned char c; //受信データの格納変数 while (!(SCI1.SSR.BYTE & 0x78)); //受信またはエラーフラグが立つまで待つ if (SCI1.SSR.BIT.RDRF == 1) { //受信完了なら c = SCI1.RDR; //データを取り出す。 SCI1.SSR.BIT.RDRF = 0; //受信フラグクリア } else { SCI1.SSR.BYTE &= 0x80; //エラーならエラーフラグクリア c = 0; } return c; } //1文字送信 void SCI1_OUT_d(char c) //文字コードを受け取る。 { while (SCI1.SSR.BIT.TDRE == 0); //0でデータあり、1になるまで待つ。 SCI1.TDR = c; //受け取った文字を送信 SCI1.SSR.BIT.TDRE = 0; //TDREビットをクリア } //BLUETOOTH初期設定 void BT_Init(void){ SCI1_OUT_d(0x02); SCI1_OUT_d(0x52); SCI1_OUT_d(0x4E); SCI1_OUT_d(0x01); SCI1_OUT_d(0x00); SCI1_OUT_d(0xA1); SCI1_OUT_d(0x03); SCI1_OUT_d(0x03); return; } int main (void){ unsigned char rd; BT_Init(); initSCI1(); while(1){ rd=SCI1_IN_d(); SCI1_OUT_d(rd); } } ------------------------------------------------------------ 問題はmain文中「initSCI1();」でSCI1を初期化するとズット変な文字化けみたいなのを延々と吐き出して、逆に初期化しないとPCでなんらかのキーを押すとRBT-001は点滅はするけど、文字を返してこないという状況です。 なので「initSCI1();」がおかしいのかと思うのですが、有線では現にこれで出来ているのでなにが原因かわかりません。 良かったらどこがダメでどうするべきか教えてください。 本当に困っています。よろしくお願いします。 通信速度9600bps データ長8ビット長 ストップピット1 パリティ無 CPU最高動作周波数25MHz -------------------RBT-001マニュアルに記載されているサンプルプログラム------------------------- char text; void BT_Init(); void MPU_Init(); int TRISB,ANSEL,ANSELH; int _LCD_FIRST_ROW,_LCD_CURSUR_OFF,_LCD_CLEAR; void main(){ MPU_Init(); BT_Init(); while(1){ if(Uart1_Data_Ready()){ text = Uart1_Read(); Uart1_Write(text); Lcd_Chr_Cp(text); } } } void MPU_Init(){ TRISB = 0; ANSEL = 0; ANSELH = 0; Uart1_init(9600); Lcd_Init(); Lcd_Cmd(_LCD_FIRST_ROW); Lcd_Cmd(_LCD_CURSUR_OFF); Lcd_Cmd(_LCD_CLEAR); return; } void BT_Init(){ Uart1_Write(0x02); Uart1_Write(0x52); Uart1_Write(0x4E); Uart1_Write(0x01); Uart1_Write(0x00); Uart1_Write(0xA1); Uart1_Write(0x03); Uart1_Write(0x03); return; } -------------------------------------------------------------------

  • AVRマイコンで4bit分のデータをシリアルで送る

    お世話になります。AVRマイコン初心者です。 ATtiny2313 を使い、メロディICの入力端子に4bit分のデータをシリアルで送りたいです。 メロディIC → SM11125ABV (セイコーNPC製) データシート → ftp://ftp.npc.co.jp/pub/pdf_j/1125abv_nc0720a.pdf やりたいことは、SM1125ABVの入力端子SI, SCに選曲のためのデータを送り、選曲することです。 データシートにあるように、1bit分のパルス幅は2μsです。 ようは、この幅のパルスを出力できればいいのですが・・・・ 何から始めればよいのか・・・・ 検索したら、UARTというのが見つかりましたが、例がやたらと文字列の送受信で… 文字列の部分を0 ,1 に置き換えたら、H、Lのパルスが出力されてくれるのか??? それとも、タイマで割り込みのタイミングでH、LをI/Oポートから出力させればいいのか??? WinAVRを使います。 どうかアドバイスよろしくお願いいたします。

  • H8S2368マイコンのTCSR_1レジスタの4ビット目が1のはずなのに0と表示される。

    いま、H8S2368マイコンのプログラムを作っているのですが、 TCSR_1レジスタの値を printf("data:%X addr:%p\n\r", TMR1.TCSR.BYTE,(void*)&TMR1.TCSR.BYTE); このプログラムでリードしてみて、UART通信で受信したところ ”data:C0 addr:ffffb3” このレジスタのデータが0xC0というのを確認しました。 このH8S2368マイコンのデータシートの502ページ目(rjj09b0162_h8s2368.pdf)では、このレジスタの4ビット目はリザーブビットで、リードすると必ず”1”が読み込まれると書かれているのですが、なぜかそのビットが”0”で帰ってきます。 ”0xD0”ならばわかるのですが、これはなぜなのでしょうか?

  • H8SマイコンでUARTを115.2kに設定したい

    現在、H8S2368マイコンとwifi通信モジュールであるESP-WROOM-02をUART通信で接続するためにプログラムを作成しています。 H8S2368のSCI0のUARTでESP-WROOM-02とをつなぎました。 とりあえずSCI0から”AT”というコマンドを出したのですが、wifiモジュールから”OK”という回答が戻ってきません。 原因を調べてみると、H8S2368のSCI0は38.4kbpsで出力していて、ESP-WROOM-02は初期通信速度が115.2kで速度があっていないことが判りました。 とりあえずH8S2368のSCI0を115.2k変更したいのですが、どのようにすれば115.2kbpsに変更できるのか教えていただきますよう、よろしくお願い致します。 現在のSCI0のUARTに関する設置はこちらです。 (hwsetup.c) SCI0.SCR.BYTE = 0x00; SCI0.SMR.BYTE = 0x00; SCI0.BRR = 15; for(i=0;i<30000L;i++); /* Async, 8-data, odd-parity, 1-stop, N-multi, CLK */ SCI0.SCR.BIT.TE = 1; /* Transmit Enable */ SCI0.SCR.BIT.RE = 0; /* Receive Enable */ SCI0.SCR.BIT.RIE = 1; /* Receive Interrupt */ SCI0.SCR.BIT.TIE = 0; /* Transmit-data-empty Interrupt */ SCI0.SCR.BIT.TEIE = 0; /* Transmit End Interrupt */ SCI0.SSR.BIT.TDRE = 0; /* Clear TDR Empty flag */ H8S2368のデータシートを見ていると、 SCI0.BRR = 15; このBBRレジスタに代入する値をもう少し下げていけば115.2kHzに近づいていくのかなぁ、と感じるのですが、正確な計算方法など教えていただけると助かります。

  • PICのプログラムについて質問です

    使用するPICは16F84Aで、MPLAB IDEv8.88を使ってこのようなプログラムを作りました。 #include"pic.h" static void pic_init(); static void Delay_ms(unsigned char ms); static void Delay_1ms(); void main(){ pic_init(); while(1) { RB0 = 1 ; Delay_ms(250); Delay_ms(250); Delay_ms(250); RB0 = 0 ; Delay_ms(250); Delay_ms(250); Delay_ms(250); } static void pic_init() { // GPIO = 0b00000000; TRISA = 0xFF ; TRISB = 0x00 } static void Delay_ms(unsigned char ms) { unsigned char c; for (c=ms ; c>0 ; c--) { Delay_1ms(); } } static void Delay_1ms() { unsigned int cnt; unsigned int i; cnt = 76; for (i=0 ; i<cnt ; i++) { NOP(); } } ポートB0の出力を0から1にするプログラムなのですが、実行すると Error [314] C:\Users\moriwaki\Desktop\PIC program\step_test2.c; 52.24 ";" expected Error [254] C:\Users\moriwaki\Desktop\PIC program\step_test2.c; 77.0 undefined variable: "pic_init" ********** Build failed! ********** というエラーが出ます。このようなエラーが出る原因を教えて頂けないでしょうか。お願いします。