【DSP】TMS320F28035串口SCI不定长字节数据FIFO收发,数据帧格式:0XFD(帧头)+数据+0XFC 0XFD(帧尾)

 

/**********************************************************************************
    自定义串口接收协议,单字节接收中断,数据帧格式: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复位
}

 

  • 7
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
关于TMS320F28027中断优先级,中断优先级是通过IPC(Interrupt Priority Control)模块控制的。IPC模块包括两个寄存器:IPC0和IPC1,它们分别用于控制CPU中断和DMA中断的优先级。 IPC0中的每个位表示一个中断源,位0表示IPC0中断源的最高优先级,位31表示IPC0中断源的最低优先级。IPC1中的每个位表示一个DMA中断源,位0表示IPC1中断源的最高优先级,位31表示IPC1中断源的最低优先级。 TMS320F28027自带了多个串口,其中SCI(串行通信接口)是最常用的。下面是一个SCI中断收发数据的例子: ``` #include "F2802x_Device.h" interrupt void sciaRxIsr(void); interrupt void sciaTxIsr(void); Uint16 ReceivedCount; Uint16 TransmitCount; char ReceivedData[16]; char TransmitData[16] = "Hello, World!\r\n"; void main(void) { InitSysCtrl(); InitSciaGpio(); InitScia(); InitPieCtrl(); InitPieVectTable(); EnableInterrupts(); while(1) { // Do nothing } } void InitScia() { // Initialize SCI-A SciaRegs.SCICCR.all = 0x0007; SciaRegs.SCICTL1.all = 0x0003; SciaRegs.SCICTL2.all = 0x0000; SciaRegs.SCICTL2.bit.TXINTENA = 1; SciaRegs.SCICTL2.bit.RXBKINTENA = 1; SciaRegs.SCIHBAUD.all = 0x0000; SciaRegs.SCILBAUD.all = 0x0027; SciaRegs.SCICTL1.all = 0x0023; } void InitSciaGpio() { // Initialize SCI-A GPIO EALLOW; GpioCtrlRegs.GPAPUD.bit.GPIO28 = 0; GpioCtrlRegs.GPAPUD.bit.GPIO29 = 0; GpioCtrlRegs.GPAQSEL2.bit.GPIO28 = 3; GpioCtrlRegs.GPAQSEL2.bit.GPIO29 = 3; GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 1; GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 1; EDIS; } interrupt void sciaRxIsr(void) { // Receive data from SCI-A ReceivedData[ReceivedCount++] = SciaRegs.SCIRXBUF.all; // Echo back received data SciaRegs.SCITXBUF.all = ReceivedData[ReceivedCount-1]; // Clear RX interrupt flag PieCtrlRegs.PIEACK.all = PIEACK_GROUP9; } interrupt void sciaTxIsr(void) { // Transmit data through SCI-A if(TransmitCount < sizeof(TransmitData)) { SciaRegs.SCITXBUF.all = TransmitData[TransmitCount++]; } else { SciaRegs.SCICTL2.bit.TXINTENA = 0; } // Clear TX interrupt flag PieCtrlRegs.PIEACK.all = PIEACK_GROUP9; } ``` 在这个例子中,我们使用SCI-A进行串口通信。在InitScia函数中,我们初始化了SCI-A的控制寄存器和波特率寄存器。在InitSciaGpio函数中,我们将SCI-A的引脚配置为GPIO模式,并设置了输入/输出上拉器和中断模式。在main函数中,我们启用了中断,并且在一个无限循环中等待中断发生。 在sciaRxIsr中断服务程序中,我们接收了从SCI-A收到的数据,并通过SCI-A将接收到的数据回显。在sciaTxIsr中断服务程序中,我们发送了一个包含“Hello, World!”字符串的数据包,并在发送完成后禁用了TX中断。 请注意,这只是一个基本的例子,实际应用中需要根据具体情况进行修改和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值