Add timer interrupt + PWM work
This commit is contained in:
BIN
Arduino-Uno-Chip-Pinout-8894.jpg
Normal file
BIN
Arduino-Uno-Chip-Pinout-8894.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 94 KiB |
@@ -29,7 +29,8 @@ Microcontroller pins are grouped as:
|
|||||||
|
|
||||||
- PC6 is RESET pin
|
- PC6 is RESET pin
|
||||||
→ DO NOT USE as GPIO
|
→ DO NOT USE as GPIO
|
||||||
→ can reset system
|
→ can reset system
|
||||||
|
→ can be used but condition is if reset is disabled.
|
||||||
|
|
||||||
- PD0 and PD1 are Serial pins (RX TX)
|
- PD0 and PD1 are Serial pins (RX TX)
|
||||||
→ used for USB upload and debugging
|
→ used for USB upload and debugging
|
||||||
|
|||||||
24
PWM-generator/Makefile
Normal file
24
PWM-generator/Makefile
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
MCU = atmega328p
|
||||||
|
F_CPU = 16000000UL
|
||||||
|
CC = C:\Users\sharm\Desktop\Embedded Programming\avrprojects\avr8-gnu-toolchain-win32_x86_64\bin\avr-gcc
|
||||||
|
OBJCOPY = C:\Users\sharm\Desktop\Embedded Programming\avrprojects\avr8-gnu-toolchain-win32_x86_64\bin\avr-objcopy
|
||||||
|
AVRDUDE = ../avrdude
|
||||||
|
AVRDUDE_PROGRAMMER = arduino
|
||||||
|
AVRDUDE_PORT = COM8
|
||||||
|
AVRDUDE_BAUD = 115200
|
||||||
|
|
||||||
|
CFLAGS = -mmcu=$(MCU) -DF_CPU=$(F_CPU) -Os -Wall
|
||||||
|
|
||||||
|
all: main.hex
|
||||||
|
|
||||||
|
main.elf: main.c
|
||||||
|
$(CC) $(CFLAGS) main.c -o main.elf
|
||||||
|
|
||||||
|
main.hex: main.elf
|
||||||
|
$(OBJCOPY) -O ihex -R .eeprom main.elf main.hex
|
||||||
|
|
||||||
|
upload: main.hex
|
||||||
|
$(AVRDUDE) -c $(AVRDUDE_PROGRAMMER) -p $(MCU) -P $(AVRDUDE_PORT) -b $(AVRDUDE_BAUD) -D -U flash:w:main.hex:i
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f main.elf main.hex
|
||||||
33
PWM-generator/main.c
Normal file
33
PWM-generator/main.c
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#include <avr/io.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
// 1. Set PB1 (OC1A) as output
|
||||||
|
DDRB |= (1 << PB1);
|
||||||
|
|
||||||
|
// 2. Fast PWM mode (WGM13:0 = 14)
|
||||||
|
TCCR1A = (1 << COM1A1) | (1 << WGM11);
|
||||||
|
TCCR1B = (1 << WGM12) | (1 << WGM13);
|
||||||
|
|
||||||
|
// 3. Prescaler = 8 (start timer)
|
||||||
|
TCCR1B |= (1 << CS11);
|
||||||
|
|
||||||
|
// 4. Set TOP value (frequency)
|
||||||
|
ICR1 = 19999; // ~50 Hz (good for visible LED dimming demo)
|
||||||
|
|
||||||
|
// 5. Initial duty cycle
|
||||||
|
OCR1A = 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
// Increase brightness
|
||||||
|
for (uint16_t i = 0; i < 2000; i++) {
|
||||||
|
OCR1A = i * 10; // increase duty
|
||||||
|
for (volatile uint32_t d = 0; d < 5000; d++); // small delay
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrease brightness
|
||||||
|
for (int16_t i = 2000; i > 0; i--) {
|
||||||
|
OCR1A = i * 10;
|
||||||
|
for (volatile uint32_t d = 0; d < 5000; d++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
Readmore.md
Normal file
15
Readmore.md
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# Timer Interrupt (ATmega328P)
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
Generated 1ms interrupt using Timer1
|
||||||
|
|
||||||
|
## Key Registers
|
||||||
|
- TCCR1B → mode + prescaler
|
||||||
|
- OCR1A → compare value
|
||||||
|
- TIMSK1 → enable interrupt
|
||||||
|
|
||||||
|
## Logic
|
||||||
|
Timer counts → match OCR1A → ISR runs → ms++
|
||||||
|
|
||||||
|
## Result
|
||||||
|
LED blink using ms counter (non-blocking)
|
||||||
24
Timer-Interrupt/Makefile
Normal file
24
Timer-Interrupt/Makefile
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
MCU = atmega328p
|
||||||
|
F_CPU = 16000000UL
|
||||||
|
CC = C:\Users\sharm\Desktop\Embedded Programming\avrprojects\avr8-gnu-toolchain-win32_x86_64\bin\avr-gcc
|
||||||
|
OBJCOPY = C:\Users\sharm\Desktop\Embedded Programming\avrprojects\avr8-gnu-toolchain-win32_x86_64\bin\avr-objcopy
|
||||||
|
AVRDUDE = ../avrdude
|
||||||
|
AVRDUDE_PROGRAMMER = arduino
|
||||||
|
AVRDUDE_PORT = COM8
|
||||||
|
AVRDUDE_BAUD = 115200
|
||||||
|
|
||||||
|
CFLAGS = -mmcu=$(MCU) -DF_CPU=$(F_CPU) -Os -Wall
|
||||||
|
|
||||||
|
all: main.hex
|
||||||
|
|
||||||
|
main.elf: main.c
|
||||||
|
$(CC) $(CFLAGS) main.c -o main.elf
|
||||||
|
|
||||||
|
main.hex: main.elf
|
||||||
|
$(OBJCOPY) -O ihex -R .eeprom main.elf main.hex
|
||||||
|
|
||||||
|
upload: main.hex
|
||||||
|
$(AVRDUDE) -c $(AVRDUDE_PROGRAMMER) -p $(MCU) -P $(AVRDUDE_PORT) -b $(AVRDUDE_BAUD) -D -U flash:w:main.hex:i
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f main.elf main.hex
|
||||||
39
Timer-Interrupt/main.c
Normal file
39
Timer-Interrupt/main.c
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
volatile uint32_t ms = 0;
|
||||||
|
|
||||||
|
void timer1_init(void) {
|
||||||
|
TCCR1A = 0;
|
||||||
|
TCCR1B = 0;
|
||||||
|
TCNT1 = 0;
|
||||||
|
|
||||||
|
TCCR1B |= (1 << WGM12);
|
||||||
|
OCR1A = 249;
|
||||||
|
TIMSK1 |= (1 << OCIE1A);
|
||||||
|
TCCR1B |= (1 << CS11) | (1 << CS10);
|
||||||
|
sei();
|
||||||
|
}
|
||||||
|
|
||||||
|
ISR(TIMER1_COMPA_vect) {
|
||||||
|
ms++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void delay_ms(uint32_t delay){
|
||||||
|
uint32_t start = ms;
|
||||||
|
while ((ms - start) < delay) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
DDRC |= (1<<PC0);
|
||||||
|
timer1_init();
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
PORTC |= (1<<PC0);
|
||||||
|
delay_ms(500);
|
||||||
|
PORTC &= ~(1<<PC0);
|
||||||
|
delay_ms(500);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
MCU = atmega328p
|
MCU = atmega328p
|
||||||
F_CPU = 16000000UL
|
F_CPU = 16000000UL
|
||||||
CC = C:\Users\sharm\Desktop\our main folder\avrprojects\avr8-gnu-toolchain-win32_x86_64\bin\avr-gcc
|
CC = C:\Users\sharm\Desktop\Embedded Programming\avrprojects\avr8-gnu-toolchain-win32_x86_64\bin\avr-gcc
|
||||||
OBJCOPY = C:\Users\sharm\Desktop\our main folder\avrprojects\avr8-gnu-toolchain-win32_x86_64\bin\avr-objcopy
|
OBJCOPY = C:\Users\sharm\Desktop\Embedded Programming\avrprojects\avr8-gnu-toolchain-win32_x86_64\bin\avr-objcopy
|
||||||
AVRDUDE = ../avrdude
|
AVRDUDE = ../avrdude
|
||||||
AVRDUDE_PROGRAMMER = arduino
|
AVRDUDE_PROGRAMMER = arduino
|
||||||
AVRDUDE_PORT = COM10
|
AVRDUDE_PORT = COM8
|
||||||
AVRDUDE_BAUD = 115200
|
AVRDUDE_BAUD = 115200
|
||||||
|
|
||||||
CFLAGS = -mmcu=$(MCU) -DF_CPU=$(F_CPU) -Os -Wall
|
CFLAGS = -mmcu=$(MCU) -DF_CPU=$(F_CPU) -Os -Wall
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ timer1_init();
|
|||||||
// prescaler 8
|
// prescaler 8
|
||||||
DDRD &= ~(1 << PD2);
|
DDRD &= ~(1 << PD2);
|
||||||
PORTD |= (1 << PD2);
|
PORTD |= (1 << PD2);
|
||||||
EICRA &= ~(1<<ISC00);
|
EICRA &= ~((1 << ISC01) | (1 << ISC00));
|
||||||
EICRA |= (1<<ISC01);
|
|
||||||
EIMSK |= (1<<INT0);
|
EIMSK |= (1<<INT0);
|
||||||
|
|
||||||
sei();
|
sei();
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ Controls how external interrupts trigger.
|
|||||||
|
|
||||||
# Interrupt Trigger Modes (INT0)
|
# Interrupt Trigger Modes (INT0)
|
||||||
|
|
||||||
## 1. Low Level (00)
|
## 1. Low Level (00) //holding button
|
||||||
|
|
||||||
EICRA &= ~((1 << ISC01) | (1 << ISC00));
|
EICRA &= ~((1 << ISC01) | (1 << ISC00));
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ Bit calculation:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 2. Any Logical Change (01)
|
## 2. Any Logical Change (01)
|
||||||
|
|
||||||
EICRA &= ~(1 << ISC01);
|
EICRA &= ~(1 << ISC01);
|
||||||
EICRA |= (1 << ISC00);
|
EICRA |= (1 << ISC00);
|
||||||
|
|||||||
Reference in New Issue
Block a user