2017-09-04 12 views
6

Tôi mới viết phần mềm cho PIC 8-bit và có thể sử dụng một số trợ giúp với mã của tôi. Tôi đang sử dụng một PIC16F1829 cho một mô-đun LED được lệnh RX. Tôi chỉ cố gắng để có được những thiết lập cơ bản như bật đèn LED khi một giá trị nhất định được nhận trên pin RX, nhưng thậm chí không thể có được điều đó.PIC16F1829 UART RX Ngắt không hoạt động bằng cách sử dụng trình biên dịch MPLABX và XC8

Muốn làm cho UART hoạt động thông qua các ngắt nhưng không thể làm cho nó hoạt động bình chọn trong vòng lặp chính. Vector ngắt của tôi được nhận xét trong mã bên dưới.

RX pin: RC5

TX pin: RB7

Pin để chuyển đổi đèn LED và tắt: RA5

Pin RA5 hoạt động tốt để chuyển đổi đèn LED và tắt. TX pin đang làm việc, mặc dù tôi đã không xác nhận nếu làm gián đoạn TXIF cũng không hoạt động như RCIF không hoạt động.

Tôi đã thử đọc RCIF và PIR1bits.RCIF. Cả hai đều được biên soạn. Không ai làm việc cả. Tôi đã thử điều này trên hai PIC khác nhau trên 2 mô-đun LED khác nhau. Họ bật, nhưng đọc RX pin đã không làm việc trên một trong hai.

Biến RXIN ban đầu được định nghĩa là 3 và do đó do vòng lặp RXIN-- trong vòng lặp chính đèn flash 3 lần khi khởi động nên tôi biết nó đang đi vào vòng lặp chính. Nhưng như xa như tôi có thể nói rằng RCIF gián đoạn không phải là bắn khi tiếp nhận tại RX pin.

Tôi đã xác nhận trên dao động rằng tín hiệu vào RX và ra khỏi chân TX sử dụng cùng một baud, vì vậy tôi nghĩ tốc độ truyền được cấu hình chính xác (300 baud, 8N1.) Tôi cũng đã xác nhận trên RX oscilloscope pin mạnh mẽ và sạch sẽ Tín hiệu 5V. Cả RCIF bỏ phiếu hoặc sử dụng một định tuyến dịch vụ gián đoạn đã làm việc cho đến nay. Nếu bất cứ ai có thể thấy các vấn đề với mã của tôi mà tôi không thấy, trợ giúp của bạn sẽ được đánh giá cao.

Mã của tôi:

#include <stdio.h> 
#include <stdlib.h> 
#include <xc.h> 

// This is for 300 baud rate 
#define _BAUD_PRESCALER_LOW_ 0x2A 
#define _BAUD_PRESCALER_HIGH_ 0x68 
#define _XTAL_FREQ 32000000 

#pragma config FOSC = INTOSC // Oscillator Selection->INTOSC oscillator: I/O function on CLKIN pin 
#pragma config WDTE = OFF // Watchdog Timer Enable->WDT enabled 
#pragma config PWRTE = OFF // Power-up Timer Enable->PWRT disabled 
#pragma config MCLRE = OFF // MCLR Pin Function Select->MCLR/VPP pin function is digital input 
#pragma config CP = OFF // Flash Program Memory Code Protection->Program memory code protection is disabled 
#pragma config CPD = OFF // Data Memory Code Protection->Data memory code protection is disabled 
#pragma config BOREN = ON // Brown-out Reset Enable->Brown-out Reset enabled 
#pragma config CLKOUTEN = OFF // Clock Out Enable->CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin 
#pragma config IESO = OFF // Internal/External Switchover->Internal/External Switchover mode is disabled 
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable->Fail-Safe Clock Monitor is disabled 

// CONFIG2 
#pragma config WRT = OFF // Flash Memory Self-Write Protection->Write protection off 
#pragma config PLLEN = ON // PLL Enable->4x PLL enabled 
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable->Stack Overflow or Underflow will cause a Reset 
#pragma config BORV = LO // Brown-out Reset Voltage Selection->Brown-out Reset Voltage (Vbor), low trip point selected. 
#pragma config LVP = OFF 

int flagRXFramingError = 0; 
int flagRXOverrunError = 0; 
volatile unsigned char RXIN = 3; 

unsigned char UARTRead(){ 
    return RCREG; 
} 

void writeRXIN(unsigned char a){ 
    RXIN = a; 
} 

void TX(unsigned char a){ 
    while(!TXIF){} 
    TXREG = a; 
} 

int main(int argc, char** argv) { 

    // SCS FOSC; SPLLEN disabled; IRCF 8MHz_HF; 
    OSCCON = 0xF0; 
    // TUN 0; 
    OSCTUNE = 0x00; 
    // Set the secondary oscillator 
    // Wait for PLL to stabilize 
    while(PLLR == 0) 
    { 
    } 

    // WDTPS 1:65536; SWDTEN OFF; 
    WDTCON = 0x16; 
    __delay_ms(5); 

    GIE = 1; // Global interrupts enabled 
    __delay_ms(5); 
    PEIE = 1; // Active peripheral interrupts enabled 
    __delay_ms(5); 
    RCIE = 1; // Enable USART Receive interrupt 
    __delay_ms(5); 
    TXIE = 1; // Enable USART Transmitter interrupt 
    __delay_ms(5); 
    ADIE = 1; // Enable ADC interrupts 
    __delay_ms(5); 
    RXDTSEL = 0; // RX is on RC5 pin 
    __delay_ms(5); 
    TXCKSEL = 0; // TX is on RB7 pin 
    __delay_ms(5); 

    TRISC5 = 1; // RX pin set as input 
    __delay_ms(5); 

    SPEN = 1; // Serial Port Enabled 
    __delay_ms(5); 
    SYNC = 0; // Asynchronous mode 
    __delay_ms(5); 
    RX9 = 0; // 8 bit reception 
    __delay_ms(5); 
    TX9 = 0; // 8-bit transmission 
    __delay_ms(5); 
    CREN = 1; // Receiver enabled 
    __delay_ms(5); 
    TXEN = 1; // Transmitter enabled 
    __delay_ms(5); 
    BRG16 = 1; // 16-bit baud generation 
    __delay_ms(5); 
    BRGH = 1; // High baud rate enabled 
    __delay_ms(5); 
    ABDEN = 0; // Auto baud detect disabled 
    __delay_ms(5); 

    // Baud prescaler n = [Fosc/(D*BR)] - 1 

    SPBRGH = _BAUD_PRESCALER_HIGH_; 
    __delay_ms(5); 
    SPBRGL = _BAUD_PRESCALER_LOW_; 
    __delay_ms(5); 

    TRISC6 = 0; // IadjPWM pin configured as output 
    __delay_ms(5); 
    ANSC6 = 0; // IadjPWM pin not analog input 
    __delay_ms(5); 
    TRISA5 = 0; // DimPWM pin configured as output 
    __delay_ms(5); 

    LATC6 = 1; // Max current for now until PWM written 
    __delay_ms(5); 

    while(1){ 

    // Inline assembly code to clear watchdog timer 
    //asm("CLRWDT"); 

    /*if(RXIN == 5){ 
     RA5 = 1; 
    } 
    else{ 
     RA5 = 0; 
    }*/ 

     if(PIR1bits.RCIF){ 
      writeRXIN(UARTRead()); 
      //RA5 = 0; 
      TX(RXIN); 
     } // end if RCIF 

     while(RXIN > 0){ 
      RA5 = 1; 
      __delay_ms(100); 
      RA5 = 0; 
      __delay_ms(100); 
      RXIN--; 
     } 

    } 
    // infinite loop 
    // never leave this loop 

    RA5 = 1; 
    return (EXIT_SUCCESS); 
} // end main 

/*void interrupt ISR(void){ 
    if(RCIF){// if USART Receive interrupt flag 
     RA5 = 1; 

     if(FERR){ 
      flagRXFramingError = 1; 
      SPEN = 0; 
      SPEN = 1; 

     } 
     if(OERR){ 
      flagRXOverrunError = 1; 
      CREN = 0; 
      CREN = 1; 
     } 

     while(RCIF){ // RCIF high as long as there is data in FIFO register. Read RCREG to clear RCIF flag 
      writeRXIN(UARTRead()); 
     } 

     RA5 = 0; 
    } 

    if (TXIF){// if USART Transmit interrupt 
     TXIF = 0; // Clear interrupt flag 
    } 
} // end ISRs*/ 
+1

Độ trễ 5ms giữa việc ghi vào sổ đăng ký hoàn toàn vô nghĩa. 5 ms là vĩnh hằng ngay cả trên một PIC crappy. Đây là những bộ đăng ký trên chip, bộ nhớ được ánh xạ - bạn không cần bất kỳ sự chậm trễ nào cả. (Trong một số trường hợp đặc biệt, bạn có thể cần phải chờ một vài chu kỳ đồng hồ sau khi thiết lập hướng dữ liệu cho cổng I/O nhưng đó là về nó.) Bắt đầu bằng cách loại bỏ tất cả những sự chậm trễ 5ms. – Lundin

+1

(Là một lưu ý phụ để tham khảo trong tương lai: trong khi câu hỏi này là tốt và chủ đề về SO, bạn nên hỏi tại https://electronics.stackexchange.com/ khi bạn có câu hỏi về thiết bị ngoại vi phần cứng cụ thể, chẳng hạn như UART trên một PIC nhất định. Rất nhiều chuyên gia PIC ẩn trên trang web đó và câu hỏi phần mềm vi điều khiển là hoàn toàn trên chủ đề có quá.) – Lundin

+0

Tuy nhiên, tôi buộc phải upvote này, chỉ cho 'đã xác nhận trên oscilloscope rằng tín hiệu vào RX và ra khỏi chân TX sử dụng cùng một baud, vì vậy tôi nghĩ rằng tốc độ truyền được cấu hình chính xác (300 baud, 8N1.) Tôi cũng đã xác nhận trên oscilloscope RX pin nhận tín hiệu 5V mạnh mẽ và sạch sẽ '. Chúng tôi nhận được quá nhiều câu hỏi nhúng hoàn toàn không có dấu hiệu cho biết phần cứng nào đang hoạt động và do đó phải xuống/đóng/xóa bỏ phiếu ngay lập tức vì không thể trả lời được trên trang web phần mềm Q & A ( –

Trả lời

0

giải quyết vấn đề

Tôi không chắc chắn chính xác những gì đã giải quyết được vấn đề nhưng tôi sẽ chia sẻ những thay đổi lớn tôi đã thực hiện và các mã mới.

  1. Tôi đã bật TXIE. TXIF hầu như luôn cao, vì vậy nó tạo ra các ngắt liên tục . Tôi không thấy lý do nào để bật ngắt TX, mặc dù có thể có một sự cố tốt. Nếu bạn muốn TX đợi cho đến khi TXIF là không phải 0 và truyền, nếu không thì tại sao lại sử dụng cờ?

  2. Tôi đã bật ngắt theo thứ tự sai. Tôi cần có kích hoạt các thiết bị ngoại vi, sau đó ngắt riêng của chúng nếu cần thiết, sau đó là PEIE và cuối cùng là GIE.

  3. Tôi đã không xử lý FERR và OERR khi gián đoạn, mặc dù chúng có thể đang kích hoạt và gây gián đoạn.

Ngoài ra tôi có RXDTSEL đặt sai trong mã ban đầu của mình.Đây là mã làm việc mới. Ngay bây giờ tất cả nó làm là echo tín hiệu RX và nhấp nháy đèn LED số lần được truyền đi.

#include <stdio.h> 
#include <stdlib.h> 
#include <xc.h> 

// This is for 300 baud rate 
#define _BAUD_PRESCALER_LOW_ 0x2A 
#define _BAUD_PRESCALER_HIGH_ 0x68 
#define _XTAL_FREQ 32000000 
#define _PIN_DIMPWMPIN_ RA5 

#pragma config FOSC = INTOSC // Oscillator Selection->INTOSC oscillator: I/O function on CLKIN pin 
#pragma config WDTE = OFF // Watchdog Timer Enable->WDT enabled 
#pragma config PWRTE = OFF // Power-up Timer Enable->PWRT disabled 
#pragma config MCLRE = OFF // MCLR Pin Function Select->MCLR/VPP pin function is digital input 
#pragma config CP = OFF // Flash Program Memory Code Protection->Program memory code protection is disabled 
#pragma config CPD = OFF // Data Memory Code Protection->Data memory code protection is disabled 
#pragma config BOREN = ON // Brown-out Reset Enable->Brown-out Reset enabled 
#pragma config CLKOUTEN = OFF // Clock Out Enable->CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin 
#pragma config IESO = OFF // Internal/External Switchover->Internal/External Switchover mode is disabled 
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable->Fail-Safe Clock Monitor is disabled 

// CONFIG2 
#pragma config WRT = OFF // Flash Memory Self-Write Protection->Write protection off 
#pragma config PLLEN = ON // PLL Enable->4x PLL enabled 
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable->Stack Overflow or Underflow will cause a Reset 
#pragma config BORV = LO // Brown-out Reset Voltage Selection->Brown-out Reset Voltage (Vbor), low trip point selected. 
#pragma config LVP = OFF 

int flagRXFramingError = 0; 
int flagRXOverrunError = 0; 
volatile unsigned char RXIN = 3; 

unsigned char RX(){ 
    return RCREG; 
} 

void writeRXIN(volatile unsigned char a){ 
    RXIN = a; 
} 

void TX(unsigned char a){ 
    while(!PIR1bits.TXIF); // TXIF is usually 1, only 0 when busy transmitting 
    TXREG = a; 
} 

int main(int argc, char** argv) { 

    // SCS FOSC; SPLLEN disabled; IRCF 8MHz_HF; 
    OSCCON = 0xF0; 
    // TUN 0; 
    OSCTUNE = 0x00; 
    // Set the secondary oscillator 
    // Wait for PLL to stabilize 
    while(OSCSTATbits.PLLR == 0){} 

    ADCON0bits.ADON = 0; 
    ANSELA = 0x00; 
    ANSELB = 0x00; 
    ANSELC = 0x00; 
    PIE1bits.ADIE = 0; // Disable ADC interrupts 

    TRISCbits.TRISC5 = 1; // RX pin set to input 
    TRISCbits.TRISC6 = 0; // IadjPWM pin configured as output 
    TRISAbits.TRISA5 = 0; // DimPWM pin configured as output 

    LATCbits.LATC6 = 1; // Max current for now until PWM written 

    //UART Init 
    BAUDCONbits.BRG16 = 1; // 16-bit baud generation 
    TXSTAbits.BRGH = 1; // High baud rate enabled 
    BAUDCONbits.ABDEN = 0; // Auto baud detect disabled 

    // Baud prescaler n = [Fosc/(D*BR)] - 1 
    SPBRGH = _BAUD_PRESCALER_HIGH_; 
    __delay_ms(1); 
    SPBRGL = _BAUD_PRESCALER_LOW_; 
    __delay_ms(1); 

    APFCON0bits.RXDTSEL = 1; // RX is on RC5 pin 
    APFCON0bits.TXCKSEL = 0; // TX is on RB7 pin 
    TXSTAbits.SYNC = 0; // Asynchronous mode 
    RCSTAbits.SPEN = 1; // Serial Port Enabled 
    RCSTAbits.RX9 = 0; // 8 bit reception 
    TXSTAbits.TX9 = 0; // 8-bit transmission 

    RCSTAbits.CREN = 1; // Receiver enabled 
    TXSTAbits.TXEN = 1; // Transmitter enabled 

    PIE1bits.TXIE = 0; // Enable USART Transmitter interrupt 
    PIE1bits.RCIE = 1; // Enable USART Receive interrupt 
    while(PIR1bits.RCIF){ 
     writeRXIN(RX()); 
    } 

    INTCONbits.PEIE = 1; // Enable peripheral interrupts 
    INTCONbits.GIE = 1; // Enable global interrupts 

    while(1){ 
     while(RXIN > 0){ 
      TX(RXIN); 
      _PIN_DIMPWMPIN_ = 1; 
      __delay_ms(100); 
      _PIN_DIMPWMPIN_ = 0; 
      __delay_ms(100); 
      RXIN--; 
     } 

    } 
    // infinite loop 
    // never leave this loop 
    return (EXIT_SUCCESS); 
} // end main 

void interrupt ISR(void){ 

    if(PIE1bits.RCIE && PIR1bits.RCIF){ // handle RX pin interrupts 
     while(PIR1bits.RCIF){ 
      writeRXIN(RX()); 
     } 
     if(RCSTAbits.FERR){ 
      flagRXFramingError = 1; 
      SPEN = 0; 
      SPEN = 1; 

     } 
     if(RCSTAbits.OERR){ 
      flagRXOverrunError = 1; 
      CREN = 0; 
      CREN = 1; 
     } 
    } // end RX pin interrupt handlers 

} // end ISRs*/ 
+0

Tôi nghĩ rằng bạn đang xóa bất kỳ lỗi đang chờ xử lý nào của thiết bị ngoại vi (bằng cách đặt lại thiết bị ngoại vi) và sau đó thiết bị thu bắt đầu hoạt động trở lại ... –

0

Một số vi điều khiển ngừng nhận byte nếu có một số loại lỗi. Đảm bảo xóa các lỗi đó. Thông thường bằng cách xóa một số bit đăng ký kiểm soát UART.

Các vấn đề liên quan