DSP28335 串口中断收发及FIFO使用
基于研旭28335一体板测试
#include "DSP2833x_Device.h" // DSP2833x 头文件
#include "DSP2833x_Examples.h" // DSP2833x 例子相关头文件
#include "string.h"
#include "stdio.h"
void InitLedGpio(void);
/**************************************函数声明************************************************/
void scia_echoback_init(void); //声明SCI-A工作方式和参数配置
void scia_xmit(int a); //声明发送字节的函数
void scia_msg(char *msg); //声明发送数组的函数
void SCIASend(char* buff);
void SCIARecvPoll(void);
interrupt void SCIRXINTA_ISRHandler(void);
interrupt void SCITXINTA_ISRHandler(void);
interrupt void SCIRXINTAFIFO_ISRHandler(void);
interrupt void SCITXINTAFIFO_ISRHandler(void);
/**********************************************************************************************/
static char RecvLen = 0;
static char RecvBuf[256] = {0};
static Uint16 SendLen = 0;
static char SendBuf[256] = {0};
static Uint16 RecvOvtime = 0;
/****************************************主程序******************************************************/
#define FIFO_DEPTH 4
void main(void)
{
// 初始化系统控制:
// 设置PLL, WatchDog, 使能外设时钟
// 下面这个函数可以从DSP2833x_SysCtrl.c文件中找到..
InitSysCtrl();
// 初始化串口SCI-A的GPIO
InitSciaGpio();
InitLedGpio();
// 清除所有中断初始化中断向量表:
// 禁止CPU全局中断
DINT;
// 初始化PIE中断向量表,并使其指向中断服务子程序(ISR)
// 这些中断服务子程序被放在了DSP280x_DefaultIsr.c源文件中
// 这个函数放在了DSP2833x_PieVect.c源文件里面.
InitPieCtrl();
// 禁止CPU中断和清除所有CPU中断标志
IER = 0x0000;
IFR = 0x0000;
// PIE 向量表指针指向中断服务程(ISR)完成其初始化.
// 即使在程序里不需要使用中断功能,也要对 PIE 向量表进行初始化.
// 这样做是为了避免PIE引起的错误.
InitPieVectTable();
EALLOW;
//PieVectTable.SCIRXINTA = &SCIRXINTA_ISRHandler;
//PieVectTable.SCITXINTA = &SCITXINTA_ISRHandler;
PieVectTable.SCIRXINTA = &SCIRXINTAFIFO_ISRHandler;
PieVectTable.SCITXINTA = &SCITXINTAFIFO_ISRHandler;
EDIS;
// 初始化SCI-A工作方式和参数配置
scia_echoback_init();
PieCtrlRegs.PIECTRL.bit.ENPIE = 1;
PieCtrlRegs.PIEIER9.bit.INTx1 = 1;
PieCtrlRegs.PIEIER9.bit.INTx2 = 1;
IER |= PIEACK_GROUP9;
sprintf(SendBuf,"%s","\r\n\n\nHello !\0");
scia_msg(SendBuf); //发送函数
sprintf(SendBuf,"%s","\r\nYou will get what you send after terminal send from PC comm tools\n\0"); //发送语句
scia_msg(SendBuf); //发送函数
EINT;
for(;;)
{
DELAY_US(100);
RecvOvtime++;
if(RecvOvtime > 50 && RecvLen)
{
SCIARecvPoll();//查询接收帧字节对接收深度取余的字节数
GpioDataRegs.GPADAT.bit.GPIO0 = 1;
memcpy(SendBuf,RecvBuf,RecvLen);
//SendLen = RecvLen-1;
SendLen = RecvLen;
RecvLen = 0;
//启动发送
SCIASend(SendBuf);
}
else if(RecvLen == 0)//查询接收小于接收深度的字节
{
SCIARecvPoll();
}
}
}
void InitLedGpio(void)
{
EALLOW;
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0; // GPIO0复用为GPIO功能
GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; // GPIO0设置为输出
GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 0; // GPIO1复用为GPIO功能
GpioCtrlRegs.GPADIR.bit.GPIO1 = 1; // GPIO1设置为输出
EDIS;
}
// Test 1,SCIA DLB, 8-bit word, baud rate 0x000F, default, 1 STOP bit, no parity
void scia_echoback_init()
{
//SCI的工作模式和参数需要用户在后面的学习中,深入的了解一个寄存器底层相关的资料了,多看看芯片手册和寄存器的意思。
//因为28335的寄存器太多了,所以在以后的学习过程中,就不会对寄存器进行详细的注释了。
SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
// No parity,8 char bits,
// async mode, idle-line protocol
SciaRegs.SCICTL1.bit.SWRESET = 0;
SciaRegs.SCICTL1.bit.RXENA = 1;
SciaRegs.SCICTL1.bit.TXENA = 1;
SciaRegs.SCICTL2.bit.TXINTENA = 0;
SciaRegs.SCICTL2.bit.RXBKINTENA =1;
#if (CPU_FRQ_150MHZ) //波特率的配置
SciaRegs.SCIHBAUD =0x0001; // 9600 baud @LSPCLK = 37.5MHz.
SciaRegs.SCILBAUD =0x00E7;
#endif
#if (CPU_FRQ_100MHZ)
SciaRegs.SCIHBAUD =0x0001; // 9600 baud @LSPCLK = 20MHz.
SciaRegs.SCILBAUD =0x0044;
#endif
SciaRegs.SCICTL1.bit.SWRESET = 1; // Relinquish SCI from Reset
/*******************************************************************/
//增加FIFO功能
SciaRegs.SCIFFTX.bit.TXFIFOXRESET = 0;
SciaRegs.SCIFFRX.bit.RXFIFORESET = 0;
SciaRegs.SCIFFTX.bit.SCIRST = 1;
SciaRegs.SCIFFTX.bit.SCIFFENA = 1; //发送FIFO使能
SciaRegs.SCIFFTX.bit.TXFFIL = FIFO_DEPTH; //发送FIFO深度16
SciaRegs.SCIFFRX.bit.RXFFIENA = 1; //接收FIFO使能
SciaRegs.SCIFFRX.bit.RXFFIL = FIFO_DEPTH; //接收FIFO深度16
SciaRegs.SCIFFCT.all = 0x00; //无发送延迟
SciaRegs.SCIFFTX.bit.TXFIFOXRESET = 1;
SciaRegs.SCIFFRX.bit.RXFIFORESET = 1;
/*******************************************************************/
}
void scia_xmit(int a)//发送字节的函数
{
//单个发送
//while (SciaRegs.SCICTL2.bit.TXRDY == 0) {}
//SciaRegs.SCITXBUF=a;
//使用发送FIFO
while(SciaRegs.SCIFFTX.bit.TXFFST >= FIFO_DEPTH) {}
SciaRegs.SCITXBUF = a;
}
void scia_msg(char * msg)//发送数组的函数
{
int i;
i = 0;
while(msg[i] != '\0')
{
scia_xmit(msg[i]);
i++;
}
}
//先发送第一个字节然后启动串口中断处理余下的字节
void SCIASend(char* buff)
{
SciaRegs.SCICTL1.bit.TXENA = 1; //使能串口发送
//SciaRegs.SCICTL2.bit.TXINTENA = 1; //常规中断
//scia_xmit(buff[0]);
SciaRegs.SCIFFTX.bit.TXFFIENA = 1; //串口FIFO发送中断
}
//查询接收,用来接收非整深度的字节数据
void SCIARecvPoll(void)
{
while(SciaRegs.SCIFFRX.bit.RXFFST > 0)
{
RecvBuf[RecvLen++] = SciaRegs.SCIRXBUF.all&0xff;
RecvOvtime = 0;
}
}
// INT9.1
interrupt void SCIRXINTA_ISRHandler(void) // SCI-A
{
GpioDataRegs.GPADAT.all &= 0xfffffffC;
// Insert ISR Code here
if(SciaRegs.SCIRXST.bit.RXRDY == 1)
{
RecvBuf[RecvLen++] = SciaRegs.SCIRXBUF.all&0xff;
RecvOvtime = 0;
}
// To receive more interrupts from this PIE group, acknowledge this interrupt
PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
}
interrupt void SCIRXINTAFIFO_ISRHandler(void) // SCI-A
{
GpioDataRegs.GPADAT.all &= 0xfffffffC;
while(SciaRegs.SCIFFRX.bit.RXFFST > 0)
{
RecvBuf[RecvLen++] = SciaRegs.SCIRXBUF.all&0xff;
RecvOvtime = 0;
}
SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1; //清除FIFO接收中断标志
PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
}
// INT9.2
interrupt void SCITXINTA_ISRHandler(void) // SCI-A
{
static Uint16 SendCnt = 1; //第一个字节已经发送用来触发进入发送中断
// Insert ISR Code here
if(SciaRegs.SCICTL2.bit.TXRDY == 1)
{
if(SendLen)
{
SciaRegs.SCITXBUF = SendBuf[SendCnt++];
SendLen--;
}
else
{
SendCnt = 1;
SciaRegs.SCICTL2.bit.TXINTENA = 0;
SciaRegs.SCICTL1.bit.TXENA = 0;
GpioDataRegs.GPADAT.bit.GPIO1 = 1;
}
}
// To receive more interrupts from this PIE group, acknowledge this interrupt
PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
}
interrupt void SCITXINTAFIFO_ISRHandler(void) // SCI-A
{
static Uint16 SendCnt = 0;
// Insert ISR Code here
if(SendLen)
{
while(SciaRegs.SCIFFTX.bit.TXFFST < FIFO_DEPTH && SendLen)
{
SciaRegs.SCITXBUF = SendBuf[SendCnt++];
SendLen--;
}
}
else
{
SendCnt = 0;
SciaRegs.SCICTL2.bit.TXINTENA = 0;
SciaRegs.SCICTL1.bit.TXENA = 0;
GpioDataRegs.GPADAT.bit.GPIO1 = 1;
}
SciaRegs.SCIFFTX.bit.TXFFINTCLR = 1; //清除FIFO发送中断标志
// To receive more interrupts from this PIE group, acknowledge this interrupt
PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
}
//===========================================================================
// No more.
//===========================================================================