
/**********************************************************************************
自定义串口接收协议,单字节接收中断,数据帧格式:0xfd+不定长数据+0xfc +0xfd(16进制)
**********************************************************************************/
#include "DSP28x_Project.h" // Device Headerfile and Examples Include File
#define CPU_FREQ 60E6
#define LSPCLK_FREQ CPU_FREQ/4
#define SCI_FREQ 100E3
#define SCI_PRD (LSPCLK_FREQ/(SCI_FREQ*8))-1
#define USART_REC_LEN 200 //定义最大接收字节数 200
__interrupt void sciaTxFifoIsr(void);
__interrupt void sciaRxFifoIsr(void);
__interrupt void scibTxFifoIsr(void);
__interrupt void scibRxFifoIsr(void);
void scia_fifo_init(void);
void scib_fifo_init(void);
void error(void);
Uint8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15, 接收完成标志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字节数目
Uint16 USART_RX_STA=0; //接收状态标记
Uint16 sdataA[20]; // Send data for SCI-A
Uint16 rdataA[20]; // Received data for SCI-A
void main(void)
{
Uint16 i;
InitSysCtrl();
InitSciGpio();
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.SCIRXINTA = &sciaRxFifoIsr;
PieVectTable.SCITXINTA = &sciaTxFifoIsr;
EDIS; // This is needed to disable write to EALLOW protected registers
scia_fifo_init(); // Init SCI-A
PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block
PieCtrlRegs.PIEIER9.bit.INTx1=1; // PIE Group 9, INT1
PieCtrlRegs.PIEIER9.bit.INTx2=1; // PIE Group 9, INT2
IER = 0x100; // Enable CPU INT
EINT;
while(1)
{
char* msg;
Uint8 len,t;
if(USART_RX_STA&0x8000)
{
len=USART_RX_STA&0x1fff;//得到此次接收到的数据长度
//msg = "\r\n您发送的消息为:\r\n\r\n";
//scia_msg(msg);
for(t=0;t<len;t++)
{
scia_xmit(USART_RX_BUF[t]);
}
//msg = "\r\n\r\n"; //插入换行
//scia_msg(msg);
USART_RX_STA=0;
}
}
}
//
// error - Error Checking function
//
void error(void)
{
__asm(" ESTOP0"); // Test failed!! Stop!
for (;;);
}
//
// sciaTxFifoIsr - SCI Tx FIFO ISR
//
__interrupt void
sciaTxFifoIsr(void)
{
Uint16 i;
for(i=0; i< 1; i++)
{
SciaRegs.SCITXBUF=sdataA[i]; // Send data
}
for(i=0; i< 1; i++) //Increment send data for next cycle
{
sdataA[i] = (sdataA[i]+1) & 0x00FF;
}
//SciaRegs.SCIFFTX.bit.TXFFIENA = 0;
SciaRegs.SCIFFTX.bit.TXFFINTCLR=1; // Clear SCI Interrupt flag
PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ACK
}
//
// sciaRxFifoIsr - SCI RX FIFO ISR
//
__interrupt void
sciaRxFifoIsr(void)
{
/*****************************************
无串口协议版本代码,随便发
******************************************/
/*
Uint16 rx;
rx = SciaRegs.SCIRXBUF.all;
scia_xmit(rx);
*/
/*****************************************
串口协议(数据+0X0D 0X0A)版本代码
******************************************/
/*
Uint8 Res;
Res = SciaRegs.SCIRXBUF.all; //读取接收到的数据;接收到的数据必须是0x0d 0x0a(回车换行)结尾
if((USART_RX_STA&0x8000)==0) //接收未完成
{
if(USART_RX_STA&0x4000) //接收到了0x0d
{
if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else USART_RX_STA|=0x8000; //接收完成了
}
else //还没收到0X0D
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
*/
/***********************************************************
USART_RX_STA(串口接收中断标志位---16位)
bit15:帧尾2--0xfd--USART_RX_STA & 0x8000--也是接收完成标志-
bit14: 帧头---0xfd--USART_RX_STA & 0x4000
bit13: 帧尾1--0xfc--USART_RX_STA & 0x2000
bit[12:0]: 存储一次接收的数据字节数,其最大为0x1fff
串口通信协议:数据帧格式为:帧头+字符串数据+帧尾1+帧尾2
本程序中实际格式为:0xfd+..........+0xfc +0xfd
作者:秋雨梧桐
时间:2017/02/28
***********************************************************/
Uint8 Res;
Res = SciaRegs.SCIRXBUF.all; //读取接收到的数据
if(USART_RX_STA & 0x8000) //判断是否接收到 帧尾2,即是否接收完成一帧数据
{ //如果接收 帧尾2,在USART_RX_STA标志位没有清零时,不执行任何操作
}
else //如果没有接收 帧尾2,则执行下面程序
{
if(USART_RX_STA & 0x2000) //判断是否接收到 帧尾1
{
if(Res == 0xfd) //判断本次接收字符是否为 帧尾2--0x8000
{
USART_RX_STA |= 0x8000; //如果本次接收数据为 帧尾2,则表明本次数据接收完成,置位接收完成标志位
USART_RX_BUF[USART_RX_STA & 0x1fff] = '\0'; //并在接收到的字符数组后面添加字符串结束标志,即把接收到的所有字符组成一个字符串
}
else
{
USART_RX_STA = 0; //在接收到帧尾1后,没有接收到帧尾2,则表明数据接收出错,清除标志位,重新接收串口中断数据
}
}
else
{
if(USART_RX_STA & 0x4000) //在没有接收到帧尾1前提下,通过标志位判断是否接收到帧头
{
if(Res == 0xfc) //如果接收到帧头,则在判断本次接收到的数据是否为 帧尾1--0x2000
{
USART_RX_STA |= 0x2000; //如果本次接收到的字节数据是 帧尾1,则置位标志位
}
else //如果接收到帧头,而本次接收的字节数据不是 帧尾1,那么就是我们要的数据了
{
USART_RX_BUF[USART_RX_STA & 0x1fff] = Res;//将数据存储在缓存中
USART_RX_STA++; //利用标志位低13位存储缓存的数据字节数
}
}
else
{
if(Res == 0xfd) //如果之前没有接收到帧头,则判断本次接收到的字节数据是否为帧头 --0x4000
{
USART_RX_STA |= 0x4000; //如果是帧头,则置位标志位
}
else
{
USART_RX_STA = 0; //否则,清除标志位,重新接收
}
}
}
}
SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1; // Clear Overflow flag
SciaRegs.SCIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag
PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ack
}
void
scia_xmit(int a)
{
while (SciaRegs.SCIFFTX.bit.TXFFST != 0)
{
}
SciaRegs.SCITXBUF=a;
}
void
scia_msg(char * msg)
{
int i;
i = 0;
while(msg[i] != '\0')
{
scia_xmit(msg[i]);
i++;
}
}
void
scia_fifo_init()
{
SciaRegs.SCICCR.all =0x0007; //8位数据格式,选择地址位协议
SciaRegs.SCICTL1.all =0x0003; //使能SCI发送和接收
SciaRegs.SCICTL2.bit.TXINTENA =1; //使能发送中断(由于下面配置失能了FIFO发送中断,所以这里使不使能都没用)
SciaRegs.SCICTL2.bit.RXBKINTENA =1; //使能接收中断
SciaRegs.SCIHBAUD = 0x0000;
SciaRegs.SCILBAUD = 0x00c2; //SCI_PRD;//设置波特率9600
SciaRegs.SCICCR.bit.LOOPBKENA =0; //关闭自测模式
SciaRegs.SCIFFTX.all=0xC001; //失能FIFO发送中断,设置发送FIFO深度为1
SciaRegs.SCIFFRX.all=0x0021; //使能FIFO接收中断,设置接收FIFO深度为1,接收一个字节数据就产生FIFO接收中断,效率不高,面对少量不定长数据发送比较合适。
SciaRegs.SCIFFCT.all=0x00; //FIFO控制寄存器
SciaRegs.SCICTL1.all =0x0023; //禁止软复位 Relinquish SCI from Reset
SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1; //发送FIFO复位
SciaRegs.SCIFFRX.bit.RXFIFORESET=1; //接收FIFO复位
}
|