📄 serial.c
字号:
#include "config.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
INT8U rcv_buf0[128]; // UART0数据接收缓冲区
INT16U rcv_buf0Len; // 要用链表来代替
INT8U rcv_buf1[128]; // UART1数据接收缓冲区
INT16U rcv_buf1Len; // 要用链表来代替
/****************************************************************************
* 名称:IRQ_UART0()
* 功能:串口UART0接收中断。
* 入口参数:无
* 出口参数:无
****************************************************************************/
void __irq UART0_IRQ(void)
{
if(0x04==(U0IIR&0x0F));
rcv_buf0[rcv_buf0Len] = U0RBR; //读取FIFO的数据,并清除中断标志
if(rcv_buf0Len < 127)
{
rcv_buf0Len++;
}
VICVectAddr = 0x00; //中断处理结束
}
/****************************************************************************
* 名称:UART0_SendByte()
* 功能:向串口UART0发送字节数据。
* 入口参数:data 要发送的数据
* 出口参数:无
****************************************************************************/
void UART0_SendByte(INT8U data)
{
U0THR = data; // 发送数据
while((U0LSR&0x20)==0);
}
/****************************************************************************
* 名称:UART0_Ini()
* 功能:初始化串口0。设置其工作模式及波特率。
* 入口参数:baud 波特率
* set 模式设置(UARTMODE数据结构)
* 出口参数:返回值为1时表示初始化成功,为0表示参数出错
****************************************************************************/
BOOLEAN UART0_Ini(INT32U baud, UARTMODE set)
{
INT32U bak;
PINSEL0 &= 0xFFFFFFF0;
PINSEL0 |= 0x00000005; // 设置I/O连接到UART0
/* 参数过滤 */
if((0==baud) || (baud>115200)) return FALSE;
if((set.datab<5) || (set.datab>8)) return FALSE;
if((0==set.stopb) || (set.stopb>2)) return FALSE;
if(set.parity>4 ) return FALSE;
/* 设置串口波特率 */
U0LCR = 0x80; // DLAB位置1
bak = (Fpclk>>4)/baud;
U0DLM = bak>>8;
U0DLL = bak&0xff;
/* 设置串口模式 */
bak = set.datab-5; // 设置字长度
if(2==set.stopb) bak |= 0x04; // 判断是否为2位停止位
if(0!=set.parity)
{
set.parity = set.parity-1;
bak |= 0x08;
}
bak |= set.parity<<4; // 设置奇偶校验
U0LCR = bak;
U0LCR &= 0X7F;
/////
rcv_buf0Len = 0;
U0FCR = 0x01; // 使能FIFO,并设置触发点为1字符
U0IER = 0x01; // 允许RBR中断,即接收中断
/* 设置中断允许 */
VICIntSelect = 0x00000000; // 设置所有通道为IRQ中断
VICVectCntl0 = 0x26; // UART0中断通道分配到IRQ slot 0,即优先级最高
VICVectAddr0 = (int)UART0_IRQ; // 设置UART0向量地址
VICIntEnable = 0x00000040;
/////
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void __irq UART1_IRQ(void)
{
if(0x04==(U1IIR&0x0F));
rcv_buf1[rcv_buf1Len] = U1RBR; //读取FIFO的数据,并清除中断标志
if(rcv_buf1Len < 127)
{
rcv_buf1Len++;
}
VICVectAddr = 0x00; //中断处理结束
}
void UART1_SendByte(INT8U data)
{
U1THR = data; // 发送数据
while((U1LSR&0x20)==0);
}
BOOLEAN UART1_Ini(INT32U baud, UARTMODE set)
{
INT32U bak;
PINSEL0 &= 0x0000FFFF;
PINSEL0 |= 0x55550000; // 设置I/O连接到UART1
/* 参数过滤 */
if((0==baud) || (baud>115200)) return FALSE;
if((set.datab<5) || (set.datab>8)) return FALSE;
if((0==set.stopb) || (set.stopb>2)) return FALSE;
if(set.parity>4 ) return FALSE;
/* 设置串口波特率 */
U1LCR = 0x80; // DLAB位置1
bak = (Fpclk>>4)/baud;
U1DLM = bak>>8;
U1DLL = bak&0xff;
/* 设置串口模式 */
bak = set.datab-5; // 设置字长度
if(2==set.stopb) bak |= 0x04; // 判断是否为2位停止位
if(0!=set.parity)
{
set.parity = set.parity-1;
bak |= 0x08;
}
bak |= set.parity<<4; // 设置奇偶校验
U1LCR = bak;
/////
rcv_buf1Len = 0;
U1FCR = 0x01; // 使能FIFO,并设置触发点为8字节
U1IER = 0x01; // 允许RBR中断,即接收中断
/* 设置中断允许 */
VICIntSelect = 0x00000000; // 设置所有通道为IRQ中断
VICVectCntl1 = 0x27; // UART1中断通道分配到IRQ slot 1,即优先级最高
VICVectAddr1 = (uint32)UART1_IRQ; // 设置UART1向量地址
VICIntEnable |= 0x00000080; // 使能UART1中断
/////
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
BOOLEAN SerPort_Open(INT8U byComPort, INT32U lBaud, UARTMODE modSet)
{
switch(byComPort)
{
case COM1:
UART0_Ini(lBaud, modSet);
break;
case COM2:
UART1_Ini(lBaud, modSet);
break;
}
return TRUE;
}
BOOLEAN SerPort_Close(INT8U byComPort)
{
return TRUE;
}
BOOLEAN SerPort_IsOk(INT8U byComPort)
{
return TRUE;
}
BOOLEAN SerPort_Avail(INT8U byComPort)
{
switch(byComPort)
{
case COM1:
return (rcv_buf0Len > 0);
break;
case COM2:
return (rcv_buf1Len > 0);
break;
}
return FALSE;
}
void SerPort_Clear(INT8U byComPort)
{
switch(byComPort)
{
case COM1:
rcv_buf0Len = 0;
break;
case COM2:
rcv_buf1Len = 0;
break;
}
}
INT16S SerPort_SendBuf(INT8U byComPort, INT8U *pcBuf, INT16U nSize)
{
INT16U wLoop;
switch(byComPort)
{
case COM1:
for(wLoop=0; wLoop<nSize; wLoop++)
{
UART0_SendByte(*(pcBuf+wLoop));
}
break;
case COM2:
for(wLoop=0; wLoop<nSize; wLoop++)
{
UART1_SendByte(*(pcBuf+wLoop));
}
break;
}
return ((INT16S)nSize);
}
INT16S SerPort_SendByte(INT8U byComPort, INT8U c)
{
switch(byComPort)
{
case COM1:
UART0_SendByte(c);
break;
case COM2:
UART1_SendByte(c);
break;
}
return 1;
}
INT16S SerPort_RecvBuf(INT8U byComPort, INT8U *pcBuf, INT16U nSize)
{
INT16U wRecLen;
switch(byComPort)
{
case COM1:
if(rcv_buf0Len < 1) return 0;
if(nSize > rcv_buf0Len)
{
wRecLen = rcv_buf0Len;
}
else
{
wRecLen = nSize;
}
memcpy(pcBuf, rcv_buf0, wRecLen);
memmove(rcv_buf0, rcv_buf0+wRecLen, 128-wRecLen);
rcv_buf0Len -= wRecLen;
break;
case COM2:
if(rcv_buf1Len < 1) return 0;
if(nSize > rcv_buf1Len)
{
wRecLen = rcv_buf1Len;
}
else
{
wRecLen = nSize;
}
memcpy(pcBuf, rcv_buf1, wRecLen);
memmove(rcv_buf1, rcv_buf1+wRecLen, 128-wRecLen);
rcv_buf1Len -= wRecLen;
break;
}
return wRecLen;
}
INT16S SerPort_RecvByte(INT8U byComPort, INT8U *pc)
{
switch(byComPort)
{
case COM1:
if(rcv_buf0Len < 1) return 0;
*pc = *rcv_buf0;
memmove(rcv_buf0, rcv_buf0+1, 128-1);
rcv_buf0Len--;
break;
case COM2:
if(rcv_buf1Len < 1) return 0;
*pc = *rcv_buf1;
memmove(rcv_buf1, rcv_buf1+1, 128-1);
rcv_buf1Len--;
break;
}
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -