8Bit Timer/Counter
* Hello_AVR.cpp
*
* Created: 2017-01-07(YYYY-MM-DD) AM 5:08:05
* Author : Michael Jun-Hyuk Im([email protected])
*/
#define F_CPU 16000000
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
volatile char tick_flag = 0;
ISR(TIMER1_OVF_vect) //OVF1 20ms timer
{
static unsigned int OVF1=0;
TCNT1 = -5000; // 20msc
OVF1++;
if(OVF1 == 1){
tick_flag=1;
OVF1=0;
}
}
ISR(TIMER1_COMPA_vect) //CTC1A 20ms timer
{
static unsigned char CTC1A=0;
CTC1A++;
if(CTC1A == 1){
tick_flag=1;
CTC1A=0;
}
}
ISR(TIMER1_COMPB_vect) //CTC1B 20ms timer
{
static unsigned char CTC1B=0;
CTC1B++;
if(CTC1B == 1){
tick_flag=1;
CTC1B=0;
}
}
ISR(TIMER1_COMPC_vect) //CTC1C 20ms timer
{
static unsigned char CTC1C=0;
CTC1C++;
if(CTC1C == 1){
tick_flag=1;
CTC1C=0;
}
}
void MI_GPIO_config()
{
DDRG = 0x03; // 0,1 보드 LED, 2,3 보드 SW
}
void MI_TC1_OVF_Config()
{
TCCR1A |= (0 << COM1A1)|(0 << COM1A0)| //COM_1A(00). No output
(0 << COM1B1)|(0 << COM1B0)| //COM_1B(00). No output
(0 << COM1C1)|(0 << COM1C0)| //COM_1C(00). No output
(0 << WGM11)|(0 << WGM10); //WGM(00) Normal Mode
TCCR1B |= (0 << ICNC1)|(0 << ICES1)| //Input Capture Noise Canceler, Input Capture Edge Selector
(0 << WGM13)|(0 << WGM12)| //WGM(00) Normal Mode
(0 << CS12)|(1 << CS11)|(1 << CS10); //CS(011).64분주비 (1/16000000)*64=0.000004=4us
TCCR1C |= (0 << FOC1A)|(0 << FOC1B)|(0 << FOC1C); //Force Output Compare for Channel 1_A,B,C
TCNT1 = -5000; // 20msc
TIMSK |= (1<<TOIE1); //Overflow Interrupt
//ETIMSK //For Channel 3
}
void MI_TC1_CTC_Config()
{
TCCR1A |= (0 << COM1A1)|(0 << COM1A0)| //COM_1A(00). No output
(0 << COM1B1)|(0 << COM1B0)| //COM_1B(00). No output
(0 << COM1C1)|(0 << COM1C0)| //COM_1C(00). No output
(0 << WGM11)|(0 << WGM10);
TCCR1B |= (0 << ICNC1)|(0 << ICES1)| //Input Capture Noise Canceler, Input Capture Edge Selector
(0 << WGM13)|(1 << WGM12)| //WGM(0100) CTC Mode(TOP depend OCR1x), WGM(1100) CTC Mode(TOP depend ICR1)
(0 << CS12)|(1 << CS11)|(1 << CS10); //CS(011).64분주비 (1/16000000)*64=0.000004=4us
TCCR1C |= (0 << FOC1A)|(0 << FOC1B)|(0 << FOC1C); //Force Output Compare for Channel 1_A,B,C
///WGM 0100
OCR1A = 5000 - 1;
OCR1B = 5000 - 1;
OCR1C = 5000 - 1;
///WGM 1100
//ICR1 = 5000 - 1;
TIMSK |= (1<<OCIE1A)|(1<<OCIE1B); //Compare Match Interrupt Enable
ETIMSK |= (1<<OCIE1C);
}
void MI_TC1_PC_PWM_Config()
{
DDRB |= (1 << PB5) | (1 << PB6) | (1 << PB7); //A,B,C
TCCR1A |= (1 << COM1A1)|(0 << COM1A0)| //COM_1A(10). Clear OC1A on compare match when up-counting. Set OC1A on compare match when down-counting.
(1 << COM1B1)|(0 << COM1B0)| //COM_1B(10).
(1 << COM1C1)|(0 << COM1C0)| //COM_1C(10).
(1 << WGM11)|(0 << WGM10);
TCCR1B |= (0 << ICNC1)|(0 << ICES1)| //Input Capture Noise Canceler, Input Capture Edge Selector
(1 << WGM13)|(0 << WGM12)| //10 WGM(1010) PWM Mode(TOP depend ICR1)
(0 << CS12)|(1 << CS11)|(1 << CS10); //CS(011).64분주비 (1/16000000)*64=0.000004=4us
TCCR1C |= (0 << FOC1A)|(0 << FOC1B)|(0 << FOC1C); //Force Output Compare for Channel 1_A,B,C
//dual slope operation.
ICR1 = 5000 - 1; //20ms * 2 = 40ms, total cycle
//ICR1 = 2500-1; //10ms * 2 = 20ms, total cycle
OCR1A = 500; //2ms * 2 = 4ms, uptime
OCR1B = 1000; //4
OCR1C = 1500; //6
}
void MI_TC1_PFC_PWM_Config()
{
DDRB |= (1 << PB5) | (1 << PB6) | (1 << PB7); //A,B,C
TCCR1A |= (1 << COM1A1)|(0 << COM1A0)| //COM_1A(10). Clear OC1A on compare match when up-counting. Set OC1A on compare match when down-counting.
(1 << COM1B1)|(0 << COM1B0)| //COM_1B(10).
(1 << COM1C1)|(0 << COM1C0)| //COM_1C(10).
(0 << WGM11)|(0 << WGM10);
TCCR1B |= (0 << ICNC1)|(0 << ICES1)| //Input Capture Noise Canceler, Input Capture Edge Selector
(1 << WGM13)|(0 << WGM12)| //10 WGM(1010) PWM Mode(TOP depend ICR1)
(0 << CS12)|(1 << CS11)|(1 << CS10); //CS(011).64분주비 (1/16000000)*64=0.000004=4us
TCCR1C |= (0 << FOC1A)|(0 << FOC1B)|(0 << FOC1C); //Force Output Compare for Channel 1_A,B,C
//dual slope operation.
ICR1 = 5000 - 1; //20ms * 2 = 40ms, total cycle
//ICR1 = 2500-1; //10ms * 2 = 20ms, total cycle
OCR1A = 500; //2ms * 2 = 4ms, uptime
OCR1B = 1000; //4
OCR1C = 1500; //6
}
void MI_TC1_FAST_PWM_Config()
{
DDRB |= (1 << PB5) | (1 << PB6) | (1 << PB7); //A,B,C
TCCR1A |= (1 << COM1A1)|(0 << COM1A0)| //COM_1A(10). Clear OC1A on compare match when up-counting. Set OC1A on compare match when down-counting.
(1 << COM1B1)|(0 << COM1B0)| //COM_1B(10).
(1 << COM1C1)|(0 << COM1C0)| //COM_1C(10).
(1 << WGM11)|(0 << WGM10);
TCCR1B |= (0 << ICNC1)|(0 << ICES1)| //Input Capture Noise Canceler, Input Capture Edge Selector
(1 << WGM13)|(1 << WGM12)| //10 WGM(1010) PWM Mode(TOP depend ICR1)
(0 << CS12)|(1 << CS11)|(1 << CS10); //CS(011).64분주비 (1/16000000)*64=0.000004=4us
TCCR1C |= (0 << FOC1A)|(0 << FOC1B)|(0 << FOC1C); //Force Output Compare for Channel 1_A,B,C
//dual slope operation.
ICR1 = 5000 - 1; //20ms, total cycle
//ICR1 = 2500-1; //10ms, total cycle
OCR1A = 500; //2ms, uptime
OCR1B = 1000; //4
OCR1C = 1500; //6
}
int main(void)
{
MI_GPIO_config();
//Select below One of Modes
MI_TC1_OVF_Config();
MI_TC1_CTC_Config();
MI_TC1_PC_PWM_Config();
MI_TC1_PFC_PWM_Config();
MI_TC1_FAST_PWM_Config();
sei();
while (1)
{
if(tick_flag == 1)
{
PORTA=PORTA^0xff;
tick_flag=0;
}
}
}