ATmega4809 Curiosity Nano

Índice

ATmega4809 Curiosity Nano Board Programming

La familia de microcontroladores tinyAVR® de Microchip, con periféricos independientes del núcleo (CIP), osciladores internos de alta velocidad y sistemas de eventos, ha sido ampliamente admirada. La nueva MCU megaAVR® de Microchip, la serie ATmega4809, tiene mayor capacidad de almacenamiento y más pines, y es una ampliación de la serie tinyAVR. Esta nueva serie ATmega4809 es una MCU auxiliar ideal para sistemas complejos que utilizan microprocesadores y puede convertirse en un excelente procesador autónomo en diseños de sistemas de control de comandos.

Características del ATmega4809

Como primer dispositivo megaAVR en integrar periféricos independientes del núcleo (CIP), el ATmega4809 realiza tareas en hardware en lugar de en software. También amplía las capacidades de los sistemas de control en tiempo real al combinar periféricos de hardware inteligentes con las características de bajo consumo del núcleo AVR®.

  • CPU AVR® de 8 bits con multiplicador de hardware
  • Memoria flash de hasta 48 KB
  • Hasta 16 canales de ADC de 10 bits de alta velocidad
  • Periféricos lógicos personalizables
  • Convertidor analógico-digital (ADC) integrado de alta velocidad

Estas características hacen que la nueva serie de microcontroladores megaAVR sea ideal para su uso como MCU complementarias en sistemas basados en microprocesadores, o como procesadores autónomos perfectos en diseños de sistemas de comando/control.

Esquema del ATmega4809 Curiosity Nano

Schematic Diagram of ATmega4809 Curiosity Nano Board
Schematic Diagram of ATmega4809 Curiosity Nano Board

Código de inicio de ATmega4809

Herramientas necesarias

  • Hardware: Placa de desarrollo ATmega4809 Curiosity Nano
  • Software: MPLAB X IDE v5.5, compilador XC8

Configuración de las opciones de compilación

De forma predeterminada, en MPLAB se utiliza el código de inicio predeterminado (integrado en MicroChip). Si desea utilizar un código de inicio personalizado en su proyecto, debe configurar las siguientes opciones de compilación:

Set compilation options in MPLAB
Set compilation options in MPLAB

Seleccione el proyecto y abra el panel de propiedades del proyecto. Añada la opción «-nostartfiles» en Opciones adicionales y guarde los cambios.

Procesamiento de la función de interrupción de la MCU

Cuando no hay ninguna instrucción de salto, el código se ejecuta uno por uno desde el principio. Cuando se produce una interrupción, el programa salta automáticamente a la dirección de entrada de interrupción correspondiente, y la dirección de entrada de interrupción es una dirección continua. Por lo general, llamamos a esta dirección de entrada de interrupción continua una tabla de vectores de interrupción. Dado que el espacio de memoria correspondiente a la dirección de entrada de interrupción es de solo 16 bits (2 bytes), este espacio no puede guardar nuestro código de función de servicio de interrupción en absoluto. Por lo tanto, colocaremos una instrucción de salto en la dirección de entrada de interrupción para saltar a la dirección de entrada de nuestra función de servicio de interrupción y ejecutar nuestra función de servicio de interrupción.

Código de inicio: versión de ensamblaje

				
					/* This file uses not the AVRASM2.exe assembler but the gnu assembler as - the GNU assembler */
/* Replace the rjmp command with jmp */

     #include <xc.h>

     .extern main; refers to the main function in the Main.c file
    
/* Interrupt vector table. Place jump instructions. When an interrupt occurs, jump to the corresponding interrupt service function to execute the interrupt function */
     .section .vectors
     jmp __ctors_end;
     jmp CRCSCAN_NMI
     jmp BOD_VLM
     jmp RTC_CNT_MEGA4809
     jmp RTC_PIT
     jmp CCL_CCL
     jmpPORTA_PORT
     jmp TCA0_OVF_vect

     
/* Code storage area that runs before the main function is run */
     .section .init2
     clr r1; Clear r1 register. Some compilers require this
     clr r16; Clear SREG status register
     out SREG, r16
     ; Init the STACK Pointer. Initialization stack. Used for calling sub-functions
     ldi r16,(RAMEND & 0xff); initialize
     out CPU_SPL,r16; stack pointer.
     ldi r16,(RAMEND >> 8) ; to RAMEND
     out CPU_SPH,r16
    
     .section .init9
     rcall main ; jump to main function
     jmp 0x00; Function executed after the main function ends. Jump directly to 0x00 to reset the MCU

  // code space
.section .text
  
//interrupt service function
.weak CRCSCAN_NMI; Use the .weak directive to define the function. When this function is defined externally, the externally defined function is used
.globalCRCSCAN_NMI
CRCSCAN_NMI:
     reti
    
.weak BOD_VLM
.global BOD_VLM
BOD_VLM:
     reti
    
.weak RTC_CNT_MEGA4809
.global RTC_CNT_MEGA4809
RTC_CNT_MEGA4809:
     reti
    
.weak RTC_PIT
.globalRTC_PIT
     RTC_PIT:
     reti
    
.weak CCL_CCL
.global CCL_CCL
     CCL_CCL:
     reti
    
.weakPORTA_PORT
.globalPORTA_PORT
     PORTA_PORT:
     reti

.end
				
			

Código de prueba

Compile el código de prueba de este archivo de inicio en la función principal para detectar si el inicio que escribimos puede entrar en la interrupción de desbordamiento TCA0.

				
					#include "mcc_generated_files/mcc.h"

volatile uint8_t flag = 0;

int main(void)
{
     /* Initializes MCU, drivers and middleware */
     SYSTEM_Initialize();

     /* Replace with your application code */
// protected_write_io(&(CLKCTRL.MCLKCTRLB),IO_KEY,0x01);
     PORTF.DIR = 0x20;
     TCA0.SINGLE.PERH = 0x4C;
     TCA0.SINGLE.PERL = 0x4B;
     TCA0.SINGLE.CTRLA = 0x0D;
     TCA0.SINGLE.INTCTRL = 0x01;
     ENABLE_INTERRUPTS();
    
     while(1)
     {
         if(flag==1)
         {
             flag = 0;
             PORTF.OUTTGL = 0x20;
         }
     }
}

ISR(TCA0_OVF_vect)
{
     flag = 1;
     TCA0.SINGLE.INTFLAGS = 0x01;//??????
}
				
			

Caja de desarrollo ATmega4809 - Salida GPIO

Herramientas necesarias

  • Hardware: Placa de desarrollo ATmega4809 Curiosity Nano
  • Software: Microchip Studio 7

Crear un nuevo proyecto

Cree un nuevo proyecto en Microchip Studio 7 y añádale una nueva carpeta.
Seleccione el proyecto, haga clic con el botón derecho del ratón y seleccione Añadir >> Nueva carpeta.

Add a Folder to ATmega4809 Project
Add a Folder to ATmega4809 Project

Añadir archivos a la carpeta, seleccionar el archivo C e introducir el nombre del archivo C VPORT.c

Add C File to ATmega4809 Project
Add C File to ATmega4809 Project

Siga el mismo método para crear un nuevo archivo VPORT.h.

Establecer la ruta del archivo de encabezado

Abre la ventana de configuración del proyecto, haz clic en la configuración del proyecto para establecer la ruta del archivo de encabezado:

Set header file path
Set header file path

Escribe el código.

Utilizamos estructuras para operar periféricos. Debido a que la dirección de memoria ocupada por la estructura es continua como la matriz, y cuando consultamos el manual del chip, también encontramos que la dirección del grupo de registros periféricos VPORTF también está conectada. Por lo tanto, podemos asignar la dirección base del registro VPORF al puntero de la estructura.

				
					typedef struct VPin_x_Jack{
         uint8_t PIT_0: 1;
         uint8_t PIN_1: 1;
         uint8_t PIN_2: 1;
         uint8_t PIN_3: 1;
         uint8_t PIN_4: 1;
         uint8_t PIN_5: 1;
         uint8_t PIN_6: 1;
         uint8_t PIN_7: 1;
}VPINx_Jack_TypeDef;

typedef struct VPort_x_Jack{
         VPINx_Jack_TypeDef DIR;
         VPINx_Jack_TypeDef OUT;
         VPINx_Jack_TypeDef IN;
         VPINx_Jack_TypeDef INTFLAGS;
}VPORTx_Jack_TypeDef;


#define VPORTA_Jack (*(VPORTx_Jack_TypeDef *)0x0000)
#define VPORTB_Jack (*(VPORTx_Jack_TypeDef *)0x0004)
#define VPORTC_Jack (*(VPORTx_Jack_TypeDef *)0x0008)
#define VPORTD_Jack (*(VPORTx_Jack_TypeDef *)0x000C)
#define VPORTE_Jack (*(VPORTx_Jack_TypeDef *)0x0010)
#define VPORTF_Jack (*(VPORTx_Jack_TypeDef *)0x0014)
				
			

Archivo de encabezado Pin en el archivo main.c

				
					#include <avr/io.h>
#include "VPORTx.h"

extern protected_write_io(void *addr, uint8_t KEY,uint8_t value);


static inline void System_Clock_Setting(void *addr,uint8_t value)
{
         protected_write_io(addr,0xD8,value);
}


void LED_Init(void)
{
         VPORTF_Jack.DIR.PIN_5 = 1; // PF5 output
         VPORTF_Jack.OUT.PIN_5 = 1; // LED off
}
 

int main(void)
{

         //Configure the system clock to 10MHZ
         System_Clock_Setting((void *)&(CLKCTRL.MCLKCTRLB),CLKCTRL_PDIV_2X_gc | 1 << CLKCTRL_PEN_bp);
         //Initialize LED port
         LED_Init();
        
     while (1)
     {
     }
}
				
			

Código de control de la luz LED:

Compruebe el diagrama del circuito para confirmar que el puerto IO conectado al pin LED es PF5. Dado que el terminal positivo del LED está conectado a la fuente de alimentación, cuando el terminal negativo del LED está bajo, el LED se enciende. De lo contrario, el LED se apaga.

				
					VPORTF_Jack.OUT.PIN_5 = 1; // LED off
VPORTF_Jack.OUT.PIN_5 = 0; // LED is on
				
			

Depuración de código

Como se muestra en la siguiente figura, configure el proyecto como Simulador y utilice el depurador de simulación para depurar el código.

Configure the debugging (programming) tool as Simulator
Configure the debugging (programming) tool as Simulator

Abra la vista E/S para ver el estado del registro de pines.

Check the status of pin register in I O Virtual Ports
Check the status of pin register in I O Virtual Ports

Suscríbete

Únete a nuestra lista de suscriptores para recibir actualizaciones mensuales del blog, noticias de tecnología y estudios de caso. Nunca enviaremos spam y puedes cancelar tu suscripción en cualquier momento.

Scroll al inicio

Cotización