【问题标题】:Microchip dsPIC33FJ256GP710A from example code for comm via UARTMicrochip dsPIC33FJ256GP710A 来自通过 UART 进行通信的示例代码
【发布时间】:2019-03-12 23:17:35
【问题描述】:

我正在尝试让我的系统使用 UART 通过 xbee 发送信号,并且我有一个良好的链接并且我正在通信。

我使用的代码应该在我按下板上的按钮时输出一些东西。

下面的代码应该是输出

  • 按下 1 时为“h”
  • 按下 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();
    }
}

【问题讨论】:

    标签: c string uart microchip


    【解决方案1】:

    嗯,这些更改应该是一个好的开始,但我想在将下一个字符加载到 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;
    }
    

    【讨论】:

    • 我做到了,它工作得很好,除了它只发送 hello 而不是整个字符串。有什么想法吗?抱歉,我在编码方面非常陌生,并且在我的高级项目中被投入其中。
    • 只有在 TX 缓冲区为空时才可写入。所以提前测试缓冲区,等它满了。
    【解决方案2】:

    只有在至少有一个位置为空时才写入TX-Buffer,否则会丢失数据:

    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;
    }
    

    【讨论】:

      猜你喜欢
      • 2021-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-09
      • 2013-03-28
      • 2021-03-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多