Advertisement
paulogp

ATmega128: T4 - Controlo de velocidade do motor

Jul 13th, 2011
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.44 KB | None | 0 0
  1. /* Pretende-se controlar a velocidade de um motor DC utilizando PWM. Os interruptores SW1, SW2, SW3 e SW4 permitem definir as velocidades de rotação do motor com os valores 0%, 40%, 70% e 100% da velocidade nominal. SW5 e SW6 definem o sentido de rotação.
  2. Qualquer alteração de velocidade/sentido deve ser implementada utilizando uma rampa de aceleração/desaceleração com uma taxa fixa de 1 unidade (OCR) / 10ms.
  3.  
  4. Sugestão:
  5. Utilizar o TC0, programado em modo CTC, para obter uma temporização base de 5ms.
  6. Utilizar o TC2, programado em modo PWM (Fast PWM ou Phase Correct PWM), para gerar o sinal de PWM na saída OC2 (PB7). A frequência deste sinal de PWM deve ser de, aproximadamente, 500Hz. O sentido de rotação será definido através das saídas Dir0 (PB4) e Dir1 (PB5). */
  7.  
  8.  
  9. #include <avr/io.h>
  10. #include <avr/interrupt.h>
  11. #include <stdlib.h>
  12. #include <math.h>
  13.  
  14. // IN1 -> 6
  15. // EN -> 8
  16. // IN2 -> 5
  17. // GND -> 8
  18. // VCC -> 7
  19.  
  20. // definicoes
  21. #define Done 1
  22. #define NotDone 0
  23. #define clock_freq 16000000
  24. #define prescaler 1024
  25.  
  26. // macros
  27. #define pwm_value(val) (255 * val) / 100
  28. #define timer_value(val) val / 5
  29. #define ocr_value(val) ((val * pow(10, -3) * clock_freq) / prescaler) -1
  30.  
  31. // retorna 1 se val negativo; 0 se val positivo
  32. #define signal(val) (val&0x8000)>>15
  33.  
  34. // 0xFE: 11111110: 11111110<<5 -> 355555520
  35. // bitwise AND (&): flags = flags & MASK -> flags &= MASK;
  36. // <<: shitft left: a<<b: desloca os bits de "a", "b" passos para a esquerda (cada passo significa "multiplicar por dois")
  37. // bitwise OR (|): flags = flags | MASK -> flags |= MASK;
  38. // bitwise NOT (~): inverte os bits
  39. #define signal_bit(port, sigbit1, sigbit0, sig) \
  40. port &= (0xFE<<sigbit1);\
  41. port &= (0xFE<<sigbit0);\
  42. port |= ((sig&0x01)<<sigbit1);\
  43. port |= ((~sig&0x01)<<sigbit0);
  44.  
  45.  
  46. typedef struct motor {
  47.     int setpoint;
  48.     int actual_point;
  49. } motor_t;
  50.  
  51. void Inic(motor_t *motor);
  52. void pwm(motor_t *motor);
  53.  
  54. unsigned char cnt = timer_value(20);
  55. unsigned char pwm_update = Done;
  56.  
  57.  
  58.  
  59. int main() {
  60.     motor_t motor;
  61.  
  62.     Inic(&motor);
  63.  
  64.     // switch da direccao e switch da velocidade em simultâneo
  65.     while(1) {
  66.         switch (PINA & 0x0F) {
  67.             case 0x0E:
  68.                 motor.setpoint = pwm_value(0);
  69.                 break;
  70.  
  71.             case 0x0D:
  72.                 if ((PINA & 0x10) == 0)
  73.                     motor.setpoint = pwm_value(-40); // -102
  74.                 else
  75.                     motor.setpoint = pwm_value(40); // 102
  76.                 break;
  77.  
  78.             case 0x0B:
  79.                 if ((PINA & 0x10) == 0)
  80.                     motor.setpoint = pwm_value(-70); // -178
  81.                 else
  82.                     motor.setpoint = pwm_value(70); // 178
  83.                 break;
  84.  
  85.             case 0x07:
  86.                 if ((PINA & 0x10) == 0)
  87.                     motor.setpoint = pwm_value(-100); // -255
  88.                 else
  89.                     motor.setpoint = pwm_value(100); // 255
  90.                 break;
  91.         }
  92.  
  93.         if (pwm_update == NotDone) {
  94.             pwm(&motor);
  95.         }
  96.     }
  97.  
  98.     return 0;
  99. }
  100.  
  101.  
  102. // inic
  103. void Inic(motor_t *motor) {
  104.     // switch
  105.     DDRA = 0x00; // 0b00000000;
  106.     PORTA = 0xC0; // 0b11000000;
  107.  
  108.     // motor
  109.     DDRB = 0xB0; // 0b10110000;
  110.     PORTB = 0x10; // 0b00010000;
  111.  
  112.     // timer 0
  113.     OCR0 = ocr_value(5);
  114.     TCCR0 = 0x0F;
  115.     cnt = timer_value(10);
  116.  
  117.     // PWM
  118.     OCR2 = 0;
  119.     TCCR2 = 0x64; // 0b01100100;
  120.  
  121.     // interr
  122.     TIMSK = TIMSK|0x2; // == TIMSK |= 0x2
  123.     SREG = SREG | 0x80;
  124.  
  125.     // inic da estrutura
  126.     motor->setpoint = 0;
  127.     motor->actual_point = 0;
  128. }
  129.  
  130.  
  131. // interrupcao
  132. ISR(TIMER0_COMP_vect) {
  133.     cnt--;
  134.  
  135.     if (cnt == 0) {
  136.         cnt = timer_value(10);
  137.         pwm_update = NotDone;
  138.     }
  139. }
  140.  
  141.  
  142. // pwm: chamada a cada 10ms
  143. void pwm(motor_t *motor) {
  144.     // coloca o motor em movimento
  145.     // coloca o motor no sentido correcto
  146.     if (motor->actual_point == 0) {
  147.         // signal pos -> output: 16
  148.         // signal neg -> output: 32
  149.         signal_bit(PORTB, 5, 4, signal(motor->setpoint));
  150.     }
  151.  
  152.     // se motor mais rapido que o pretendido
  153.     if (motor->actual_point > motor->setpoint) {
  154.         motor->actual_point--;
  155.         OCR2 = abs(motor->actual_point);
  156.     }
  157.  
  158.     // se motor mais lento que o pretendido
  159.     if (motor->actual_point < motor->setpoint) {
  160.         motor->actual_point++;
  161.         OCR2 = abs(motor->actual_point);
  162.     }
  163.  
  164.     pwm_update = Done;
  165. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement