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;
}
  • 8
    点赞
  • 72
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值