I'm very new to microcontroller development and I'm doing my best to follow the data sheet for the Atmega328P-PU on the Arduino Uno R3 shield, but there are some concepts I'm having a hard time grasping. I have the code I'm using for a working RGB LED below (it blinks Red/Green). Some explanations/advice would be greatly appreciated! I'm also not using the Arduino IDE; I'm using a text file/terminal to flash the file onto the microcontroller, if that matters to you.
I've gotten the built-in led and normal led on a breadboard to blink, but when I'm trying to fade in/out an RGB led using Phase Correct PWM (I've read from other forums this is what I should use, I could be incorrect), I feel like doing it wrong (even though it technically works).
I understand the TCNTn is used for accessing the different Timer/Counters and the OCRxn's are used with the timers for constant comparison, but I don't really understand what exactly happens when a compare match is met. I've looked a lot online but I see a lot of different answers to people's questions about this stuff, but doesn't really make a ton of sense to me.
Is the port the OCRxn (OCR0A --> PD6) is linked to being sent an electrical current based on the OCRxn value and the led's brightness matches that value during each clock cycle (rising edge)?
Adjusting the OCRxn value after each cycle means changing the brightness of the led because the match from TCNTn and OCRxn meets at a higher value?
Are interrupts inseparable from compare matches or do I need them (for this specific pulsing led example)? Are interrupts only used for inputs (like buttons or motor controls)?
Phase Correct PWM
Similar to other modes, but it has an incline and decline for counting and the OCRxn registers are used the same way?
If so, how is the decline used? How is it different than using, let's say, Fast PWM and increasing/decreasing OCRxn for each cycle to create a fading effect?
I believe those are the main questions I have. Any explanations or questions you have would be great. Thank you!
Depending on the settings you've configured for the PWM generation on that particular timer, when the compare match happens then the associated pin either turns on, turns off, or toggles.
By making that happen at a later or earlier time, you are changing the duty cycle of the PWM on that pin.
If you're using the PWM generation then you don't need any interrupt. You can also configure the compare match to fire an interrupt, but that's not part of what you're doing.
Interrupts are for things that happen extremely fast. A human pressing a button would not be an example of a good use of an interrupt.
I know this subject is not the reason for your topic.
But I was curious how you load the microcontroller without using the IDE.
Do you use USBasp?
Or some other interface combined with other software?
If you could elaborate further on this subject, I would appreciate it.
I cannot, understand and I apologize for my request.
Thanks in advance.
I'm using the Elegoo Uno R3 Arduino shield with the Atmega328P microcontroller. It has a USB port on the shield, which lets you power on the board and/or program the microcontroller by connecting your computer to it. I'm not sure how to connect the controller to your PC if you're using a standalone microcontroller without the built-in USB port.
It's not too complicated. You need to install some packages through your terminal to communicate with the microcontroller. You need to install avr-libc, avrdude, binutils-avr, and gcc-avr onto your computer by using terminal commands (exactly how its installed depends on your OS, ie. "gcc-avr" or "avr-gcc" - this is also written in C, so if you're using C++ or another language I believe a couple changes to the names of the packages is all you need). You can look online as well to figure out how to do it on your OS. There are some tutorials, but you may need to do some digging on the web to find them.
These are the commands I use for MacOS to flash the text file onto the controller:
avr-gcc -Os -DF_CPU=16000000UL -mmcu=atmega328P -c -o file_name.o file_name.c
avr-gcc -mmcu=atmega328P file_name.o -o file_name
avr-objcopy -O ihex -R .eeprom file_name file_name.hex
avrdude -V -F -c stk500v1 -p atmega328P -P port_serial_name -b 115200 -U flash:w:file_name.hex
Change the "file_name" to whatever the name of the text file the code is on and
remember to save the text file to the format of the language youre using
(file_name.c for C, file_name.cpp for C++, etc.)
Also, change the "port_serial_name" to whatever port name the USB cable is
connected to for the board. Look through the system settings on your pc to
figure out which port the USB cable in connected to.
Also, here's a link to a YouTube video I used that explains what each command does in the above snippet (he's using Linux, FYI). He explains it at around minute 4:30. There are other videos/online resources you can find that also do the same thing, but again, it may take some looking because they aren't usually the top search result.
Install the packages, write your code like normal in a text file (I use TextMate on my MacBook, but you can use any texteditor you want), save it with the file extension of your programming language, navigate to the saved file through your terminal, then use the commands to put the file onto the controller. Any time you want to upload the code onto the controller, just put in that command (or save it) and it works.
Yeah, an rgb led. I want to program the hardware/registers directly (bare metal programming) without using Arduino's libraries so I can learn how the controller works. Their functions hide a lot of the inner-workings of the controller, but I get that it's a lot easier.