📄 uart1.c
字号:
/* ----------------------------------------------------
模块名: Uart1.c:
描 述: 串口1接口函数
--------------------------------------------------------*/
#include "config.h"
#define USE_SEMAPHORE_RX 1 /* 打开后不稳定问题解决 */
static OS_EVENT *Uart1TxSem;
#if USE_SEMAPHORE_RX
static OS_EVENT *Uart1RxSem;
#else
volatile uint8 uart1_inbufsign; /* 接收缓冲区非空标志-有=1 */
#endif
//volatile char RxBuf12[uart1_LenRxBuf]; /* just test */
volatile char RxBuf1[uart1_LenRxBuf];
volatile int rxHead1; /* 收发缓冲区读写指针 */
volatile int rxTail1;
volatile int nUart1RxLen;
volatile char TxBuf1[uart1_LenTxBuf]; /* 收发缓冲区实体 */
volatile int txHead1; /* 收发缓冲区读写指针 */
volatile int txTail1;
volatile int nUart1TxLen;
void UART1_data_transfer(void*);
/*------------------------------------------------------------
名 称:UART1_Ini()
功 能:初始化串口0。设置其工作模式及波特率。
入口参数:set 模式设置(UARTMODE数据结构)
出口参数:返回值为1时表示初化成功,为0表除参数出错
------------------------------------------------------------*/
uint8 UART1_Ini(UARTMODE *set)
{
uint32 bak;
VICIntEnClr = 1 << 7; //禁止uart1中断
/* 参数过滤 */
if((0 == set->baudrate)||(set->baudrate > 115200) ) return(0);
if((set->datab < 5) ||(set->datab > 8) ) return(0);
if((0 == set->stopb)||(set->stopb > 2) ) return(0);
if( set->parity > 2 ) return(0);
/* 设置I/O连接到UART1 */
PINSEL0 = (PINSEL0 & 0xfff0ffff) | 0x00050000;
//PINSEL0 = (PINSEL0 & 0x0000ffff) | 0x55550000;
/* 设置串口波特率 */
U1LCR = 0x80; // DLAB位置1
bak = (FPCLK>>4)/set->baudrate;
U1DLM = bak>>8;
U1DLL = bak&0xff;
/* 设置串口模式 */
bak = set->datab - 5; // 设置字长度
if(2 == set->stopb) bak |= 0x04; // 判断是否为2位停止位
if(0 != set->parity)
{
if(set->parity == 1)
{
bak |= 0x08; // 设置为奇校验
}
else
{
bak |= 0x18; // 设置为偶校验
}
}
U1LCR = bak;
//U1FCR = 0x01; // 每接收到一个字符就产生一次中断
U1FCR = 0xc1;
U1IER = 0x03; // 允许RBR和THRE中断,即接收中断
/* 初始化串口所用到的全局变量 */
nUart1RxLen = 0;
rxHead1 = 0;
rxTail1 = 0;
nUart1TxLen = 0;
txHead1 = 0;
txTail1 = 0;
//memset(RxBuf12, 0, sizeof(RxBuf12));
Uart1TxSem = OSSemCreate(1); // 信号量用于发送缓冲区满后等待发送
#if USE_SEMAPHORE_RX
Uart1RxSem = OSSemCreate(0); // 信号量用于等待串口接收字符中断
#else
uart1_inbufsign = 0;
#endif
//VICIntEnable = 1 << 7; // 允许uart0中断
return 0;
}
//
// 向硬件发送一个字节
//
void uart1PhySend(void)
{
if( nUart1TxLen )
{
if( txHead1 == uart1_LenTxBuf)
{
txHead1 = 0;
}
OS_ENTER_CRITICAL();
if( LSR_TEMT & U1LSR )
{
U1THR = TxBuf1[txHead1++] ;
nUart1TxLen--;
}
OS_EXIT_CRITICAL();
}
}
//
// 从硬件获取数据
//
void uart1PhyRecv(void)
{
char c;
//int i;
//for( i = 0; i < 16; i++ )
while(1)
{
if( U1LSR & LSR_RDR ) // 有数据
{
c = U1RBR;
OS_ENTER_CRITICAL();
if( nUart1RxLen < uart1_LenRxBuf )
{
// if reach the end, turn round
if( rxTail1 == uart1_LenRxBuf)
{
rxTail1 = 0;
}
RxBuf1[rxTail1++] = c;
nUart1RxLen++;
}
OS_EXIT_CRITICAL();
}
else break;
}
}
/*------------------------------------------------------------
名 称:UART1_Exception()
功 能:串口UART1接收中断。
入口参数:无
出口参数:无
------------------------------------------------------------*/
void Uart1_Exception(void)
{
uint8 Uart1Int;
OS_ENTER_CRITICAL();
if(((Uart1Int = U1IIR)&0x01) == 0)
{
switch(Uart1Int & 0x0e)
{
case 0x02: /* 发送中断处理 */
OSSemPost(Uart1TxSem);
//uart1PhySend();
break;
case 0x04: /* 接收中断处理 */
{
uart1PhyRecv();
//if(nUart1RxLen!=1)
// OSUntimeout(UART1_data_transfer, NULL);
//OSTimeout(UART1_data_transfer, NULL, 1);
}
break;
case 0x06: /* 串口接收线路状态错误中断 */
{
Uart1Int = U1LSR; /* 一定要进行该操作,用以清除中断标志,否则串口会死掉! */
}
break;
case 0x0c: /* 串口字符超时指示(CTI)中断 */
{
uart1PhyRecv();
//OSUntimeout(UART1_data_transfer, NULL);
//UART1_data_transfer((void*)0);
//Uart1Int = U1RBR; /* 一定要进行该操作,用以清除中断标志,否则串口会死掉! */
}
break;
default:
Uart1Int = U1LSR;
break;
}
}
OS_EXIT_CRITICAL();
VICVectAddr = 0x00; // 中断处理结束
}
/*------------------------------------------------------------
** 函数名称: UART1_PutChar
** 功能描述: 从UART1往外发送一字节
** 输 入: 待发送数据
** 输 出: 无
** 返 回: 待发送数据
------------------------------------------------------------*/
char UART1_PutChar(char c)
{
UART1_PutData( &c, 1 );
return c;
}
/*------------------------------------------------------------
** 函数名称: UART1_PutChar
** 功能描述: 从UART1往外发送一指定长度字符串
** 输 入: 待发送数据
** 输 出: 无
** 返 回: 无
------------------------------------------------------------*/
int UART1_PutData(char *str, int len)
{
int i;
int nTempLen;
//int nNeedToSend = FALSE;
//uint8 err;
if( nUart1TxLen >= uart1_LenTxBuf )
return 0;
OS_ENTER_CRITICAL();
nTempLen = min(len, uart1_LenTxBuf - nUart1TxLen );
for( i = 0; i < nTempLen; i++ )
{
if( txTail1 == uart1_LenTxBuf )
txTail1 = 0;
TxBuf1[txTail1++] = str[i];
nUart1TxLen ++;
}
OS_EXIT_CRITICAL();
return len;
}
//
// read data direct
//
int ReadDataNowait(char *buffer,int limit)
{
int i;
int templen;
templen = min(limit, nUart1RxLen);
for( i = 0; i < templen; i++ )
{
if( rxHead1 == uart1_LenRxBuf )
rxHead1 = 0;
buffer[i] = RxBuf1[rxHead1++];
}
OS_ENTER_CRITICAL();
nUart1RxLen -= templen;
OS_EXIT_CRITICAL();
return templen;
}
//
// 读取串口数据
// buf: 缓冲地址
// len: 缓冲长度
// timeout: 超时时间
// 返回: 数据长度
//
int ReadData(char *buffer,int limit,int timeout)
{
//uint8 err;
//OSSemPend(Uart1RxSem, timeout, &err);
//if(OS_NO_ERR != err)
//{
// return 0;
//}
return ReadDataNowait(buffer, limit);
}
//
// check if there any data to read
//
int ReadDataWaiting(void)
{
return nUart1RxLen;
}
//
// notify the application to read data
//
void UART1_data_transfer(void* p)
{
OSSemPost(Uart1RxSem);
}
//
// 发送数据
// buffer: 数据缓冲地址
// size: 缓冲大小
// 返回: 已发送数据长度
//
int SendData(char* buffer, int size)
{
UART1_PutData( buffer, size );
return size;
}
//
// 清空串口缓冲
//
void ClearComm(void)
{
OS_ENTER_CRITICAL();
nUart1RxLen = 0;
rxHead1 = 0;
rxTail1 = 0;
nUart1TxLen = 0;
txHead1 = 0;
txTail1 = 0;
OS_EXIT_CRITICAL();
}
unsigned char IsOpened(void)
{
return 0;
}
//
// set the DTR control line
//
void uart1_set_dtr( int value )
{
/*IODIR = IODIR | UART1_DTR;
if( value )
IOSET = IOSET | UART1_DTR; // 置1 无效
else
IOCLR = IOCLR | UART1_DTR; // 置0, 有效
*/
}
int uart1_get_dcd(void)
{
//P1.22
if ((IO1PIN & 0x00400000) != 0)
{
return 1;
}
else
{
return 0;
}
}
int uart1_get_cts(void)
{
//P0.11
if ((IO0PIN & 0x00000800) != 0)
{
return 1;
}
else
{
return 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -