Pickit 5 with AVR
#define F_CPU 16000000UL  // 1. Define CPU Frequency (16MHz is common for 328PB)
#include <avr/io.h>
#include <util/delay.h>   // 2. Include the delay library

int main(void) {
    // 3. Set PD7 as an output
    // DDRD is the Data Direction Register for Port D
    DDRD |= (1 << DDD7); 

    while (1) {
        // 4. Toggle PD7 using the XOR operator
        PORTD ^= (1 << PORTD7);
        
        // 5. Wait for 500 milliseconds
        _delay_ms(500);
    }
}

To burn the hex to avr in mac using command line, use this Makefile

export PATH="/Applications/microchip/mplabx/v6.30/mplab_platform/mplab_ipe/:$PATH"
MODEL=atmega328p
MODEL_AVRDUDE=m328pb
# MODEL_ISP=usbasp-clone
MODEL_ISP=avrisp2 # mkII

# For Microchip IPECMD, the device name usually needs to match the exact chip
MODEL_IPE=ATmega328PB
# IPECMD Tool Configuration
# -TPPK5 tells IPE to use the PICkit 5
TOOL_IPE=-TPPK5

all: SSD1306.o TWI.o main.hex

SSD1306.o: ssd1306/SSD1306.c
	avr-gcc -mmcu=$(MODEL)  -Wall -Os -c $? -o $@

TWI.o: ssd1306/TWI.c
	avr-gcc -mmcu=$(MODEL)  -Wall -Os -c $? -o $@

main.hex: main.c
	avr-gcc -mmcu=$(MODEL)  -Wall -Os -o main.elf SSD1306.o TWI.o main.c
	avr-objcopy -j .text -j .data -O ihex main.elf main.hex
	avr-size --format=avr --mcu=$(MODEL) main.elf

upload:
	avrdude -c $(MODEL_ISP) -p $(MODEL_AVRDUDE) -U flash:w:main.hex

upload_pickit5:
	ipecmd.sh $(TOOL_IPE) -P$(MODEL_IPE) -F"$(CURDIR)/main.hex" -M

readfuse:
	avrdude -c $(MODEL_ISP) -p $(MODEL_AVRDUDE) -U hfuse:r:-:h -U lfuse:r:-:h

writefuse:
	avrdude -c $(MODEL_ISP) -p $(MODEL_AVRDUDE) -U lfuse:w:0x62:m -U hfuse:w:0xD9:m -U efuse:w:0xFF:m -U lock:w:0xFF:m

clean:
	-rm *.o
	-rm main.hex
	-rm main.elf