printfデバッグ

AVRの実機上でデバッガを使ったデバッグするためには, 高価なICEを使わなければいけないので,せめてprintfデバッグをできるようにしましょう.

AVRにはディスプレイが繋がっていないのでprintfの出力先が問題です. そこで,書き込みみ使ったHIDaspxでPCとAVRの間の通信をしてみましょう. 流石に貴重な入出力を4本もそのために使ってしまうのは問題かもしれませんが.

ソフト

HIDaspのサイトから, hidaspxtermをダウンロードします. (まだWindows用しか用意してません)

回路

通信するときは, 書き込み時にRESET(1番ピン)に繋いでいた線を,SS(16番ピン)に繋ぎ変えます. 切り替えスイッチをつけても良いですが, とりあえずは手動でブレッドボード上の配線を切り替えてください.

面倒な場合は,書き込み時はRESETとSSの両方に配線しておいて, 動作時はRESETの方をはずす…というのでもとりあえずは大丈夫です.

サンプルプログラム

WinAVR等に付いているavr-libcには機能制限版ですが「stdio.h」があります.

  • 定期的に文字列を表示
  • エコーバック
   // sample for atmega88
   #define F_CPU 8000000
   #include <avr/io.h>
   #include <avr/interrupt.h>
   #include <util/delay.h>
   #include <stdio.h>
   
   #define BUFSIZE 64 // 2^n size
   volatile char spi_rxbuf[BUFSIZE];
   volatile char spi_txbuf[BUFSIZE];
   volatile uint8_t spi_rxr=0, spi_rxw=0;
   volatile uint8_t spi_txr=0, spi_txw=0;
   
   ISR(SPI_STC_vect) {
       uint8_t c=SPDR;
       if (spi_txr!=spi_txw) {
           SPDR = spi_txbuf[spi_txr];
           spi_txr=(spi_txr+1)&(BUFSIZE-1);
       } else {
           SPDR=0;
       }
       if (c) {
           spi_rxbuf[spi_rxw]=c;
           spi_rxw=(spi_rxw+1)&(BUFSIZE-1);
       }
   }
   
   void SPI_init_slave() {
       SPCR = (1<<SPE)|(1<<SPIE); // SPI許可, 割り込み許可
       DDRB |= (1<<PB4);  // MISO出力
       DDRB &= ~((1<<PB2) | (1<<PB3) | (1<<PB5)); SCK,MOSI,SSは入力
   }
   
   static int spi_recv_chk(){
       return spi_rxr!=spi_rxw;
   }
   static int spi_send_chk(){
       return ((spi_txw+1)&(BUFSIZE-1))!=spi_txr;
   }
   
   static int spi_putchar(uint8_t d) {
   //  while(!spi_send_chk());
       spi_txbuf[spi_txw]=d;
       spi_txw=(spi_txw+1)&(BUFSIZE-1);
       return 0;
   }
   static int spi_getchar() {
       spi_rxr&=(BUFSIZE-1);
       while(spi_rxr==spi_rxw);
       return spi_rxbuf[spi_rxr++];
   }
   
   void delay_ms(uint16_t t) {
      while (t--) _delay_ms(1);
   }
   
   static FILE spistream = FDEV_SETUP_STREAM(spi_putchar, spi_getchar, _FDEV_SETUP_RW); 
   
   int main() {
       // 初期化
       DDRB = 0xFF;
       DDRD = 0xFF;
       stdout=&spistream;
       stdin=&spistream;
       SPI_init_slave();
       sei();
       
       int i=0,j=0;
       for (;;) {
           delay_ms(1);
           while(spi_recv_chk()) {
               putchar(getchar());
           }
           if (++i==1000) {
               printf("Hello! j=%d\n",j);
               j++;
               i=0;
           }
       }
       return 0;
   }
total: 8153  / today: 1  / yesterday: 0  / now: 1

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2015-09-22 (火) 17:29:40 (1247d)