簡體   English   中英

初學者-AVR32開啟LED,編譯器看不到變量

[英]Beginner - avr32 turn on led, compiler does not see variables

我有微處理器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和PORT視為變量。 我該如何解決? 屏幕表格Atmel Studio

在此處輸入圖片說明

您正在使用AVR8架構的GPIO示例。 AVR32體系結構完全不同,引入GPIO模塊作為通過PBA連接的獨立硬件模塊(我認為)。 沒有像DDRC這樣的寄存器...

您可以將AVR32架構視為子組件網絡上的組件,其中MCU內核只是模塊之一。 有2條主總線PBAPBB分別連接到不同的模塊。

要使AVR32固件正常工作,您需要執行以下操作:

  1. 配置並啟動您要使用的主MCU核心時鍾

    復位后,AVR32 MCU內核通常以低32KHz時鍾運行。 為了獲得更好的性能,您需要更高的時鍾,最高可達66MHz。 通常,我通常以某個公共頻率啟動PLL ,然后再將所有時鍾( CPU,PBA,PBB,HSB )分頻。 作為PLL的源,您需要一些時鍾,例如內部RC或由外部晶振驅動的振盪器。 如果您還需要USB,則需要記住它需要特定的頻率,因此請妥協...有關更多信息,請查看數據表和/或示例中的SCIF模塊。

  2. 正確啟動后切換到它

    請稍等(100ms)或檢查時鍾是否直接運行(我認為SCIF模塊具有某些功能)。

  3. 配置/啟動使用的硬件模塊

  4. 現在做你的東西

  5. 布特勞德

    您需要注意的另一件事是引導加載程序。 我不喜歡JTAG,因為我對JTAG的體驗很差(不需要花太多時間就可以炒了,並且使用它進行編程確實很不舒服)。 使用JTAG,您可以輕松擦除Bootloader(每個芯片都附帶了),並相信我讓它恢復正常工作真是令人討厭。

    另一方面,Bootloader簡單而優雅。 例如,我使用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 Studio bin目錄中。

    使用Bootloader時,您需要告訴編譯器您的程序不是從0x0000開始的,因為這會與Bootloader重疊。 為此,請參見蹦床示例。

這是我的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);
     }
//------------------------------------------------------------------------------------------------

我不使用框架管理器,而是自己添加內容...並且重寫了框架,以避免不必要的包含和編譯速度降低。 還請注意,框架更新並不總是兼容的,因此有時在更新后您的代碼將無法編譯...最好有一個可靠的框架,除非確實需要,否則不要對其進行更新。

僅選擇您需要的模塊(無需全部包含它們)。 例如,您需要intc,gpio,scif等,我的包含項來自較大的項目,因此其中許多對您無用,而且並非所有的AVR32芯片都具有所有的標頭/模塊。

我沒有話題(我認為是必要的),所以回到GPIO

API和體系結構已完全更改。 不要被引腳名稱所迷惑。 例如,針腳PA35並不表示端口A針腳35 沒有端口PA這只是命名約定,對體系結構沒有任何實際意義,這有點愚蠢,我花了一些時間來適應它。 有足夠多的端口可以覆蓋所有引腳。 每個端口支持32引腳,而引腳號是您真正需要知道的。

每個引腳在avr32/io.h中的某個位置定義為AVR32_PIN_PA04類的定義,並且包含芯片GPIO中引腳位置的數值。 要獲取gpio端口/掩碼,您只需執行以下操作:

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

現在直接訪問GPIO寄存器,我建議看一下gpio.c 您可以一次設置,解析,測試,讀取32個引腳以加快速度(如果它們位於同一端口)。 速度主要取決於總線時鍾(通常為GPIO的 PBA ),因此,如果您的時鍾較低,則不要期望較高的觸發速率。 注意GPIO的訪問速度很慢,如果使用不當可能會破壞代碼的性能...

如果明智地為您的應用選擇了硬件引腳,那么您的速度就會非常快。 例如,我獲得了大約2-5 MHz的切換速度!

這是從gpio.c設置引腳的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也是通過總線連接的單獨模塊,錯誤設置時鍾或等待狀態可能會導致嚴重問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM