📄 tcuart.c
字号:
/** @file tcuart.c
* @brief S3C44B0X UART驱动层程序
* @Notice 采用中斷FIFO方式
* @Author Mars.zhu 2008-02-22 16:39
* @欢迎测试使用, 如有问题请发邮件至 Mars.zhu@hotmail.com , 谢谢!
*/
#include "option.h"
#include "tcuart.h"
#include "Sermem.h"
/**********************************************************************************************************
* 中断回调函数, 全部定义为内部函数
**********************************************************************************************************/
/** @func UART0_RxHandle
* @brief 串口接收中断(FIFO模式)
*/
static void __irq
UART0_RxHandle(void)
{
uint8 dat;
rI_ISPC |= BIT_URXD0; // 清除中断标志
while ((rUFSTAT0&0x0F) > 0) {
dat = rURXH0; // 读数
UartPutc(0, dat);
}
}
/** @func UART0_TxHandle
* @brief 串口接收中断(FIFO模式)
*/
static void __irq
UART0_TxHandle(void)
{
uint8 dat;
while (!(rUFSTAT0 & 0x0200)) { // 直到发送缓冲区满
if (UartGetc(0, &dat) == 0) rUTXH0 = dat;
else {
rUCON0 &= ~__BIT(9); // 发生完毕
break;
}
}
rI_ISPC |= BIT_UTXD0;
}
/** @func UART1_RxHandle
* @brief 串口1接收中断(FIFO模式)
*/
static void __irq
UART1_RxHandle(void)
{
uint8 dat;
rI_ISPC |= BIT_URXD1; // 清除中断标志
while ((rUFSTAT1&0x0F) > 0) {
dat = rURXH1; // 读数
UartPutc(1, dat);
}
}
/** @func UART1_TxHandle
* @brief 串口1接收中断(FIFO模式)
*/
static void __irq
UART1_TxHandle(void)
{
uint8 dat;
while (!(rUFSTAT1 & 0x0200)) { // 直到发送缓冲区满
if (UartGetc(1, &dat) == 0) rUTXH1 = dat;
else {
rUCON1 &= ~__BIT(9);
break;
}
}
rI_ISPC |= BIT_UTXD1;
}
/** @func UARTn_RxErrHandle
* @brief 串口接收错误中断(FIFO模式)
*/
static void __irq
UARTn_RxErrHandle(void)
{
uint8 dat;
rI_ISPC |= BIT_UERR01;
while ((rUFSTAT0&0x0F) > 0) {
dat = rURXH0;
}
while ((rUFSTAT1&0x0F) > 0) {
dat = rURXH1;
}
}
/**********************************************************************************************************
* 驱动接口函数
**********************************************************************************************************/
/** @func UARTn_Init()
* @brief 實現串口初始化
* @param fd 串口号
* termios 串口數據結構
* @Retval D_OK 成功
* D_ERR 錯誤
*/
D_Result
UARTn_Init(uint8 fd, S_Termios* tios_p)
{
uint8 bak;
uint16 baud;
switch (tios_p->c_cflag & CS_MASK) { // 设置字长
case CS5: bak = 0; break;
case CS6: bak = 1; break;
case CS7: bak = 2; break;
case CS8: bak = 3; break;
default: return D_ERR;
}
if (tios_p->c_cflag & CSTOPB) // 判断是否为2位停止位
bak |= __BIT(2);
if (tios_p->c_cflag & PARENB) { // 使能校验位
bak |= __BIT(5);
if (tios_p->c_cflag&PARODD == 0) // 偶校验
bak |= __BIT(3);
if (tios_p->c_cflag & PARFOR) // 强制
bak |= __BIT(4);
}
baud = ((uint32)(MCLK/16.0/tios_p->c_baud + 0.5) - 1);
switch (fd) {
case 0: { // Uart 0初始化
/** 中断处理程序*/
pISR_UTXD0 = (unsigned)UART0_TxHandle;
pISR_URXD0 = (unsigned)UART0_RxHandle;
pISR_UERR01 = (unsigned)UARTn_RxErrHandle;
/*
* 串口FIFO设置
* 44B0的串口FIFO收发触发点可以分别设置, 在本例中设为收发相同, 并在复位后清空FIFO
*/
if (tios_p->c_FIFO) { // FIFO 使能
rUFCON0 = (2<<6) | (1<<4) | (3<<1) | 1; // 收发均为8Byte触发
} else {
rUFCON0 = 0x00;
}
rUMCON0 = 0x00;
/** 设置线控制寄存器*/
rULCON0 = bak;
/*
* 串口控制寄存器设置
* 发送中断(9): Level 接收中断(8): Pulse 接收错误中断使能(6)
* 发送模式: 中断请求 接收模式: 中断请求
*/
rUCON0 = 0xC5; // Bit8写1会增加中断开销
rUBRDIV0= baud;
rINTMSK&= ~(BIT_GLOBAL|BIT_UTXD0|BIT_URXD0|BIT_UERR01);
break;
}
case 1: { // Uart 1初始化
/** 中断处理程序*/
pISR_UTXD1 = (unsigned)UART1_TxHandle;
pISR_URXD1 = (unsigned)UART1_RxHandle;
pISR_UERR01 = (unsigned)UARTn_RxErrHandle;
/*
* 串口FIFO设置
* 44B0的串口FIFO收发触发点可以分别设置, 在本例中设为收发相同, 并在复位后清空FIFO
*/
if (tios_p->c_FIFO) { // FIFO 使能
rUFCON1 = (2<<6) | (1<<4) | (3<<1) | 1; // 收发均为8Byte触发
} else {
rUFCON1 = 0x00;
}
rUMCON1 = 0x00;
/** 设置线控制寄存器*/
rULCON1 = bak;
/*
* 串口控制寄存器设置
* 发送中断(9): Level 接收中断(8): Pulse 接收错误中断使能(6)
* 发送模式: 中断请求 接收模式: 中断请求
*/
rUCON1 = 0x45;
rUBRDIV1= baud;
rINTMSK&= ~(BIT_GLOBAL|BIT_UTXD1|BIT_URXD1|BIT_UERR01);
break;
}
default:
return D_ERR;
}
return D_OK;
}
/** @func __UART_Flush
* @brief 手动激活发送中断, 内部函数
*/
void
__UART_Flush(uint8 fd)
{
switch (fd) {
case 0:
rUCON0 |= __BIT(9);
return;
case 1:
rUCON1 |= __BIT(9);
return;
default:
return;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -