Pesquisar neste blog

18/06/2023

Frequência em motor de passo com PIC 16F877A

Objetivo: Fazer um motor de passo com os seguintes requisitos :
1. O motor de passo deve girar no sentido horário ou anti-horário
2. Sua velocidade de rotação deve ser controlada por um potenciômetro
3. Deve ser acionada por 2 botões
4. Deve ser informada os dados no display LCD:
  • Posição do ângulo
  • Dados da frequência angular em que está girando
  • Dados da frequência em Hz em que está girando
5. Se o motor estiver off, deverá ser acionado 1 Led e desligar os demais
6. Se o motor estiver ON no sentido horário deverá ser acionado o Led 2 e desligar os demais
7, Se o motor estiver ON no sentido anti-horário, deverá ser acionado o Led 3 e desligar os demais
8. Se o motor estiver off, deverá informar no Display LCD a quantidade de tempo e dias parado.

Resolução feita em CCS C Compiler e software Protheus
Circuito para identificar 1 ciclo de trabalho
















Circuito
























Simulação feita no Protheus 7.9


CÓDIGO FEITO EM CCS C Compiler

#include <16F877A.h>
#device adc = 8
#use delay(clock = 20MHz)
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, BROWNOUT, NOLVP, NOCPD, NOWRT, NOWRT
#include <lcd.c>
#define size 8

#define PIN_1 PIN_C4
#define PIN_2 PIN_C5
#define PIN_3 PIN_C6
#define PIN_4 PIN_C7

unsigned int A, B, i = 0, POSITION;
unsigned int16 VALUE;
unsigned int8 MOTOR[size] = {64, 96, 32, 48, 16, -112, -128, -64};
unsigned int16 posicao1[size] = {45, 90, 135, 180, 225, 270, 315, 360};
unsigned int16 posicao2[size] = {360, 315, 270, 225, 180, 135, 90, 45};
unsigned int DIAS, HORAS, MINUTOS, SEGUNDOS = 0;

char setaH[size] = {
    0b00000,
    0b00100,
    0b00110,
    0b11111,
    0b00110,
    0b00100,
    0b00000,
    0b00000
};

char setaA[size] = {
    0b00000,
    0b00100,
    0b01100,
    0b11111,
    0b01100,
    0b00100,
    0b00000,
    0b00000
};

char graus[size] = {
   0b00110,
   0b01001,
   0b00110,
   0b00000,
   0b00000,
   0b00000,
   0b00000,
   0b00000
};

int1 nuevopulso = 0, cambio = 0;
int16 TFB = 0, TFS = 0, TF = 0;
float TEMPO = 0.0, frequencia;

#int_ccp1
void ccp1_int(){
   if(cambio == 0){
      TFS = CCP_1;
      setup_ccp1(CCP_CAPTURE_RE);
      cambio = 1;
   }else{
      TFB = CCP_1;
      setup_ccp1(CCP_CAPTURE_RE);
      cambio = 0;
      
      if(nuevopulso == 0){
         nuevopulso = 1;
      }
   }
}

#INT_TIMER0
void  TIMER0_isr(void) {
   
   if (nuevopulso >= 1){
      TF = (TFB - TFS);
      TEMPO = TF * 1.0 / 1000.0;
      frequencia = 1.0 / (TEMPO / 1000.0);
      nuevopulso = 0;
   }
   
}

#INT_TIMER1
void  TIMER1_isr(void) {
   A = input(PIN_B0);
   B = input(PIN_B1);
   
}

void main(){
   
   setup_adc_ports(AN0);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_timer_0(T1_DIV_BY_1); 
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);      //13,1 ms overflow
   
   setup_ccp1(CCP_CAPTURE_RE);
   enable_interrupts(int_ccp1);
   
   enable_interrupts(INT_TIMER1);
   enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);
      
   lcd_init();
   lcd_set_cgram_char(4, graus);
   
   while(TRUE) {
      output_high(PIN_B5);
      output_low(PIN_B6);
      output_low(PIN_B7);
      
      SEGUNDOS++;
      if ( SEGUNDOS > 59 ){SEGUNDOS = 0 ; MINUTOS++ ;}
      if ( MINUTOS > 59 ){MINUTOS = 0 ; HORAS++ ; }
      if ( HORAS > 23 ) {HORAS = 0 ; DIAS++ ; }
           
      lcd_gotoxy(1, 1);
      printf(lcd_putc,"\f\t\t\tMOTOR OFF !");
      
      lcd_gotoxy(1, 2);
      printf(lcd_putc, "%02u:%02u:%02u",HORAS, MINUTOS, SEGUNDOS);
      
      lcd_gotoxy(21, 1);
      printf(lcd_putc, "DIAS PARADO: %u",DIAS);
      
      delay_ms(1000);
      
      while(A == 1 && B == 0){
         output_high(PIN_B6);
         output_low(PIN_B7);
         output_low(PIN_B5);
         
         VALUE = read_adc();
         
         lcd_set_cgram_char(2, setaH);
         lcd_gotoxy(1, 1);
         printf(lcd_putc, "\f\t\tMOTOR ON ! \t%c", 2);
         
         lcd_gotoxy(1, 2);
         printf(lcd_putc,"ANGULO = [%lu%c]" posicao1[i], 4);
         
         lcd_gotoxy(21, 1);
         printf(lcd_putc,"W = %.2f rad/s", frequencia * 2 * 3.1415);
         
         lcd_gotoxy(21, 2);
         printf(lcd_putc, "F = %.2f Hz", frequencia);
         
         POSITION = MOTOR[i];
         output_bit(PIN_1, POSITION & 16);
         output_bit(PIN_2, POSITION & 32);
         output_bit(PIN_3, POSITION & 64);
         output_bit(PIN_4, POSITION & 128);
         i = (i + 1) % (sizeof(MOTOR) / sizeof(int));
         
         delay_ms(VALUE);
      }
      
      while(A == 0 && B == 1){
         output_high(PIN_B7);
         output_low(PIN_B6);
         output_low(PIN_B5);
         
         VALUE = read_adc();
         
         lcd_set_cgram_char(3, setaA);
         lcd_gotoxy(1, 1);
         printf(lcd_putc, "\f%c\tMOTOR ON !", 3);
         
         lcd_gotoxy(1, 2);
         printf(lcd_putc,"ANGULO = [-%lu%c]" posicao2[i], 4);
         
         lcd_gotoxy(21, 1);
         printf(lcd_putc,"W = %.2f rad/s", frequencia * 2 * 3.1415);
         
         lcd_gotoxy(21, 2);
         printf(lcd_putc, "F = %.2f Hz", frequencia);
         
         POSITION = MOTOR[i];
         output_bit(PIN_4, POSITION & 128);
         output_bit(PIN_3, POSITION & 64);
         output_bit(PIN_2, POSITION & 32);
         output_bit(PIN_1, POSITION & 16);
         i = (i - 1) % (sizeof(MOTOR) / sizeof(int));
         
         delay_ms(VALUE);
      }
      
   }
}

Nenhum comentário: