📄 sci.c
字号:
/* Description : SCI module functions.
*
* $Author: 王琢玉
* $Date: 2007/02/23
* $Name: SCI.c
*/
#define SCI_GLOBALS
#include <string.h>
#include "include.h"
/*************************************************************************************
SCI串口
MC13213有两个串口 SCI1、SCI2。
在SCI工作前,首先要初始化SCI,通过调用函数void SCIInitGeneric(UINT32 , UINT32 , UINT8 )
实现,在促使化函数中首先要设置SCI的波特率。然后打开接收中断,关闭发送中断。
SCI的接收和发送各有一个8位的data寄存器(Rx data buffer 和 Tx data buffer),发送数据时,
调用函数void SCIStartTransmit(UINT8 , UINT8)实现一个字节的数据发送。首先要判断发送的数据寄存
器(Tx data buffer)是否为空,只有当Tx data buffer为空时(SCInS1_TDRE == 1),才可以往buffer中写入
待发送的8位数据。当数据写入buffer中后,数据开始通过串口向外发送,当SCI2S1_TC == 1表示数据发送
完成,读该位清 SCI2S1_TC 标志。这时单个字节数据发送完成。
如果需要发送一个数组,调用函数void SCITransmitArray(UINT8 *, UINT8, UINT8),该函数实际上
就是不停的调用void SCIStartTransmit(UINT8 , UINT8)。
当SCI接收到数据后,就会将数据保存到 Rx data buffer 中,然后将标志位 RDRF 置高,如果中断允许,
就会产生中断。
定义一个数组ScinFifo[SCIn_FIFO_SIZE],一个 计数器 Sci2FifoWrite。初始化时计数器 Sci2FifoWrite
清零。在串口接收到一个字节后,放进 ScinFifo[Sci2FifoWrite],同时 Sci2FifoWrite ++;并判断该fifo有
没有溢出,如果溢出,溢出标志位置高,否则,打开定时器,定时SCIn_OVERTIME,如果在定时器超时之前接收
到新的数据,那么重复上面的步骤,然后刷新定时器重新定时。如果超时,那么说明一帧数据接收完成,通过
标志位通知后台进行处理。
**************************************************************************************/
/************************************************************
Function: SCIInitGeneric (u32, u32, SCI_PORT)
Parameter: u32BusClock Bus Clock
u32BaudRate The BaudRate of SCI
u8ComNumber Select SCI1 or SCI2
Description: initializing the SCI to the requested baud rate
based on the supplied busclock in kilohertz on the com port
that is selected
************************************************************/
void SCIInitGeneric(UINT32 u32BusClock, UINT32 u32BaudRate, UINT8 u8ComNumber)
{
UINT16 u16Sbr = 0;
u16Sbr = (UINT16) ((u32BusClock) / (u32BaudRate << 4));
switch (u8ComNumber)
{
case SCI_PORT1:
SCI1BDL = (UINT8) u16Sbr;
u16Sbr = u16Sbr >> 8;
SCI1BDH = (UINT8) u16Sbr;
SCI1C2 = INIT_SCI1C2;
Sci1FifoWrite = 0;
Sci1Info.u8Val = 0;
break;
case SCI_PORT2:
SCI2BDL = (UINT8) u16Sbr;
u16Sbr = u16Sbr >> 8;
SCI2BDH = (UINT8) u16Sbr;
SCI2C2 = INIT_SCI2C2;
Sci2FifoWrite = 0;
Sci2Info.u8Val = 0;
break;
}
CLRWDT();
}
/************************************************************
Function: SCIStartTransmit(u8, u8)
Parameter: cData The data which will transmit by sci
u8ComNumber Com port select
Description: Transmit one 8-Bit data by SCI
************************************************************/
void SCIStartTransmit(UINT8 cData, UINT8 u8ComNumber)
{
UINT8 delay;
if(u8ComNumber == SCI_PORT1)
{
while (!SCI1S1_TDRE)CLRWDT(); /* ensure Tx data buffer empty */
SCI1D = cData; /* load data to SCI1 register */
while (!SCI1S1_TC)CLRWDT(); /* wait for Tx complete */
}
else
{
while (!SCI2S1_TDRE)CLRWDT(); /* ensure Tx data buffer empty */
SCI2D = cData; /* load data to SCI2 register */
while (!SCI2S1_TC)CLRWDT(); /* wait for Tx complete */
}
//如果串口接到 485 上,那么需要延时,具体延时多少,可以现场调试
for(delay=0;delay<0x0f;delay++)CLRWDT();
}
/************************************************************
Function: SCITransmitArray(u8 *, u8, u8)
Parameter: *pStr the array which will transmit by sci
length the lengh of this array
u8ComNumber Com port select
Description: Transmit one array by SCI
************************************************************/
void SCITransmitArray(UINT8 *pStr, UINT8 length, UINT8 u8ComNumber)
{
UINT8 i;
for (i = 0; i < length; i ++)
{
SCIStartTransmit(pStr[i],u8ComNumber);
}
}
/************************************************************
Function: SCITransmitStr(u8 *, u8)
Parameter: *pStr the character string which will transmit by sci
u8ComNumber Com port select
Description: Transmit one character string by SCI
************************************************************/
void SCITransmitStr(UINT8 *pStr, UINT8 u8ComNumber)//发送字符串
{
UINT8 i;
UINT8 nStrLen = (UINT8)strlen(pStr);
for (i = 0; i < nStrLen; i++)
{
SCIStartTransmit(pStr[i], u8ComNumber);
}
}
/************************************************************
Function: interrupt VSCI1Rx()
Parameter:
Description: SCI1 中断函数
************************************************************/
interrupt void VSCI1Rx(void) //外部通信
{
UINT8 u8status, u8temp;
do
{
u8status = SCI1S1;
} while ((u8status & 0x20) == 0);
//如果RDRF置高,先将 Buffer 中的数据读取出来,然后再判断 error 和 overflow,
//必须注意在 return 前,先读取出 Buffer中的数据。
u8temp = SCI1D;
/* Check for Errors (Framing, Noise, Parity) */
if((u8status & 0x07) != 0) return;
/* Check if Fifo is OverFlow*/
if(Sci1Info.u8Val != 0) return;
Sci1Fifo[Sci1FifoWrite ++] = u8temp;
if(Sci1FifoWrite == SCI1_FIFO_SIZE)
{
Sci1Info.bits.FifoIsFlow = 1; //溢出
return;
}
//如果没有溢出,打开定时器,定时 SCIn_OVERTIME
TPM2C0V = TPM2CNT + SCI1_OVERTIME;
TPM2C0SC &= 0x7f;
TPM2C0SC = 0x50;
}
/************************************************************
Function: interrupt VSCI2Rx()
Parameter:
Description: SCI2 中断函数
************************************************************/
interrupt void VSCI2Rx(void)
{
UINT8 u8status, u8temp;
do
{
u8status = SCI2S1;
} while ((u8status & 0x20) == 0);
u8temp = SCI2D;
/* Check for Errors (Framing, Noise, Parity) */
if((u8status & 0x07) != 0) return;
/* Check if Fifo is OverFlow*/
if(Sci2Info.u8Val != 0) return;
Sci2Fifo[Sci2FifoWrite ++] = u8temp;
if(Sci2FifoWrite == SCI2_FIFO_SIZE)
{
Sci2Info.bits.FifoIsFlow = 1;
}
TPM2C0V = TPM2CNT + SCI2_OVERTIME;
TPM2C0SC &= 0x7f;
TPM2C0SC = 0x50;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -