初学者-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 模块作为单独的 HW 块通过 PBA 连接(我认为)。没有像 DDRC,...

这样的寄存器

您可以将 AVR32 架构视为子组件网络,其中 MCU 核心只是模块之一。有 2 条主总线 PBAPBB 分别连接到不同的模块。

要使 AVR32 固件正常工作,您需要这样做:

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

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

  2. 正常启动切换到

    要么稍等(100 毫秒),要么直接检查时钟是否为 运行(我认为 SCIF 模块具有一些功能)。

  3. configure/start 使用硬件模块

  4. 现在做你的事

  5. Bootlaoder

    您需要注意的另一件事是引导加载程序。我不喜欢 JTAG,因为我对它的体验很差(炸它不需要太多,用它编程真的很不舒服)。使用 JTAG,您可以轻松清除引导加载程序(每个芯片都随附),相信我让它恢复工作真的很糟糕。

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

    使用引导加载程序,您需要告诉编译器您的程序不是从 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);
     }
//------------------------------------------------------------------------------------------------

我不使用框架管理器,而是我自己包含这些东西...并且我的框架被重写以避免不必要的包含和编译速度减慢。还要注意框架更新并不总是兼容,所以有时更新后你的代码将无法编译......最好有一个可靠的框架,除非你真的需要,否则不要更新它。

Select 仅包含您需要的模块(无需全部包含)。例如,您需要 intc,gpio,scif 等等,我的包含来自更大的项目,所以其中很多对您来说都是无用的,而且并非所有 headers/modules 都适用于所有 AVR32芯片。

我有点跑题了(我认为这是必要的)所以回到 GPIO

API 和体系结构完全改变了。不要被引脚名称所迷惑。例如 pin PA35 并不意味着端口 A pin 35 !!!没有端口 PA 这只是命名约定 对体系结构没有任何实际意义 这有点傻,我花了一段时间才适应它。根据需要有尽可能多的端口来覆盖所有引脚。每个端口支持 32 个引脚,引脚号是您需要知道的真实数字。

每个引脚在 avr32/io.h 中的某处定义为类似 AVR32_PIN_PA04 的定义,它包含芯片 GPIO 中引脚位置的数值。要获得 gpio port/mask 你只需这样做:

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

现在要直接访问 GPIO 寄存器我建议查看 gpio.c。您可以一次设置、解析、测试、读取 32 个引脚以加快速度(如果它们在同一端口)。速度主要取决于总线时钟(通常 PBA 用于 GPIO)所以如果你的时钟很低,不要期望高切换率。当心 GPIO 访问速度很慢,如果使用不当会降低代码的性能...

如果为您的应用程序选择的 HW 引脚是明智的选择,您可以获得非常快的速度。例如,我的切换速度约为 2-5 MHz !!!

这里是从gpio.c

设置一个pin的例子
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 也是一个单独的模块,通过总线连接并且错误地设置了时钟或等待状态会导致巨大的问题。