2013-10-02 47 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?
  • 测试用一个灯泡,而不是一个直流电机,电流和电压降少
  • 这闻起来像一个硬件问题
相关问题