本为酱油 发表于 2016-12-9 22:18

DSP28335SCI中断FIFO问题!

DSP要和屏幕通信,SCI方式。单独查询发送的时候没问题,加了中断接收后,DSP发送出去的数据错了,且很多重复数据。接收数据是10个字一包,我用的10级接收FIFO,自己再另建个FIFO,接20个字处理一次。不知道哪里出问题了。代码如下:/****问题是单独发送可以,加了中断接收后,发送出来的数据乱了*********/
#include "DSP28x_Project.h"   // Device Headerfile and Examples Include File
#include "AD7656.h"
#include "math.h"
#include "modbus.h"
#include "control.h"

//===========================================================================
unsigned int check=0,fup=0,fdown=0; int cs; int counter=0; int counter2=0;

void InitEPwmMod(unsigned int lh_freq);                //ePWM模块设置
void InitEPwm6ADC(double f);//AD采样电路出发脉冲生成,f为KHz
interrupt void ADC_Int(void);//AD采样中断函数
interrupt void cpu_timer0_isr(void);//定时器0用于产生定时中断
//interrupt void scibTxFifoIsr(void);
interrupt void sciaRxFifoIsr(void);
void Gpio_select(void);
void protect(void);

void scia_fifo_init(void);
//void scic_fifo_init(void);
//void scib_fifo_init(void);

//unsigned char sdataC;
unsigned char sdataA,sdataB,rdataB,pretc=0;//pretc=0 指示灯绿色 pretc=1 指示灯红色
Uint16 rdata_pointB;                //SCIB接收数据检测
//unsigned int sdataA;
unsigned int sw1=0;
Uint16 i=0,j=0,j1=0,k=0,a=2,b=2;   // Send data for SCI-B
Uint16 lh_1=0,lh_2=0,lh_3=150,lh_4=300,lh_5=300,lh_6=0;//Recive data from SCI-A
unsigned int freq=300,freqt=300,sciRxcounter=0;// Initialization Frequency is 300Hz   unsigned int range 0-65535
void main(void)
{
//      int i=0;
//      Uint16 j=0;
      InitSysCtrl();

      DELAY_US(10000L);
      DELAY_US(10000L);
      DELAY_US(10000L);

   InitEPwm1Gpio();
   InitEPwm2Gpio();

   Gpio_select();
   InitEPwm6Gpio();    //AD_CLOCK
   InitEPwm6ADC(20.0);


//      Configure XINT1
   XIntruptRegs.XINT1CR.bit.POLARITY = 0;      // Falling edge interrupt
   XIntruptRegs.XINT1CR.bit.ENABLE = 1;                //      Enable XINT1
   asm("NOP");
   GpioDataRegs.GPBCLEAR.bit.GPIO60=1;

   InitXintf();
   InitSciGpio();

   DINT;

   InitPieCtrl();

   IER = 0x0000;
   IFR = 0x0000;
   InitPieVectTable();

   EALLOW;// This is needed to write to EALLOW protected registers
   PieVectTable.TINT0 = &cpu_timer0_isr;
   EDIS;

   EALLOW;// This is needed to write to EALLOW protected registers
   PieVectTable.SCIRXINTA = &sciaRxFifoIsr;
//   PieVectTable.SCITXINTA = &sciaTxFifoIsr;
   EDIS;

   EALLOW;      //This is needed to write to EALLOW protected registers
   PieVectTable.XINT1 = &ADC_Int;//Set XINT1 in PIE
   EDIS;    //This is needed to disable write to EALLOW protected registers

   EALLOW;
   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
   EDIS;

//   InitEPwmMod();
//   freq=300;   //Initialization output PWM 300Hz
   InitEPwmMod(freq);

   EALLOW;
   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
   EDIS;
         
   InitCpuTimers();//初始化时钟
//   ConfigCpuTimer(&CpuTimer0, 15000, 100000);//定时器0定时10s中断一次
   ConfigCpuTimer(&CpuTimer0, 15000, 100000);
   CpuTimer0Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0
   CpuTimer0.InterruptCount = 0;   //计数初值为0

   PieCtrlRegs.PIECTRL.bit.ENPIE = 1;//使能PIE模块
   PieCtrlRegs.PIEIER9.bit.INTx1 = 1;//PIE: Group 9 interrupt 1 SCI-A 接收中断
// PieCtrlRegs.PIEIER9.bit.INTx2 = 1;//PIE: Group 9 interrupt 2 SCI-A 发送中断
   PieCtrlRegs.PIEIER1.bit.INTx4 = 1;//Enable INTn in the PIE: Group 1 interrupt 4
   PieCtrlRegs.PIEIER1.bit.INTx7 = 1;// Enable TINT0 in the PIE: Group 1 interrupt 7
   IER |= M_INT1;//Enable CPU INT1;
   IER |= M_INT9;//Enable CPU INT1;
      scia_fifo_init();   
//    scib_fifo_init();   // Init SCI-A B C
//      scic_fifo_init();

   EINT;   // Enable Global interrupt INTM
   ERTM;   // Enable Global realtime interrupt DBGM
for(i=0;i<40;i++)
{
      sdataA=sdataB=rdataB=0x00;      
}
for(;;)
//--------------------传送数据至上位机--------------------
      {
    sdataB=0x03;
      sdataB=0x06;
      sdataB=0x02;
      sdataB=00;            //01:16位数据高8位(人为设定地址位)
    sdataB=Ig;//电压信号   //01:16位数据低8位(人为设定地址位)
    //sdataB=100;
    sdataB=00;               //02高8位
    sdataB=freq*0.5; // 工作频率   02低8位
    //sdataB=300*0.5;
      sdataB=00;            //03高8位
      sdataB=pretc; //03低8位
    //sdataB=1;
      sdataB=00;            //04高8位
      sdataB=Ib;//04低8位
      check=CRC16(sdataB,11);//CRC校验,check是16位,故应右移8位
      sdataB=(check>>8)&(0x00FF);
      sdataB=check&0x00FF;

      freq=freqt;
      if(sciRxcounter == 2)
      {
                /*******以下6句共用于禁止SCI-A接收中断*************/
                DINT;//禁止全局中断INTM = 1
                PieCtrlRegs.PIEIER9.bit.INTx1 = 0;//0-禁止接收中断   1-允许接收中断
      for(lh_6=30;lh_6<35;lh_6++)   sdataA = rdataB;//5个空周期
                PieCtrlRegs.PIEIFR9.bit.INTx1 = 0;//清除外设中断位
                PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;//清除ACK位
                EINT;//使能全局中断INTM = 0
                /*******以上6句共用于禁止SCI-A接收中断*************/
               
                for(lh_6=0;lh_6<20;lh_6++)                sdataA = rdataB;//取回FIFO里的20个数据
                for(lh_6=0;lh_6<20;lh_6++)
                {
                        if(sdataA == 0x06)
                        {
                              lh_3 =         sdataA;      //取回来数据是100-250,表示200-500
                              lh_4 = lh_3*2;      //数据回归到200-500
                        }
                }
                freqt = lh_4;   //屏幕发回来的真实想要数值
                if((freqt<501) && (freqt>199))
                {      
                        if(freq != freqt)
                        {
                              lh_5 = freqt;
                              InitEPwmMod(freqt);      
                        }
                }
                sciRxcounter =0;
      }
      DELAY_US(10000L);   // it need to commented out for Frequence changes
      /*发送数据正常应该是03 02 06 00 Ig 00 Freq 00 pretc 00 Ib CRC CRC共13个字*/
      /* 其中Freq 根据串口接收到的值改变*/
      for(i=0;i<13;i++)
          {
         SciaRegs.SCITXBUF=sdataB;//SCITXBUF:SCIB发送器数据缓冲寄存器
      }         
      PieCtrlRegs.PIEIER9.bit.INTx1 = 1; //0-禁止接收中断   1-允许接收中断
    }   
}

interrupt void ADC_Int(void)
{
      unsigned int i;
//      unsigned int fcnum,freq;
    //f is 20KHz 1 interrupt =0.05ms10ms for key action once
    //counter num = 10/0.05         =200

      for(i=0;i<7;i++)
      {
                SampleTable= * AD_CHIPSEL;
      }
      GpioDataRegs.GPASET.bit.GPIO0=1;

      Ug= (SampleTable+10) * 0.000305176;//Ug
      Ia= (SampleTable-20) * 0.000305176* 11.11111;//Ia
      XIntruptRegs.XINT1CR.bit.ENABLE = 1;
      PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Enable to receive more interrupts from PIE1
      GpioDataRegs.GPACLEAR.bit.GPIO0=1;
      protect();
      }

interrupt void sciaRxFifoIsr(void)
      {
      //      unsigned intlh_i;
            if(sciRxcounter == 0)
                {
                        for(lh_2=0;lh_2<10;lh_2++)
                              {
                                        rdataB = (SciaRegs.SCIRXBUF.all) & 0x00FF;      //读取数据
                              }
                }
                if(sciRxcounter == 1)
                {
                        //sciRxcounter =0;
                        for(lh_2=10;lh_2<20;lh_2++)
                              {
                                        rdataB = (SciaRegs.SCIRXBUF.all) & 0x00FF;      //读取数据
                              }
                }
                sciRxcounter++;
                /*正常收到的一组数据应该为06 FF FF FF FF 00 98 E7 5E 11 */

                SciaRegs.SCIFFRX.bit.RXFFOVRCLR = 1;                //清除溢出标志位
                SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1;                //清除中断标注位
                SciaRegs.SCIFFTX.bit.TXFFINTCLR = 1;
                PieCtrlRegs.PIEACK.all |= 0x100;      
      }


void scia_fifo_init()
{
   SciaRegs.SCICCR.all =0x0007;    // 1 stop bit,No loopback
                                 // No parity,8 char bits,
                                 // async mode, idle-line protocol
   SciaRegs.SCICTL1.all =0x0003;   // enable TX, RX, internal SCICLK,
                                 // Disable RX ERR, SLEEP, TXWAKE
   SciaRegs.SCICTL2.bit.TXINTENA =1;//使能发送中断
   SciaRegs.SCICTL2.bit.RXBKINTENA =1;//使能接收中断
   SciaRegs.SCIHBAUD    =0x0003; //这两个值根据LSPCLK决定,LOSPCP来决定LSPCLK 现在LOSPCP=0,所以LSPCLK=SYSCLK/1 即150MHZ;
   SciaRegs.SCILBAUD    =0x00D0;//SCI_PRD;波特率为19200--3D0
   SciaRegs.SCICCR.bit.LOOPBKENA =0; // 1-Enable 0-disable loop back
   SciaRegs.SCIFFTX.all=0xCD28;// 发送FIFO有13个字
   SciaRegs.SCIFFRX.all=0x0A21;// 接收FIFO有10个字
   SciaRegs.SCIFFCT.all=0x00;

   SciaRegs.SCICTL1.all =0x0023;   // Relinquish SCI from Reset
   SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1;
   SciaRegs.SCIFFRX.bit.RXFIFORESET=1;
}




//--------------------------------------------------------------------------
//------------------------------NO MORE--------------------------------
//--------------------------------------------------------------------------

JY-DX-JY 发表于 2016-12-12 15:08

我觉得你还是先把SCI模块中断接收单独调好,再把屏幕功能加上比较好

hong7817 发表于 2016-12-19 21:08

没耐心看这么长的代码

JUST1 发表于 2020-2-20 18:25

问题解决没有?
页: [1]
查看完整版本: DSP28335SCI中断FIFO问题!