Burning bootloader and programming ATMega328p

Hi all, I'm super new to programming and using Arduino. I need to program an ATMega328p with a hex file. I'm using Tiny Programmer and am programming the MCU on a breadboard. I'm using IDE 1.8.19. I selected "Arduino Uno" board, "COM4" port, "USBtinyISP" programmer. I'm trying to follow:

As I understand, I need to run both the board detector and board programmer sketches. I've tried it with a crystal and without. I also had this working and set the fuses previously but never programmed it. That was weeks ago. So I tried to come in and repeat what I did and I get the detailed error below.

I go to sketch>upload via programmer.

I get the following:

Arduino: 1.8.19 (Windows 10), Board: "Arduino Uno"

C:\Users\adamf\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/bin/avrdude -CC:\Users\adamf\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf -v -patmega328p -cusbtiny -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDE:m -Ulfuse:w:0xFF:m

avrdude: Version 6.3-20190619
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2014 Joerg Wunsch

     System wide configuration file is "C:\Users\adamf\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf"

     Using Port                    : usb
     Using Programmer              : usbtiny

avrdude: usbdev_open(): Found USBtinyISP, bus:device: bus-0:\.\libusb0-0001--0x1781-0x0c9f
AVR Part : ATmega328P
Chip Erase delay : 9000 us
PAGEL : PD7
BS2 : PC2
RESET disposition : dedicated
RETRY pulse : SCK
serial program mode : yes
parallel program mode : yes
Timeout : 200
StabDelay : 100
CmdexeDelay : 25
SyncLoops : 32
ByteDelay : 0
PollIndex : 3
PollValue : 0x53
Memory Detail :

                              Block Poll               Page                       Polled

       Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack

       ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------

       eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
       flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
       lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
       hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
       efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
       lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
       calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
       signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

     Programmer Type : USBtiny
     Description     : USBtiny simple USB programmer, https://learn.adafruit.com/usbtinyisp

avrdude: programmer operation not supported
avrdude: Using SCK period of 10 usec
avrdude: initialization failed, rc=-1
Double check connections and try again, or use -F to override
this check.

avrdude done. Thank you.
Error while burning bootloader.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Did you have the crystal connected during the attempt that produced the output you shared in your post?

The "Arduino Uno" board definition is configured to run the ATmega328P from an external clock. This makes me think you probably have configured the fuses for an external clock. If so, you will only be able to upload to the board while a crystal is connected and it is expected that the attempt will fail without one connected. Conversely, if you configured the fuses to use the internal oscillator, having an external crystal connected won't do any harm, so leaving it connected won't do any harm and removes one factor from the equation.

Please provide a detailed description of the procedure you followed to set the fuses.

Did you use Arduino IDE's Tools > Burn Bootloader feature to do that, or did you set the fuses in some other way?

I have another bare MCU and I will try to program that with an actual Arduino Uno today to see if I get different results.

To answer your questions, yes, previously I had a crystal connected when I produced the output above.

Previously to set the fuses, I sent this code via cmd:

avrdude -c usbtiny -p m328p -U lfuse:w:0xe2:m -U hfuse:w:0xd1:m -U efuse:w:0xff:m

After sending this code, I received the following:

C:\Users\adamf>avrdude -c usbtiny -p m328p -U lfuse:w:0xe2:m -U hfuse:w:0xd1:m -U efuse:w:0xff:m

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.03s

avrdude: Device signature = 0x1e950f
avrdude: reading input file "0xe2"
avrdude: writing lfuse (1 bytes):
Writing | ################################################## | 100% 0.00s
avrdude: 1 bytes of lfuse written
avrdude: verifying lfuse memory against 0xe2:
avrdude: load data lfuse data from input file 0xe2:
avrdude: input file 0xe2 contains 1 bytes
avrdude: reading on-chip lfuse data:
Reading | ################################################## | 100% 0.02s
avrdude: verifying ...
avrdude: 1 bytes of lfuse verified
avrdude: reading input file "0xd1"
avrdude: writing hfuse (1 bytes):
Writing | ################################################## | 100% 0.02s
avrdude: 1 bytes of hfuse written
avrdude: verifying hfuse memory against 0xd1:
avrdude: load data hfuse data from input file 0xd1:
avrdude: input file 0xd1 contains 1 bytes
avrdude: reading on-chip hfuse data:
Reading | ################################################## | 100% 0.02s
avrdude: verifying ...
avrdude: 1 bytes of hfuse verified
avrdude: reading input file "0xff"
avrdude: writing efuse (1 bytes):
Writing | | 0% 0.00s ***failed;
Writing | ################################################## | 100% 0.09s
avrdude: 1 bytes of efuse written
avrdude: verifying efuse memory against 0xff:
avrdude: load data efuse data from input file 0xff:
avrdude: input file 0xff contains 1 bytes
avrdude: reading on-chip efuse data:
Reading | ################################################## | 100% 0.00s
avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x0000
0xff != 0x07
avrdude: verification error; content mismatch
avrdude: safemode: efuse changed! Was ff, and is now 7

Would you like this fuse to be changed back? [y/n] n
avrdude: safemode: Fuses OK
avrdude done. Thank you.

To be perfectly honest, I don't know what I'm doing. I have an Arduino Uno and a separate bare 328p. I need to put a .hex file on that 328p for a radio I'm building. If you could point me to a tutorial online, I would be forever grateful. It seems like there are so many permutations out there, I get lost quickly.

That won't work, as a few extra parts are needed. Did you add those, as described in Gammon Forum : Electronics : Microprocessors : How to make an Arduino-compatible minimal board

Did you start with a "factory fresh", genuine ATmega328P chip? If so, it has the internal RC oscillator selected, with the CKDIV8 fuse set, for an clock frequency of 1 MHz. The programmer has to be set to 250 kHz or less.

Please post a photo of your setup.

Edit: Cross post. The background info is here: ATMega328P - SparkFun Electronics Forum

Yes, I built the breadboard as designed on Gammon Forum.

Yes, factory fresh ATMega328P chip. I do not know how to set the frequency of the programmer.

Your linked cross post is mine as I am bfpierce99.

Can I just load the hex file onto the ATMega328p that is on my Arduino Uno, then take that MCU off and install it in my radio?

My plan when I get home tonight is to prepare the bare 328p using this site:

I'll ignore the led program they have.

Then I will use avrdudess to flash my hex file.

Should this work?

UPDATE:
It didn't work. Followed this procedure and and when I went to upload ArduinoISP sketch, got this error:

Warning: Board breadboard:avr:atmega328bb doesn't define a 'build.board' preference. Auto-set to: AVR_ATMEGA328BB
Sketch uses 4342 bytes (14%) of program storage space. Maximum is 30720 bytes.
Global variables use 482 bytes of dynamic memory.
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x1c
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x1c
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x1c
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x1c
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x1c
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x1c
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x1c
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x1c
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x1c
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x1c
Failed uploading: uploading error: exit status 1

Why is this so difficult?

Update for this morning.

I started at the beginning. Connected my new Arduino Uno and ran the Blink program from Examples in the IDE. Got it to work after several resets and reboots of my computer.

I connected my Arduino Uno to my breadboard with the bare MCU per this website.

Opened avrdudess as it seems simpler to use. Hit detect and it could see my MCU.

: avrdude.exe -c arduino -P COM4 -b 115200 -p m8
Detected 1e950f = ATmega328p

Hit ellipsis and searched for the .hex file I want to flash.

Set programmer to "Arduino board as programmer using arduino as ISP firmware".
Hit Program!

: avrdude.exe -c arduino_as_isp -p m328p -P COM4 -b 115200 -U flash:w:"blahblah.hex path":a

Then I get this error:
avrdude error: programmer is not responding
avrdude warning: attempt x of 10: not in sync: resp=0xe0
...
avrdude error: unable to open port COM4 for programmer arduino_as_isp
avrdude error: avrdude built without libserialport support; please compile again with libserialport installed

I feel like I'm much closer than last night.

I think I finally got it. I changed programmer to "Arduino bootloader using STK500v1 protocol. The installation appeared to be completed. Hopefully this works when I put it in my radio. And hopefully my incompetence will help someone else down the line.

Is there a way to test whether or not the .hex file got added to the right MCU? Started to think I put it on the MCU that is mounted to Arduino Uno board instead of the MCU that was wired up on the breadboard.

Any code to program atmega328p externally?