protocolo_TBS_bipolar.ino 8.95 KB
Newer Older
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
//-------------------------------------------Protocolo TBS bipolar:
//Timer 1 (positivo em 12 (inv), negativo em 11 (n-inv), negativo em 13 (n-inv))
//Timer 3 (positivo em 5 (inv), negativo em 2 (n-inv), negativo em 3 (n-inv))
//Timer 4 (positivo em 7 (inv), negativo em 6 (n-inv), negativo em 8 (n-inv))
//Timer 5 (positivo em 45 (inv), negativo em 46 (n-inv), negativo em 44 (n-inv))

//Limites testados:
//PP entre 1ms e 50ms
//PN entre 1ms e 50ms
//IEI entre 50ms e 500ms
//ITI entre 100ms e 1000ms
//n_pulso entre 1 e 15
//n_epoca entre 1 e 15

//Bibliotecas
#include <avr/io.h>                //inclui biblioteca de input/output do AVR
#include <avr/eeprom.h>           //inclui biblioteca de EEPROM
#include <avr/interrupt.h>        //inclui biblioteca de interrupt
#include <stdlib.h>               //inclui biblioteca padrao
#include <string.h>               //inclui biblioteca de strings

//Variaveis globais
unsigned int PN = 5;                     //define largura de pulso (em ms)
unsigned char PP = 5;                   //define intervalo entre pulsos (em ms) 
unsigned int IEI = 100;                  //define intervalo entre epocas (em ms)
unsigned int ITI = 500;                     //define intervalo entre trens de epocas (em ms)
unsigned char n_pulso = 4;
unsigned char n_epoca = 8;
unsigned int epoca = 0;
unsigned int pulso=0;
unsigned char estado=1;
unsigned int contador = 0;
int estado_botao = 0;

//Rotinas de interrupcao
ISR(TIMER1_COMPA_vect)                    //interrupt quando acontece match entre OCR1X e TCNT1 (PWM baixa)
{
  pulso++;                                 //incrementa contagem de pulso
  if(epoca==(n_epoca+1))
  {
    if(contador == ((ITI)/(PP+PN)))
    {
43 44
      epoca = 0;      
      estado = 1;      
45
      pulso = 0;
46
      contador = 0;      
47 48 49 50 51 52 53 54
    }
    else
    {
      contador++;
    }
  }
  else
  {
55
    if(pulso==n_pulso && estado == 1)              //se tem o terceiro pulso, desativa PWMs  
56 57
    {
      
58 59 60 61 62
      TCCR1A &= ~(1 << COM1A0);      
      TCCR1A &= ~(1 << COM1A1);  
      TCCR1A &= ~(1 << COM1B0);  
      TCCR1A &= ~(1 << COM1B1);  
      TCCR1A &= ~(1 << COM1C0);  
63
      TCCR1A &= ~(1 << COM1C1);  
64 65 66 67 68
      TCCR3A &= ~(1 << COM3A0);      
      TCCR3A &= ~(1 << COM3A1);  
      TCCR3A &= ~(1 << COM3B0);  
      TCCR3A &= ~(1 << COM3B1);  
      TCCR3A &= ~(1 << COM3C0);  
69
      TCCR3A &= ~(1 << COM3C1);
70 71 72 73 74
      TCCR4A &= ~(1 << COM4A0);      
      TCCR4A &= ~(1 << COM4A1);  
      TCCR4A &= ~(1 << COM4B0);  
      TCCR4A &= ~(1 << COM4B1);  
      TCCR4A &= ~(1 << COM4C0);  
75 76
      TCCR4A &= ~(1 << COM4C1);
      TCCR5A &= ~(1 << COM5A0);
77 78 79 80 81 82 83 84
      TCCR5A &= ~(1 << COM5A1);  
      TCCR5A &= ~(1 << COM5B0);  
      TCCR5A &= ~(1 << COM5B1);  
      TCCR5A &= ~(1 << COM5C0);  
      TCCR5A &= ~(1 << COM5C1);  
      estado = 0;                         //entra em estado de PWM desligado  
      pulso=0;  
      epoca++;                            //incrementa contagem de epoca  
85 86
    }
  
87 88 89 90 91 92 93
    if(pulso==((PP+IEI)/(PP+PN)) && estado == 0)  
    {      
      TCCR1A |= ((1 << COM1A1) | (1 << COM1B1) | (1 << COM1B0) | (1 << COM1C1));  
      TCCR1A &= ~(1 << COM1A0);  
      TCCR1A &= ~(1 << COM1C0);  
      TCCR3A |= ((1 << COM3A1) | (1 << COM3B1) | (1 << COM3B0) | (1 << COM3C1));  
      TCCR3A &= ~(1 << COM3A0);  
94
      TCCR3A &= ~(1 << COM3C0); 
95 96
      TCCR4A |= ((1 << COM4A1) | (1 << COM4B1) | (1 << COM4B0) | (1 << COM4C1));  
      TCCR4A &= ~(1 << COM4A0);  
97
      TCCR4A &= ~(1 << COM4C0); 
98 99 100 101 102
      TCCR5A |= ((1 << COM5A1) | (1 << COM5B1) | (1 << COM5B0) | (1 << COM5C1));  
      TCCR5A &= ~(1 << COM5A0);  
      TCCR5A &= ~(1 << COM5C0);   
      pulso = 0;                          //limpa quantidade de pulsos  
      estado = 1;                         //entra em estado de PWM ligado  
103 104 105 106 107 108 109 110 111 112
    }
  }
}

//Funcao principal
int main()                                                  //funcao principal
{
  config_timer1();                                      //realiza configuracao do timer 1 - canal 1
  config_timer3();                                      //realiza configuracao do timer 3 - canal 2
  config_timer4();                                      //realiza configuracao do timer 4 - canal 3
113
  config_timer5();                                      //realiza configuracao do timer 5 - canal 4           
114 115 116 117 118 119 120 121 122 123 124 125 126 127
  while(1);
  return 0;
}

void config_timer1()                          //funcao que configura o microcontrolador
{
  cli();                                      //desativa interrupts para fazer configuracao
  //PWM
  //Ativa pinos do canal 1:
  DDRB |= (1 << PB5);                //ativa pino PB5 (OC1A) - pino 11
  DDRB |= (1 << PB6);                //ativa pino PB6 (OC1B) - pino 12
  DDRB |= (1 << PB7);                //ativa pino PB7 (OC1C) - pino 13
  //Limpa registradores de controle do timer 1
  TCCR1A = 0;
128
  TCCR1B = 0;  
129 130 131 132 133 134 135 136 137 138 139 140 141 142
  //Define timer 1 no modo Fast-PWM 14 (TOP definido por ICR1)
  TCCR1A |= (1 << WGM11);
  TCCR1B |= (1 << WGM12);
  TCCR1B |= (1 << WGM13);
  //Saida de PWM nao-inversor em A e inversor em B e nao-inversor em C
  TCCR1A |= ((1 << COM1A1) | (1 << COM1B1) | (1 << COM1B0) | (1 << COM1C1));
  TCCR1A &= ~(1 << COM1A0);
  TCCR1A &= ~(1 << COM1C0);
  // Define frequencia do PWM e Duty Cycle
  ICR1 = (250*(PP+PN))-1;
  OCR1A = ICR1/((PP+PN)/PN);
  OCR1B = ICR1/((PP+PN)/PN);
  OCR1C = ICR1/((PP+PN)/PN);
  //Inicia timer 1
143
  TCCR1B |= ((1 << CS11)| (1 << CS10));        //define prescaler de 64 para timer 1 e inicia
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
  //Ativa interrupt do timer 1:
  TIMSK1 |= (1<<OCIE1A);
  sei();                                       //Reativa os interrupts
}

void config_timer3()                          //funcao que configura o microcontrolador
{
  cli();                                      //desativa interrupts para fazer configuracao
  //PWM
  //Ativa pinos do canal 2:
  DDRE |= (1 << PE3);                //ativa pino PE3 (OC3A) - pino 5
  DDRE |= (1 << PE4);                //ativa pino PE4 (OC3B) - pino 2
  DDRE |= (1 << PE5);                //ativa pino PE5 (OC3C) - pino 3
  //Limpa registradores de controle do timer 3
  TCCR3A = 0;
  TCCR3B = 0;
  //Define timer 3 no modo Fast-PWM 14 (TOP definido por ICR3)
  TCCR3A |= (1 << WGM31);
  TCCR3B |= (1 << WGM32);
  TCCR3B |= (1 << WGM33);
  //Saida de PWM nao-inversor em A e inversor em B e nao-inversor em C
  TCCR3A |= ((1 << COM3A1) | (1 << COM3B1) | (1 << COM3B0) | (1 << COM3C1));
  TCCR3A &= ~(1 << COM3A0);
  TCCR3A &= ~(1 << COM3C0);
  // Define frequencia do PWM e Duty Cycle
  ICR3 = (250*(PP+PN))-1;
  OCR3A = ICR3/((PP+PN)/PN);
  OCR3B = ICR3/((PP+PN)/PN);
  OCR3C = ICR3/((PP+PN)/PN);
  //Inicia timer 3
  TCCR3B |= ((1 << CS31)| (1 << CS30));        //define prescaler de 64 para timer 3 e inicia  
  sei();                                       //Reativa os interrupts
}

void config_timer4()                          //funcao que configura o microcontrolador
{
  cli();                                      //desativa interrupts para fazer configuracao
  //PWM
  //Ativa pinos do canal 3:
  DDRH |= (1 << PH3);                //ativa pino PH3 (OC4A) - pino 6
  DDRH |= (1 << PH4);                //ativa pino PH4 (OC4B) - pino 7
  DDRH |= (1 << PH5);                //ativa pino PH5 (OC4C) - pino 8
  //Limpa registradores de controle do timer 4
  TCCR4A = 0;
  TCCR4B = 0;
  //Define timer 4 no modo Fast-PWM 14 (TOP definido por ICR4)
  TCCR4A |= (1 << WGM41);
  TCCR4B |= (1 << WGM42);
  TCCR4B |= (1 << WGM43);
  //Saida de PWM nao-inversor em A e inversor em B e nao-inversor em C
  TCCR4A |= ((1 << COM4A1) | (1 << COM4B1) | (1 << COM4B0) | (1 << COM4C1));
  TCCR4A &= ~(1 << COM4A0);
  TCCR4A &= ~(1 << COM4C0);
  // Define frequencia do PWM e Duty Cycle
  ICR4 = (250*(PP+PN))-1;
  OCR4A = ICR4/((PP+PN)/PN);
  OCR4B = ICR4/((PP+PN)/PN);
  OCR4C = ICR4/((PP+PN)/PN);
  //Inicia timer 4
  TCCR4B |= ((1 << CS41)| (1 << CS40));        //define prescaler de 64 para timer 4 e inicia  
  sei();                                       //Reativa os interrupts
}

void config_timer5()                          //funcao que configura o microcontrolador
{
  cli();                                      //desativa interrupts para fazer configuracao
  //PWM
  //Ativa pinos do canal 4:
  DDRL |= (1 << PL3);                //ativa pino PL3 (OC5A) - pino 46
  DDRL |= (1 << PL4);                //ativa pino PL4 (OC5B) - pino 45
  DDRL |= (1 << PL5);                //ativa pino PL5 (OC5C) - pino 44
  //Limpa registradores de controle do timer 5
  TCCR5A = 0;
  TCCR5B = 0;
  //Define timer 5 no modo Fast-PWM 14 (TOP definido por ICR5)
  TCCR5A |= (1 << WGM51);
  TCCR5B |= (1 << WGM52);
  TCCR5B |= (1 << WGM53);
  //Saida de PWM nao-inversor em A e inversor em B e nao-inversor em C
  TCCR5A |= ((1 << COM5A1) | (1 << COM5B1) | (1 << COM5B0) | (1 << COM5C1));
  TCCR5A &= ~(1 << COM5A0);
  TCCR5A &= ~(1 << COM5C0);
  // Define frequencia do PWM e Duty Cycle
  ICR5 = (250*(PP+PN))-1;
  OCR5A = ICR5/((PP+PN)/PN);
  OCR5B = ICR5/((PP+PN)/PN);
  OCR5C = ICR5/((PP+PN)/PN);
  //Inicia timer 5
  TCCR5B |= ((1 << CS51)| (1 << CS50));        //define prescaler de 64 para timer 5 e inicia  
  sei();                                       //Reativa os interrupts
}