-
Notifications
You must be signed in to change notification settings - Fork 1
/
t45.c
117 lines (85 loc) · 2.18 KB
/
t45.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#ifndef F_CPU
#define F_CPU 1000000UL
#endif
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define LED PB4 // Blinking LED on PB4
#define SQWAVE PB2 // 500Hz square wave on PB2
uint8_t SavedMCUSR = 0;
volatile uint32_t Milliseconds = 0UL;
volatile uint8_t Tick = 0;
/* TIMER1_COMPA_vect --- ISR for Timer/Counter 1 overflow, used for 1ms ticker */
ISR(TIMER1_COMPA_vect)
{
Milliseconds++;
Tick = 1;
PINB = (1 << SQWAVE); // DEBUG: 500Hz on PB2 pin
}
/* millis --- return milliseconds since reset */
uint32_t millis(void)
{
uint32_t ms;
cli();
ms = Milliseconds;
sei();
return (ms);
}
/* initMCU --- set up the microcontroller in general */
static void initMCU(void)
{
SavedMCUSR = MCUSR;
MCUSR = 0;
}
/* initGPIOs --- set up the GPIO pins */
static void initGPIOs(void)
{
// Set Pin 3 (PB4), Pin 7 (PB2) and Pin 6 (PB1) as output pins
DDRB |= (1 << LED) | (1 << SQWAVE) | (1 << PB1) | (1 << PB0);
PORTB = 0; // All LEDs off
}
/* initPWM --- set up PWM channels */
static void initPWM(void)
{
// Config Timer 0 for PWM
TCCR0A = (1 << COM0A1) | (1 << COM0B1) | (1 << WGM00);
TCCR0B = (1 << CS01); // Clock source = CLK/8, start PWM
OCR0A = 0x80;
OCR0B = 0x80;
#if 0
// Config Timer 1 for PWM
TCCR1A = (1 << COM0A1) | (1 << COM0B1) | (1 << WGM00);
TCCR1B = (1 << CS01); // Clock source = CLK/8, start PWM
OCR1A = 0x80;
OCR1B = 0x80;
#endif
}
/* initMillisecondTimer --- set up a timer to interrupt every millisecond */
static void initMillisecondTimer(void)
{
// Set up Timer/Counter 1 for regular 1ms interrupt
TCCR1 = (1 << CTC1) | (1 << CS11) | (1 << CS10); // Prescaler /4
OCR1A = 249; // 250 counts gives 1ms
TCNT1 = 0;
TIMSK = (1 << OCIE1A); // Enable interrupts
}
int main(void)
{
initMCU();
initGPIOs();
initPWM();
initMillisecondTimer();
sei(); // Enable interrupts
while (1) {
// Switch LED on
PORTB |= 1 << LED;
OCR0A += 16;
OCR0B -= 16;
_delay_ms(500);
// Switch LED off
PORTB &= ~(1 << LED);
OCR0A += 16;
OCR0B -= 16;
_delay_ms(500);
}
}