2016-05-27 15 views
0

私は、標準的なブートローダ(avra + avrdude)を備えたArduino UNOボード上で、AVRファミリのアセンブリプログラミングのレジスタを手にしています。arduino uno、timer0設定のAVRアセンブリ?

私はTimer0に問題があります。 I短いプログラムWICHに問題が

  • になっている低下しました(B5 =ピン13上)に赤色LEDを置く
  • ノーマルモードのタイマ0を設定し、プレスケール1024
  • カウンタを設定しました0
  • ループを入力し、カウンタが200以上200未満の場合はエスケープします。
  • 次に、緑色のLEDをオンにします(B4)。

症状:緑色のLEDが一度も点灯しません。他の値が200より大きい場合は、ランダムな時間(秒)後にオンになります。ここで

はコードです:

.include "./m328Pdef.inc" 

    .EQU ROUGE = 0b0100000 ; red 
    .EQU VERT = 0b0010000 ; green 


main: 
    ldi r16,ROUGE+VERT  ; pins activated 
    out DDRB,r16 
    ldi r16,ROUGE   ; red on 
    out portB,r16 

    ;; configure timer 
    lds r16,TCCR0B 
    andi r16,0b11111000 
    ori r16,0b00000101  ; prescale 1024 
    sts TCCR0B,r16 

    ldi r16,0  ; count is 0 
    sts TCNT0,r16 

loop: 
    lds r16,TCNT0    
    cpi r16,100 
    brlo loop 

    ldi r16,VERT  ; green on 
    out PortB,r16 

z: 
    nop 
    rjmp z 

同じプログラムタイマー1とそれに関連するレジスタで正しく動作するようです。

どういうところが間違っていますか?いくつかのブートローダーへの干渉?

EDIT HEXファイル:avra bug0.asm

アップロード::

:020000020000FC 
:1000000000E304B900E205B900912500087F05600E 
:100010000093250000E0009326000091260004369E 
:0A002000E0F300E105B90000FECF97 
:00000001FF 

はでコンパイルDDRBPORTBTCCR0BTCNT0など評価:

avrdude -q -V -D -p atmega328p -C /etc/avrdude.conf \ 
    -c arduino -b 115200 -P /dev/ttyACM0 \ 
    -U flash:w:bug0.hex:i 
+0

コードはOKと思われます。あなたはボードをフラッシュするためにあなたが何を使用するか/ hex/hexを含めることができますか? –

+0

Arduino UNOの標準ブートローダーのソースは、https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/bootloaders/optiboot/optiboot.cをご覧ください。ブートローダーはtimer1を使用しますが、timer0はそのままです。 –

+0

編集:質問に追加された16進数およびコンパイル/アップロードコマンド –

答えて

1

問題は定数であることです〜I/Oアドレスin/outで使用するのは問題ありませんが)TCCR0BTCNT0lds/stsを使用し、そのオペランドにはのデータスペースアドレスが含まれていると想定しています。

ソリューションはTCCR0BTCNT0in/outを使用するかのいずれかである - それはOKですが、これらのレジスタは、に属しているので、I/Oがを登録する(に対立するものとしては、I/Oは、そのデータ・スペースを使用してアクセスする必要がありますを登録延長しましたアドレス):

.include "./m328Pdef.inc" 

    .EQU ROUGE = 0b0100000 ; red 
    .EQU VERT = 0b0010000 ; green 


main: 
    ldi r16,ROUGE+VERT  ; pins activated 
    out DDRB,r16 
    ldi r16,ROUGE   ; red on 
    out portB,r16 

    ;; configure timer 
    in r16,TCCR0B 
    andi r16,0b11111000 
    ori r16,0b00000101  ; prescale 1024 
    out TCCR0B,r16 

    ldi r16,0  ; count is 0 
    out TCNT0,r16 

loop: 
    in r16,TCNT0 
    cpi r16,100 
    brlo loop 

    ldi r16,VERT  ; green on 
    out PortB,r16 

z: 
    nop 
    rjmp z 

やデータ空間アドレスにこのI/Oアドレスを作るために:

.include "./m328Pdef.inc" 

    .EQU ROUGE = 0b0100000 ; red 
    .EQU VERT = 0b0010000 ; green 


main: 
    ldi r16,ROUGE+VERT  ; pins activated 
    out DDRB,r16 
    ldi r16,ROUGE   ; red on 
    out portB,r16 

    ;; configure timer 
    lds r16,TCCR0B+0x20 
    andi r16,0b11111000 
    ori r16,0b00000101  ; prescale 1024 
    sts TCCR0B+0x20,r16 

    ldi r16,0  ; count is 0 
    sts TCNT0+0x20,r16 

loop: 
    lds r16,TCNT0+0x20 
    cpi r16,100 
    brlo loop 

    ldi r16,VERT  ; green on 
    out PortB,r16 

z: 
    nop 
    rjmp z 

これらの定数に0x20を追加する必要がある理由については、第8.3章SRAMデータメモリ(特に図)m328p datasheetおよびthis bug reportの章を参照してください。


元のコードはなぜtimer1で動作したのですか?

Timer1レジスタは拡張I/O空間にあり、avraは拡張I/O空間アドレス(おそらくI/O空間アドレスを持たないため)で名前を置き換えています。


なぜ元のコードがtimer0でエラーを起こしたのですか?

lds r16,TCNT0lds r16,PINC+0x20と書くことができます。フローティングピンの状態を読み取ると、多かれ少なかれランダムな結果が得られます。


私はコマンドavr-objdump -b ihex -m avr5 -D *.hexを使用したものavraがあなたのコードでやっ確認するには、それは実際にマイコンに書き込まれているかを示しています。

SFRアドレスについては、第36章を参照してください。Register Summary of the aforementioned atmega328p datasheet

このコマンドを使用するには、avr-gccまたはavr-binutilsをインストールする必要があります。

+0

これは今すぐ動作します。説明に感謝します。 私が今理解しているように、AVRファミリの開発では、より大きなプロセッサにはタイマーが増えましたが、TIMER0とは異なる空間にアドレスがあります。 TIMER1の例から私は(間違って)私はTIMER0に同じ命令を使用することができます。 自分自身への注意:ドキュメントを読むことを検討してください。 実際TCNT0のような名前がの.incファイルで定義されてい .EQU \t TCNT0 \t = 0x26 のでアヴラは、それらについて何も知りません。ちょうど数字。 –

+0

助けがあれば、私の答えを受け入れることができます;)。 –

+0

また、2010年からavraが「死んでいる」ことに気がついたかどうかわかりません。代わりに、avr-gccアセンブラ(まあ、静かで構文がわかるのに時間がかかります)とインラインアセンブリそれを適切に使用する方法を学ぶためにしばらく時間がかかります)。 –