使用SCI模块进行通信,是装置与外界的主要方式。比如与上位机通信,接入GPRS模块,接入485电度表,或者板间通信等等。

SCI的控制应该说还是比较简单的,但是也是非常灵活的。支持FIFO模式,支持测试模式,支持中断模式,而且还有各种通信参数的设置等。

DSP2812有两个SCI模块。其实DSP28335这样的片子的很多外设和2812是一样使用的,程序都是可以通用的。这里我们只对2812进行封装。

先定义一个基类:CSci,然后为SCI-A和SCI-B分别定义子类CScia,CScib.

基类定义如下:

namespace NF281x{/*** SCI基类*/
class CSci{
public:CSci( volatile unsigned int& ccr,volatile unsigned int& ctl1,volatile unsigned int& ctl2,volatile unsigned int& lbaud,volatile unsigned int& hbaud,volatile unsigned int& rxst,volatile unsigned int& rxbuf,volatile unsigned int& txbuf,volatile unsigned int& fftx,volatile unsigned int& ffrx,volatile unsigned int& ffct);
private:volatile unsigned int& m_ccr;volatile unsigned int& m_ctl1;volatile unsigned int& m_ctl2;volatile unsigned int& m_lbaud;volatile unsigned int& m_hbaud;volatile unsigned int& m_rxst;volatile unsigned int& m_rxbuf;volatile unsigned int& m_txbuf;volatile unsigned int& m_fftx;volatile unsigned int& m_ffrx;volatile unsigned int& m_ffct;
};

一看基类的构造函数这么复杂,其实没关系,应用程序使用时没有这些的。

应用程序时不会直接使用基类的构造函数的,这在我们定义子类的时候传入相应的寄存器即可。

其实也说明了一点,SCI的使用还是有点复杂,不说难,也是容易出错的。所以,封装成简洁的接口是很有必要的。

看看子类的接口:

namespace NF281x{class CScia:public CSci{
public:CScia();
};}
namespace NF281x{
class CScib:public CSci{
public:CScib();
};
}

也就是说应用程序使用SCI-B对象时,只需要定义一个CScib的对象,而且构造时不需要任何参数。

接下来是通讯参数的相关接口

 /*** 获取停止位数* @return* - 0x00 1bit停止位* - 0x80 2bits停止位*/inline unsigned int getStop()const{return NDm::getBit<volatile unsigned int,7,unsigned int>(m_ccr);}/*** 是否是1位停止位* @return*/inline bool isStop_1()const{return getStop()==0;}/*** 是否是2位停止位* @return*/inline bool isStop_2()const{return getStop()!=0;}/*** 设置停止位* @param st* @see getStop()*/inline void setStop( const unsigned int& st ){if( st==0 )setStop_1();elsesetStop_2();}/*** 设置1位停止位*/inline void setStop_1(){NDm::bitClr<volatile unsigned int,7,unsigned int>(m_ccr);}/*** 设置2位停止位*/inline void setStop_2(){NDm::bitSet<volatile unsigned int,7,unsigned int>(m_ccr);}/*** 获取校验方式* @return* - 0x40: 奇校验* - 0x60: 偶校验* - 其他: 无校验*/inline unsigned int getParity()const{return m_ccr & 0x60;  // bit 6-5}/*** 是否奇校验* @return*/inline bool isParity_odd()const{return getParity()==0x40;}/*** 是否偶校验* @return*/inline bool isParity_even()const{return getParity()==0x60;}/*** 是否无校验* @return*/inline bool isParity_none()const{return (getParity())&0x20==0;}/*** 设置校验方式* @param p* @see getParity();*/inline void setParity( const unsigned int& p ){if( p==0x60 )setParity_even();else if( p==0x40 )setParity_odd();elsesetParity_none();}/*** 设置无校验*/inline void setParity_none(){NDm::bitClr<volatile unsigned int,5,unsigned int>(m_ccr);}/*** 设置为偶校验*/inline void setParity_even(){m_ccr |= 0x60;}/*** 设置为奇校验*/inline void setParity_odd(){m_ccr = (m_ccr&0xDF) | 0x20;}/*** 获取字符长度* @return 0~7:1~8*/inline unsigned int getChar()const{return m_ccr&0x07;  // bit 0~3}/*** 设置字符长度* @param len* @see getChar();*/inline void setChar( const unsigned int& len ){m_ccr = (m_ccr&0xF8) | (len&0x07);}/****************  通信参数  **************/inline unsigned long getBps( const CClocking& clk )const{return clk.getClk_sci()/(( getBrr()+1 ) * 8);}inline void setBps( const unsigned long& bps,const CClocking& clk ){setBrr(clk.getClk_sci()/(8*bps) -1 );}void init( const unsigned int& ch=8,const unsigned int& stop=1,const unsigned int& parity=0 );

定义丰富的接口查看运行状态

 /*** 发送缓冲区可写* @return*/inline bool isTxRdy()const{return NDm::isBitSet<volatile unsigned int,7,unsigned int>(m_ctl2);}/*** 发送线路空闲* @return*/inline bool isTxEmpty()const{return NDm::isBitSet<volatile unsigned int,6,unsigned int>(m_ctl2);}/*** 接收缓冲区可读* @return*/inline bool isRxRdy()const{return NDm::isBitSet<volatile unsigned int,6,unsigned int>(m_rxst);}

定义操作相关接口

inline bool isTxEn()const{return NDm::isBitSet<volatile unsigned int,1,unsigned int>(m_ctl1);}inline void enTx( const bool& en ){if( en )enTx();elsedisTx();}inline void enTx(){NDm::bitSet<volatile unsigned int,1,unsigned int>(m_ctl1);}inline void disTx(){NDm::bitClr<volatile unsigned int,1,unsigned int>(m_ctl1);}inline bool isRxEn()const{return NDm::isBitSet<volatile unsigned int,0,unsigned int>(m_ctl1);}inline void enRx( const bool& en ){if( en )enRx();elsedisRx();}inline void enRx(){NDm::bitSet<volatile unsigned int,0,unsigned int>(m_ctl1);}inline void disRx(){NDm::bitClr<volatile unsigned int,0,unsigned int>(m_ctl1);}inline void tx( const unsigned char& c ){m_txbuf = c;}inline void rx( unsigned char& c )const{c = m_rxbuf&0xFF;}/*** 复位模块状态机* 该操作不会修改参数* @param delay 处于复位时常*/void reset(  const unsigned int& delay=100 );

定义错误检测的接口

 /*** 接收错误* 这是一个总的接收错误标志。* 一般程序测试错误,都应该测试该标志* 当有错误标志时,必须使用reset来进行复位。* @return*/inline bool isRxErr()const{return NDm::isBitSet<volatile unsigned int,7,unsigned int>(m_rxst);}/*** 接收信号至少有10bit的低电平* @return*/inline bool isRxErr_break()const{return NDm::isBitSet<volatile unsigned int,5,unsigned int>(m_rxst);}/*** 没有收到正确的停止位* @return*/inline bool isRxErr_frame()const{return NDm::isBitSet<volatile unsigned int,4,unsigned int>(m_rxst);}/*** 校验没通过* @return*/inline bool isRxErr_parity()const{return NDm::isBitSet<volatile unsigned int,2,unsigned int>(m_rxst);}/*** 程序或者DMA没有及时取走接收到的数据* @return*/inline bool isRxErr_overrun()const{return NDm::isBitSet<volatile unsigned int,3,unsigned int>(m_rxst);}/*** FIFO顶层数据有帧错误* @note 只在FIFO模式下有效* @return*/inline bool isFFErr_frame()const{return NDm::isBitSet<volatile unsigned int,15,unsigned int>(m_rxbuf);}/*** FIFO顶层数据有校验错误* @note 只在FIFO模式下有效* @return*/inline bool isFFErr_parity()const{return NDm::isBitSet<volatile unsigned int,14,unsigned int>(m_rxbuf);}

定义中断相关的接口

 /*** 接收错误时产生中断* @return*/inline bool isIntEn_rxErr()const{return NDm::isBitSet<volatile unsigned int,6,unsigned int>(m_ctl1);}inline void enInt_rxErr( const bool& en ){if( en )enInt_rxErr();elsedisInt_rxErr();}inline void enInt_rxErr(){NDm::bitSet<volatile unsigned int,6,unsigned int>(m_ctl1);}inline void disInt_rxErr(){NDm::bitClr<volatile unsigned int,6,unsigned int>(m_ctl1);}/*** 可以读取接收缓冲区或者检测到Break时产生中断* @return*/inline bool isIntEn_rxRdyOrBreak()const{return NDm::isBitSet<volatile unsigned int,1,unsigned int>(m_ctl2);}inline void enInt_rxRdyOrBreak( const bool& en ){if( en )enInt_rxRdyOrBreak();elsedisInt_rxRdyOrBreak();}inline void enInt_rxRdyOrBreak(){NDm::bitSet<volatile unsigned int,1,unsigned int>(m_ctl2);}inline void disInt_rxRdyOrBreak(){NDm::bitClr<volatile unsigned int,1,unsigned int>(m_ctl2);}/*** 可以写数据到发送缓冲区时产生中断* @return*/inline bool isIntEn_txRdy()const{return NDm::isBitSet<volatile unsigned int,0,unsigned int>(m_ctl2);}inline void enInt_txRdy( const bool& en ){if( en )enInt_txRdy();elsedisInt_txRdy();}inline void enInt_txRdy(){NDm::bitSet<volatile unsigned int,0,unsigned int>(m_ctl2);}inline void disInt_txRdy(){NDm::bitClr<volatile unsigned int,0,unsigned int>(m_ctl2);}

定义FIFO相关的接口

 inline bool isEnFifo()const{return NDm::isBitSet<volatile unsigned int,14,unsigned int>(m_fftx);}inline void enFifo(){NDm::bitSet<volatile unsigned int,14,unsigned int>(m_fftx);}/*** 复位* 复位FIFO与SCI模块* @param wait*/void resetFf( const unsigned int& wait=1000 );/*** 复位发送队列* @param wait*/void resetTxFf( const unsigned int& wait=100 );/*** 复位接收队列* @param wait*/void resetRxFf( const unsigned int& wait=100 );/*** 发送字符延时* @return*/inline unsigned int getFfTxDelay()const{return m_ffct & 0x00FF;}inline void setFfTxDelay( const unsigned int& delay=0 ){m_ffct = (m_ffct&0xFF00)| (delay&0x00FF);}int tx( const unsigned char* buf,const int& size );int rx( unsigned char* buf,const int& size )const;/*** 发送队列数据个数* @return*/inline unsigned int txFfState()const{return (m_fftx&0x1F00)>>8;}/*** 接收队列数据个数* @return*/inline unsigned int rxFfState()const{return (m_ffrx&0x1F00)>>8;}/*** 接收队列溢出* @return*/inline bool isRxFfOverFlow()const{return NDm::isBitSet<volatile unsigned int,15,unsigned int>(m_ffrx);}/*** 清除接收队列溢出标志*/inline void clrRxFfOverFlow(){NDm::bitSet<volatile unsigned int,14,unsigned int>(m_ffrx);}/*** 使能发送队列中断*/inline void enInt_txFf(){NDm::bitSet<volatile unsigned int,5,unsigned int>(m_fftx);}/*** 使能接收队列中断*/inline void enInt_rxFf(){NDm::bitSet<volatile unsigned int,5,unsigned int>(m_ffrx);}/*** 禁用发送队列中断*/inline void disInt_txFf(){NDm::bitClr<volatile unsigned int,5,unsigned int>(m_fftx);}/*** 禁用接收队列中断*/inline void disInt_rxFf(){NDm::bitClr<volatile unsigned int,5,unsigned int>(m_ffrx);}/*** 发送队列中断是否使能* @return*/inline bool isIntEn_txFf()const{return NDm::isBitSet<volatile unsigned int,5,unsigned int>(m_fftx);}/*** 接收队列中断是否使能* @return*/inline bool isIntEn_rxFf()const{return NDm::isBitSet<volatile unsigned int,5,unsigned int>(m_ffrx);}/*** 是否有发送队列中断* @return*/inline bool isInt_txFf()const{return NDm::isBitSet<volatile unsigned int,7,unsigned int>(m_fftx);}/*** 是否有接收队列中断* @return*/inline bool isInt_rxFf()const{return NDm::isBitSet<volatile unsigned int,7,unsigned int>(m_ffrx);}/*** 清除发送队列中断*/inline void clrInt_txFf(){NDm::bitSet<volatile unsigned int,6,unsigned int>(m_fftx);}/*** 清除接收队列中断*/inline void clrInt_rxFf(){NDm::bitSet<volatile unsigned int,6,unsigned int>(m_ffrx);}/*** 获取发送队列中断级别* @return*/inline unsigned int getTxFfIntLevel()const{return m_fftx & 0x001F;}/*** 获取接收队列中断级别* @return*/inline unsigned int getRxFfIntLevel()const{return m_ffrx & 0x001F;}/*** 设置发送队列中断级别* @param level*/inline void setTxFfIntLevel( const unsigned int& level=0 )const{m_fftx = ((m_fftx&0xFFE0)|(level&0x001F));}/*** 设置发送队列中断级别* @param level*/inline void setRxFfIntLevel( const unsigned int& level=16 )const{m_ffrx = ((m_ffrx&0xFFE0)|(level&0x001F));}

这里我还定义了一个为将来扩展使用的函数,用于一般性的串口使用初始化过程函数

 /*** 默认的初始化参数* 这个函数给后续简单使用做封装* 默认设置使用FIFO模式,但是参数不对通信速率初始化*/void defaultInit();

也就是说,面对SCI这么灵活的使用方法,这么多接口,应用程序使用起来还是比较麻烦的。将来要抽象出SCI的普遍用法,或者说几种比较实用的用法。

DSP 2812: 使用C++封装SCI相关推荐

  1. DSP 2812: 使用C++封装定时器及应用举例

    2812中有三个定时器,结构都是一样的. 一般的操作就是设置周期,使能中断,启动计时器. 我们先定义定时器的基类,然后对每个定时器再分别定义各自的子类. 一般地,我们都将特定芯片的类申明在一个命名空间 ...

  2. java dsp_GitHub - Onemeaning/JavaDsp: 数字信号处理(DSP)方面的Java封装,包含常用的一些处理方法,如滤波、信号变换等等。...

    JavaDsp 数字信号处理(DSP)方面的Java封装,包含常用的一些处理方法,如滤波.信号变换等等. 该类库是我本科毕业设计中的一部分,绝大部分都是我自己写实现的,很少部分算法有我另外几个朋友参与 ...

  3. Simulink嵌入式自动代码DSP F28335(2)——SCI通信

    Simulink嵌入式自动代码DSP F28335(2)--SCI通信 简述 1.文件模型建立 1.1 自动代码文件 1.2 上位机文件Host 2.环境配置 2.1 Simulink配置 2.2 电 ...

  4. DSP—2812、28335串行通信接口SCI

    文章来自:http://blog.csdn.net/wu159632/article/details/7996886 SCI(Serial Communication Interface),即串行通信 ...

  5. 基于ARM+DSP进行应用开发-经验共享

    针对当前应用的复杂性,SOC芯片更好能能满足应用和媒体的需求,集成众多接口,用ARM做为应用处理器进行多样化的应用开发和用户界面和接口,利用DSP进行算法加速,特别是媒体的编解码算法加速,既能够保持算 ...

  6. TI基于DSP+ARM的双核架构如何相互通信

    1 通信结构简介 针对当前应用的复杂性,SOC芯片更好能能满足应用和媒体的需求,集成众多接口,用ARM做为应用处理器进行多样化的应用开发和用户界面和接口,利用DSP进行算法加速,特别是媒体的编解码算法 ...

  7. F28335的SCI通讯模块

    文章目录 1 概述 2 通讯简述 3 SCI模块 3.1 SCI模块简介 3.2 模块接收发送原理过程 3.3 SCI模块的FIFO 3.4 SCI波特率 4 功能实现 4.1 SCI模块初始化 4. ...

  8. 【DSP开发】【Linux开发】基于ARM+DSP进行应用开发

    针对当前应用的复杂性,SOC芯片更好能能满足应用和媒体的需求,集成众多接口,用ARM做为应用处理器进行多样化的应用开发和用户界面和接口,利用DSP进行算法加速,特别是媒体的编解码算法加速,既能够保持算 ...

  9. DVSDK/EZSDK软件框架简介

    from: http://code.61ic.com.cn/Article/DaVinci/TMS320DM81x/201203/41583.html 下面对DVSDK的软件架构,各个软件模块的功能等 ...

  10. OMAP3530资料

    OMAP3 CPU OMAP35x系列启动流程:(自己总结的) 第一步:配置CPU的启动方式(sys_boot): 第二步:bootROM会从NAND 中读取x-loader,ECC校验通过以后,就跳 ...

最新文章

  1. java参数传递(超经典)
  2. Oracle创建自增字段方法-ORACLE SEQUENCE的简单介绍
  3. Spring AOP功能和目标
  4. 汇编:采用顺序编程方法,实现在屏幕上显示大写字幕A
  5. 针对 Java 开发人员的 C# 编程语言
  6. (已更新)漫画小程序,自动采集资源,漫画源码简单即可发布
  7. Java笔记01——JAVA基础部分
  8. presenting view controller Vs presented view controller
  9. TensorFlow 从入门到精通(8)—— 泰坦尼克号旅客生存预测
  10. 解决Excel中使用VBA出现microsoft visual c++ runtime错误
  11. 微信分享与支付开发详解
  12. 三分钟教会你微信炸一炸,满屏粑粑也太可爱了!
  13. 沟渠指什么_什么是生态拦截沟渠?作用是什么?
  14. “expression cannot be used as a function”报错
  15. 第3章 分布式操作系统的进程和处理机
  16. ogc是一个非营利性组织_非营利组织的21个最佳WordPress主题
  17. 妙味课堂H5音乐播放器项目实战 ajax实战教程
  18. 电商API分享:获取淘宝商品历史价格api调用示例 参数说明
  19. 岁月温柔-11 妈妈出汗多秋衣湿了不换的真正原因
  20. python中and not是什么意思,python中的not,and, or

热门文章

  1. STM8S003F3 uart的使用
  2. 51c语言延时作用,51单片机C语言延时函数的使用 - 51单片机C语言延时函数怎么定义和使用...
  3. 一个简单的爬虫例子(代码)
  4. 西门子840d备份到u盘_840dsl 启动服务U盘制作和CF卡数据备份回装
  5. Java的8种基本数据类型
  6. font-family:中文字体的英文名称
  7. 人脸识别-倍加信梯控控制
  8. 【Python】SVM分类 特征标准化+网格搜索最优模型参数+十折交叉验证
  9. [解读] GuiltyGearXrd‘s Art Style : The X Factor Between 2D and 3D - GGX 3D 渲染 2D 风格
  10. XILINX VIVADO2018.2官方下载全教程记录.