Микрочип dsPIC33FJ256GP710A из примера кода для связи через UART - PullRequest
1 голос
/ 13 марта 2019

Я пытаюсь, чтобы моя система отправляла сигнал через xbee, используя UART, и у меня есть хорошая ссылка, и я общаюсь.

Код, который я использую, должен выводить что-то, когда я нажимаю кнопку на доске.

Предполагается, что приведенный ниже код будет выводить

  • 'h' при нажатии 1
  • 'Привет как дела' при нажатии 2
  • «3» при нажатии 3
  • «4» при нажатии 4

1,3, и 4 работают безупречно, но когда я нажимаю 2, все, что я получаю, это «о, э»,Почему это?

#include <p33FJ256GP710A.h>
#include "string.h"

_FOSCSEL(FNOSC_FRC);            // Internal FRC oscillator
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF  & POSCMD_NONE);  
                            // Clock Switching is enabled and Fail Safe 
Clock Monitor is disabled
                            // OSC2 Pin Function: OSC2 is Clock Output
                            // Primary Oscillator Mode: XT Crystanl


#define TRUE    1
#define FALSE   0

unsigned char S3Flag, S4Flag, S5Flag, S6Flag;
const char A[] = {'hello', ' ', 'how', ' ', 'are'};
int i;


void __attribute__ ((interrupt, no_auto_psv)) _U2RXInterrupt(void) {
    LATA = U2RXREG;
    IFS1bits.U2RXIF = 0;
}
void __attribute__ ((interrupt, no_auto_psv)) _U2TXInterrupt(void) {
    IFS1bits.U2TXIF = 0;
}

void InitClock() {
    PLLFBD = 38;    // M = 40
    CLKDIVbits.PLLPOST = 0; // N1 = 2
    CLKDIVbits.PLLPRE = 0;  // N2 = 2
    OSCTUN = 0;
    RCONbits.SWDTEN = 0;

    // Clock switch to incorporate PLL
    __builtin_write_OSCCONH(0x01);      // Initiate Clock Switch to 
                                                // FRC with PLL (NOSC=0b001)
    __builtin_write_OSCCONL(0x01);      // Start clock switching
    while (OSCCONbits.COSC != 0b001);   // Wait for Clock switch to occur   

    while(OSCCONbits.LOCK != 1) {};
}

void InitUART2() {
    // This is an EXAMPLE, so brutal typing goes into explaining all bit sets

    // The HPC16 board has a DB9 connector wired to UART2, so we will
    // be configuring this port only

    // configure U2MODE
    U2MODEbits.UARTEN = 0;  // Bit15 TX, RX DISABLED, ENABLE at end of func
    //U2MODEbits.notimplemented;    // Bit14
    U2MODEbits.USIDL = 0;   // Bit13 Continue in Idle
    U2MODEbits.IREN = 0;    // Bit12 No IR translation
    U2MODEbits.RTSMD = 0;   // Bit11 Simplex Mode
    //U2MODEbits.notimplemented;    // Bit10
    U2MODEbits.UEN = 0;     // Bits8,9 TX,RX enabled, CTS,RTS not
    U2MODEbits.WAKE = 0;    // Bit7 No Wake up (since we don't sleep here)
    U2MODEbits.LPBACK = 0;  // Bit6 No Loop Back
    U2MODEbits.ABAUD = 0;   // Bit5 No Autobaud (would require sending '55')
    U2MODEbits.URXINV = 0;  // Bit4 IdleState = 1  (for dsPIC)
    U2MODEbits.BRGH = 0;    // Bit3 16 clocks per bit period
    U2MODEbits.PDSEL = 0;   // Bits1,2 8bit, No Parity
    U2MODEbits.STSEL = 0;   // Bit0 One Stop Bit

    // Load a value into Baud Rate Generator.  Example is for 9600.
    // See section 19.3.1 of datasheet.
    //  U2BRG = (Fcy/(16*BaudRate))-1
    //  U2BRG = (37M/(16*9600))-1
    //  U2BRG = 240
    U2BRG = 240;    // 40Mhz osc, 9600 Baud

    // Load all values in for U1STA SFR
    U2STAbits.UTXISEL1 = 0; //Bit15 Int when Char is transferred (1/2 config!)
    U2STAbits.UTXINV = 0;   //Bit14 N/A, IRDA config
    U2STAbits.UTXISEL0 = 0; //Bit13 Other half of Bit15
    //U2STAbits.notimplemented = 0; //Bit12
    U2STAbits.UTXBRK = 0;   //Bit11 Disabled
    U2STAbits.UTXEN = 0;    //Bit10 TX pins controlled by periph
    U2STAbits.UTXBF = 0;    //Bit9 *Read Only Bit*
    U2STAbits.TRMT = 0; //Bit8 *Read Only bit*
    U2STAbits.URXISEL = 0;  //Bits6,7 Int. on character recieved
    U2STAbits.ADDEN = 0;    //Bit5 Address Detect Disabled
    U2STAbits.RIDLE = 0;    //Bit4 *Read Only Bit*
    U2STAbits.PERR = 0;     //Bit3 *Read Only Bit*
    U2STAbits.FERR = 0;     //Bit2 *Read Only Bit*
    U2STAbits.OERR = 0;     //Bit1 *Read Only Bit*
    U2STAbits.URXDA = 0;    //Bit0 *Read Only Bit*

    IPC7 = 0x4400;  // Mid Range Interrupt Priority level, no urgent reason

    IFS1bits.U2TXIF = 0;    // Clear the Transmit Interrupt Flag
    IEC1bits.U2TXIE = 1;    // Enable Transmit Interrupts
    IFS1bits.U2RXIF = 0;    // Clear the Recieve Interrupt Flag
    IEC1bits.U2RXIE = 1;    // Enable Recieve Interrupts

    U2MODEbits.UARTEN = 1;  // And turn the peripheral on

    U2STAbits.UTXEN = 1;
    // I think I have the thing working now.
}

void InitPorts() {
    // S3 (portD Pin 6, chosen as trigger for sending 'M' to UART)
    // S6 (portD Pin 7, chosen as trigger for sending 'C' to UART)
    // S5 (portA Pin 7, chosen as trigger for sending 'H' to UART)
    // S4 (portD Pin 13, chosen as trigger for sending 'P' to UART)

    TRISD = 0x20C0; // D6,7,13 inputs
    AD1PCFGHbits.PCFG23 = 1;    // This is important.  RA7 is muxxed with AN23,
        // So we need to config the pin as DIGITAL
    TRISA = 0x0080; // only 0th bit needs be output. A7 is input
    S3Flag = S4Flag = S5Flag = S6Flag = 0;  // Some Debounce Flags
}

void SoftwareDebounce() {
    if(PORTDbits.RD6 == FALSE) {
        if( S3Flag == FALSE ) {
            S3Flag = TRUE;
            U2TXREG = 'h';
        }
    }
    else {
        S3Flag = FALSE;
    }
    if(PORTDbits.RD7 == FALSE) {
        if( S6Flag == FALSE ) {
            S6Flag = TRUE;
            for(i=0; i<=4;i++){
                U2TXREG = ("%s", A[i]);
            }
        }
    }
    else {
        S6Flag = FALSE;
    }
    if(PORTAbits.RA7 == FALSE) {
        if( S5Flag == FALSE ) {
            S5Flag = TRUE;
            U2TXREG = '3';
        }
    }
    else {
        S5Flag = FALSE;
    }
    if(PORTDbits.RD13 == FALSE) {
        if( S4Flag == FALSE ) {
            S4Flag = TRUE;
            U2TXREG = '4';
        }
    }
    else {
        S4Flag = FALSE;
    }
}
int main(void) {

    InitClock();    // This is the PLL settings

    InitUART2();    // Initialize UART2 for 9600,8,N,1 TX/RX

    InitPorts();    // LEDs outputs, Switches Inputs

    while(1) {  // The ever versatile Infinite Loop!
        SoftwareDebounce();
    }
}

Ответы [ 2 ]

0 голосов
/ 18 марта 2019

Вам следует записывать в TX-буфер, только когда хотя бы одна позиция пуста, иначе вы потеряете данные:

const char *A = "hello how are";

if(PORTDbits.RD7 == FALSE) {
    if( S6Flag == FALSE ) {
        S6Flag = TRUE;
        int len = strlen(A);
        for(i=0; i<len; i++){
            while (U2STAbits.UTXBF == 1);    //wait for an empty position in the buffer
            U2TXREG = A[i];
        }
    }
}
else {
    S6Flag = FALSE;
}
0 голосов
/ 13 марта 2019

Что ж, эти изменения должны быть хорошим началом, но я думаю, что есть еще один регистр, который нужно заблокировать перед загрузкой следующего символа в U2TXREG.Вы должны попытаться найти последовательную библиотеку для использования, чтобы вы могли просто передать строку (строки), которую вы хотите напечатать, и сделать так, чтобы они помещались в кольцевой буфер, из которого извлекается обработчик прерываний, когда оборудование готово к следующему байту.

const char *A = "hello how are";

if(PORTDbits.RD7 == FALSE) {
    if( S6Flag == FALSE ) {
        S6Flag = TRUE;
        int len = strlen(A);
        for(i=0; i<len; i++){
            U2TXREG = A[i];
        }
    }
}
else {
    S6Flag = FALSE;
}
...