代码之家  ›  专栏  ›  技术社区  ›  Hamza khalid

图18f47k40 EUSART设置

  •  0
  • Hamza khalid  · 技术社区  · 1 年前

    我试图在一个具有PIC18f47k40 MCU的设备中实现Modbus RTU,该MCU的波特率为19200。

    我首先设置eusart1用于发送和接收。 这是main.c中应该打印数组的代码:

        DIR_RS486_SetHigh();  // Set RS485 direction to transmit
        const char message[] = "Hello world";
        DelayUs(100);      // Short delay to allow direction to stabilize
        DIR_RS486_SetHigh();
        for (uint8_t i = 0u; i < sizeof(message)-1; i++)  // Loop to send each character
            {
            WDIFeed();
            EUSART1_Write(message[i]);  // Send each character
            }  
        DIR_RS486_SetLow();
        DelayUs(100);
    

    这是EUSART.c代码:

    /**
      EUSART1 Generated Driver File
    
      @Company
        Microchip Technology Inc.
    
      @File Name
        eusart1.c
    
      @Summary
        This is the generated driver implementation file for the EUSART1 driver using PIC10 / PIC12 / PIC16 / PIC18 MCUs
    
      @Description
        This source file provides APIs for EUSART1.
        Generation Information :
            Product Revision  :  PIC10 / PIC12 / PIC16 / PIC18 MCUs - 1.65.2
            Device            :  PIC18F47K40
            Driver Version    :  2.01
        The generated drivers are tested against the following:
            Compiler          :  XC8 1.45
            MPLAB             :  MPLAB X 4.15
    */
    
    /*
        (c) 2018 Microchip Technology Inc. and its subsidiaries. 
        
        Subject to your compliance with these terms, you may use Microchip software and any 
        derivatives exclusively with Microchip products. It is your responsibility to comply with third party 
        license terms applicable to your use of third party software (including open source software) that 
        may accompany Microchip software.
        
        THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER 
        EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY 
        IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS 
        FOR A PARTICULAR PURPOSE.
        
        IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, 
        INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND 
        WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP 
        HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO 
        THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL 
        CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT 
        OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS 
        SOFTWARE.
    */
    
    /**
      Section: Included Files
    */
    #include "eusart1.h"
    /**
      Section: Macro Declarations
    */
    
    #define EUSART1_TX_BUFFER_SIZE 128
    #define EUSART1_RX_BUFFER_SIZE 128
    
    /**
      Section: Global Variables
    */
    volatile uint8_t eusart1TxHead = 0;
    volatile uint8_t eusart1TxTail = 0;
    volatile uint8_t eusart1TxBuffer[EUSART1_TX_BUFFER_SIZE];
    volatile uint8_t eusart1TxBufferRemaining;
    
    volatile uint8_t eusart1RxHead = 0;
    volatile uint8_t eusart1RxTail = 0;
    volatile uint8_t eusart1RxBuffer[EUSART1_RX_BUFFER_SIZE];
    volatile uint8_t eusart1RxCount;
    
    /**
      Section: EUSART1 APIs
    */
    void EUSART1_Initialize(void)
    {
        // disable interrupts before changing states
        PIE3bits.RC1IE = 0;
        EUSART1_SetRxInterruptHandler(EUSART1_Receive_ISR);
        PIE3bits.TX1IE = 0;
        EUSART1_SetTxInterruptHandler(EUSART1_Transmit_ISR);
        // Set the EUSART1 module to the options selected in the user interface.
    
        // ABDOVF no_overflow; SCKP Non-Inverted; BRG16 16bit_generator; WUE disabled; ABDEN disabled; 
        BAUD1CON = 0x08;
    
        // SPEN enabled; RX9 8-bit; CREN enabled; ADDEN disabled; SREN disabled; 
        RC1STA = 0x90;
    
        // TX9 8-bit; TX9D 0; SENDB sync_break_complete; TXEN enabled; SYNC asynchronous; BRGH hi_speed; CSRC slave; 
        TX1STA = 0x24;
    
        // SP1BRGL 103; 
        SP1BRGL = 0x67;
    
        // SP1BRGH 0; 
        SP1BRGH = 0x00;
    
    
        // initializing the driver state
        eusart1TxHead = 0;
        eusart1TxTail = 0;
        eusart1TxBufferRemaining = sizeof(eusart1TxBuffer);
    
        eusart1RxHead = 0;
        eusart1RxTail = 0;
        eusart1RxCount = 0;
    
        // enable receive interrupt
        PIE3bits.RC1IE = 1;
    }
    
    //uint8_t EUSART1_is_tx_ready(void)
    //{
    //    return eusart1TxBufferRemaining;
    //}
    
    //uint8_t EUSART1_is_rx_ready(void)
    //{
    //    return eusart1RxCount;
    //}
    //
    //bool EUSART1_is_tx_done(void)
    //{
    //    return TX1STAbits.TRMT;
    //}
    
    //uint8_t EUSART1_Read(void)
    //{
    //    uint8_t readValue  = 0;
    //    
    //    while(0 == eusart1RxCount)
    //    {
    //    }
    //
    //    readValue = eusart1RxBuffer[eusart1RxTail++];
    //    if(sizeof(eusart1RxBuffer) <= eusart1RxTail)
    //    {
    //        eusart1RxTail = 0;
    //    }
    //    PIE3bits.RC1IE = 0;
    //    eusart1RxCount--;
    //    PIE3bits.RC1IE = 1;
    //
    //    return readValue;
    //}
    // EUSART1_Write sends one byte to the EUSART transmit buffer
    void EUSART1_Write(uint8_t txData)
    {
        while (!PIR3bits.TX1IF);  // Wait until the transmit buffer is empty
        TX1REG = txData;          // Load the byte into the transmit register
    }
    
    //void EUSART1_Write(uint8_t txData)
    //{
    //     uint16_t timeout = 1000;  // Set a timeout limit
    //    while(0 == eusart1TxBufferRemaining)
    //    {
    //        if (--timeout == 0)
    //        {
    //            // Handle timeout error, perhaps reset the buffer or return an error code
    //            return;  // Exit the function to avoid getting stuck
    //        }
    //    }
    //    if(0 == PIE3bits.TX1IE)
    //    {
    //        TX1REG = txData;
    //    }
    //    else
    //    {   
    //        PIE3bits.TX1IE = 0;
    //        eusart1TxBuffer[eusart1TxHead++] = txData;
    //        if(sizeof(eusart1TxBuffer) <= eusart1TxHead)
    //        {
    //            eusart1TxHead = 0;
    //        }
    //        eusart1TxBufferRemaining--;
    //    }
    //    PIE3bits.TX1IE = 1;
    //}
    
    char getch(void)
    {
        return EUSART1_Read();
    }
    
    void putch(char txData)
    {
        EUSART1_Write(txData);
    }
    
    void EUSART1_Transmit_ISR(void)
    {
    
        // add your EUSART1 interrupt custom code
        if(sizeof(eusart1TxBuffer) > eusart1TxBufferRemaining)
        {
            TX1REG = eusart1TxBuffer[eusart1TxTail++];
            if(sizeof(eusart1TxBuffer) <= eusart1TxTail)
            {
                eusart1TxTail = 0;
            }
            eusart1TxBufferRemaining++;
        }
        else
        {
            PIE3bits.TX1IE = 0;
        }
    }
    
    void EUSART1_Receive_ISR(void)
    {
        
        if(1 == RC1STAbits.OERR)
        {
            // EUSART1 error - restart
    
            RC1STAbits.CREN = 0;
            RC1STAbits.CREN = 1;
        }
    
        // buffer overruns are ignored
        eusart1RxBuffer[eusart1RxHead++] = RC1REG;
        if(sizeof(eusart1RxBuffer) <= eusart1RxHead)
        {
            eusart1RxHead = 0;
        }
        eusart1RxCount++;
    }
    
    void EUSART1_SetTxInterruptHandler(void (* interruptHandler)(void)){
        EUSART1_TxDefaultInterruptHandler = interruptHandler;
    }
    
    void EUSART1_SetRxInterruptHandler(void (* interruptHandler)(void)){
        EUSART1_RxDefaultInterruptHandler = interruptHandler;
    }
    /**
      End of File
    */
    
    

    大多数函数定义都被注释掉了,因为我没有使用这些函数,我遇到了一个错误。

    这是中断处理程序代码(有时我的设备会卡在这里):

    void __interrupt() INTERRUPT_InterruptManagerHigh (void)
    {
    //   // interrupt handler
    //    if(PIE3bits.BCL2IE == 1 && PIR3bits.BCL2IF == 1)
    //    {
    //        i2c2_driver_busCollisionISR();
    //    }
    //    else if(PIE3bits.SSP2IE == 1 && PIR3bits.SSP2IF == 1)
    //    {
    //        i2c2_driver_i2cISR();
    //    }
    //    else
    //    {
    //        //Unhandled Interrupt
    //    }
        // interrupt handler
        if(PIE3bits.TX1IE == 1 && PIR3bits.TX1IF == 1)
        {
            EUSART1_TxDefaultInterruptHandler();
        }
        else if(PIE3bits.RC1IE == 1 && PIR3bits.RC1IF == 1)
        {
            EUSART1_RxDefaultInterruptHandler();
        }
        else
        {
            //Unhandled Interrupt
        }
    }
    

    我尝试了不同的功能将hello world打印到串行终端,但有时hello world会被打印出来,但设备会收到看门狗。取消注释中断处理程序代码后,设备不再卡住,但串行终端显示垃圾正在打印。

    0 回复  |  直到 1 年前
    推荐文章