#include "..\..\includes.h"
#if CFG_UART_EN > 0
#if CFG_UART_RX_BUF_EN > 0
// 串口接收缓冲区的存储空间
static INT8U idata UART0_RxBuf[UART0_RX_BUF_SIZE];
static INT8U idata UART1_RxBuf[UART1_RX_BUF_SIZE];
// 串口接收缓冲区
static RING_QUEUE UART0_RingRxBuf;
static RING_QUEUE UART1_RingRxBuf;
#endif
//-------------------------------------------------------------------
static COMM_ERR_TYPE CommCfgPort( INT8U commNum, INT32U baudRate );
//-------------------------------------------------------------------
// 串口初始化
//-------------------------------------------------------------------
extern COMM_ERR_TYPE CommInit( INT8U commNum, INT32U baudRate )
{
COMM_ERR_TYPE err;
// 配置端口
err = CommCfgPort( commNum, baudRate );
if( err!=COMM_NO_ERR )
return err;
#if CFG_UART_RX_BUF_EN > 0
// 初始化接收缓冲区
if( commNum == UART0 )
{
Queue_Init( &UART0_RingRxBuf, UART0_RX_BUF_SIZE, UART0_RxBuf );
}
else if( commNum == UART1 )
{
Queue_Init( &UART1_RingRxBuf, UART1_RX_BUF_SIZE, UART1_RxBuf );
}
#endif
return COMM_NO_ERR;
}
/*
//------------------------------------------------------
// 串口0中断服务程序
//------------------------------------------------------
void UART0_ISR( void ) interrupt UART0_VECTOR_NUMBER
{
INT8U ch;
// 必须由软件来清除串口的中断源
if( TI==1 )
{
TI=0;
}
else if( RI==1 )
{
RI=0;
ch = SBUF;
CommSendByte( UART0, ch );
}
}
//------------------------------------------------------
// 串口1中断服务程序
//------------------------------------------------------
void UART1_ISR( void ) interrupt UART1_VECTOR_NUMBER
{
INT8U ch;
// 必须由软件来清除串口的中断源
if( TI1==1 )
{
TI1=0;
}
else if( RI1==1 )
{
RI1=0;
ch = SBUF1;
CommSendByte( UART1, ch );
}
}
*/
//-------------------------------------------------------------------
// 设置串口的波特率
//
// 说明:
// 在Winbond77E58中,串口0可以用定时器1或2做波特率发生器,串口1只能用定时器1
// 做波特率发生器。
// 为了避免冲突,我们约定:在本程序中,串口0用定时器2做波特率发生器,
// 串口1用定时器1做波特率发生器。
//
// 如果使用定时器2的波特率发生器模式作为波特率发生器,则波特率和以下几个因素有关:
// (1) Fosc 晶振
// (2) 特殊寄存器PMR中的CD1 CD0位
// (3) 定时器2的计数初值
//
// 如果使用定时器1作为波特率发生器,则波特率和以下几个因素有关:
// (1) Fosc 晶振
// (2) 特殊寄存器PMR中的CD1 CD0位
// (3) 特殊寄存器CKCON中的T1M位
// (4) 特殊寄存器PCON中的SMOD位(控制串口0的波特率是否倍增),
// 或特殊寄存器WDCON中的SMOD_1位(控制串口1的波特率是否倍增)
// (5) 定时器1的计数初值
//-------------------------------------------------------------------
static COMM_ERR_TYPE CommCfgPort( INT8U commNum, INT32U baudRate )
{
INT16U initValue;
if( commNum == UART0 )
{
#if CFG_UART0_BAUDRATE_TIMER==2 // 串口0的波特率发生器使用定时器2
// 串口方式1,8个数据位,1个停止位,允许接收
SCON = 0x50;
// 使用定时器2的波特率发生器模式作为波特率发生器
RCLK = 1;
TCLK = 1;
// 根据波特率计算定时器的计数初值
initValue = (INT32U)65536 - (Fosc/32)/baudRate;
// 装入波特率对应的初值
TH2 = (INT8U)(initValue>>8);
TL2 = (INT8U)(initValue&0xff);
RCAP2H = (INT8U)(initValue>>8);
RCAP2L = (INT8U)(initValue&0xff);
// 启动定时器2
TR2 = 1;
#endif
#if CFG_UART0_BAUDRATE_TIMER==1 // 串口0的波特率发生器使用定时器1
// 串口方式1,8个数据位,1个停止位,允许接收
SCON = 0x50;
// 定时器1,定时用,软启动,模式2,8位自动重装
Timer_Init( TIMER1, TIMER_WORK_MODE_TIMER, TIMER_START_MODE_SOFT, 2 );
// 波特率倍增
// 注意:串口1的波特率倍增位是WDCON中的bit7位(SMOD_1)
// 参见Winbond77E58 datasheet 的27页
// 串口0的波特率倍增位是PCON中的bit7位(SMOD)
PCON |= 0x80;
// 根据波特率计算定时器的计数初值
initValue = 256 - ( (Fosc/16)/CFG_TIMER_DIVIDE_CLOCK )/baudRate;
// 装入波特率对应的初值
TH1 = (INT8U)(initValue&0xff);
TL1 = (INT8U)(initValue&0xff);
// 启动定时器1
TIMER1_START();
#endif
}
else if( commNum == UART1 )
{
// 串口方式1,8个数据位,1个停止位,允许接收
SCON1 = 0x50;
// 定时器1,定时用,软启动,模式2,8位自动重装
Timer_Init( TIMER1, TIMER_WORK_MODE_TIMER, TIMER_START_MODE_SOFT, 2 );
// 波特率倍增
// 注意:串口1的波特率倍增位是WDCON中的bit7位(SMOD_1)
// 参见Winbond77E58 datasheet 的27页
// 串口0的波特率倍增位是PCON中的bit7位(SMOD)
SMOD_1 = 1;
// 根据波特率计算定时器的计数初值
initValue = 256 - ( (Fosc/16)/CFG_TIMER_DIVIDE_CLOCK )/baudRate;
// 装入波特率对应的初值
TH1 = (INT8U)(initValue&0xff);
TL1 = (INT8U)(initValue&0xff);
// 启动定时器1
TIMER1_START();
}
else
{
return COMM_BAD_CH;
}
return COMM_NO_ERR;
}
//-------------------------------------------------------------------
// 串口查询方式发送一个字节
//
// 参数说明:
// commNum 串口号
// byte 要发送的字节数据
//
// 返回值:
// 如果发送成功,函数返回COMM_NO_ERR
// 如果串口编号出错,函数返回COMM_BAD_CH
// 如果发送超时,函数返回COMM_TX_TIMEOUT
//-------------------------------------------------------------------
extern COMM_ERR_TYPE CommSendByte( INT8U commNum, INT8U byte )
{
INT8U temp;
COMM_ERR_TYPE err = COMM_NO_ERR;
#define TIMEOUT_VALUE 10000
INT16U timeout=TIMEOUT_VALUE;
temp = IE;
if( commNum == UART0 )
{
UART0_INT_DIS();
SBUF = byte;
while( TI==0 && (--timeout)>0);
TI = 0;
if( timeout == 0 )
{
err = COMM_TX_TIMEOUT;
}
}
else if( commNum == UART1 )
{
UART1_INT_DIS();
SBUF1 = byte;
while( TI1==0 && (--timeout)>0);
TI1 = 0;
if( timeout == 0 )
{
err = COMM_TX_TIMEOUT;
}
}
else
{
err = COMM_BAD_CH;
}
IE = temp;
return err;
}
//-------------------------------------------------------------------
// 串口查询方式发送字符串
//
// 参数说明:
// commNum 串口号
// str 要发送的字符串
//
// 返回值:
// 如果发送成功,函数返回COMM_NO_ERR
// 如果串口编号出错,函数返回COMM_BAD_CH
// 如果发送超时,函数返回COMM_TX_TIMEOUT
//-------------------------------------------------------------------
extern COMM_ERR_TYPE CommSendString( INT8U commNum, const INT8U *str )
{
COMM_ERR_TYPE err;
while( *str != '\0' )
{
err = CommSendByte( commNum, *str );
++str;
if( err != COMM_NO_ERR )
return err;
}
return COMM_NO_ERR;
}
#if CFG_UART_PRINTF_EN > 0
//---------------------------------------------------------------------------
// 串口打印函数
//
// 说明:
// 本函数和ANSI C标准库stdio.h中定义的printf()函数保持兼容,本函数只是在
// 形参中多了一个“串口号”参数,其余和printf()函数完全兼容,包括形参和返回值。
//
// 开发过程:
// 2005-1-12 13:57
// 目前这个版本的CommPrintf()函数一次还不能打印太多的东西,因为
// 它是将所有要打印的东西都打印到print_buf[]中,如果一次打印的东西太多,
// 会造成print_buf[]的溢出。
//---------------------------------------------------------------------------
extern int CommPrintf( INT8U commNum, const char *format, ... )
{
#define PRINT_BUF_SIZE 32
static INT8U idata print_buf[ PRINT_BUF_SIZE ];
int cnt;
va_list args;
va_start( args, format );
cnt = vsprintf( print_buf, format, args );
va_end( args );
if( cnt > PRINT_BUF_SIZE-1 )
{
// vsprintf()实际输出到print_buf[]中�
UART.rar_1c20_CF卡_Corporation
版权申诉
39 浏览量
2022-09-21
03:56:53
上传
评论
收藏 6KB RAR 举报
林当时
- 粉丝: 100
- 资源: 1万+
最新资源
- 常用爆破用户名字典top500
- meta-llama-3-8b-instruct 的 model-00003-of-00004.safetensors 的2/3
- bootstrap-select.js bootstrap-select.css
- EasyPoi Excel和 Word简易工具类
- 华为实验一 MPI 矩阵运算
- 网卡MAC地址修改工具 HardDiskSNC HWID changer 等电脑信息修改工具小软件合集(8个).zip
- 华为实验一 MPI 矩阵运算
- mysql语句大全及用法简介及基础教程及特点阐述.txt
- 指令调度和延迟分支简介及基础教程及特点阐述.txt
- HTML5小游戏【动态视力-考眼力的小游戏】游戏源码分享下载 - dtsl.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈