Keluarga mikrokontroler tinyAVR® dari Microchip yang dilengkapi dengan Core Independent Peripherals (CIP), osilator internal berkecepatan tinggi, dan sistem peristiwa telah mendapat sambutan luas. MCU megaAVR® terbaru dari Microchip – seri ATmega4809 – memiliki kapasitas penyimpanan yang lebih besar dan jumlah pin yang lebih banyak, serta merupakan pengembangan dari seri tinyAVR. Seri ATmega4809 yang baru ini merupakan MCU tambahan yang ideal untuk sistem kompleks yang menggunakan mikroprosesor, dan dapat menjadi prosesor mandiri yang sangat baik dalam desain sistem komando-kontrol.
Fitur ATmega4809
Sebagai perangkat megaAVR pertama yang mengintegrasikan periferal independen inti (CIP), ATmega4809 menjalankan tugas-tugas secara perangkat keras, bukan perangkat lunak. Perangkat ini juga memperluas kemampuan sistem kontrol waktu nyata dengan menggabungkan periferal perangkat keras cerdas dengan fitur hemat daya dari inti AVR®.
- CPU AVR® 8-bit dengan pengali perangkat keras
- Memori flash hingga 48 KB
- Hingga 16 saluran ADC 10-bit berkecepatan tinggi
- Periferal logika khusus yang dapat dikonfigurasi
- Konverter analog-ke-digital (ADC) berkecepatan tinggi terintegrasi
Fitur-fitur ini menjadikan seri mikrokontroler megaAVR yang baru sangat cocok untuk digunakan sebagai MCU pendamping dalam sistem berbasis mikroprosesor, atau sebagai prosesor mandiri yang sempurna dalam desain sistem perintah/kontrol.
Skema ATmega4809 Curiosity Nano

Kode Awal ATmega4809
Peralatan yang diperlukan
- Perangkat keras: Papan pengembangan ATmega4809 Curiosity Nano
- Perangkat lunak: MPLAB X IDE v5.5, kompiler XC8
Pengaturan opsi kompilasi
Secara default, kode startup bawaan (yang sudah terintegrasi dalam MicroChip) digunakan di MPLAB. Jika Anda ingin menggunakan kode startup buatan sendiri dalam proyek Anda, Anda perlu mengatur opsi kompilasi berikut:

Pilih proyek dan buka panel properti proyek. Tambahkan opsi "-nostartfiles" di bagian Opsi Tambahan, lalu simpan perubahan.
Pemrosesan fungsi interupsi MCU
Jika tidak ada pernyataan lompatan, kode akan dijalankan satu per satu mulai dari awal. Ketika terjadi interupsi, program akan secara otomatis melompat ke alamat masuk interupsi yang sesuai, dan alamat masuk interupsi tersebut merupakan alamat yang berurutan. Umumnya, kita menyebut alamat masuk interupsi yang berurutan ini sebagai tabel vektor interupsi. Karena ruang memori yang sesuai dengan alamat masuk interupsi hanya sebesar 16 bit (2 byte), ruang ini sama sekali tidak cukup untuk menyimpan kode fungsi layanan interupsi kita. Oleh karena itu, kita akan menempatkan pernyataan lompat di alamat masuk interupsi untuk melompat ke alamat masuk fungsi layanan interupsi kita guna menjalankan fungsi layanan interupsi tersebut.
Kode awal - versi assembly
/* This file uses not the AVRASM2.exe assembler but the gnu assembler as - the GNU assembler */
/* Replace the rjmp command with jmp */
#include
.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
Kode pengujian
Kompilasi kode pengujian dari berkas startup ini di dalam fungsi utama untuk mendeteksi apakah startup yang telah kita tulis dapat memicu interupsi overflow 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;//??????
}
Kotak Pengembangan ATmega4809 - Output GPIO
Peralatan yang diperlukan
- Perangkat keras: Papan pengembangan ATmega4809 Curiosity Nano
- Perangkat lunak: Microchip Studio 7
Buat proyek baru
Buat proyek baru di Microchip Studio 7 dan tambahkan folder baru ke dalamnya.
Pilih proyek tersebut, lalu klik kanan dan pilih Tambahkan >> Folder Baru

Tambahkan berkas ke dalam folder, pilih berkas C, lalu masukkan nama berkas C tersebut: VPORT.c

Ikuti langkah yang sama untuk membuat berkas VPORT.h yang baru.
Tentukan jalur file header
Buka jendela pengaturan proyek, klik pengaturan proyek untuk mengatur jalur file header:

Tulis kode tersebut
Kami menggunakan struktur untuk mengendalikan perangkat periferal. Karena alamat memori yang ditempati oleh struktur bersifat berurutan seperti halnya array, dan ketika kita memeriksa manual chip, kita juga akan menemukan bahwa alamat kelompok register periferal VPORTF juga saling terhubung. Oleh karena itu, kita dapat menetapkan alamat dasar register VPORTF ke penunjuk struktur.
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)
Sematkan berkas header di berkas main.c
#include
#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)
{
}
}
Kode pengendali lampu LED:
Periksa diagram rangkaian untuk memastikan bahwa port IO yang terhubung ke pin LED adalah PF5. Karena terminal positif LED terhubung ke sumber daya, ketika terminal negatif LED dalam keadaan rendah, LED akan menyala. Sebaliknya, LED akan padam.
VPORTF_Jack.OUT.PIN_5 = 1; // LED off
VPORTF_Jack.OUT.PIN_5 = 0; // LED is on
Memperbaiki kode
Seperti yang ditunjukkan pada gambar di bawah ini, atur proyek sebagai Simulator dan gunakan debugger simulasi untuk men-debug kode.

Buka Tampilan I/O untuk melihat status register pin.





