📄 sci.c
字号:
/******************************************************************************************
* 目的:串口驱动
* 功能:提供基本的串口操作接口
* 模块依赖:MCS51 串口中断 硬件端口 及 操作方式
******************************************************************************************/
#include "io8052A.h"
#include "SCI.h"
#define lFosc 24000000 //晶振频率24MZ
struct _tagScon //串口中断内部数据结构
{
pFnSCON pfncon; //串口中断指针
} Sconer;
/*
**-------------------------------------------------------------------------------------
** 初始化串口中断处理模块 C51scon
**-------------------------------------------------------------------------------------
*/
void Init_SCI()
{
Sconer.pfncon = (pFnSCON)0;
}
/*
**-------------------------------------------------------------------------------------
** 读取读总线状态
**-------------------------------------------------------------------------------------
*/
char SCIRXD()
{
if( P3_bit.RxD )
{
return 1;
}
else
{
return 0;
}
}
/*
**-------------------------------------------------------------------------------------
** 送发送总线状态
** stat: 状态值 (TLOW~THIGH)
**-------------------------------------------------------------------------------------
*/
void SCITXD(unsigned char stat)
{
if( stat )
{
P3_bit.TxD = 1;
}
else
{
P3_bit.TxD = 0;
}
}
/*
**-------------------------------------------------------------------------------------
** 返回串口发送中断标志
**-------------------------------------------------------------------------------------
*/
char SCISE()
{
if( SCON_bit.TI )
{
SCON_bit.TI = 0; // 软件清0
return 1;
}
return 0;
}
/*
**-------------------------------------------------------------------------------------
** 返回串口读中断标志
**-------------------------------------------------------------------------------------
*/
char SCIRE()
{
if( SCON_bit.RI )
{
SCON_bit.RI = 0; // 软件清0
return 1;
}
return 0;
}
/*
**-------------------------------------------------------------------------------------
** 中断标志允许控制
** signal: 0表示不允许读取中断 1表示允许
**-------------------------------------------------------------------------------------
*/
void SCIENcontrol(unsigned char signal)
{
if( signal )
{
SCON_bit.REN = 1;
}
else
{
SCON_bit.REN = 0;
}
}
/*
**-------------------------------------------------------------------------------------
** 查询方式向发送数据 byter
** 外部条件:当前串口中断不允许
**-------------------------------------------------------------------------------------
*/
void SCIsend(unsigned char byter)
{
SCON_bit.REN = 0;
SBUF = byter;
while ( !SCON_bit.TI )
{
//NULL
}
SCON_bit.TI = 0;
ACC = SBUF;
}
/*
**-------------------------------------------------------------------------------------
** 查询方式读取当前已接收数据
** 外部条件:当前串口中断不允许
**-------------------------------------------------------------------------------------
*/
unsigned char SCIread()
{
SCON_bit.REN = 1;
while ( !SCON_bit.RI )
{ //WdtOn();
}
SCON_bit.RI = 0;
return( SBUF );
}
/*
**-------------------------------------------------------------------------------------
** 内部中断中发送函数byter
**-------------------------------------------------------------------------------------
*/
void SCIsendin(unsigned char byter)
{
SCON_bit.REN = 0;
SBUF = byter;
//ACC = SBUF;
}
/*
**-------------------------------------------------------------------------------------
** 内部中断读取函数
**-------------------------------------------------------------------------------------
*/
unsigned char SCIreadin()
{
unsigned char rbyte;
rbyte = SBUF;
return rbyte;
}
/*
**-------------------------------------------------------------------------------------
** 初始化串口,波特率flash,工作模式1,定时器2做波特率发生器
**-------------------------------------------------------------------------------------
*/
char SCIini(unsigned int flash)
{
unsigned int buf;
if(flash<=0||(lFosc/flash<32)||((lFosc/flash)/32>65536)) // 拨特率超出可设定范围
{
return 0;
}
IE_bit.ES = 0; // 串口中断关闭
IE_bit. EA = 0; // 所有中断关
IP = 0x10;
PCON = 0x80; // 串口波特率翻倍SMOD=1
SCON = 0x50; // 串口工作模式1: 10位通用异步接收/发送器 REN=1
T2CON = 0x30; // 定时器2做波特率发生器
buf = 65536-(lFosc/flash)/32; // 计算波特率
RACAP2L = buf;
buf>>=8;
RACAP2H = buf; // 装入波特率
T2CON_bit.TR2 = 1; // T2置工作位,串口开始按指定波特率工作
SCON_bit.RI = 0; // 读中断标志0
SCON_bit.TI = 0; // 发送中断标志0
IE_bit.EA = 1; // 所有中断开
SCON_bit.REN = 0;
return 1;
}
/*
**-------------------------------------------------------------------------------------
** 动态波特率设定函数
**-------------------------------------------------------------------------------------
*/
char SCIDynamicBuad()
{
unsigned int baudrate;
unsigned int time;
time = 0;
TMOD = ( TMOD & 0XF1 ) | 0x01; //16位记数器
TH0 = 0; //ms
TL0 = 0;
TCON_bit.TR0 = 1; // T0置工作位
TCON_bit.TF0 = 0;
while( 1 ) //等待一个回应
{
if( !P3_bit.RxD )
{
break; //遇到一个高电平
}
else if( TCON_bit.TF0 )
{
TH0 = 0; //ms
TL0 = 0;
TCON_bit.TF0 = 0;
time++;
if( time > 100 ) return 0;
}
}
//0x55以当前汽车内定波特发给仪器
TMOD = ( TMOD & 0XF1 ) | 0x01; //16位记数器
TH0 = 0; //ms
TL0 = 0;
TCON_bit.TF0 = 0;; //初始化T0做记数器
TCON_bit.TR0 = 0; // T0置工作位
while( !P3_bit.RxD );
//TimeStart(TIMER0); //在开始收到0x55第一个位时开始记数
TCON_bit.TR0 = 1; // T0置工作位
while( P3_bit.RxD ){ if( TCON_bit.TF0 ) return 0; }
while( !P3_bit.RxD ){ if( TCON_bit.TF0 ) return 0; }
while( P3_bit.RxD ){ if( TCON_bit.TF0 ) return 0; }
while( !P3_bit.RxD ){ if( TCON_bit.TF0 ) return 0; }
while( P3_bit.RxD ){ if( TCON_bit.TF0 ) return 0; }
while( !P3_bit.RxD ){ if( TCON_bit.TF0 ) return 0; }
while( P3_bit.RxD ){ if( TCON_bit.TF0 ) return 0; }
while( !P3_bit.RxD ){ if( TCON_bit.TF0 ) return 0; }
TCON_bit.TR0 = 0;
//0x55收完,结束记数,计算和设定波特率
time = TH0;
time <<= 8;
time |= TL0; //读取记数值
baudrate = (unsigned int)(750000*64/(3*time)); //波特率=750000*64/(3*记数值)
SCIini( baudrate ); //由定时器0记数 设定波特率
return 1;
}
/*
**-------------------------------------------------------------------------------------
** 装入串口协议
**-------------------------------------------------------------------------------------
*/
char SCIload(pFnSCON pfnc)
{
Sconer.pfncon = pfnc;
SCON_bit.TI = 0; // 清标志
SCON_bit.RI = 0;
IE_bit.ES = 1; // 串口中断开
return 1;
}
/*
**-------------------------------------------------------------------------------------
** 销毁串口协议
**-------------------------------------------------------------------------------------
*/
char SCIdestroy()
{
if( Sconer.pfncon )
{
Sconer.pfncon = (pFnSCON)0;
IE_bit.ES = 0; // 串口中断关
return 1;
}
return 0;
}
/*
**-------------------------------------------------------------------------------------
** 释放串口
**-------------------------------------------------------------------------------------
*/
void SCIRelease()
{
IE_bit.ES = 0; // 串口中断关闭
PCON = 0x80; // 串口波特率翻倍SMOD=1
SCON = 0x50; // 串口工作模式1: 10位通用异步接收/发送器 REN=1
SCON_bit.RI = 0; // 读中断标志0
SCON_bit.TI = 0; // 发送中断标志0
SCON_bit.REN = 0; // 不允许发送
Sconer.pfncon = (pFnSCON)0; // 回调指针 0
}
/*
**-------------------------------------------------------------------------------------
** 串口中断
**-------------------------------------------------------------------------------------
*/
#pragma vector=TI_int
__interrupt void SCON_INT(void)
{
IE_bit.EA = 0; // 关闭所有中断
if( Sconer.pfncon )
{
Sconer.pfncon();
}
IE_bit.EA = 1; // 开启所有中断
}
//----------------------------------------------------------------- End Of File --------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -