2098|0

1140

帖子

0

TA的资源

纯净的硅(初级)

楼主
 

DSP 2812 SPI 双机通信 实现 [复制链接]

手上需要两片2812对四个电机进行控制,需要主机向从机发送控制信号,从机向主机发送编码器信息.所以,两机稳定,实时,迅速的通信是很重要的,这里我采用SPI通信 . 虽然是一小段通信代码,也调了很久,TI的东西用的还不是很熟练.其中遇到问题主要有进不去中断,而且数据错位.下面将程序贴下. 两片2812 的SPISOMI,SPISIMO,SPISTEA,SPICLK 互相连接 . 程序中均把引脚功能调为SPI功能.        
  EALLOW;  
   GpioMuxRegs.GPFMUX.bit.SPICLKA_GPIOF2 = 1;
   GpioMuxRegs.GPFMUX.bit.SPISIMOA_GPIOF0 =1;
   GpioMuxRegs.GPFMUX.bit.SPISOMIA_GPIOF1 =1;
   GpioMuxRegs.GPFMUX.bit.SPISTEA_GPIOF3 = 1;           
  EDIS;
复制代码


对于主机SPI初始化,程序如下.开启中断.        
SpiaRegs.SPICCR.all = 0x000F;    //复位,上升沿,16位数据位
        SpiaRegs.SPICTL.all = 0x0007;    //使能主模式,正常相位,开启SPI中断
        SpiaRegs.SPIBRR = 0x007F;        //时钟频率,300k
        SpiaRegs.SPICCR.all = 0x008F;
复制代码
对于从机SPI初始化,和主机一样,不过把SPICTL位2置0;        
SpiaRegs.SPICCR.all = 0x000F;    //复位,上升沿,16位数据位
        SpiaRegs.SPICTL.all = 0x0003;    //使能从模式,正常相位,开启SPI中断
        SpiaRegs.SPIBRR = 0x007F;        //时钟频率,300k
        SpiaRegs.SPICCR.all = 0x008F;      
复制代码
对于主从的主程序,大体上都一样.开启中断,发送数据.注意发送数据时要判断SpiaRegs.SPISTS.bit.BUFFULL_FLAG位的状态.不然会出现数据错位. 判断函数如下:        
unsigned int Spi_TxReady(void)
{
        unsigned int i;
        if(SpiaRegs.SPISTS.bit.BUFFULL_FLAG == 1)
        {
                i = 0;
        }
        else
        {
                i = 1;
        }
        return(i);
}
复制代码
主机写数据函数如下:        
void Write(Uint16 data)
{
        if(Spi_TxReady() == 1)
        {
                SpiaRegs.SPITXBUF = data;        
        }
        while(Spi_TxReady()!=1);
}
复制代码
主函数如下.使用SPI接收中断        
void main(void)
{
        unsigned long int a;
                              //Step1,初始化系统控制
                              //使能相关外设时钟,PLL锁相环备频和WatchDog(看门狗)使用默认设置
        InitSysCtrl();
                                  // Step2,清除所有的中断并初始化PIE中断向量表
                                 
                                  //禁止CPU中断
        DINT;
                                  //并清除所有的CPU中断标志位
        IER = 0x0000;
        IFR = 0x0000;
                              //初始化PIE控制寄存器为默认值,默认值即所有的PIE中断都被禁止切标志位清零
        InitPieCtrl();
                              //初始化PIE中断向量表,并设置当中断发生时,程序会自动跳转到服务程序(ISR)处
        InitPieVectTable();        
                                  //step3,初始化相关外设,本例中主要是将IO设置为外设功能
        InitPeripherals();
        EALLOW;
        PieVectTable.SPIRXINTA = &spiRxIsr;
        EDIS;                                
    IER |= M_INT6;                        
        PieCtrl.PIEIER6.bit.INTx1=1;
    EINT;                                      //Enable INTM
    ERTM;                                          //Enable DBGM
    sdata = 0xA802;
        while(1)
        {
                Write(sdata);
                for(a=0;a<500000;a++);                     
        }
}
复制代码
关键的接收中断函数如下:        
interrupt void spiRxIsr(void)
{
  rdata = SpiaRegs.SPIRXBUF;
  SpiaRegs.SPISTS.bit.OVERRUN_FLAG = 1;
  PieCtrl.PIEACK.bit.ACK6 = 1;  
}
复制代码
对于从机,则在接收中断函数中发送数据回主机.因为SPI时钟只由主机提供.所以从机写数据进主机需要主机向从机提供时钟.例如当主机向从机写0x0030的时候,从机接收中断函数,将所需写入数据写入SpiaRegs.SPITXBUF,实现从机向主机写数据. 从机接收中断函数如下:        
interrupt void spiRxIsr(void)
{
        rdata = SpiaRegs.SPIRXBUF;        
        sdata = rdata;
        Write(sdata);                        
        SpiaRegs.SPISTS.bit.OVERRUN_FLAG = 1;
        PieCtrl.PIEACK.bit.ACK6 = 1;   
}
复制代码

点赞(1) 关注(1)
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表