初学者 - avr32打开led,编译器看不到变量

时间:2016-04-12 10:58:56

标签: c include led atmelstudio avr32

我有微处理器 at32uc3b0256 ,我想打开LED,(示例中的简单程序)。为此,我使用Atmel Studio。我找到了示例代码:

"workout"=>{"title"=>"",
 "workout_sets_attributes"=>{"0"=>{"_destroy"=>"false",
 "intro_video"=>"70",
 "title"=>""}}},
 "image"=>"",
 "sound_logo"=>"",
 "intro_video"=>"",
 "commit"=>"Create workout"}

但是当我把它写到Atmel Studio时我遇到了一些错误,Atmel Studio没有看到DDRC和PORTs变量。我该如何解决? 屏幕形式Atmel Studio

enter image description here

1 个答案:

答案 0 :(得分:1)

您正在 AVR8 架构中使用 GPIO 示例。 AVR32 架构完全不同,将 GPIO 模块作为单独的 HW 块通过 PBA 连接(我认为)。没有像DDRC,...

这样的寄存器

您可以将 AVR32 架构视为子组件网络,其中 MCU 核心只是其中一个模块。有2条主要总线 PBA PBB 各自连接到不同的模块。

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

  1. 配置并启动您要使用的主MCU内核时钟

    AVR32 MCU内核通常在复位后以低32KHz时钟运行。要获得更好的性能,您需要更高的时钟频率至66MHz。我通常以某个常见频率启动 PLL ,然后将所有时钟( CPU,PBA,PBB,HSB )除以。作为 PLL 的源,您需要一些时钟,例如内部 RC 或由外部晶振驱动的振荡器。如果您还需要 USB ,那么您需要记住它需要特定的频率以便妥协...有关更多信息,请查看数据表和/或示例中的 SCIF 模块。

  2. 正确启动时切换到

    要么等待一段时间(100ms),要么检查时钟是否正在直接运行( SCIF 模块我认为它具有一些功能)。

  3. 配置/启动使用过的硬件模块

  4. 现在做你的东西

  5. <强> Bootlaoder

    您需要注意的另一件事是启动加载程序。我不喜欢 JTAG ,因为我对它有不好的经验(不需要花很多时间来煎炸它并且用它编程真的很不舒服)。使用 JTAG ,您可以轻松地清除引导加载程序(每个芯片都附带它)并相信我让它恢复工作真的很讨厌。

    另一方面,Bootloader简单而优雅。例如,我使用 FLIP 并且具有用于编程芯片的简单comandline文件。然后我只是打开命令提示符执行它。在每次重建/编程时,我只需按向上箭头重复提示中的最后一个命令,然后按回车键。与使用 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目录中。

    使用Bootloader,您需要告诉编译器您的程序不是从0x0000开始,因为它与引导加载程序重叠。为此,请参阅蹦床示例。

  6. 这就是我的 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 访问速度很慢,如果不明智地使用会导致代码性能下降......

    如果为您的应用程序选择的 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 也是由buss连接的单独模块,错误设置时钟或等待状态可能会导致严重问题。