转:DSP28335使用FIFO的串口中断总结

版权声明:本文为CSDN博主「E_ROAD_BY_U」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/E_ROAD_BY_U/article/details/53221479

一、串行通信与并行通信
DSP控制器间,DSP控制器与外部设备间交换信息,通信,可采取的通信方式主要两大类1、串行通信 2、并行通信。

并行通信一般包括多条数据线、多条控制线和状态线,传输速度快,传输线路多,硬件开销大,不适合远距离传输。一般用在系统内部,如XINTF接口或者控制器内部如DMA控制器。

串行通信则在通信线路上既传输数据信息也传输联络控制信息,硬件开销小,传输成本低,但是传输速度慢,且收发双方需要通信协议,可用于远距离通信。串行通信可以分为两大类1、同步通信 2、异步通信

同步通信:发送器和接收器通常使用同一时钟源来同步。方法是在发送器发送数据时同时包含时钟信号,接收器利用该时钟信号进行接收。典型的如I²C、SPI。

异步通信:收发双方的时钟不是同一个时钟,是由双方各自的时钟实现数据的发送和接收。但要求双方使用同一标称频率,允许有一定偏差。典型的如SCI。

二、28335SCI介绍
F28335处理器共提供3个SCI接口,相对TI的C240X系列DSP的SCI接口,功能上有很大的改进,在原有功能基础上增加了通信速率自动检测和FIFO缓冲等新的功能,为了减小串口通信时CPU的开销,F28335的串口支持16级接收和发送FIFO。也可以不使用FIFO缓冲。SCI接收器和发送器有各自独立的中断和使能位,可以独立地操作实现半双工通信,或者同时操作实现全双工通信。为了保证数据完整,SCI模块对接收到的数据进行间断、极性、超限和帧错误的检测。为了减少软件的负担,SCI采用硬件对通信数据进行极性和数据格式检查。通过对16位的波特率控制寄存器进行编程,可以配置不同的SCI通信速率。

所谓的FIFO就是先进先出的意思。SCI工作在FIFO模式下一般是因为所传输的信息并不是以一个帧为单位,而是以多个帧组成的一个包为信息单位的。比如说我的一个数据包由5个帧组成,第一个为控制字节,后四个字节共同组成一个浮点数。这时你可以设置FIFO接收中断为5个字节时产生中断。设置以后,每接收到5个字节后才会产生一次中断,而不是每接收一次产生一次中断。这样可以大幅减小CPU的开销。而先进先出的意思就是:在中断中,你读FIFO接收寄存器读到的数据是首先接收到的数据,再读一次的话读到的是接收到的第二个数据。而16深度的话就是最多能保存最近的16个接收数据,如果接收数据超过16个的话会产生相应的溢出,可以软件编程对溢出进行处理。
对于发送FIFO也是一样,你可以一次将多个数据放到发送FIFO中,然后DSP按先后顺序依次发送数据。

三、SCI模块的特点如下(通过相应的寄存器可以对这些功能进行设置)
   (1)2个外部引脚:SCITXD为SCI数据发送引脚;SCIRXD为SCI数据接收引脚。两个引脚为多功能复用引脚,如果不使用可以作为通用数字量I/O。

   (2)可编程通信速率,可以设置64K种通信速率。

   (3)数据格式:

        ◇ 1个启动位;

        ◇ 1~8位可编程数据字长度;

        ◇可选择奇校验、偶校验或无效校验位模式;

        ◇ 1或2位的停止位。

   (4)4种错误检测标志位:奇偶错误、超越错误、帧错误和间断检测。

   (5)2种唤醒多处理器方式:空闲线唤醒(Idle-line)和地址位唤醒(AddressBit)。

   (6)全双工或者半双工通信模式。

   (7)双缓冲接收和发送功能。

   (8)发送和接收可以采用中断和状态查询2种方式。

   (9)独立地发送和接收中断使能控制。

   (10)NRZ(非归零)通信格式。

   (11)13个SCI模块控制寄存器,起始地址为7050H。

   (12)自动通信速率检测(相对F140x增强的功能)。

   (13)16级发送/接收FIFO(相对F240x增强的功能)。

四、SCI主要功能单元
   (1) 1个发送器(TX)及相关寄存器。

            ◇ SCITXBUF:发送数据缓冲寄存器,存放要发送的数据(由CPU装载);


        ScicRegs.SCITXBUF=a;//向数据缓冲寄存器中写入数据即可发送该数据
            ◇ TXSHF寄存器:发送移位寄存器,从SCITXBUF寄存器接收数据,并将数据移位到SCITXD引脚上,每次移1位数据。

   (2)1个接收器(RX)及相关寄存器。

            ◇ RXSHF寄存器:接收移位寄存器,从SCIRXD引脚移入数据,每次移1位;

            ◇ SCIRXBUF:接收数据缓冲寄存器,存放CPU要读取的数据,来自远程处理器的数据装入寄存器RXSHF,然后又装入接收数据缓冲寄存器SCIRXBUF和接收仿真缓冲寄存器SCIRXEMU中。

   (3)一个可编程的波特率产生器。

   (4)数据存储器映射的控制和状态寄存器。

五、SCI寄存器

SCICCR寄存器各位的功能如图所示,可以配置SCI的发送或接收的数据长度、是否使用奇偶校验、结束位的个数等。同理可知每个寄存器的各位有不同功能,写程序的时候查找相应的寄存器即可。(其实许多东西TI已经帮我们写好了,例如有FIFO的测试函数,我们可以在别人写好的基础上进行修改,加快进度)

六、SCI发送与接收功能介绍


可编程的中断级:发送和接收FIFO都能产生CPU中断,只要发送FIFO状态位TXFFST(位12~8)与中断触发优先级TXFFIL(位4~0)相匹配,就产生一个中断触发,从而为SCI的发送和接收提供一个可编程的中断触发逻辑。

标准SCI的一个字的发送缓冲器作为发送FIFO和移位寄存器间的发送缓冲器。只有移位寄存器的最后一位被移出后,一个字的发送缓冲才从发送FIFO装载。使能FIFO后,经过一个可选择的延迟(SCIFFCT),TXSHF被直接装载而不再使用TXBUF。(与标准SCI相比,中断源变了,发送时标准的SCI是TXBUF为空)

SCI发送数据过程划线处置位与清除都是硬件自动完成的。

七、仿真结果分析
最终的程序在下面。编写的程序功能是使用FIFO中断的形式发送一个数组,数组中起始数据是5,5,5,5。先发送这些数据(注意串口接收与发送的都是字符数据,发送数字量的时候要注意转化),然后在中断中修改第四个数据为中断的次数,然后发送新的数据。第一次的执行结果如图所示,

正确结果应该是5555,5551,...,分析结果可知,似乎是在开启中断之后就产生一次串口发送中断。但是中断标志位清零的啊。(猜测是因为串口发送缓冲寄存器中此时没有数据,给理解成了发送完毕。难道需要对发送缓冲寄存器先赋值再开中断?)(测试了下,把第一次要发送的数据再启动中断之前放入了FIFO中,输出结果是正确的)

在处理上一个问题的时候,遇到的另一个问题如下:


如上,串口实验的时候为什么先禁止发送功能后面的配置就不起作用了呢?我是在最后又开启了发送功能,但是接收不到数据,如果开始的时候没有禁止发送功能就可以接收到数据。其实原因如下,

虽然最后开启发送功能了,但是最后SW RESET位确被写入了0,导致复位,所有的配置都被复位了。(由此也说明了配置寄存器的时候要小心,确定每位的功能。而且配置的时候尽量只配置你需要的那一位,其他的不要改动。用bit,不要用all)

最终的结果如图所示,达到了预期的结果。也得出当FIFO中的数据全部发送完毕才会产生中断。


八、总结
实现一个功能的时候首先查看相关的资料,例如数据手册,论坛、百度、书籍等,搜集各种相关资料,然后看别人是如何实现的,分析下相关步骤,理清好思路。针对不懂的地方继续查找资料,层层递进。(如果想省事,可以在别人正确代码的基础上进行修改,看他配置了什么寄存器,实现了什么功能,然后根据自己的需求,查看数据手册重新配置),实现的时候可以一个个小功能的实现,遇到疑惑的除求助外,也可试着观察不同的情况下会出现什么结果。总之就是多搜,多想,多动手,多总结。

#include "DSP2833x_Device.h"
#include "DSP2833x_Examples.h"
#define SCIB 0
#define SCIC 1
// Prototype statements for functions found within this file.
void scic_fifo_init(void);
void scic_xmit(int a);
interrupt void uart_send(void);
 
// Global counts used in this example
Uint16 isrCount=0;
Uint16 ErrorCount=0;
Uint16 sdata[4]={5,5,5,5};//要发送的数据
void main(void)
{
    Uint16 i=0;
// Step 1. Initialize System Control registers, PLL, WatchDog, Clocks to default state:
// This function is found in the DSP2833x_SysCtrl.c file.
    InitSysCtrl();
 
// Step 2. Select GPIO for the device or for the specific application:
// This function is found in the DSP2833x_Gpio.c file.
// InitGpio(); skip this as this is example selects the I/O
// for SCI-A in this file itself
   InitSciGpio();
 
// Step 3. Initialize PIE vector table:
// The PIE vector table is initialized with pointers to shell Interrupt
// Service Routines (ISR).  The shell routines are found in DSP2833x_DefaultIsr.c.
// Insert user specific ISR code in the appropriate shell ISR routine in
// the DSP28_DefaultIsr.c file.
 
// Disable and clear all CPU interrupts:
    DINT;
    IER = 0x0000;
    IFR = 0x0000;
 
      // Initialize Pie Control Registers To Default State:
      // This function is found in the DSP2833x_PieCtrl.c file.
      // InitPieCtrl();  PIE is not used for this example
 
      // Initialize the PIE Vector Table To a Known State:
      // This function is found in DSP2833x_PieVect.c.
      // This function populates the PIE vector table with pointers
      // to the shell ISR functions found in DSP2833x_DefaultIsr.c.
      InitPieVectTable();
 
      // Enable CPU and PIE interrupts
      // This example function is found in the DSP2833x_PieCtrl.c file.
      EnableInterrupts();
 
// Step 4. Initialize all the Device Peripherals to a known state:
// This function is found in DSP2833x_InitPeripherals.c
// InitPeripherals(); skip this for SCI tests
// Step 5. User specific functions, Reassign vectors (optional), Enable Interrupts:
 
    isrCount = 0;
    ErrorCount = 0;
#if SCIB
    scib_fifo_init();       // Initialize the SCI FIFO
    scib_loopback_init();  // Initalize SCI 
#elif SCIC
    scic_fifo_init();       // Initialize the SCI FIFO
#endif
// Send a character ,先给发送缓冲寄存器赋值。
    for(i=0;i<4;i++)
    {
        scic_xmit(sdata[i]+0x30);
    } 
   scic_xmit(' ');
// Step 6. Send Characters forever starting with 0x00 and going through
// 0xFF.  After sending each, check the recieve buffer for the correct value
 EALLOW;  
//  PieVectTable.SCIRXINTC = &uartIsr;  
    PieVectTable.SCITXINTC = &uart_send;  
    EDIS;  
    PieCtrlRegs.PIECTRL.bit.ENPIE=1;  
//  PieCtrlRegs.PIEIER8.bit.INTx5=1;  
    PieCtrlRegs.PIEIER8.bit.INTx6=1;  
    IER|=M_INT8;  
    EINT;  
    ERTM;    
    for(;;){ }
}
interrupt void uart_send(void)  
{  
    Uint16 i;   
    isrCount++;
    sdata[3]=isrCount;
    for(i=0;i<4;i++)
    {
      scic_xmit(sdata[i]+0x30);
    }  
    scic_xmit(' '); 
    if(isrCount==10)
    {
        ScicRegs.SCICTL1.bit.TXENA =0;//禁止发送缓冲器工作。
    }
    PieCtrlRegs.PIEACK.all=0xffff;//0x0080; 
    ScicRegs.SCIFFTX.bit.TXFFINTCLR=1;    // Clear SCI Interrupt flag
}  
 
// Transmit a character from the SCI'
void scic_xmit(int a)//发送一个数据a,类型为int
{
   ScicRegs.SCITXBUF=a;//向数据缓冲寄存器中写入数据即可发送该数据
}
 
// Initalize the SCI FIFO
void scic_fifo_init()
{
// Test 1,SCIC  DLB, 8-bit word, baud rate 9.6k, default, 1 STOP bit, no parity
//功能是配置发送模式
// Note: Clocks were turned on to the SCIC peripheral
//  in the InitSysCtrl() function
//  ScicRegs.SCICTL1.all =0x0000; //开始的时候先禁止接收与发送功能 
    ScicRegs.SCICCR.all =0x0007;   // 1 stop bit,  No loopback
                                   // No parity,8 char bits,                   
                                   // async mode, idle-line protocol
//数据长度8位,一个结束位,无奇偶校验,空闲线模式,禁止回送    
                                 
//  ScicRegs.SCICTL1.all =0x0003;  // enable TX, RX, internal SCICLK,
                                      // Disable RX ERR, SLEEP, TXWAKE
                                   
    ScicRegs.SCICTL1.all =0x0002; //允许发送,禁止接收                              
//  ScicRegs.SCICTL2.all =0x0001;//发送缓冲器中断使能。似乎与下面的重复了
    ScicRegs.SCICTL2.bit.TXINTENA =1;//发送缓冲器中断使能。
//  ScicRegs.SCICTL2.bit.RXBKINTENA =1;
    ScicRegs.SCIHBAUD    =0x0001;
    ScicRegs.SCILBAUD    =0x00e7;
 //上面是波特率设置,书上写的0x00e7   
    
//  ScicRegs.SCICCR.bit.LOOPBKENA =0;// enable(Disable) loop back
    ScicRegs.SCICTL1.all =0x0022;     // Relinquish SCI from Reset
//FIFO设置
    ScicRegs.SCIFFTX.bit.TXFIFOXRESET=0;
//  ScicRegs.SCIFFRX.bit.RXFIFORESET=0;
 
    ScicRegs.SCIFFTX.all=0xE060;
//  ScicRegs.SCIFFRX.all=0x204f;
    ScicRegs.SCIFFCT.all=0x0;
}
 
//===========================================================================
// No more.
//===========================================================================

————————————————
版权声明:本文为CSDN博主「E_ROAD_BY_U」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/E_ROAD_BY_U/article/details/53221479

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: DSP28335是德州仪器推出的一款高性能数字信号处理器,可以用于很多应用场景,其中包括CAN数据通信。CAN(Controller Area Network)是一种广泛应用于汽车和工业控制等领域的串行通信协议。 要进行DSP28335的CAN数据发送,首先需要进行如下几个步骤: 1. 初始化CAN控制器:通过将相应的寄存器设置为指定值来初始化CAN控制器,包括设置时钟频率、总线宽等参数。 2. 配置发送消息对象:CAN数据传输采用消息对象进行,需要设置消息对象的标识符、数据长度等参数。可以通过写入对应寄存器来配置发送消息对象的参数。 3. 准备发送数据:将要发送的数据存储在缓冲区中,并将缓冲区的地址传递给发送消息对象的相应寄存器。 4. 发送数据:通过将发送消息对象的相应设置为1来触发发送操作。CAN控制器会将消息对象的数据发送到总线上。 5. 检查发送状态:可以通过读取相应的寄存器来检查发送状态,例如发送成功与否、发送错误等信息。 以上是DSP28335进行CAN数据发送的基本步骤。在实际应用中,还需要根据具体的通信需求进行配置,例如设置波特率、过滤器等。 总的来说,DSP28335可以通过配置寄存器来实现CAN数据发送功能,灵活性高、性能强大,适用于各种CAN通信应用场景。 ### 回答2: DSP28335是一款数字信号处理器,可以通过CAN总线进行数据发送。要在DSP28335上实现CAN数据的发送,首先需要配置CAN控制器的参数。 配置CAN控制器的步骤如下: 1. 设置CAN控制器的时钟源和波特率。可以通过设置寄存器来选择时钟源和配置波特率,以使得CAN控制器与其他设备能够正确通信。 2. 配置CAN控制器的过滤器和屏蔽。过滤器用于过滤接收到的CAN消息,而屏蔽用于屏蔽特定标识符的CAN消息。 3. 配置CAN控制器的发送缓冲区。根据需要,可以配置多个发送缓冲区,并将要发送的数据存储在相应的缓冲区中。 4. 启动CAN控制器。通过设置相应的寄存器,可以启动CAN控制器开始发送数据。 发送CAN数据的步骤如下: 1. 将要发送的数据存储在发送缓冲区中。根据之前配置的发送缓冲区,将需要发送的数据存储在相应的缓冲区中。 2. 配置发送缓冲区的参数。这包括设置数据长度、标识符等信息,以及选择使用的发送缓冲区。 3. 启动数据发送。通过设置相应的寄存器,启动CAN控制器开始发送数据。 4. 检查发送状态。可以通过相应的寄存器来获取发送状态,以判断数据是否发送成功。 5. 根据需要,可以多次重复上述步骤来发送多个CAN数据。 总之,通过配置CAN控制器的参数和发送缓冲区,以及适时的启动数据发送操作,可以在DSP28335上实现CAN数据的发送。 ### 回答3: DSP28335是一款数字信号处理器,它具备CAN(Controller Area Network)通信功能,可以用于数据的发送和接收。 要实现DSP28335的CAN数据发送,首先需要配置CAN控制寄存器,包括波特率、工作模式、中断使能以及数据长度等参数。然后,通过设置CAN发送缓冲区的ID和数据,将待发送的数据写入发送缓冲区。 在数据发送过程中,DSP28335会自动将发送缓冲区中的数据换成CAN总线所需的物理信号,并通过CAN接口发送出去。此外,还可以通过查询CAN状态寄存器来判断数据是否发送成功。 在使用DSP28335进行CAN数据发送时,需要注意以下几点: 1. 确保配置正确的波特率,以与其他CAN节点相匹配。 2. 在发送数据之前,确保发送缓冲区是空的,否则可能会丢失已有数据。 3. 在发送数据后,需要等待一段时间以确保数据已成功发送。如果发送失败,可以通过查询错误寄存器来检查错误原因。 总而言之,通过配置CAN控制寄存器和发送缓冲区,以及合理处理发送过程中的错误,可以在DSP28335上实现CAN数据的有效发送。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值