2013-10-02 8 views
0

PIC 18 마이크로 컨트롤러를 사용하여 PWM을 사용하여 DC 모터의 속도를 제어합니다. 아래 코드를 사용하여 회전시킬 수있었습니다. 그리고 H-Bridge가 100 % 기능을 수행하는지 테스트했습니다.PIC 18 DC 모터 제어 PWM

그러나 회로에 12V, 로직에 5V를 스위치하면 RS232 통신 모듈을 사용하여 회로에 명령을 보낸다. (테스트를 거쳤으므로 올바르게 송신한다.) 프로그램이 재설정되고 벤치 전원 공급 장치의 전류가 0A로 떨어집니다. 때로는 모터가 거의 회전하지 않는 것처럼 거의 움직이지 않지만 정지합니다.

내가 잘못 될 수있는 아이디어가 있습니까?

/* 
* File: serial.c 
* Author: Chris Lombaard 
* 
* Created on September 13, 2013, 2:39 PM 
*/ 

#pragma config FOSC = INTIO7 // Oscillator Selection bits (Internal oscillator block, CLKOUT function on OSC2) 
#pragma config PLLCFG = OFF  // 4X PLL Enable (Oscillator used directly) 
#pragma config PRICLKEN = ON // Primary clock enable bit (Primary clock is always enabled) 
#pragma config FCMEN = OFF  // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled) 
#pragma config IESO = OFF  // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled) 
#pragma config PWRTEN = OFF  // Power-up Timer Enable bit (Power up timer disabled) 
#pragma config BOREN = SBORDIS // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled)) 
#pragma config BORV = 190  // Brown Out Reset Voltage bits (VBOR set to 1.90 V nominal) 
#pragma config WDTEN = OFF  // Watchdog Timer Enable bits (WDT is always enabled. SWDTEN bit has no effect) 
#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768) 
#pragma config CCP2MX = PORTC1 // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1) 
#pragma config PBADEN = ON  // PORTB A/D Enable bit (PORTB<5:0> pins are configured as analog input channels on Reset) 
#pragma config CCP3MX = PORTB5 // P3A/CCP3 Mux bit (P3A/CCP3 input/output is multiplexed with RB5) 
#pragma config HFOFST = ON  // HFINTOSC Fast Start-up (HFINTOSC output and ready status are not delayed by the oscillator stable status) 
#pragma config T3CMX = PORTC0 // Timer3 Clock input mux bit (T3CKI is on RC0) 
#pragma config P2BMX = PORTD2 // ECCP2 B output mux bit (P2B is on RD2) 
#pragma config MCLRE = EXTMCLR // MCLR Pin Enable bit (MCLR pin enabled, RE3 input pin disabled) 
#pragma config STVREN = ON  // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset) 
#pragma config LVP = OFF   // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled if MCLRE is also 1) 
#pragma config XINST = OFF  // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode)) 
#pragma config CP0 = OFF  // Code Protection Block 0 (Block 0 (000800-001FFFh) not code-protected) 
#pragma config CP1 = OFF  // Code Protection Block 1 (Block 1 (002000-003FFFh) not code-protected) 
#pragma config CP2 = OFF  // Code Protection Block 2 (Block 2 (004000-005FFFh) not code-protected) 
#pragma config CP3 = OFF  // Code Protection Block 3 (Block 3 (006000-007FFFh) not code-protected) 
#pragma config CPB = OFF  // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected) 
#pragma config CPD = OFF  // Data EEPROM Code Protection bit (Data EEPROM not code-protected) 
#pragma config WRT0 = OFF  // Write Protection Block 0 (Block 0 (000800-001FFFh) not write-protected) 
#pragma config WRT1 = OFF  // Write Protection Block 1 (Block 1 (002000-003FFFh) not write-protected) 
#pragma config WRT2 = OFF  // Write Protection Block 2 (Block 2 (004000-005FFFh) not write-protected) 
#pragma config WRT3 = OFF  // Write Protection Block 3 (Block 3 (006000-007FFFh) not write-protected) 
#pragma config WRTC = OFF  // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected) 
#pragma config WRTB = OFF  // Boot Block Write Protection bit (Boot Block (000000-0007FFh) not write-protected) 
#pragma config WRTD = OFF  // Data EEPROM Write Protection bit (Data EEPROM not write-protected) 
#pragma config EBTR0 = OFF  // Table Read Protection Block 0 (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks) 
#pragma config EBTR1 = OFF  // Table Read Protection Block 1 (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks) 
#pragma config EBTR2 = OFF  // Table Read Protection Block 2 (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks) 
#pragma config EBTR3 = OFF  // Table Read Protection Block 3 (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks) 
#pragma config EBTRB = OFF  // Boot Block Table Read Protection bit (Boot Block (000000-0007FFh) not protected from table reads executed in other blocks) 

#include <P18F45K22.h> 
#include <xc.h> 
#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 
#define _XTAL_FREQ 4000000 
#define length(x) (sizeof(x)/sizeof(x[0])) //Length of array 

void writeUART(const unsigned char string[]); 
void setup(void); 
void inputCheck(void); 
void stepF(void); 
void stepB(void); 
unsigned char buffer[8] = {'\0'}; 
unsigned char prevPos = 0; 
unsigned char currPos = 0; 
unsigned char bufferLength; 
unsigned char direction = 0; 
unsigned char speed = 0; 
unsigned char isSetup = 0; 


char main(void){ 
    if(isSetup == 0){ 
     setup(); 
     writeUART("ERD 320 Practical 2 ----- Group 1\n"); 
     writeUART("JC Lombaard - 11028786\n"); 
     writeUART("VFDC Henriques - 11100232\n"); 
     writeUART("William Reeler - 11228866\n"); 
     writeUART("FAN POSITION: 1"); 
     PORTDbits.RD1 = 1; 
     PORTDbits.RD0 = 0; 
     PORTCbits.RC3 = 0; 
     PORTCbits.RC0 = 0; 
     PORTAbits.RA6 = 0; 
    } 

    while(1){ 
     if(PORTEbits.RE1 == 1) 
      stepB(); 
     if(PORTEbits.RE0 == 1){ 
      writeUART("\nFan calibrated!\n"); 
      break; 
     } 
    } 

    bufferLength = 0; 
    while (1); 
    return (EXIT_SUCCESS); 
} 

void interrupt high_priority isr_high(void) { 
    if(PIR1bits.RC1IF == 1){ 
     if(RCREG1 == '\n'){ 
      buffer[bufferLength++] = '\0'; 
      bufferLength = 0; 
      inputCheck(); 
     }else{ 
      buffer[bufferLength++] = RCREG1; 
      PIR1bits.RC1IF = 0; 
     } 
    } 
} 

void interrupt low_priority isr_low(void){ 
    PIR1bits.TMR2IF = 0; 
    TMR2 = 0; 
} 

void inputCheck(void) { 
    const unsigned char commands[11][3] = {"S0", "S1", "S2", "S3", "S4", "P1", "P2", "P3", "P4", "R", "F"}; 
    unsigned char choice = 0; 
    for(; choice < 11; choice++) 
     if (strcmp(buffer, commands[choice]) == 0){ 
      break; 
     } 
    switch(choice){   
     case 0: 
      writeUART("FAN SPEED: 0% DC"); 
      PORTA = 0b00111111; 
      speed = 0; 
      if(direction == 0){ 
       CCPR1L = 0x00; 
      }else{ 
       CCPR2L = 0x00; 
      } 

      break; 
     case 1: 
      writeUART("FAN SPEED: 10% DC"); 
      PORTA = 0b00000110; 
      speed = 0b01101110 ; 
      if(direction == 0){ 
       CCPR1L = 0b11010000 ; 
       __delay_ms(100); 
       CCPR1L = 0b01101110 ; 
      }else{ 
       CCPR2L = 0b11010000 ; 
       __delay_ms(100); 
       CCPR2L = 0b01101110 ; 
      } 
      break; 
     case 2: 
      writeUART("FAN SPEED: 30% DC"); 
      PORTA = 0b01011011; 
      speed = 0b10001100; 
      if(direction == 0){ 
       CCPR1L = 0b11010000; 
       __delay_ms(100); 
       CCPR1L = 0b10001100; 
      }else{ 
       CCPR2L = 0b11010000 ; 
       __delay_ms(100); 
       CCPR2L = 0b10001100 ; 
      } 
      break; 
     case 3: 
      writeUART("FAN SPEED: 60% DC"); 
      PORTA = 0b01001111; 
      speed = 0b10101101; 
      if(direction == 0){ 
       CCPR1L = 0b11010000 ; 
       __delay_ms(100); 
       CCPR1L = 0b10101101 ; 
      }else{ 
       CCPR2L = 0b11010000 ; 
       __delay_ms(100); 
       CCPR2L = 0b10101101 ; 
      } 
      break; 
     case 4: 
      writeUART("FAN SPEED: 90% DC"); 
      PORTA = 0b01100110; 
      speed = 0b11010000 ; 
      if(direction == 0){ 
       CCPR1L = 0b11010000; 
      }else{ 
       CCPR2L = 0b11010000; 
      } 
      break; 
     case 5: 
      currPos = 1; 
      if(prevPos > currPos){ 
       for(int i = prevPos+1; i > currPos; i--) 
       stepB(); 
      }else{ 

      } 
      writeUART("FAN POSITION: 1"); 
      PORTDbits.RD1 = 1; 
      PORTDbits.RD0 = 0; 
      PORTCbits.RC3 = 0; 
      PORTCbits.RC0 = 0; 
      prevPos = currPos; 
      break; 
     case 6: 
      prevPos = currPos; 
      currPos = 2; 
      if(prevPos > currPos){ 
       for(int i = prevPos+1; i > currPos; i--) 
       stepB(); 
      }else{ 
       for(int i = currPos+1; i > prevPos; i--) 
       stepF(); 
      } 
      writeUART("FAN POSITION: 2"); 
      PORTDbits.RD1 = 0; 
      PORTDbits.RD0 = 1; 
      PORTCbits.RC3 = 0; 
      PORTCbits.RC0 = 0; 
      prevPos = currPos; 
      break; 
     case 7: 
      prevPos = currPos; 
      currPos = 3; 
      if(prevPos > currPos){ 
       for(int i = prevPos+1; i > currPos; i--) 
       stepB(); 
      }else{ 
       for(int i = currPos+1; i > prevPos; i--) 
       stepF(); 
      } 
      writeUART("FAN POSITION: 3"); 
      PORTDbits.RD1 = 0; 
      PORTDbits.RD0 = 0; 
      PORTCbits.RC3 = 1; 
      PORTCbits.RC0 = 0; 
      prevPos = currPos; 
      break; 
     case 8: 
      prevPos = currPos; 
      currPos = 4; 
      if(prevPos > currPos){ 
       for(int i = prevPos+1; i > currPos; i--) 
       stepB(); 
      }else{ 
       for(int i = currPos+1; i > prevPos; i--) 
       stepF(); 
      } 
      writeUART("FAN POSITION: 4"); 
      PORTDbits.RD1 = 0; 
      PORTDbits.RD0 = 0; 
      PORTCbits.RC3 = 0; 
      PORTCbits.RC0 = 1; 
      prevPos = currPos; 
      break; 
     case 9: 
      direction = 1; 
      CCP1CON = 0b00000000; 
      CCP2CON = 0b00111100; 
      CCPR2L = speed; 
      writeUART("FAN DIRECTION: REVERSED"); 
      break; 
     case 10: 
      direction = 0; 
      CCP1CON = 0b00111100; 
      CCP2CON = 0b00000000; 
      CCPR1L = speed; 
      writeUART("FAN DIRECTION: FORWARD"); 
      break; 
     default: 
      break; 
    } 
} 

void stepF(void){ 
    for(int i = 0; i < 1; i++){ 
     PORTB = 0b0001; 
     __delay_ms(100); //Delay between transitions 
     PORTB = 0b0010; 
     __delay_ms(100); //Delay between transitions 
     PORTB = 0b0100; 
     __delay_ms(100); //Delay between transitions 
     PORTB = 0b1000; 
     __delay_ms(100); //Delay between transitions 
    } 
} 

void stepB(void){ 
    for(int i = 0; i < 1; i++){ 
     PORTB = 0b1000; 
     __delay_ms(100); //Delay between transitions 
     PORTB = 0b0100; 
     __delay_ms(100); //Delay between transitions 
     PORTB = 0b0010; 
     __delay_ms(100); //Delay between transitions 
     PORTB = 0b0001; 
     __delay_ms(100); //Delay between transitions 
    } 
} 

void defaultPos(void){ 
    PORTB = 0b1000; 
    __delay_ms(100); //Delay between transitions 
    PORTB = 0b0100; 
    __delay_ms(100); //Delay between transitions 
    PORTB = 0b0010; 
    __delay_ms(100); //Delay between transitions 
    PORTB = 0b0001; 
    __delay_ms(100); //Delay between transitions 
} 

void writeUART(const unsigned char string[]){ 
    for(unsigned char j = 0; j < strlen(string); j++){ 
     TXREG1 = string[j]; 
     __delay_us(1000); 
    } 
} 

void setup(void){ 
    isSetup = 1; 
    //PORTC 
    PORTC = 0x00; 
    LATC = 0x00; 
    TRISC = 0xC0; //Set RC6 & RC7 as inputs for EUSART 
    TRISCbits.RC6 = 0; 
    TRISCbits.RC7 = 1; 
    ANSELC = 0x00; 

    //PORTD 
    PORTD = 0x00; 
    LATD = 0x00; 
    TRISD = 0x00; 
    ANSELD = 0x00; 

    //PORTE 
    PORTE = 0x00; 
    LATE = 0x00; 
    TRISEbits.RE0 = 1; 
    TRISEbits.RE1 = 1; 
    ANSELE = 0x00; 

    //PORTB 
    PORTB = 0x00; 
    LATB = 0x00; 
    TRISB = 0x00; 
    ANSELB = 0x00; 

    PORTA = 0x00; 
    LATA = 0x00; 
    TRISA = 0x00; 
    ANSELA = 0x00; 

    //Oscillator 
    OSCCON = 0b01011100; //4 MHz oscillator 

    //EUSART 
    TXSTA1bits.BRGH = 1; //Highspeed baudrate 
    BAUDCON1bits.BRG16 = 0; 
    SPBRG1 = 12; //Baudrate of 19230 (FOSC = 4 MHz, BRGH = 1, BRG16 = 0) 
    TXSTA1bits.SYNC = 0; //Asynchronous 
    RCSTA1bits.SPEN = 1; //Enable rx & tx pins as serial pins 
    RCSTA1bits.CREN = 1; //Enable continuous reception, enable receiver 
    TXSTA1bits.TXEN = 1; //Enable transmitter 
    TXREG1 = 0x00; 
    RCREG1 = 0x00; 

    //Interrupts 
    RCONbits.IPEN = 1; //Enable priorities 
    INTCONbits.GIE_GIEH = 1; //Enable high priority interrupts 
    INTCONbits.PEIE_GIEL = 1; //Enable low priority interrupts 
    PIE1bits.TMR2IE = 1; 
    IPR1bits.TMR2IP = 0; 
    PIE1bits.RC1IE = 1; //Enable RX interrupt 
    PIR1bits.RC1IF = 0; //Clear interrupt flag 
    IPR1bits.RC1IP = 1; //High priority for RX interrupts 

    //PWM 
    PR2 = 0b11111001 ; 
    T2CON = 0b00000100; //1 KHz pulse frequency on CCP1 pin 
    CCPR1L = 0x00; 
    CCPR2L = 0x00; 

    CCP1CON = 0b00111100; 
    CCP2CON = 0b00000000; 
    TMR2 = 0; 
} 
+0

하드웨어 문제 냄새

  • 드롭 ... 리셋은 재현? 그렇다면 프로그램에서 어디에서 재설정 할 수 있는지 확인 했습니까? – ouah

  • +2

    우선 순위가 높은 인터럽트 루틴 (또는 하나에 의해 호출되는 inputCheck)에서'writeUART' 또는'__delay_ms'를 호출해야합니까? 감시 타이머가 활성화 된 경우 (PIC) 그것은 당신이 high prio ISR 내부에서 기다리는 동안 리셋 될 수 있습니다 ...? –

    +0

    안녕하세요, 워치 독 타이머가 꺼져 있습니다. 또한 지연을 100에서 더 높게 변경할 수 없습니다. 나는 이유를 모른다. 케이스 문에 도달하면 재설정되고 "FAN SPEED : 10 % DC"를 출력 한 다음 재설정됩니다. 그래서 문제가 거기에 있다고 생각합니다. – Chris

    답변

    0

    몇 가지 제안 ,

    • Oscilliscope? 전구보다는 DC 모터와
    • 테스트, 적은 전류와 전압이 너무 많은 선이
    관련 문제