真的是超级新手,完全小白,希望能有大师指点一下,非常感谢!
我的任务是用串口助手从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)
{
}
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
如果没由特殊要求,最好是UART0或UART3接收到完整的一包数据后,再转发
谢谢你的建议,我检查了一下,UART3确实有问题,现在UART3已经弄好了。但是想请问怎么能实现收到完整的数据包后再转发呢? 请问你有没有这方面的程序能让我参考一下,谢谢了
一周热门 更多>