0

私はマイクロプロセッサat32uc3b0256を持っていて、LED をオンにしたいです (例からの簡単なプログラム)。これを行うには、Atmel Studio を使用します。サンプルコードを見つけました:

#ifndef F_CPU
#define F_CPU 16000000UL // 16 MHz clock speed
#endif

#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
  DDRC = 0xFF; //Makes PORTC as Output
  while(1) //infinite loop
  {
    PORTC = 0xFF; //Turns ON All LEDs
    _delay_ms(1000); //1 second delay
    PORTC= 0x00; //Turns OFF All LEDs
    _delay_ms(1000); //1 second delay
  }
}

しかし、それを Atmel Studio に書き込んだときにエラーが発生しました。Atmel Studio は DDRC とポートを変数として認識しません。どうすれば修正できますか?画面フォーム Atmel Studio

ここに画像の説明を入力

4

1 に答える 1

1

AVR8アーキテクチャのGPIOの例を使用しています。AVR32アーキテクチャは完全に異なり、GPIOモジュールをPBAを介して接続された別のHWブロックとして導入します (私はそう思います)。のようなレジスタはありません...DDRC

MCUコアがモジュールの 1 つにすぎないサブコンポーネントのネットワークとして、 AVR32アーキテクチャを見ることができます。2 つのメイン バスPBAPBBがあり、それぞれが異なるモジュールに接続されています。

AVR32ファームウェアを機能させるには、次のことを行う必要があります。

  1. 使用するメイン MCU コア クロックを設定して開始します

    AVR32 MCU コアは通常、リセット後 32KHz の低いクロックで動作しています。パフォーマンスを向上させるには、最大 66MHz までのより高いクロックが必要です。私は通常、いくつかの共通周波数でPLLを開始し、後ですべてのクロック ( CPU、PBA、PBB、HSB ) を分周します。PLLのソースとして、外部水晶で駆動される内部RCや発振器などのクロックが必要です。USBも必要な場合は、特定の周波数が必要なので妥協する必要があることに注意する必要があります...詳細については、データシートまたは例のSCIFモジュールを確認してください。

  2. 正常に起動したらそれに切り替えます

    少し(100ms)待つか、クロックが直接動作しているかどうかを確認します(SCIFモジュールにはいくつかの機能があると思います)。

  3. 使用されるハードウェア モジュールの構成/開始

  4. 今あなたのことをしてください

  5. ブートローダー

    もう 1 つ気を付けなければならないのは、ブートローダーです。私はJTAGで悪い経験があるので好きではありません (それを揚げるのにそれほど時間はかからず、それを使ったプログラミングは本当に不快です)。JTAGを使用すると、ブートローダーを簡単に一掃できます (各チップには出荷時に付いています)。

    一方、ブートローダーはシンプルでエレガントです。たとえば、私はFLIPを使用し、チップをプログラミングするための単純なコマンドラインファイルを持っています. 次に、コマンドプロンプトを開いて実行します。そして、再構築/プログラミングのたびに、上向き矢印を押してプロンプトの最後のコマンドを繰り返し、Enterキーを押します。JTAGでの多くのクリックと比較して、これははるかに高速で簡単です。cmd の例:

    avr32-objcopy -O ihex AT32UC3L064.elf AT32UC3L064.hex
    Batchisp -device AT32UC3L064 -hardware RS232 -port COM1 -baudrate 115200 -operation onfail abort memory flash erase f blankcheck loadbuffer AT32UC3L064.hex program start reset 0
    

    これavr32-objcopy.exeは AVR スタジオの bin ディレクトリにあります。

    0x0000ブートローダーを使用すると、ブートローダーと重複するため、プログラムが開始されていないことをコンパイラーに伝える必要があります。これを行うには、トランポリンの例を参照してください。

これは、私のAVR32アプリが通常どのように見えるかです:

#include <avr32/io.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "intc.c"
#include "gpio.c"
#include "pm_uc3l.c"
#include "scif_uc3l.c"
#include "adcifb.c"
#include "flashcdw.c"
#include "pdca.c"
//#include "pwma.c"
#include "tc.c"
#include "usart.c"
#include "eic.c"

#include "genclk.h"
#include "osc.c"
#include "dfll.c"
#include "sysclk.c"

#include "status_codes.h"
#include "cycle_counter.h"
#include "sleep.h"
#include "delay.c"
#define cpu_clk 30000000

#define _LED AVR32_PIN_PA04


void system_init()
    {
    delay_init(115000);

    Disable_global_interrupt();
    INTC_init_interrupts();
    scif_start_rc120M();
    delay_ms(100);

    pm_set_clk_domain_div((pm_clk_domain_t)AVR32_PM_CLK_GRP_CPU,PM_CKSEL_DIVRATIO_4);
    pm_set_clk_domain_div((pm_clk_domain_t)AVR32_PM_CLK_GRP_PBA,PM_CKSEL_DIVRATIO_4);
    pm_set_clk_domain_div((pm_clk_domain_t)AVR32_PM_CLK_GRP_PBB,PM_CKSEL_DIVRATIO_4);
    pm_set_clk_domain_div((pm_clk_domain_t)AVR32_PM_CLK_GRP_HSB,PM_CKSEL_DIVRATIO_4);
    pm_set_all_cksel(SCIF_RC120M_FREQ_HZ,cpu_clk,cpu_clk,cpu_clk);
    flashcdw_set_flash_waitstate_and_readmode(cpu_clk);
    pm_set_mclk_source(PM_CLK_SRC_RC120M);

    delay_init(cpu_clk);
    }
//------------------------------------------------------------------------------------------------
void wait_ms(U32 dt)
    {
    U32 t0,t1;
    t0=Get_system_register(AVR32_COUNT);
    dt=((dt*cpu_clk)+999)/1000;
    t0&=RDTSC_mask;
    for (;;)
        {
        t1=Get_system_register(AVR32_COUNT);
        t1&=RDTSC_mask;
        if (t0>t1)  t1+=RDTSC_mask+1;
        if ((t1-t0)>=dt) break;
        }
    }
//------------------------------------------------------------------------------------------------
void wait_us(U32 dt)
    {
    U32 t0,t1;
    t0=Get_system_register(AVR32_COUNT);
    dt=((dt*cpu_clk)+999999)/1000000;
    t0&=RDTSC_mask;
    for (;;)
        {
        t1=Get_system_register(AVR32_COUNT);
        t1&=RDTSC_mask;
        if (t0>t1)  t1+=RDTSC_mask+1;
        if ((t1-t0)>=dt) break;
        }
    }
//------------------------------------------------------------------------------------------------
int main(void)
    {
    system_init();

    // here init what you need
    gpio_configure_pin(_LED,GPIO_DIR_OUTPUT|GPIO_INIT_HIGH);

    for (;;)
     {
     // here do your stuff
     gpio_tgl_gpio_pin(_LED);
     wait_ms(200);
     }
//------------------------------------------------------------------------------------------------

私はフレームワークマネージャーを使用せず、代わりに自分でインクルードしています...そして、不要なインクルードとコンパイルのスローダウンを避けるためにフレームワークを書き直しました。また、フレームワークの更新は常に互換性があるとは限らないため、更新後にコードがコンパイルされない場合があることに注意してください... 1 つのしっかりしたフレームワークを用意し、本当に必要でない限り更新しない方がよいでしょう。

必要なモジュールのみを選択します (すべてを含める必要はありません)。たとえば、必要な場合intc,gpio,scifなど、私のインクルードはより大きなプロジェクトからのものであるため、それらの多くは役に立たず、すべてのヘッダー/モジュールがすべてのAVR32チップで利用できるわけではありません。

少し話が逸れたので(必要だったと思います)GPIOに戻ります

APIとアーキテクチャが完全に変更されました。ピン名に惑わされないでください。たとえば、ピンはPA35ポートピンを意味しません!!! ポートはありません。これはアーキテクチャにとって何の意味もない単なる命名規則であり、少しばかげていて、慣れるまでに時間がかかりました。すべてのピンをカバーするために必要な数のポートがあります。各ポートはピンをサポートしており、ピン番号は実際に知っておく必要があります。A35PA32

各ピンは定義avr32/io.hのような場所で定義されてAVR32_PIN_PA04おり、チップ GPIO のピン位置の数値が含まれています。gpio ポート/マスクを取得するには、次のようにします。

port = pin>>5
mask = 1<<(pin&31)

GPIOレジスタに直接アクセスするには、 を参照することをお勧めしますgpio.c。一度に 32 個のピンを設定、再設定、テスト、読み取りして速度を上げることができます (それらが同じポートにある場合)。速度は主にバス クロック (通常はGPIOのPBA )に依存するため、クロックが低い場合は高いトグル レートを期待しないでください。GPIOアクセスは遅く、賢明に使用しないとコードのパフォーマンスが低下する可能性があることに注意してください...

アプリ用に選択されたHWピンが賢明に行われると、非常に高速になる可能性があります。たとえば、トグル速度は約 2 ~ 5 MHz でした !!!

ここからピンを設定する例gpio.c

void gpio_set_gpio_pin(uint32_t pin)
{
  U32 bit= 1 << (pin & 0x1F);
  volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
  gpio_port->ovrs  = bit; // Value to be driven on the I/O line: 1.
  gpio_port->oders = bit; // The GPIO output driver is enabled for that pin.
  gpio_port->gpers = bit; // The GPIO module controls that pin.
}

bitこれを使用して、設定したいすべてのピンのマスクと交換するだけで、同じポートに複数のピンを設定できます...

GPIOに割り込みを使用している場合は、割り込みコントローラーINTCもバスで接続された別のモジュールであり、誤ってクロックまたは待機状態を設定すると大きな問題が発生する可能性があることに注意してください。

于 2016-07-15T08:46:02.823 に答える