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.
 //===========================================================================
