2013-10-02 73 views
0

使用PIC 18單片機來控制使用PWM的直流電機的速度。我已經設法讓它旋轉使用下面的代碼。我已經測試過我的H-Bridge是100%功能的。但是,當我接通電路時,12V連接到電機,5V連接到邏輯電路,然後使用我的RS232通信模塊(我已經測試並接收並正確傳輸)發送命令給電路,程序復位,臺式電源上的電流降至0A。有時候馬達會輕微搖晃,好像它試圖旋轉一樣,但隨後停下來。使用PIC 18 PWM控制直流電機

任何想法,我可能會出錯?

/* 
* 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 )當你在高級ISR內部等待時,它可能重置...? –

+0

嗨,看門狗定時器關閉。此外,它不允許我將延遲從100更改爲更高。我不知道爲什麼。我發現一旦它到達case語句就重置,它輸出「FAN SPEED:10%DC」,然後重置。所以即時考慮問題在那裏.. – Chris

回答

0

一些建議,

  • Oscilliscope?
  • 測試用一個燈泡,而不是一個直流電機,電流和電壓降少
  • 這聞起來像一個硬件問題
相關問題