延续主动站程序框架的介绍,这里介绍从动站程序框架。
应用程序的编写
首先先给大家展示一下应用程序是如何使用这个程序框架的:
第一步初始化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作为主动站的程序介绍