DSP

DSP 2812: 使用C++实现的SCI从动站程序框架

2019-07-13 17:44发布

延续主动站程序框架的介绍,这里介绍从动站程序框架。

应用程序的编写

首先先给大家展示一下应用程序是如何使用这个程序框架的:

第一步初始化SCI

scia().setBps(115200,board.clock());
这里也是以SCIA为例。 设置其通信速率为115200.

第二步定义从动站类对象,设置发送缓冲区

第二步事实上是在函数initComTask()中执行的。 static unsigned char txBuf[256]; void comRx( const unsigned char* buf,const unsigned int& size,NDm::NApp::NF281x::CSciSlaver& slaver ){ slaver.send(buf,size); } void initComTask(){ NDm::NApp::NF281x::CSciASlaver& slaver = NDm::NApp::NF281x::CSciASlaver::ins(); slaver.setTxBuf(txBuf,256); slaver.setRxFun(comRx); slaver.reset(); slaver.send( (const unsigned char*)("start slaver "),13); }

第三步定义回调函数

setRxFun()函数设置了一个回调函数,这个回调函数会在每次收到数据时调用。 我们这里使用了函数comRx(). 它将收到的数据再发送回去。

驱动程序的设计

驱动程序时设计一个基类,然后为各串口实现子类。在子类中设定中断向量和相应的处理串口类。

基类的设计

namespace NF281x { /** * SCI从模块驱动 * 可实现串口驱动型功能 */ class CSciSlaver{ public: typedef TRingBuf CRingBuf; typedef CRingBuf::CRingPos CRingPos; /** * 回调函数类型 * @note 回调函数的处理时间应该尽量短,否则可能会导致系统阻塞 * @param buf 收到的数据缓冲区 * @param size 收到的数据长度 * @param slaver */ typedef void (*FUN_RxProc)( const unsigned char* buf,const unsigned int& size,CSciSlaver& slaver ); public: CSciSlaver( NDm::NHw::NF281x::CSci& sci );
private: unsigned char m_rx[16]; unsigned int m_rxSize; CRingBuf m_tx; CRingPos m_txPos; NDm::NHw::NF281x::CSci& m_sci; NDm::NHw::NF281x::CPie& m_pie; FUN_RxProc m_rxProc; }; }
这部分的代码和主动站的程序类似。只是不需要接受循环缓冲区,而是使用了一个16字节的缓冲区。因为FIFO最多只有16级。 同时增加了一个回调函数类型。用于设定用户需要回调的函数的类型。
定义了相关的操作接口 /** * 设置接收处理函数 * @param proc */ void setRxFun( FUN_RxProc proc ); /** * 复位 * 复位发送队列,接收队列 */ void reset(); bool isError()const; inline NDm::NHw::NF281x::CSci& sci(){ return m_sci; } inline const NDm::NHw::NF281x::CSci& sci()const{ return m_sci; } inline void setTxBuf( unsigned char* buf,const unsigned int& size ){ m_tx.setBuf(buf,size); } int send( const unsigned char* buf,const int& size ); inline bool ifTxEmpty()const{ return m_tx.getPos()==m_txPos; }
定义了中断响应的函数调用接口
/** * 中断处理函数 * 这些函数应该在中断函数中被调用执行 * 用户程序应该执行PIE级别的ACK操作 */ void irsRx(); void irsTx(); inline NDm::NHw::NF281x::CPie& pie(){ return m_pie; } protected: /** * 启动发送过程 */ void startTx();

使用这个程序框架的优点是,SCI通讯的主程序不需要在主过程(一般是main函数)中被循环调用。 而是由SCI中断直接调用。 使用时也需要注意一点,其回调函数不能占用太长时间,否则会导致中断执行时间过长。

其他的内容可以参考SCI作为主动站的程序介绍