📄 uart0.c
字号:
#define _UART0_C_
#include "Queue.h"
#include "UART0.h"
static volatile uint8 sendQSemPendFlag = 0;
static volatile uint8 ReceiveQSemPendFlag = 0;
static QUEUE UART0SendQ;
static QUEUE UART0ReceiveQ;
static QUEUE_TYPE UART0SendQBuf[UART0_SENDQ_LENGTH];
static QUEUE_TYPE UART0ReceiveQBuf[UART0_Receive_LENGTH];
uint8 UART0_Init(uint32 baud, uint8 dataBits, uint8 parityCheck, uint8 stopBits)
{
uint8 err;
UART0_SemCreate(UART0SendSem, 1, &err);
if(err == 0)
{
UART0_SemCreate(UART0ReceiveSem, 1, &err);
if(err == 0)
{
UART0_SemCreate(UART0SendQSem, 0, &err);
if(err == 0)
{
UART0_SemCreate(UART0ReceiveQSem, 0, &err);
if(err == 0 &&
QueueInit(&UART0SendQ, UART0SendQBuf, UART0_SENDQ_LENGTH) == QRET_OK &&
QueueInit(&UART0ReceiveQ, UART0ReceiveQBuf, UART0_Receive_LENGTH) == QRET_OK)
{
PINSEL0 = (PINSEL0 & 0xfffffff0) | 0x05; /* 选择管脚为UART0 */
UART0_Setup(baud, dataBits, parityCheck, stopBits);
U0FCR = 0x07;
U0IER = 0x01;
return 1;
}
}
}
}
return 0;
}
void UART0_Setup(uint32 baud, uint8 dataBits, uint8 parityCheck, uint8 stopBits)
{
uint16 fdiv;
uint8 value = 0;
fdiv = (uint16)(Fpclk/16/baud);
U0LCR |= 0x80;
U0DLM = (uint8)(fdiv >> 8);
U0DLL = (uint8)fdiv;
U0LCR &= ~0x80;
switch(dataBits)
{
case 5:
value |= 0x00;
break;
case 6:
value |= 0x01;
break;
case 7:
value |= 0x02;
break;
case 8:
default:
value |= 0x03;
break;
}
if(stopBits == 2)
{
value |= (0x01 << 2);
}
switch(parityCheck)
{
case NO_PARITY:
value |= (0x00 << 3);
break;
case ODD:
value |= (0x04 << 3);
break;
case EVEN:
value |= (0x05 << 3);
break;
case FORCE_0:
value |= (0x07 << 3);
break;
case FORCE_1:
value |= (0x06 << 3);
break;
default:
value |= (0x00 << 3);
break;
}
U0LCR = (U0LCR & 0xc0) | value;
}
static void UART0_PutChar(uint8 data)
{
while(QueueIn(&UART0SendQ, data) == QRET_FULL)
{
sendQSemPendFlag = 1;
UART0_SemPend(UART0SendQSem);
}
U0IER |= 0x02;
}
static uint8 UART0_GetChar(void)
{
uint8 data;
while(QueueOut(&UART0ReceiveQ, &data) == QRET_EMPTY)
{
ReceiveQSemPendFlag = 1;
UART0_SemPend(UART0ReceiveQSem);
}
return data;
}
void UART0_Send(uint8 *buf, uint32 nBytes)
{
UART0_SemPend(UART0SendSem);
while((nBytes--) > 0)
{
UART0_PutChar(*(buf++));
}
UART0_SemPost(UART0SendSem);
}
void UART0_Receive(uint8 *buf, uint32 nBytes)
{
UART0_SemPend(UART0ReceiveSem);
while((nBytes--) > 0)
{
*(buf++) = UART0_GetChar();
}
UART0_SemPost(UART0ReceiveSem);
}
void UART0_IntService(void)
{
uint8 IIR, data, i;
UART0_EnterCritical();
while(((IIR = U0IIR) & 0x01) == 0)
{
switch(IIR & 0x0e)
{
case 0x02: /*-->THRE中断*/
for(i = 0; i < 16; i++)
{
if(QueueOut(&UART0SendQ, &data) == QRET_OK)
{
U0THR = data;
}
else
{
U0IER &= ~0x02; /*队列空则停止发送,禁止THRE中断*/
break;
}
}
if(sendQSemPendFlag == 1)
{
sendQSemPendFlag = 0;
UART0_SemPost(UART0SendQSem); /*通知发送任务队列有位置放数据*/
}
break;
case 0x04: /*-->接收数据可用(RDA)*/
case 0x0c: /*-->字符超时指示(CTI)*/
data = U0RBR;
while(QueueIn(&UART0ReceiveQ, data) == QRET_FULL)
{
QueueOut(&UART0ReceiveQ, &i); /*队列满则丢弃最旧的数据*/
}
if(ReceiveQSemPendFlag == 1)
{
ReceiveQSemPendFlag = 0;
UART0_SemPost(UART0ReceiveQSem);
}
break;
case 0x06: /* -->接收线状态(RLS)*/
data = U0LSR;
break;
default:
break;
}
}
VICVectAddr = 0;
UART0_ExitCritical();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -