LPC1769 UART通信问题

2019-07-15 17:08发布

真的是超级新手,完全小白,希望能有大师指点一下,非常感谢!
我的任务是用串口助手从PC向单片机通过UART0发送一个信号,然后再用UART3将这个信号传递给外部连接的电池(中间通过RS485收发器转换电平,P2.12是作为RS485收发器的Enable引脚)。电池收到信号后,通过UART3返回信号到单片机,再经过UART0返回到电脑显示在串口助手上。

现在发送和接受都有问题,但是我真的太新手,完全不知道该从哪里下手解决问题。
我觉得UART的初始化和timer的初始化应该是没有问题的,主要问题应该在UART0_IRQHander和UART3_IRQHander里,希望各位前辈能提提意见,不胜感谢!


#ifdef __USE_CMSIS
#include "LPC17xx.h"
#endif

#include "stdutils.h"

#define SBIT_WordLenght    0x00u
#define SBIT_DLAB          0x07u
#define SBIT_FIFO          0x00u
#define SBIT_RxFIFO        0x01u
#define SBIT_TxFIFO        0x02u

#define SBIT_RDR           0x00u
#define SBIT_THRE          0x05u

uint8_t Uart0RecvBuf;
uint8_t Uart3RecvBuf;

#define SBIT_TIMER0  1
#define SBIT_TIMER1  2

#define SBIT_MR0I    0
#define SBIT_MR0R    1

#define SBIT_CNTEN   0

#define PCLK_TIMER0  2
#define PCLK_TIMER1  4
#define MiliToMicroSec(x)  (x)  // ms is multiplied by 1000 to get us

extern unsigned int SystemCoreClock;
unsigned int getPrescalarForUs0(uint8_t timerPclkBit);

// Function to initialize the UART0 and UART3 at specific baud rate
void uart_init(uint32_t baudrate)
{
    uint32_t var_UartPclk_u32_0,var_Pclk_u32_0,var_RegValue_u32_0;
    uint32_t var_UartPclk_u32_3,var_Pclk_u32_3,var_RegValue_u32_3;

    LPC_SC->PCONP |= (1<<3)|(1<<25);     //enable UART0,UART3 power/clock control bit

    LPC_PINCON->PINSEL0 &= ~0x000000FF;
    LPC_PINCON->PINSEL0 |= 0x0000005A;            // Enable TxD3 P0.0 and P0.1,TxD0 P0.2 and p0.3

    LPC_UART0->FCR = (1<<SBIT_FIFO) | (1<<SBIT_RxFIFO) | (1<<SBIT_TxFIFO); // Enable FIFO and reset Rx/Tx FIFO buffers
    LPC_UART0->LCR = (0x03<<SBIT_WordLenght) | (1<<SBIT_DLAB);             // 8bit data, 1Stop bit, No parity
    LPC_UART3->FCR = (1<<SBIT_FIFO) | (1<<SBIT_RxFIFO) | (1<<SBIT_TxFIFO); // Enable FIFO and reset Rx/Tx FIFO buffers
    LPC_UART3->LCR = (0x03<<SBIT_WordLenght) | (1<<SBIT_DLAB);             // 8bit data, 1Stop bit, No parity

    var_UartPclk_u32_0 = (LPC_SC->PCLKSEL0 >> 6) & 0x03;
    var_UartPclk_u32_3 = (LPC_SC->PCLKSEL1 >> 18) & 0x03;

    switch( var_UartPclk_u32_0 )
    {
    case 0x00:
        var_Pclk_u32_0 = SystemCoreClock/4;
        break;
    case 0x01:
        var_Pclk_u32_0 = SystemCoreClock;
        break;
    case 0x02:
        var_Pclk_u32_0 = SystemCoreClock/2;
        break;
    case 0x03:
        var_Pclk_u32_0 = SystemCoreClock/8;
        break;
    }
    var_RegValue_u32_0 = ( var_Pclk_u32_0 / (16 * baudrate ));
    LPC_UART0->DLL =  var_RegValue_u32_0 & 0xFF;
    LPC_UART0->DLM = (var_RegValue_u32_0 >> 0x08) & 0xFF;

    switch( var_UartPclk_u32_3 )
    {
    case 0x00:
        var_Pclk_u32_3 = SystemCoreClock/4;
        break;
    case 0x01:
        var_Pclk_u32_3 = SystemCoreClock;
        break;
    case 0x02:
        var_Pclk_u32_3 = SystemCoreClock/2;
        break;
    case 0x03:
        var_Pclk_u32_3 = SystemCoreClock/8;
        break;
    }
    var_RegValue_u32_3 = ( var_Pclk_u32_3 / (16 * baudrate ));
    LPC_UART3->DLL =  var_RegValue_u32_3 & 0xFF;
    LPC_UART3->DLM = (var_RegValue_u32_3 >> 0x08) & 0xFF;

    util_BitClear(LPC_UART0->LCR,(SBIT_DLAB));  // Clear DLAB after setting DLL,DLM
    util_BitClear(LPC_UART3->LCR,(SBIT_DLAB));

    LPC_UART0->IER = 0x01;        //enable RDA interrupt
    LPC_UART3->IER = 0x01;

    NVIC_EnableIRQ(UART0_IRQn);
    NVIC_EnableIRQ(UART3_IRQn);
}

unsigned int getPrescalarForUs0(uint8_t timerPclkBit)
{
    unsigned int pclk,prescalarForUs;
    pclk = (LPC_SC->PCLKSEL0 >> timerPclkBit) & 0x03;  /* get the pclk info for required timer */

    switch ( pclk )                                    /* Decode the bits to determine the pclk*/
    {
    case 0x00:
        pclk = SystemCoreClock/4;
        break;

    case 0x01:
        pclk = SystemCoreClock;
        break;

    case 0x02:
        pclk = SystemCoreClock/2;
        break;

    case 0x03:
        pclk = SystemCoreClock/8;
        break;

    default:
        pclk = SystemCoreClock/4;
        break;
    }

    prescalarForUs =pclk/1000000;                      /* Prescalar for 1us (1000000Counts/sec) */

    return prescalarForUs;
}

//Initialize P2.12 as RS485-Transceiver Enable
void Pin_Init(void)
{
        LPC_PINCON->PINSEL4 &= (~(1<<24)&(1<<25));  //set p2.12 as GPIO
        LPC_GPIO2->FIODIR |= (1<<12);          //set P2.12 as output
}

//Data send from PC to Battery
//UART0 Receive (from PC)
uint8_t uart0_Receive()
{
        while(util_IsBitCleared(LPC_UART0->LSR,SBIT_RDR));  // Wait till the data is received
        return(LPC_UART0->RBR);                             // Read received data
}
void uart3_Transmit(uint8_t ch)
{
    while(util_IsBitCleared(LPC_UART3->LSR,SBIT_THRE)); // Wait for Previous transmission
    LPC_UART3->THR=ch;                                  // Load the data to be transmitted
}

//Data receive from Battery to PC
//UART3 Receive (from Battery)
uint8_t uart3_Receive()
{
        while(util_IsBitCleared(LPC_UART3->LSR,SBIT_RDR));  // Wait till the data is received
        return(LPC_UART3->RBR);                             // Read received data
}
void uart0_Transmit(uint8_t ch)
{
    while(util_IsBitCleared(LPC_UART0->LSR,SBIT_THRE)); // Wait for Previous transmission
    LPC_UART0->THR=ch;                                  // Load the data to be transmitted
}

//PC interface receive:
void UART0_IRQHandler(void)
{
        NVIC_EnableIRQ(TIMER0_IRQn);                          // Enable Timer0
        //NVIC_DisableIRQ(UART0_IRQn);                          // Disable UART0_Interrupt

        if(((LPC_UART0->IIR>>1) & 0x07) == 0x02)
        {
                LPC_UART0->IER = 0x00;
                LPC_GPIO2->FIOSET |= (1<<12);                         // Set P2.12 to high
                Uart0RecvBuf = uart0_Receive();                       // UART0 Receive
                LPC_UART0->IER = 0x01;                                // Enable RDA Interrupt
                uart3_Transmit(Uart0RecvBuf);                         // UART3 Transmit
        }
}

void UART3_IRQHandler(void)
{
        NVIC_EnableIRQ(TIMER1_IRQn);                          // Enable Timer1
        //NVIC_DisableIRQ(UART3_IRQn);                          // Disable UART3_Interrupt

        if(((LPC_UART3->IIR>>1) & 0x03) == 0x02)
        {
                LPC_UART3->IER = 0x00;
                LPC_GPIO2->FIOCLR |= (1<<12);                         // Set P2.12 to low
                Uart3RecvBuf = uart3_Receive();                       // UART0 Receive
                LPC_UART3->IER = 0x01;                                // Enable RDA Interrupt
                uart0_Transmit(Uart3RecvBuf);                         // UART0 Transmit
        }
}


//Initialize timer
void Timer_Init()
{
        LPC_SC->PCONP |= (1<<SBIT_TIMER0)|(1<<SBIT_TIMER1) ; // Power ON Timer0,1

    LPC_TIM0->MCR  = (1<<SBIT_MR0I) | (1<<SBIT_MR0R);     // Clear TC on MR0 match and Generate Interrupt
    LPC_TIM0->PR   = getPrescalarForUs0(PCLK_TIMER0);      // Prescalar for 1us */
    LPC_TIM0->MR0  = MiliToMicroSec(100);                 // Load timer value to generate 100us delay
    LPC_TIM0->TCR  = (1 <<SBIT_CNTEN);                    // Start timer by setting the Counter Enable

    LPC_TIM1->MCR  = (1<<SBIT_MR0I) | (1<<SBIT_MR0R);     /* Clear TC on MR0 match and Generate Interrupt*/
    LPC_TIM1->PR   = getPrescalarForUs0(PCLK_TIMER1);      /* Prescalar for 1us */
    LPC_TIM1->MR0  = MiliToMicroSec(100);                 /* Load timer value to generate 500ms delay*/
    LPC_TIM1->TCR  = (1 <<SBIT_CNTEN);                    /* Start timer by setting the Counter Enable*/
}

void TIMER0_IRQHandler(void)
{
    unsigned int isrMask;
    NVIC_DisableIRQ(TIMER0_IRQn);    // Disable Timer0

    isrMask = LPC_TIM0->IR;
    LPC_TIM0->IR = isrMask;         // Clear the Interrupt Bit

    LPC_GPIO2->FIOCLR |= (1<<12);    // Reset P2.12
}
void TIMER1_IRQHandler(void)
{
    unsigned int isrMask;
    NVIC_DisableIRQ(TIMER1_IRQn);    // Disable Timer1

    isrMask = LPC_TIM1->IR;
    LPC_TIM1->IR = isrMask;         // Clear the Interrupt Bit

    LPC_GPIO2->FIOSET |= (1<<12);    // Reset P2.12
}

int main()
{
    SystemInit();
    Pin_Init();
    uart_init(115200);  // Initialize the UART0 and UART3
    Timer_Init();

    while(1)
    {

    }
}


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
2条回答
人中狼
1楼-- · 2019-07-15 20:00
建议分开调试,先把UART0和UART3的接收发送功能都调通,正确了,再联调。
如果没由特殊要求,最好是UART0或UART3接收到完整的一包数据后,再转发
cherrynana
2楼-- · 2019-07-15 23:13
人中狼 发表于 2018-5-3 03:18
建议分开调试,先把UART0和UART3的接收发送功能都调通,正确了,再联调。
如果没由特殊要求,最好是UART0或UART3接收到完整的一包数据后,再转发

谢谢你的建议,我检查了一下,UART3确实有问题,现在UART3已经弄好了。但是想请问怎么能实现收到完整的数据包后再转发呢? 请问你有没有这方面的程序能让我参考一下,谢谢了