我想用一个按键中断来改变程序里面的采样率,但是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 可屏蔽中断
{
// 软件断点 方便调试
//SW_BREAKPOINT;
GPIOBankIntDisable(SOC_GPIO_0_REGS, 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 i;
CacheEnableMAR((unsigned int)0xC0000000, (unsigned int)0x8000000);
CacheEnable(L1DCFG_L1DMODE_32K | L1PCFG_L1PMODE_32K | L2CFG_L2MODE_256K);
//初始化的顺序有讲究
// 外设使能配置
PSCInit();
GPIOBankPinMuxSet();
GPIOBankPinInit();
InterruptInit();
GPIOBankPinInterruptInit();
LcdInit();
TouchInit();
//AD8568Init(Fs); ////若GPIO的配置放在采样之后则AD模块失效,显示屏不显示,但是按键中断有效。若放在前面则当按加键进入按键中断是,Fs=0,LCD横坐标显示88888,右下角还显示个p'num.其他正常显示;这中情况可能和内存配置有关
{
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);//
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:
在单步调试的时候,内容显示都是正常的吗?
你的中断函数中处理的内容太多了,不要放太多代码,最好分隔开,建议先将这一部分重新优化一下。