打印
[DSP编程]

有关2812 SCI模块通信的问题

[复制链接]
3922|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
raoxianbin|  楼主 | 2013-10-18 15:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请问各位,关于2812串行通信SCI模块,如果定义的通信协议是八位数据位,无校验位的情况下,为什么在查询模式下实现通信的话,必须遵行相应的通信协议(即比如发7位数据,就不能实现通信),但是为什么当使用中断实现通信的时候,就不用遵行相应的通信协议呢,就是说发几位都可以实现通信。

麻烦各位帮忙解答一下,谢谢!

相关帖子

沙发
pinda_| | 2013-10-18 16:12 | 只看该作者
你的中断发送与中断接收优先级的寄存器怎么设置的?

使用特权

评论回复
板凳
raoxianbin|  楼主 | 2013-10-18 16:34 | 只看该作者
pinda_ 发表于 2013-10-18 16:12
你的中断发送与中断接收优先级的寄存器怎么设置的?

和这有关系吗,我没配置这些啊,也就是默认的收(INTX.1)高于发(INTx.2)

使用特权

评论回复
地板
zhangmangui| | 2013-10-18 17:04 | 只看该作者
你说的查询模式是什么啊   
查询模式一般是指查询接收中断标志位是否置位  
也就是不进入中断而已  
中断可以 查询也应该可以的

使用特权

评论回复
5
raoxianbin|  楼主 | 2013-10-18 17:13 | 只看该作者
zhangmangui 发表于 2013-10-18 17:04
你说的查询模式是什么啊   
查询模式一般是指查询接收中断标志位是否置位  
也就是不进入中断而已  


我这的查询就是通过查询它的接收和发送标志位例如下面的程序
        for(;;)
        {
               
                /*查询方式实现发送功能*/
                if((SciaTx_Ready() == 1) && (Send_Flag == 1)) //发送准备已经就绪而且有数据需要发送
                {
                        SciaRegs.SCITXBUF = Sci_VarRx; //发送数据
                        Send_Flag = 0;  //清标志位
                        i++;
                        if(i == 100)
                        {
                                i = 0;
                        }
                }
            
            /*查询方式实现接收功能*/
        if(SciaRx_Ready() == 1) //接收数据准备已经就绪
                {
                        Sci_VarRx = SciaRegs.SCIRXBUF.all;  //接收数据
                        Send_Flag = 1;  //标志位置位,有数据等待发送
                }

        }



其中的SCIatx_Ready函数是:
int SciaTx_Ready(void)
{
        unsigned int i;
        if(SciaRegs.SCICTL2.bit.TXRDY == 1)
        {
                i = 1;
        }
        else
        {
                i = 0;
        }
        return(i);
}
简单的说就是查询相应的标志位,我就发现通过串口调试的时候,它必须遵行相应的通信模式,即必须发送的事8个字符或数字

但是若果我用SCI中断实现的时候,就可以随便发送几个数据,都能接收

就是这个地方不是很理解,谢谢斑竹解答一下。。。

使用特权

评论回复
6
raoxianbin|  楼主 | 2013-10-18 17:54 | 只看该作者
pinda_ 发表于 2013-10-18 17:38
SCIFFTX.bit.TXFFILIL 和   SCIFFRX.bit.RXFFIL  

这两个寄存器位表示进行中断的条件,假设

恩  我大概知道您的意思 但是我所指的中断也是在标准的SCI模式下,没有采用FIFO模式啊   但是它还是不用遵循8位数据的通信协议啊,麻烦您再帮忙解答一下,谢谢。。
还有有个地方我不是很理解  就是在存数据的时候  Sci_VarRx = SciaRegs.SCIRXBUF.all;  //接收数据   如果我所定义的数组unsigned  int  Sci_VarRx [100]     经过上面这条语句的话,是把SciaRegs.SCIRXBUF.all 中的所有数据都存在SCI_VarRx[0](假设此时的i值为零),还是一位一位的存在在整个数组中?即每个值分别存在SCI_VarRx[0]~SCI_VarRx[7]中呢     我通过CCS观察,它的结果是第二种情况,即分别存储的,但是我的疑问就是按理说,貌似这个一个数组的一位(例如SCI_VarRx[0])是可以把所有的数据都存下的啊,实现分开存储的原因是什么啊   是因为计算机串口发送的数据是一位一位的吗?  还是什么    说的有点乱     不知道表达清楚没   呵呵

使用特权

评论回复
7
zhangmangui| | 2013-10-18 18:16 | 只看该作者
raoxianbin 发表于 2013-10-18 17:13
我这的查询就是通过查询它的接收和发送标志位例如下面的程序
        for(;;)
        {

你说的用SCI实现是指用用收发中断吗  通信格式肯定是用遵守的  
数据格式的8位指的是一个字节的   发送字符和数字最终都是ascii码
看了你的查询代码   没什么问题

使用特权

评论回复
8
raoxianbin|  楼主 | 2013-10-18 18:42 | 只看该作者
本帖最后由 raoxianbin 于 2013-10-18 18:43 编辑
zhangmangui 发表于 2013-10-18 18:16
你说的用SCI实现是指用用收发中断吗  通信格式肯定是用遵守的  
数据格式的8位指的是一个字节的   发送字 ...


en   是的  用的收发中断
中断代码如下:

interrupt void SCIRXINTA_ISR(void)     
  {
                        if((SciaRx_Ready() == 1)
          {Sci_VarRx = SciaRegs.SCIRXBUF.all; //接收数据        
                 Send_Flag=1; //有数据需要发送,置位标志

            if((SciaTx_Ready() == 1)
        {
            SciaRegs.SCITXBUF=Sci_VarRx; //启动第一次发送,然后才能使用发送中断
         
        }
        }
    PieCtrl.PIEACK.all=0x0100;  //使得同组其他中断能够得到响应
    EINT;  //开全局中断vcc

}

/****************************************************************************
*
*名    称:SCITXINTA_ISR()
*
*功    能:发送中断函数
*
*入口参数:无
*
*出口参数:无
*
****************************************************************************/

interrupt void SCITXINTA_ISR(void)     
{
   if(Send_Flag==1)
   {

       i++;

           if(i==100)
           {
              i=0;
           }
Send_Flag=0;
        }
   
    PieCtrl.PIEACK.all=0x0100;  //使得同组其他中断能够得到响应
    EINT;  //开全局中断
   
    //SCITXBUF中的数据移入TXSHF寄存器,将数据发送出去,TXRDY标志位置1
}


关于您说的“数据格式的8位指的是一个字节的 ”  我好像有点思路了   能麻烦您说的再详细一点吗  、、

我最不能理解的就是不知道为什么在这么模式下就能单独发送比如数字“1”  而在查询模式就不能能  
谢谢!

使用特权

评论回复
9
raoxianbin|  楼主 | 2013-10-18 18:49 | 只看该作者
本帖最后由 raoxianbin 于 2013-10-18 19:18 编辑
zhangmangui 发表于 2013-10-18 18:16
你说的用SCI实现是指用用收发中断吗  通信格式肯定是用遵守的  
数据格式的8位指的是一个字节的   发送字 ...


最终是ASCII码,不错,通信协议设置的字符长度为8位      


版主,那如果我把它设置为字符长度为6位呢? 即SciaRegs.SCICCR.bit.SCICHAR=5;  那如果我发送一个数据,例如“1” 它转换为ASCII   即0011 0001   那它会出现什么情况啊   是丢失,还是就是直接不符合通信协议呢   

使用特权

评论回复
10
pinda_| | 2013-10-18 19:33 | 只看该作者
raoxianbin 发表于 2013-10-18 17:54
恩  我大概知道您的意思 但是我所指的中断也是在标准的SCI模式下,没有采用FIFO模式啊   但是它还是不用 ...

(1)关于SCICHAR的说明:
          SCICCR.bit.SCICHAR仅仅只是用来控制接收字符长度的,这里,假设,A、B两端进行通信,A发送一个字节长度的数据给B,B接收到的数据就要根据字符长度来判断到底该取几位,结果按右对齐。
(2)关于不用遵循8位数据的通信协议的解释:
          在SCI中SCIRXBUF存在16级深度,也就是说一次最多能接收16个字节的数据,SCI控制器会自动进行收发处理(这里,我的理解是SCI属于低速设备,在大数据传输环境中,一般难以实现一传一收,再实现对应功能的时序控制,所以,有时候,我们在测试调试的时候,往往只采用少量的数据,结果,对一些复杂的问题就难以说明其根据性)。
(3)关于取数据存储的问题:
          我无法提供身边的例子,就直接按你的代码来说明。
          for(;;)
          {
                  if(SciaRx_Ready() == 1) //接收数据准备已经就绪
                  {
                        Sci_VarRx = SciaRegs.SCIRXBUF.all;  //接收数据
                        Send_Flag = 1;  //标志位置位,有数据等待发送
                  }
          }
        
          以上这个程序,将不断的将接收到的数据存入Sci_VarRx[0]中,无法实现实际意义。更改方法:
          int  i;
          for(;;)
          {
                  if(SciaRx_Ready() == 1) //接收数据准备已经就绪
                  {
                        Sci_VarRx = SciaRegs.SCIRXBUF.all;  //接收数据
                        Send_Flag = 1;  //标志位置位,有数据等待发送
                        i++;
                  }
          }
          以上,就可以将N个数据放入数组Sci_VarRx中。
         
          同理,中断中的实现方法是:
          int i;
          for(i = 0; i < 8; i++)
          {
                    Sci_VarRx = SciaRegs.SCIRXBUF.all;
           }
          以上是在每次发送8个字节数据下,实现的方法,实际情况实际考虑。

          至于你的理解:
               SCI_VarRx = SciaRegs.SCIRXBUF.all;
          那么SCI_VarRx是如何移位的?BUF中是每取一个字节的数据,后面的数据就会自动移到最上面,形成一个移位的环。

          不知道说的对不对,有什么错误,望解答。
         

使用特权

评论回复
评分
参与人数 1威望 +6 收起 理由
zhangmangui + 6 赞一个!
11
raoxianbin|  楼主 | 2013-10-18 20:25 | 只看该作者
pinda_ 发表于 2013-10-18 19:33
(1)关于SCICHAR的说明:
          SCICCR.bit.SCICHAR仅仅只是用来控制接收字符长度的,这里,假设,A ...

EN  谢谢你  我再理解一下  

使用特权

评论回复
12
zhangmangui| | 2013-10-18 23:26 | 只看该作者
raoxianbin 发表于 2013-10-18 20:25
EN  谢谢你  我再理解一下

嗯   楼上解释的很全面

使用特权

评论回复
13
raoxianbin|  楼主 | 2013-10-19 09:26 | 只看该作者
pinda_ 发表于 2013-10-18 19:33
(1)关于SCICHAR的说明:
          SCICCR.bit.SCICHAR仅仅只是用来控制接收字符长度的,这里,假设,A ...

你好  麻烦再问一下,所谓的接收缓存寄存器的就绪标志位RXRDY 置位,即有八位的数据并行移入SCIRXBUF  
这的“8位”是指转换后的ASCII吗   就是说例如每个字符转换后的2进制数    就是说是不是每个字符移入SCIRXBUF后是不是都会将RXRDY置位,例如发送"HELLODDO"这八个字符就被置位8次

使用特权

评论回复
14
raoxianbin|  楼主 | 2013-10-19 09:27 | 只看该作者
zhangmangui 发表于 2013-10-18 23:26
嗯   楼上解释的很全面

你好  麻烦再问一下,所谓的接收缓存寄存器的就绪标志位RXRDY 置位,即有八位的数据并行移入SCIRXBUF  
这的“8位”是指转换后的ASCII吗   就是说例如每个字符转换后的2进制数    就是说是不是每个字符移入SCIRXBUF后是不是都会将RXRDY置位,例如发送"HELLODDO"这八个字符就被置位8次

使用特权

评论回复
15
zhangmangui| | 2013-10-19 11:17 | 只看该作者
raoxianbin 发表于 2013-10-19 09:27
你好  麻烦再问一下,所谓的接收缓存寄存器的就绪标志位RXRDY 置位,即有八位的数据并行移入SCIRXBUF  
...

准备就绪就是指一个字节已经收到  可以读取   
嗯  你说的字符串是要置位8为  8个字节

使用特权

评论回复
16
pinda_| | 2013-10-19 12:21 | 只看该作者
raoxianbin 发表于 2013-10-19 09:26
你好  麻烦再问一下,所谓的接收缓存寄存器的就绪标志位RXRDY 置位,即有八位的数据并行移入SCIRXBUF  
...

不太看的懂你的描述。

我想你的意思应该是RXRDY与SCIRXBUF之间的关系怎么样……

首先,需要明白的是标准SCI,我们一般采用空闲线模式,而空闲线模式的每一帧的帧格式为

               起始位|LSB|2|3|4|5|6|7|MSB|奇/偶/极性|结束位

之前已经说过,SCICHAR表示的是从该帧中取几位数据出来,结果右对齐。那么,每次移动,只是移动一帧,移动帧内多少位由SCICHAR决定。至于SCI中保存的是什么类型的数据,一般,我们采用的unsigned char数据类型来取值,表示把每一帧的八位数据放入该变量中。

至于第二点“是不是每个字符移入SCIRXBUF后是不是都会将RXRDY置位”。
        从DATASHEET上说明的是 从SCIRXBUF读取一个字符后,RXRDY才会置位。而不是从RXSHF移入SCIRXBUF,就将对应的RXRDY置位。

建议,再仔细看一下SCI的手册,特别关注下SCIRXST寄存器的说明与SCI中断标志和中断全能逻辑那幅图。

不知道说的对不对,有什么错误,望解答。
(下午不在。)

使用特权

评论回复
17
raoxianbin|  楼主 | 2013-10-19 13:53 | 只看该作者
本帖最后由 raoxianbin 于 2013-10-19 14:07 编辑
pinda_ 发表于 2013-10-19 12:21
不太看的懂你的描述。

我想你的意思应该是RXRDY与SCIRXBUF之间的关系怎么样……


en   很感谢你一直为我解答
下面是我的一段查询模式的代码
麻烦您帮我看看有什么不对的地方吗?
我没实现相应的功能
谢谢!



#include   "DSP28_Device.h"
#include    "DSP28_Globalprototypes.h"

unsigned int N=8;
float  adc[16];//用于存储ADC的转换结果
float  adcl0;
unsigned  int Sci_varRx[100];
unsigned int i;
unsigned int Send_Flag;
unsigned int j;
int SciaRx_Ready(void);
int SciaTx_Ready(void);
void  delay (void);


void main(void)
{

InitSysCtrl();
DINT;
IER=0x0000;
IFR=0x0000;
InitPieCtrl();
InitPieVectTable();    //初始化PIE模块中的CPU定时器0的中断
InitSci();
InitGpio();
   for(j=0;j<100;j++)
  {
        Sci_varRx[j]=0;
  
  
  }
  j=0;
  Send_Flag=0;

  while(1)
{   

if((SciaTx_Ready()==1)&&(Send_Flag==1))
{
        while(j<N)
         {
         if(SciaRegs.SCICTL2.bit.TXRDY==1)
         {
        SciaRegs.SCITXBUF=Sci_varRx[j];        
                j++;
         }
        
        }
        Send_Flag=0;
        j=0;

}
if(SciaRx_Ready()==1)
{
        Sci_varRx[j]=SciaRegs.SCIRXBUF.all;
                j++;
        

        if(j==N)
        {
              j=0;
         Send_Flag=1;
        }
}








}



}





   void delay (void)
   {
        short i;
        for(i=0;i<10000;i++)
        {}
}





  int SciaTx_Ready(void)
        {
                unsigned  int i;
                if(SciaRegs.SCICTL2.bit.TXRDY==1)
                {
                        i=1;
               
               
                }
         else
         {
                i=0;
         
         
         
         }
        return(i);
        }



        int SciaRx_Ready(void)
        {
                     unsigned int i;
                        if(SciaRegs.SCIRXST.bit.RXRDY==1)
                                {
                                        i=1;
                                
                                
                                }
                                else
                                {
                                        i=0;
                                
                                
                                
                                }
                                return(i);

}

使用特权

评论回复
18
raoxianbin|  楼主 | 2013-10-19 14:39 | 只看该作者
调试出来了,是由于工程中涉及到东西有点多了,不小心把的I/O整错了,谢谢上面两位大哥的指导,谢谢!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

36

主题

244

帖子

1

粉丝