458|2

6943

帖子

19

资源

纯净的硅(中级)

DSP串口SCI最高效的接收和发送不定长度的方案 [复制链接]

本文介绍dsp高效接收和发送不定长度的数据,该方法减小cpu的中断次数,经过长时间检验,该方法安全可靠效率最大。我使用的是28034只有4级FIFO,在优化前中断深度设置为1,cpu频繁中断,导致正常程序受影响。经过改进,设置发送中断深度为0级,接收中断为4级,只有在数据发送完成和接收满4个字节中断。
接收流程为:等待接收中断—》读取4个fifo数据—》超时检查—》读取fifo剩余数据。这样就会接收完整的一帧数据。
发送流程:触发中断开始发送数据—》写入4个数据到发送fifo----》等到fifo为空中断–》写入下4个数据到fifo----》写入最后剩余数据。
具体如下:
(1)初始化配置

void scia_init()
{
    // Note: Clocks were turned on to the SCIA peripheral
    // in the InitSysCtrl() function
     SciaRegs.SCICCR.all =0x0007;   // 1 stop bit,  No loopback
                                   // No parity,8 char bits,
                                   // async mode, idle-line protocol
    SciaRegs.SCICTL1.all =0x0003;  // enable TX, RX, internal SCICLK,
                                   // Disable RX ERR, SLEEP, TXWAKE
    SciaRegs.SCICTL2.bit.TXINTENA = 1;//使能发送中断


    
    SciaRegs.SCICTL2.bit.RXBKINTENA = 1;//使能接收中断
                            
    //BRR = (LSPCLK / (SCI Asynchronous Baud * 8)) - 1 ,LSPCLK=30M,
    //BRR = 0x0020, baud=115200
    //BRR = 0x0007, baud=460800
    //BRR = 0x0061, baud=38400
    SciaRegs.SCIHBAUD    =0x0000;
    SciaRegs.SCILBAUD    =0x0020;//
    SciaRegs.SCICCR.bit.LOOPBKENA =0; // Enable loop back
    SciaRegs.SCICCR.bit.STOPBITS = 2; //

    SciaRegs.SCIFFTX.all=0xC020;//设置发送中断为0级
    SciaRegs.SCIFFRX.all=0x0024;//设置接收中断为4级
    SciaRegs.SCIFFCT.all=0x0;

    SciaRegs.SCIPRI.bit.FREE = 0;//仿真模式下是否自由运行
    SciaRegs.SCICTL1.all =0x0023;     // Relinquish SCI from Reset

    SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1;  //发送FIFO复位
    SciaRegs.SCIFFRX.bit.RXFIFORESET=1;   //接收FIFO复位    
}

(2)接收中断和发送中断


interrupt void SCI1_RXD_isr(void)
{
    UINT16 RxData;

    //RxData = SciaRegs.SCIRXBUF.all;

    //上一个数据帧应用层未取走,数据丢弃
    if ((KeyBoardRxFrame.status == UART_FRAME_RX_END) || (KeyBoardRxFrame.index >= 40))
    {
        KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
        KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
        KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
        KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
    }else
    {
        KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
        KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
        KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
        KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
        KeyBoardRxFrame.ticker = KeyBoardRxFrame.spacetime;
    }
    
    SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1;   // Clear Overflow flag
    SciaRegs.SCIFFRX.bit.RXFFINTCLR=1;   // Clear Interrupt flag
 
    PieCtrlRegs.PIEACK.all|=0x100;       // Issue PIE ack

}

interrupt void SCI1_TXD_isr(void)
{
    Uint16 i;
    Uint16 len;
    // 发送一帧数据没有完成
    if(KeyBoardTxFrame.index + 4 < KeyBoardTxFrame.len)         
    {
        SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
        SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
        SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
        SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
        
        SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;  // Clear SCI Interrupt flag清除后产生中断
    }
    else
    {
        //发送剩下的数据
        len = KeyBoardTxFrame.len - KeyBoardTxFrame.index;
        for(i = 0; (len <= 40) && (i < len); i++)
        {
            SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
        }
        
        //一帧数据结束
        if(KeyBoardTxFrame.len)
        {
            KeyBoardTxFrame.status = UART_FRAME_TX_IT_END;
        }
     }

    PieCtrlRegs.PIEACK.all|=0x100;      // Issue PIE ACK
}


(3)读取不到4个字节的数据


void SCI1_RX_FIFO(UART_FRAME *pFrame)
{
    Uint16 maxNum = 0;
    while(SciaRegs.SCIFFRX.bit.RXFFST && maxNum < 4)
    {
        pFrame->pdata[pFrame->index++] = SciaRegs.SCIRXBUF.all;
        maxNum++;
    }
}


(4)在应用程序需要2ms周期查询接收数据是否结束

static void KeyboardJudgeRxFinish(void)
{
    //超时或数据长度大于40一帧接收完成
    if(((KeyBoardRxFrame.ticker <= 0)&&(KeyBoardRxFrame.index > 0)) || KeyBoardRxFrame.index >= 40)
    {
        SCI1_RX_FIFO(&KeyBoardRxFrame);
        KeyBoardRxFrame.len = KeyBoardRxFrame.index;
        KeyBoardRxFrame.status = UART_FRAME_RX_END;//数据接收完成,应用可以取走数据
    }

    if(KeyBoardRxFrame.ticker > 0)
    {
        KeyBoardRxFrame.ticker--;
    }
}

(6)发送

void KeyboardRs485TxFrame(void)
{
    SCI1SetTxMode();

    //如果当前帧正在发送,又重新请求发送一帧数据,则请求的数据丢弃
    if(KeyBoardTxFrame.status == UART_FRAME_TX_ING)
    {
        return ;
    }
    //启动发送第一个字节后,产生中断,接着数据在中断中发送完成
    KeyBoardTxFrame.index = 0;
    SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;//启动发送中断
    KeyBoardTxFrame.status = UART_FRAME_TX_ING;
}


回复

3184

帖子

1

资源

五彩晶圆(初级)

不定长确实处理起来很讨厌。

个人签名人已离开,无事别找,找也找不到。

回复

3028

帖子

0

资源

纯净的硅(高级)

中断写程序有优点也有缺点


回复
您需要登录后才可以回帖 登录 | 注册

最新文章 更多>>
    关闭
    站长推荐上一条 1/5 下一条

    About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

    站点相关: 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

    北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

    电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2021 EEWORLD.com.cn, Inc. All rights reserved
    快速回复 返回顶部 返回列表