• 締切済み

トランジスタ技術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()

みんなの回答

  • moochin
  • ベストアンサー率0% (0/0)
回答No.4

一番最後の受信ループのところ; URXDA==0 じゃあないのかなあ。1になるまで待っている。

nekotatsu
質問者

お礼

moochinさん 回答ありがとうございます。 >URXDA=0 : 少なくとも1文字は読み取り可能 >URXDA=1 : 受信バッファが空 while( URXDA==0 ) {;} が正解ですね・・・ 送信フラグの方の条件とこんがらがっていたようです。 改めてテストしてみましたが、やはりランダム値(ノイズ?)が現れて、正しいデータの送信も受信も行えませんでした。 というか、dsPICの送信バッファに何も書き込んでないにも関わらず、ランダム値が延々と出力されているようです。 (ADM3202レベルコンバータ経由でハイパーターミナル確認) 根本的な問題で、基盤のUART回りが壊れてる可能性もあらわれてきました。ili○| ̄|_ dsPIC30F2012の17,18ピンと付録基盤の23,24ピンの間は通電はしているので、dsPIC30F2012自体が壊れているのかもしれません。

  • moochin
  • ベストアンサー率0% (0/0)
回答No.3

ごめんなさい。RIDLEは読み込み専用でしたね。ここを書き換えてもダメですね。うーん、判らない。

  • moochin
  • ベストアンサー率0% (0/0)
回答No.2

あ、そうでしたか。ピンは正しかった。するとソフトですね。 よく判らないけど、U1STAの論理績を見るとRIDLEが1になっているように 思えます。受信がアイドル状態なので読み込んだつもりでもデータがおかしいのでは? U1STAbits.RIDLE=0;と明示してみたらどうでしょうか?

  • moochin
  • ベストアンサー率0% (0/0)
回答No.1

ピンが違っているのでは?17--U1TX, 18--U1RX です。 または ALTIO を Enable にして、11,12 を使う。

nekotatsu
質問者

お礼

moochinさん 回答ありがとうございました。 16,17ピンというのは私の間違いでした。実際には17,18ピンに接続していました。 dsPICとPCのRS-232のTx-Rxをレベルコンバータ越しに接続してみました。PICのU1TXをPCのRxに、PICのU1RXをPCのTxに繋げているのですが、正常な信号出力が確認できませんでした。でたらめなランダム値が出るか、PICからの信号が全く現れないのどちらか。 また片方の配線接続を外すとランダムな信号(ノイズ?)が受信されてしまいました。 ジャンパをカットしてALTTX、ALTRXで通信も試してみたのですが、やはりうまくいきませんでした。

関連するQ&A

  • DMAを使ったUARTの受信が一度しかできない

    STM32F3 シリーズにて DMA を利用した UART 通信の受信を行ってます。 通信するデータは 7Byte 1Set の固定データで、連続して送信されます。 デバッグを開始して最初の 7Byte は受信できるのですが、それきり受信が止まってしまいます。 何か考えられる原因はありますか? 該当すると思われる箇所のコードを以下にピックアップします。 UART_HandleTypeDef huart1; DMA_HandleTypeDef hdma_usart1_rx; #define USART1_RX_LEN 7 uint8_t USART1_RXD_Buffer[USART1_RX_LEN]; int main(void) { HAL_Init(); SystemClock_Config(); HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_1); HAL_NVIC_SetPriority(SysTick_IRQn, 0, 1); MX_GPIO_Init(); MX_DMA_Init(); MX_USART1_UART_Init(); HAL_UART_Receive_DMA(&huart1, &USART1_RXD_Buffer[0], USART1_RX_LEN); while (1) { } } ちなみに、最初に 7Byte を正常に受信した後、 huart1.Lock = HAL_UNLOCKED huart1.State = HAL_UART_STATE_READY huart1.ErrorCode = HAL_UART_ERROR_NONE hdma_usart1_rx.Lock = HAL_UNLOCKED hdma_usart1_rx.State = HAL_DMA_STATE_READY となってます。 (この状態で受信も受信による割り込みも発生しない状態になってしまいます。)

  • 困っています

    どうしても、--unsigned型のビット内容表示--の所が意味が分かりません。分かりやすく教えてください。宜しくお願いします。 /* 0~UINT_MAXを2進・8進・16進で表示 */ #include <stdio.h> #include <limits.h> /*--- 整数xのセットされたビット数を返す ---*/ int count_bits(unsigned x) { int count =0; while (x) { if (x & 1u) count++; x>>=1; } return (count); } /*---- unsigned型のビット数を返す ----*/ int int_bits(void) { return (count_bits(~0U)); } /*---- unsigned型のビットを内容を表示 ---*/ void print_bits(unsigned x) { int i; for (i=int_bits() -1; i>=0; i--) putchar(((x>>i) & 1U) ? '1' : '0'); } int main(void) { unsigned i; for (i=0; i<UINT_MAX; i++) { print_bits(i); printf(" %6o %5u %4X\n", i, i, i); } return(0); }

  • USART通信で文字化け

    __CONFIG( WDTDIS & UNPROTECT & BORDIS & MCLRDIS & PWRTEN & HS & LVPDIS ); // // test.c 2009/07/30 HI-TECH C Compiler // プリスケーラ1/256 セラミック発振子10MHz使用 1命令当り102us // unsigned char buff[10]; unsigned int RecCnt=0; main(){ /*Port initalizeなど .................... */ RCSTA = 0x90; TXSTA = 0x24; SPBRG = 0x40; //BaudRate 9600 FOCS 10MHz unsigned int i; while(1){ putch('A'); for(i=0; i<60000; i++); putch('K'); for(i=0; i<60000; i++); } } ヘッダーファイル #ifndef _SERIAL_H_ #define _SERIAL_H_ #define BAUD 9600 #define FOSC 10000000L #define NINE 0 // Use 9bit communication? FALSE=8bit #define DIVIDER ((int)(FOSC/(16UL * BAUD) -1)) #define HIGH_SPEED 1 #if HIGH_SPEED == 1 #define SPEED 0x04 #else #define SPEED 0 #endif #define RX_PIN TRISB1 #define TX_PIN TRISB2 /* Serial initialization */ #define init_comms()\ RX_PIN = 1; \ TX_PIN = 1; \ SPBRG = DIVIDER; \ RCSTA = (NINE_BITS|0x90); \ TXSTA = (SPEED|NINE_BITS|0x20) void putch(unsigned char); unsigned char getch(void); unsigned char getche(void); #endif void putch(unsigned char byte) { unsigned int i; /* output one byte */ while(!TXIF) /* set when register is empty */ continue; TXREG = byte; } unsigned char getch() { /* retrieve one byte */ while(!RCIF) /* set when register is not empty */ continue; return RCREG; } 上記が自分で作成したUSART通信を使用したプログラムです。AとKを送信しています。ですがハイパーターミナルで受信した文字列を見てみるとまったく異なる文字や空白など文字化けをしていました。 前に作成した時は正常に表示されたのですが、今また流用してみると文字化けしていました。 発振子に10MHz使用でBRGH=1(高速)と9600bps→SPBRG=0x40 原因はここだと思うのですが、、、謎です。 丸投げな感じですが、どうか分かる方回答をお願いします。

  • 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; } -----------------------------------------------

  • ビット構成について

    今、ビットについて勉強しているのですが、わからないところがありますので、質問しました。わかる方がいれば、わかりやすく教えてください。(例として、整数xは10とした場合をしてもらえる助かります。) int count_bits(unsigned x){ int count = 0; while (x){ if (x & 1U) count++; x >>= 1; } return (count); } int int_bits(void){ return (count_bits(~0U)); } void print_bits(unsigned x){ int i; for ( i = int_bits() - 1 ; i >= 0; i--) putchar(((x >> i) & 1U) ? '1' : '0'); } 以上 まず、 int count_bits(unsigned x){ int count = 0; while (x){ if (x & 1U) count++; x >>= 1; } return (count); } についてですが、整数Xを10とした場合、私の考えではcount=2となると思うのですが・・・。 次に int int_bits(void){ return (count_bits(~0U)); } についてなのですが、count_bits関数で整数Xを10とした場合count=2となったあと、int_bits関数では全ビットを1にするということみたいですが、count_bits関数でおこなった作業をどうint_bits関数で処理するのかわかりません。 最後が for文の中の、(i = int_bits() - 1 ; i >= 0; i--) についてですが、整数10のときの i = int_bits() はどうなっているのでしょうか?? わかりにくい質問ですみません。 回答宜しくお願いします。

  • unsigned型のビット構成を表示するプログラムが理解できません。

    unsigned型ビット構成の表示プログラム #include<stdio.h> int count_bits(unsigned x) { int count=0; while(x){ if(x&1U)count++; x>>=1; } return(count); } int int_bits(void) { return(count_bits(~0U)); } void print_bits(unsigned x) { int i; for(i=int_bits()-1;i>=0;i--) putchar(((x>>i)&1U)?'1':'0'); } int main(void) { unsigned nx; printf("非負の整数を入植してください。:"); scanf("%u",&nx); print_bits(nx); putchar('\n'); return(0); } このプログラムで10を入力したら、00000000000000000000000000000001010と表示され。 18だと00000000000000000000000000000010010と表示される原理が理解できません。 自分なりにプログラムを追ってこういう考えてます。 まず、10を入力したらcount_bitsの関数の処理からスタート。 while(x){ if(x&1U)count++; x>>=1; if(x&1U)の処理を行い。x=10はbit単位表示で、1010として考え。一番右側の101「0」とunsigned型の1との論理比較を行う。0と1なので偽で何もせずにif文を抜けて、x>>=1;を行いx=0101となり。while(x)から再びif(x&1U)行う。x=0101の一番右側のunsigned型の1との論理比較を行い0と1なので真なのでcount++を行いcount=1としてif文を抜け、x>>=1;を行いX=0010になり。三度目のif(x&1U)の処理を行う。0010の一番左側のunsigned型の1との論理比較を行い0と1なので偽でif文を終了。x>>=1;を行い0001となり、再びif(x&1U)行う。 00 01の一番左側のunsigned型の1との論理比較を行い0と1なので真なのでcount++を行いcount=2となり、x>>=1;を行い0000なのでwhile(x)を抜けて返り値2をint_bitsへ返して関数は終了 int_bitsではunsinged型の2が戻り値としてprint_bitsへ返し、int_bitsの関数は終了。 print_bitsの処理が始まり。for(i=int_bits()-1;i>=0;i--)の処理がスタート。 i=int_bits()-1の処理でiは2-1でi=1からスタート。 putchar(((x>>i)&1U)?'1':'0');の処理。 (x>>i)でx=10,i=1なので1010>>1だから0101。 0101の一番右側の1とunsigned型の1と論理比較を行う 真なのでputcharは'1'を一度表示。 for文に戻りiをデクリメントとしてi=0なのi>=0から 一度、putchar(((x>>i)&1U)?'1':'0');処理。 (x>>i)は0101>>0の0右シフト行い0101。 unsignedと1を0101の一番右側の1と論理比較を行う 真なのでputcharは'1'を一度表示。 for文に戻りiをデクリメントとしてi=-1なのでi>=0からfor文を終了してprint_bitsの処理を終了。mainの関数処理に戻り。putchar('\n');を出力して関数処理は終了。表示として「11」が表示される。18も同様に考えているので、「11」が表示されてしまうのでは?という考えに陥ってます。実際は、両方とも正しくunsigned型ビット構成の表示されるので、自分の考え方が間違えている。なのですが、どう間違えているかがわかりません。 多少説明文の省略しているためわかりにくいかもしれませんが、間違えを指摘していただけないでしょうか?

  • 4バイトでのサムチェックコード作成プログラミング

    下記のようにTx[1]からTx[19]までのサムチェックコードを Tx[21](上位)、Tx[22](下位)に格納したいのですが上手くいきません。記述の訂正点やもっと良い方法があったら教えて下さい。 unsigned char Tx[30]; unsigned int sum; for( i = 1; i < 20; i++ ) // サムチェックコード作成 sum ^= Tx[ i ]; Tx[ 22 ] = sum; //23 サムチェックコード2 sum = sum >> 8; Tx[ 21 ] = sum; //22 サムチェックコード1

  • 関数とビット列

    C言語勉強中です。下記本から抜粋したものですが、 関数の流れや、1U、~0Uなどの意味がわかりません。 それぞれ関数の中でどのような処理をしているのでしょうか? scanfで正数入力し、print_bitsにnxを渡し、そこのxを1と&して 2進の0か1を表示させるのはなんとなく解るのですが、PCのCPUの ビット数を確認する為?の動きなどがわかりません。 どうか、解説していただける方、よろしくお願いします。 #include <stdio.h> int count_bits(unsigned x) {     int count = 0;     while (x) {           if (x & 1U) {              count++;           }           x >>= 1;      }      return (count); } int int_bits(void) {      return (count_bits(~0U)); } void print_bits(unsigned x) {      int i;      for (i = int_bits() - 1; i >= 0; i--) {           putchar(((x >> i) & 1U) ? '1' : '0');      } } int main(void) {      unsigned nx;      printf("非負の整数を入力してください:");      scanf("%u", &nx);      print_bits(nx);      putchar('\n');      return (0); }

  • C言語 unsigned 表示

    #include<stdio.h> int count_bits(unsigned x){ int count=0; while(x){ if(x&1U){ count++; } x>>=1; } return count; } int int_bits(void){ return(count_bits(~0U)); } unsigned rrotate(unsigned x1 ,int n){ int bits=int_bits(); n%=bits; return(n? (x1>>n)|(x1<<(bits-n)):x1); } int main (void){ unsigned nx,b; b=rrotate(nx,2); printf("%u\n",b); return(0); } 3221225476や1073741829と表示されることがあります。 入力値を4で割った数を表示するには、どうしたらよいでしょう・ 御指摘お願いします。

  • C++の無限ループを解決してください

    アルゴリズムを勉強するときに以下のソースを書きました; void weighted_quick_union_algorithm() { static const int volume = 10; enum status { terminate_, union_, find_ }; string str; status sta; vector<int> system(volume, 0); vector<int> size(volume, 1); for (int index = 0; index != volume; ++index) { system[index] = index; } do { cout<<"cin"<<endl; cin >> str; for (string::size_type index = 0; index != str.size(); ++index) str[index] = toupper(str[index]); if (str == "UNION") sta = union_; else if (str == "FIND") sta = find_; else if (str == "TERMINATE") sta = terminate_; switch (sta) { case(0): { cout << str << endl; break; } case(1): { cout << str << sta << endl; int p(0), q(0), i(0), j(0); while (cin >> p) { cin >> q; for (i = p; i != system[i]; i = system[i]); for (j = q; j != system[j]; j = system[j]); if (i == j) continue; if (size[i] < size[j]) { system[i] = j; size[j] += size[i]; } else { system[j] = i; size[i] += size[j]; } cout << p << " - " << q << endl; } cout<<"break"<<endl; break; } case(2): { cout << str << sta << endl; break; } } } while (sta); } しかし unionを入力しあと ; でwhile(cin>>p)をブレイクしたら cin break UNION1 cin break Union1 で無限ループ 結構時間かかったが間違いがわかりません ちなみに最少は while(cin>>p>>q)と書いていましたが同じ結果です。 どうかお願いします