This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

中断映射问题

我想用一个按键中断来改变程序里面的采样率,但是ADC里面有一个定时器中断,原始例程里面的按键GPIO中断和定时器中断映射到了同一个可屏蔽中断,

GPIO的引脚中断初始化为:

IntRegister(C674X_MASK_INT4, USER0KEYIsr);   //注册中断服务函数

IntEventMap(C674X_MASK_INT4, SYS_INT_GPIO_B0INT); // 映射中断到 DSP 可屏蔽中断

实验结果是按键无效,所以我想将GPIO的中断映射到其它可屏蔽中断去,就将上面的改为

IntRegister(C674X_MASK_INT7, USER0KEYIsr);   //注册中断服务函数

IntEventMap(C674X_MASK_INT7, SYS_INT_GPIO_B0INT); // 映射中断到 DSP 可屏蔽中断

void USER0KEYIsr(void)
{
    // 软件断点 方便调试
    //SW_BREAKPOINT;
    // 禁用 GPIO BANK 0 中断
    GPIOBankIntDisable(SOC_GPIO_0_REGS, 0);
    // 清除 GPIO BANK 0 中断状态
    IntEventClear(SYS_INT_GPIO_B0INT);
   // unsigned int i;
    if(GPIOPinIntStatus(SOC_GPIO_0_REGS, 7) == GPIO_INT_PEND)
    {
        // 清除 GPIO0[6] 中断状态
        GPIOPinIntClear(SOC_GPIO_0_REGS, 7);
        Flag_gpio_key=1;
        Fs=Fs*2;
    }
    // 使能 GPIO BANK 0 中断
    GPIOBankIntEnable(SOC_GPIO_0_REGS, 0);
}

调试的时候发现按键有效了,但是从调试的变量观察力读到的采样率Fs和主程序里面读到的Fs不一样(通过显示在LCD屏幕上),调试器观察到的Fs减半而LCD显示的不变。请问除了在注册中断服务函数的时候改变C674X_MASK_INT7,还要改变其它的东西吗。

int main(void)
{
 int i;
 //使能缓存
 CacheEnableMAR((unsigned int)0xC0000000, (unsigned int)0x8000000);
 CacheEnable(L1DCFG_L1DMODE_32K | L1PCFG_L1PMODE_32K | L2CFG_L2MODE_256K);
//初始化的顺序有讲究
  // 外设使能配置
    PSCInit();
    // GPIO 管脚复用配置
    GPIOBankPinMuxSet();
    // GPIO 管脚初始化
    GPIOBankPinInit();
    // DSP 中断初始化
    InterruptInit();
    // GPIO 管脚中断初始化
    GPIOBankPinInterruptInit();
    //初始化LCD   //这两个模块放在后面则是原来的正常显示,按键无效,放在GPIO配置前就会出现下面那条注释情况
    LcdInit();
    // 触摸屏初始化
    TouchInit();

 // AD8568 初始化 采样率510K
 //AD8568Init(Fs);           ////若GPIO的配置放在采样之后则AD模块失效,显示屏不显示,但是按键中断有效。若放在前面则当按加键进入按键中断是,Fs=0,LCD横坐标显示88888,右下角还显示个p'num.其他正常显示;这中情况可能和内存配置有关

 while(1)
 {
     if(Flag_gpio_key==1||Flag_gpio_key==2)                           //循环点亮LED灯
        {
            // 核心板 LED
            for(i=0x00FFFFFF;i>0;i--);                         
            GPIOPinWrite(SOC_GPIO_0_REGS, 3, GPIO_PIN_LOW);  //
            GPIOPinWrite(SOC_GPIO_0_REGS, 1, GPIO_PIN_HIGH);//
            for(i=0x00FFFFFF;i>0;i--);                         
            GPIOPinWrite(SOC_GPIO_0_REGS, 3, GPIO_PIN_HIGH);//
            GPIOPinWrite(SOC_GPIO_0_REGS, 1, GPIO_PIN_LOW);//
        }
     AD8568Init(Fs);
        if(display_count >= Tn)
        {
            flag_parm_display++;
            Grline(1,1,10);
            if(!(flag_parm_display%1))                //参数变化的显示刷新频率降低30倍
            {
                //sprintf(freq_max_display,"freq_max= %d Hz",getF.key);
                //sprintf(p_num_display,"p_num= %d ",getF.p_num);       //标准化输出,不能习惯性用%d
                //sprintf(freq_base_display,"freq_base= %d Hz",getF.freq_base/*/(getF.p_num-1)*/);
                sprintf(SMI_amp_display,"mainFreq=%d Hz",getF.key);         //SMI_amp
                sprintf(Cmo_max_display,"Fs=%d V",Fs);               //getF.value
            }
....
  • qioa chen 说:

    调试的时候发现按键有效了,但是从调试的变量观察力读到的采样率Fs和主程序里面读到的Fs不一样(通过显示在LCD屏幕上),调试器观察到的Fs减半而LCD显示的不变。请问除了在注册中断服务函数的时候改变C674X_MASK_INT7,还要改变其它的东西吗。

    按键有效能进入中断服务函数说明中断配置成功,不需要再配置其他的。

    请问你的意思是中断服务函数中的Fs=Fs*2没有生效?才会导致调试窗口的变量值和LCD显示值不一样?

    qioa chen 说:
    int main(void)
    {
     int i;
     //使能缓存
     CacheEnableMAR((unsigned int)0xC0000000, (unsigned int)0x8000000);
     CacheEnable(L1DCFG_L1DMODE_32K | L1PCFG_L1PMODE_32K | L2CFG_L2MODE_256K);
    //初始化的顺序有讲究
      // 外设使能配置
        PSCInit();
        // GPIO 管脚复用配置
        GPIOBankPinMuxSet();
        // GPIO 管脚初始化
        GPIOBankPinInit();
        // DSP 中断初始化
        InterruptInit();
        // GPIO 管脚中断初始化
        GPIOBankPinInterruptInit();
        //初始化LCD   //这两个模块放在后面则是原来的正常显示,按键无效,放在GPIO配置前就会出现下面那条注释情况
        LcdInit();
        // 触摸屏初始化
        TouchInit();

     // AD8568 初始化 采样率510K
     //AD8568Init(Fs);           ////若GPIO的配置放在采样之后则AD模块失效,显示屏不显示,但是按键中断有效。若放在前面则当按加键进入按键中断是,Fs=0,LCD横坐标显示88888,右下角还显示个p'num.其他正常显示;这中情况可能和内存配置有关

    这边看起来像是LCD和GPIO管脚使用冲突,查查原理图看看是不是存在引脚复用的问题。

  • 您好。有趣的是,当按键改变采样率从小于8192,往上翻倍是,调试窗口的变量显示Fs和LCD上显示的是一样的,只不过LCD上面改变的慢一点,但是数值从高往下调到8192,再往下调,调试窗口的Fs是会跟着按键相应改变,而LCD显示却不再改变

  • 那可能需要单步调试看看是哪里的问题了。
  •     while(1)
        {       

         if(Flag_gpio_key==1)
            {
                // 核心板 LED
                for(i=0x00FFFFFF;i>0;i--);                          // 延时


                for(i=0x00FFFFFF;i>0;i--);                          // 延时
              
            }

          
            AD8568Init(Fs);

    //原因找到了 ,目的是想做一个频谱仪,所以想通过两个按键来动态改变采样率Fs,原因出在   AD8568Init(Fs)前面必须要加上延时     for(i=0x00FFFFFF;i>0;i--);   否则将会出现当按键改变采样率大于采样点数Tn时,品目会一直刷新,且采样得到的数据全为0,继续加大采样率采样得到的正常波形(疑惑);当采样率下降到小于等于Tn时,屏幕不刷新,采样得到的数据全为0。请问为什么在主程序里面要加延迟呢;另外当加上延迟,显示正常后,我增大采样率后,屏幕的刷新速度反而降低,这也很奇怪,按理说应该加快才对。我是采集Tn哥数据后,就画一次波形的。

  • AD8568Init 是读取采样数据吗?请问是怎样判断AD转换结束并读取结果的?
  • void AD8568Init(unsigned int SamplingRate)                                         //#########################
    {
        // GPIO 管脚复用配置
        GPIOPinMuxSetup();

        // 定时器 / 计数器初始化
        if(SamplingRate > 510000) SamplingRate = 510000;
        TMR_PERIOD_LSB32 = 228000000/SamplingRate;      //决定定时器每隔多少个时钟周期进行一次中断也就是计数器从0记到TMR_PERIOD_LSB32后从新开始计数
        TimerInit(TMR_PERIOD_LSB32);

        //定时器 / 计数器中断初始化
        TimerInterruptInit();

        // AD8568  IO初始化
        AD8568GPIOInit();

        // EMIF 初始化
        EMIFAInit();

        AD8568Reset();

        // 使能REF,设置量程为+-12V
        AD8568_WriteReg(AD8568_WRITE_ENABLE    | AD8568_REF_ENABLE |
                        AD8568_REF_SET3V | AD8568_REFDAC_FULL);
    }

    //数据的采集在定时器中断里面,采集800个点以后就拿去画图形。

    void TimerIsr(void)                                                                     //*##########################
    {
        // 清除中断标志
        IntEventClear(SYS_INT_T64P2_TINTALL);

        TimerIntStatusClear(SOC_TMR_2_REGS, TMR_INT_TMR12_NON_CAPT_MODE);

        //启动AD8568转换
        AD8568Start();


        if(display_count <Tn)
        {
            emif_rbuffer[0] = ((short *)SOC_EMIFA_CS2_ADDR)[1];
            emif_rbuffer[1] = ((short *)SOC_EMIFA_CS2_ADDR)[2];
            emif_rbuffer[2] = ((short *)SOC_EMIFA_CS2_ADDR)[3];
            emif_rbuffer[3] = ((short *)SOC_EMIFA_CS2_ADDR)[4];
            emif_rbuffer[4] = ((short *)SOC_EMIFA_CS2_ADDR)[5];
            emif_rbuffer[5] = ((short *)SOC_EMIFA_CS2_ADDR)[6];
            emif_rbuffer[6] = ((short *)SOC_EMIFA_CS2_ADDR)[7];
            emif_rbuffer[7] = ((short *)SOC_EMIFA_CS2_ADDR)[8];

            //在滴4个通道采集二次谐波电压值
            if(emif_rbuffer[3] < 32768){
                    emif3[j] = (float)emif_rbuffer[3]*12/32768;    //float  emif[Tn]是将采集到的电压数字量转为实际的电压值
                    display_secHarmonic[NewDisBuf][display_count] = 350 - secHarmAmp*emif_rbuffer[3]/100;       //160         //调波形显示的幅度
             }
            else{
                    emif3[j] =(float) -((65536-emif_rbuffer[3])*12)/32768;//采样参考电压为12V
                    display_secHarmonic[NewDisBuf][display_count] = 350 + secHarmAmp*(65536-emif_rbuffer[3])/100;
             }
            display_count++;
            j++;
            if(j>=Tn) j=0;
        }

        /*else
            display_count=0;*/
    }

  • 在单步调试的时候,内容显示都是正常的吗?
    你的中断函数中处理的内容太多了,不要放太多代码,最好分隔开,建议先将这一部分重新优化一下。