* printfデバッグ [#m6b7df51]

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

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

** ソフト [#sa682df3]

[[HIDasp>https://web.archive.org/web/20111216032110/http://www.binzume.net/library/avr_hidasp.html]]のサイトから, hidaspxtermをダウンロードします. (まだWindows用しか用意してません)

** 回路 [#p0904e25]

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

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

** サンプルプログラム [#lb794cd6]

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: 8384  / today: 1  / yesterday: 0  / now: 1

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS