wip mod04 ex01
This commit is contained in:
3
Makefile
3
Makefile
@@ -74,6 +74,9 @@ flash:
|
||||
restore:
|
||||
avrdude -p $(AVRDUDE_MCU_TYPE) -c $(PROGRAMMER_ID) -b $(BAUD_RATE) -P $(SERIAL_PORT) -U flash:w:$(DUMP_ORI)
|
||||
|
||||
dump:
|
||||
avrdude -p $(AVRDUDE_MCU_TYPE) -c $(PROGRAMMER_ID) -b $(BAUD_RATE) -P $(SERIAL_PORT) -U flash:r:dump.hex
|
||||
|
||||
clean:
|
||||
rm -f main.hex main.bin *.o
|
||||
|
||||
|
||||
@@ -36,16 +36,16 @@
|
||||
#define PULLUP_ON(elem) SET(CONCAT(PORT, GET_PORT(elem)), GET_BIT(elem))
|
||||
#define PULLUP_OFF(elem) CLEAR(CONCAT(PORT, GET_PORT(elem)), GET_BIT(elem))
|
||||
|
||||
// Bit definitions
|
||||
#define D1 0
|
||||
#define D2 1
|
||||
#define D3 2
|
||||
#define D4 4
|
||||
#define SW1 2
|
||||
#define SW2 4
|
||||
#define D5B 3
|
||||
#define D5R 5
|
||||
#define D5G 6
|
||||
// Bit definitions (<pin number> // <pin name>)
|
||||
#define D1 0 // PB0
|
||||
#define D2 1 // PB1
|
||||
#define D3 2 // PB2
|
||||
#define D4 4 // PB4
|
||||
#define SW1 2 // PD2
|
||||
#define SW2 4 // PD4
|
||||
#define D5B 3 // PD3
|
||||
#define D5R 5 // PD5
|
||||
#define D5G 6 // PD6
|
||||
|
||||
// Elements (port, bit)
|
||||
#define LED1 (B, D1)
|
||||
|
||||
@@ -14,5 +14,7 @@
|
||||
// PROTOTYPES
|
||||
//
|
||||
// main.c
|
||||
void blink_led_1();
|
||||
void vary_duty();
|
||||
|
||||
#endif // HEADER_H
|
||||
@@ -27,11 +27,62 @@
|
||||
// - if i choose prescaler 64 for a duration of 0.01 seconds, i need to restart the clock after how many cycles :
|
||||
// - (16000000 / 64) * 0.01 = 2500 ticks -> set ICR1 = 2500
|
||||
|
||||
// alternatively, can use the default values :
|
||||
// - Fast PWM, 8-bit, TOP 0x00FF (255)
|
||||
// - Fast PWM, 9-bit, TOP 0x01FF (511)
|
||||
// - Fast PWM, 10-bit, TOP 0x03FF (1023)
|
||||
|
||||
// no need to set a second for the "blinking" with PWM and duty cycle :
|
||||
// only need to use a top value convenient, like a multiple of 100
|
||||
// if choose top value of 100 :
|
||||
// - at prescaler 1 : 100 / 16000000 = 0.00000625s (it takes this time to do a cycle)
|
||||
// - at prescaler 8 : (100 * 8) / 16000000 = 0.00005s
|
||||
// - at prescaler 64 : (100 * 64) / 16000000 = 0.0004s
|
||||
// - at prescaler 256 : (100 * 256) / 16000000 = 0.0016s
|
||||
// - at prescaler 1024 : (100 * 1024) / 16000000 = 0.0064s
|
||||
// if choose top value of 1000 :
|
||||
// - at prescaler 1 : 1000 / 16000000 = 0.0000625s (it takes this time to do a cycle)
|
||||
// - at prescaler 8 : (1000 * 8) / 16000000 = 0.0005s
|
||||
// - at prescaler 64 : (1000 * 64) / 16000000 = 0.004s
|
||||
// - at prescaler 256 : (1000 * 256) / 16000000 = 0.016s
|
||||
// - at prescaler 1024 : (1000 * 1024) / 16000000 = 0.064s
|
||||
|
||||
// 16.9.3 : timer1 fast PWM
|
||||
|
||||
#define LED1_PWM_PRESCALER 8 // can be 1, 8, 64, 256, 1024
|
||||
#define LED1_PWM_PRESCALER 256 // can be 1, 8, 64, 256, 1024
|
||||
#define DUTY_CYCLE_PERCENT 9
|
||||
#define FRQUENCY_MS 1
|
||||
#define FREQUENCY_MS 1
|
||||
#define TOP_VALUE 1000
|
||||
|
||||
volatile uint8_t duty_cycle = DUTY_CYCLE_PERCENT;
|
||||
|
||||
void blink_led_1() {
|
||||
TCCR1A = (1 << WGM11); // Table 16-4 : set timer1 in fast PWM mode 14, with TOP ICR1, so we can use OCR1A for duty cycle and keep ICR1 for frequency
|
||||
TCCR1B = (1 << WGM13) | (1 << WGM12); // mode 15 with OCR1A TOP prevent using duty cycle trigger on OC1A (OCR1B is free but triggers OC1B -> PB2)
|
||||
// other fast PWM modes 5, 6, and 7 uses predefined TOP, preventing to define a multiple of 100 for percent accuracy
|
||||
|
||||
TCCR1A |= (1 << COM1A1); // Table 16-2 : set non-inverting mode to trigger OC1A on fast PWM (14.3.1 : OC1A is alternate function of PB1)
|
||||
|
||||
TCCR1B |= PRESCALE_SET(LED1_PWM_PRESCALER); // Table 16-5 : set the appropriate prescale values
|
||||
|
||||
// ICR1 = TIME_MS(FREQUENCY_MS, LED1_PWM_PRESCALER); // top value for Xms
|
||||
ICR1 = TOP_VALUE;
|
||||
OCR1A = PERCENT(duty_cycle, ICR1); // 16.9.3 : duty cycle
|
||||
}
|
||||
|
||||
vary_duty() {
|
||||
// TCCR0A = (1 << WGM11); // Table 15-8 : set timer0 in CTC mode, with TOP OCRA
|
||||
// TCCR1B = (1 << WGM13) | (1 << WGM12);
|
||||
|
||||
// TCCR1A |= (1 << COM1A1); // Table 16-2 : set non-inverting mode to trigger OC1A on fast PWM (14.3.1 : OC1A is alternate function of PB1)
|
||||
|
||||
// TCCR1B |= PRESCALE_SET(LED1_PWM_PRESCALER); // Table 16-5 : set the appropriate prescale values
|
||||
|
||||
// // ICR1 = TIME_MS(FREQUENCY_MS, LED1_PWM_PRESCALER); // top value for Xms
|
||||
// ICR1 = TOP_VALUE;
|
||||
// OCR1A = PERCENT(duty_cycle, ICR1); // 16.9.3 : duty cycle
|
||||
|
||||
}
|
||||
|
||||
// use timers interruptions to varie led1 intensity using duty cycle, from 0% to 100% to 0% in 1 second
|
||||
// timer1 sets the led duty cycle, timer0 change the duty cycle percentage
|
||||
@@ -40,19 +91,15 @@ int main() {
|
||||
CLEAR_ELEM(LED1);
|
||||
MODE_OUTPUT(LED2);
|
||||
CLEAR_ELEM(LED2);
|
||||
MODE_OUTPUT(LED3);
|
||||
CLEAR_ELEM(LED3);
|
||||
MODE_OUTPUT(LED4);
|
||||
CLEAR_ELEM(LED4);
|
||||
|
||||
SREG |= ENABLE_GLOBAL_INTERRUPT;
|
||||
|
||||
TCCR1A = (1 << WGM11); // Table 16-4 : set fast PWM mode with TOP ICR1, so we can use OCR1A for duty cycle and keep ICR1 for frequency
|
||||
TCCR1B = (1 << WGM13) | (1 << WGM12);
|
||||
|
||||
TCCR1A |= (1 << COM1A1); // Table 16-2 : set non-inverting mode to trigger OC1A on fast PWM
|
||||
|
||||
TCCR1B |= PRESCALE_SET(LED1_PWM_PRESCALER); // Table 16-5 : set the appropriate prescale values
|
||||
|
||||
ICR1 = TIME_MS(FRQUENCY_MS, LED1_PWM_PRESCALER); // top value for Xms
|
||||
|
||||
OCR1A = PERCENT(DUTY_CYCLE_PERCENT, ICR1); // duty cycle frequence
|
||||
blink_led_1();
|
||||
vary_duty();
|
||||
|
||||
while (1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user