TI中文支持网
TI专业的中文技术问题搜集分享网站

中断映射问题

我想用一个按键中断来改变程序里面的采样率,但是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
            }
….
Nancy Wang:

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.其他正常显示;这中情况可能和内存配置有关

qioa chen:

回复 Nancy Wang:

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

Nancy Wang:

回复 qioa chen:

那可能需要单步调试看看是哪里的问题了。

qioa chen:

回复 Nancy Wang:

    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哥数据后,就画一次波形的。

Nancy Wang:

回复 qioa chen:

AD8568Init 是读取采样数据吗?请问是怎样判断AD转换结束并读取结果的?

qioa chen:

回复 Nancy Wang:

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;*/}

Nancy Wang:

回复 qioa chen:

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

赞(0)
未经允许不得转载:TI中文支持网 » 中断映射问题
分享到: 更多 (0)