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.
您好!
我们正在尝试实现一种算法、在该算法中、只要触发 XINT1、就会根据 EPWM1触发器对 ADC 进行周期性采样。
我们希望实现具有50%占空比的2MHz PWM、以实现快速 ADC 采样。
XINT_ISR 被触发、但映射到 EPWM1上触发的 ADC_ISR (上计数/下计数)不会被触发。
请根据以下代码提供建议。 谢谢!!
void system_init (void) { volatile int status = false; volatile file *fid; //初始化此应用程序所需的所有句柄 myAdc = ADC_init ((void *) ADC_base_ADDR、sizeof (ADC_Obj)); myClk = CLK_init ((void *) CLK_base_ADDR、sizeof (CLK_Obj)); myCpu = cpu_init ((void *) NULL、sizeof (cpu_Obj)); myFlash = flash_init ((void *) flash_base_ADDR、sizeof (flash_Obj)); myGpio = GPIO_init ((void *) GPIO_base_ADDR、sizeof (GPIO_Obj)); myPie = PI_init ((void *) PIE_BASE_ADDR、sizeof (PIE_Obj)); myPll = PLL_init ((void *) PLL_base_ADDR、sizeof (PLL_Obj)); mySci = SCI_init ((void *) SCIA_BASE_ADDR、sizeof (SCI_Obj)); myWdDog = WDOG_INIT ((void *) WDOG_BASE_ADDR、sizeof (WDOG_Obj)); mySpi = SPI_init ((void *) SPIA_BASE_ADDR、sizeof (SPI_Obj)); myComp = COMP_INIT ((void *) COMP2_base_ADDR、sizeof (COMP_Obj)); myCap = cap_init ((void *) CAPA_base_ADDR、sizeof (cap_Obj)); myPwm = PWM_init ((void *) PWM_ePWM1_base_ADDR、sizeof (PWM_Obj)); //执行基本系统初始化 WDOG_DISABLE (myWDog); //启用到 ADC 的时钟 CLK_enableAdcClock (myClk); (*Device_cal)(); CLK_enableHrPwmClock (myClk); //启用 PWM 时钟 CLK_enablePwmClock (myClk、PWM_NUMBER_1); //选择内部振荡器1作为时钟源 CLK_setOscSrc (myClk、CLK_OscSrc_Internal); //将 PLL 设置为 x10 /2、这将产生50MHz = 10MHz * 10/2 PLL_setup (myPll、PLL_Multiplier_12、PLL_DivideSelect_CLKIN_BY_2); DSP28x_usDelay (2000); //--启用到外设的时钟 //禁用 PIE 和所有中断 PIE_DISABLE (myPie); PI_DisableAllInts (myPie); CPU_disableGlobalInts (myCpu); CPU_clearIntFlags (myCpu); //如果从闪存运行,则只将 RAM 复制到 RAM #ifdef _flash memcpy (&RamfuncsRunStart、&RamfuncsLoadStart、(size_t)&RamfuncsLoadSize); #endif //初始化 GPIO //启用 XCLOCKOUT 以允许对振荡器1进行监控 GPIO_setMode (myGpio、GPIO_Number_18、GPIO_18_Mode_XCLKOUT); CLK_setClkOutPreScaler (myClk、CLK_ClkOutPreScale_SYSCLKOUT_By_1); //设置调试矢量表并启用 PIE PI_setDebugIntVectorTable (myPie); PIE_ENABLE (myPie); // GPI05中断(DSP_INTn) PI_registerPieIntHandler (myPie、PI_GroupNumber_1、PI_SubGroupNumber_4、(intVec_t)&XINT_ISR); // TODO ADC ePWM PI_registerPieIntHandler (myPie、PI_GroupNumber_10、PI_SubGroupNumber_1、(intVec_t)&ADC_ISR); //初始化 GPIO GPIO_init(); ifdef Launchpad //初始化 SCIA scia_init(); #endif EALLOW; GpioIntRegs.GPIOXINT1SEL.bit.GPIOSEL = 12;//将 GPIO 配置为 XINT1 EDIS; //初始化 ADC adc_init(); //初始化 PWM PWM_init(); //初始化 SPI spi_init(); //初始化 SPI FIFO SPI_Fifo_init(); //启用全局中断和更高优先级的实时调试事件 cpu_enableGlobalInts (myCpu); CPU_enableDebugInt (myCpu); //在 Delta DSP 中将 GPIO12配置为 XINT1 GPIO_setMode (myGpio、GPIO_Number_12、GPIO_12_Mode_generalpurpose); GPIO_setDirection (myGpio、GPIO_Number_12、GPIO_Direction_Input); GPIO_setPullUp (myGpio、GPIO_Number_12、GPIO_PULLUP_Enable); GPIO_setExtInt (myGpio、GPIO_Number_12、CPU_ExtIntNumber_1); //设置中断极性 PI_setExtIntPolarity (myPie、CPU_ExtIntNumber_1、PI_ExtIntPolarity_RisingAndFallingEdge); //启用 XINT1 PI_enableExtInt (myPie、CPU_ExtIntNumber_1); //启用 PIE - XINT1 PI_enableInt (myPie、PI_GroupNumber_1、PI_InterruptSource_XINT_1); //启用 SPI TX 中断 PI_enableInt (myPie、PI_GroupNumber_6、PI_InterruptSource_SPIATX); //启用 CPU - INT1 CPU_enableInt (myCpu、CPU_IntNumber_1); // TODO ADC ePWM CPU_enableInt (myCpu、CPU_IntNumber_10); //将闪存 OTP 等待状态设置为最小值。 这很重要 //以获得温度转换功能的性能。 FLASH_setup (myFlash); //将 STDOUT 重定向到 SCI 状态= add_device ("scia"、_ssa、SCI_open、SCI_close、SCI_read、 SCI_WRITE、SCI_LSEEK、SCI_unlink、SCI_rename); FID = fopen ("scia"、"w"); freopen ("scia:"、"w"、stdout); setvbuf (stdout、NULL、_IONBF、0); } void adc_init () { adc_enableBandGap (myAdc); ADC_enableRefBuffers (myAdc); ADC_POWERUP (myAdc); ADC_ENABLE (myAdc); ADC_setVoltRefSrc (myAdc、ADC_VoltageRefSrc_Int); //在 PIE 中启用 ADCINT1 PIE_enableAdcInt (myPie、ADC_IntNumber_1); //启用 CPU 中断1 CPU_enableInt (myCpu、CPU_IntNumber_10); //配置 ADC ADC_setIntPulseGenMode (myAdc、ADC_IntPulseGenMode_Prior); //ADCINT1在 AdcResults 锁存后跳闸 ADC_enableInt (myAdc、ADC_IntNumber_1); //启用 ADCINT1 ADC_setIntMode (myAdc、ADC_IntNumber_1、ADC_IntMode_EOC); //禁用 ADCINT1连续模式 ADC_setIntSrc (myAdc、ADC_IntNumber_1、ADC_IntSrc_EOC1); //设置 EOC1以触发 ADCINT1触发 ADC_setSockChanNumber (myAdc、ADC_SockNumber_0、ADC_SockChanNumber_A4);//将 SOC0通道选择设置为 ADCINA4 ADC_setSockChanNumber (myAdc、ADC_SockNumber_1、ADC_SockChanNumber_A4);//将 SOC1通道选择设置为 ADCINA4 ADC_setSockTrigSrc (myAdc、ADC_SockNumber_0、ADC_SockTrigSrc_EPWM1_ADCSOCA);//设置 EPWM1A 上的 SOC0启动触发器、由于轮询 SOC0先转换、然后 SOC1 ADC_setSockTrigSrc (myAdc、ADC_SockNumber_1、ADC_SockTrigSrc_EPWM1_ADCSOCB);//设置 EPWM1A 上的 SOC1启动触发器,由于轮询 SOC0先转换,然后 SOC1 ADC_setSockSampleWindow (myAdc、ADC_SockNumber_0、ADC_SockSampleWindow_7_cycles);//将 SOC0 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1) ADC_setSockSampleWindow (myAdc、ADC_SockNumber_1、ADC_SockSampleWindow_7_cycles);//将 SOC1 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1) } void PWM_init () { //设置 PWM PWM_enableSockpulse (myPwm); //在组上启用 SOC PWM_setSockAPulseSrc (myPwm、PWM_SockPulseSrc_CounterEqualCmpAcincr);//从 CPMA 向上计数选择 SOC PWM_setSockAPeriod (myPwm、PWM_SockPeriod_FirstEvent); //在发生第一个事件时生成脉冲 PWM_setCmpA (myPwm、30); //设置比较 A 值(30 TBCLK 计数=> 50%占空比) PWM_setPeriod (myPwm、60); //为 ePWM1设置周期(60 TBCLK 计数=> 2MHz) PWM_setCounterMode (myPwm、PWM_CounterMode_UpDown); //向上计数并启动 } 中断 void ADC_ISR (void) { //在 SOC0和 SOC1上强制转换开始 ADC_forceConversion (myAdc、ADC_SockNumber_0); ADC_forceConversion (myAdc、ADC_SockNumber_1); //if (!is_full) // write_buffer (adc_readResult (myAdc、adc_ResultNumber_1)); PULSE_Ampl = ADC_readResult (myAdc、ADC_ResultNumber_1); SPI_WRITE (mySpi、10); //清除 ADCINT1 ADC_clearIntFlag (myAdc、ADC_IntNumber_1); //确认 PIE 中断 PI_clearInt (myPie、PI_GroupNumber_10); } 中断 void XINT_ISR (void) { if (GpioDataRegs.GPADAT.bit.GPIO12 == true) { //待办事项区域 SUM_ADC_16b_val =错误; SUM_ADC_PULSE_Val = false; //设置高于阈值标志 高于 se_thrsh = true; //清除 PIE - XINT1中断 PI_clearInt (myPie、PI_GroupNumber_1); } if (GpioDataRegs.GPADAT.bit.GPIO12 == false) { //未设置超出阈值标志 高于 se_thrsh = false; //清除 PIE - XINT1中断 PI_clearInt (myPie、PI_GroupNumber_1); } //清除 PIE - XINT1中断 PI_clearInt (myPie、PI_GroupNumber_1); } void main () { int i = 0; //系统初始化 system_init(); ifdef Launchpad printf ("\n\r 已初始化 DSP 系统\n\r"); #endif //用中值(0x08)点亮二进制显示 GPIO_setPortData (myGpio、GPIO_Port_A、(~0x08)和0x0F); ifdef Launchpad EALLOW; compsts = Comp2Regs.COMPSTS.bit.COMPSTS; GPBDAT = GpioDataRegs.GPBDAT.bit.GPIO34; EDIS; printf ("比较器状态:%d "、压缩); printf ("GPIO 34/COMP2OUT 状态:%d "、GPBDAT); #endif //初始化 ADC 缓冲器 adc_buffer_init (); //主程序循环-持续采样温度 for (;;){ } }
尊敬的惠特尼:
是的、我设法通过 ePWM 触发 ADC SOC、然后修复这两个问题并进一步清理代码。
不过、我现在要面对下一个挑战:该算法背后的理念是在1MHz ePWM 下对脉冲进行采样。 我实现的方法之一是使用循环 FIFO 将每个样本转储到 ADC_ISR 中,并在 main ()中对其进行读取和后处理,然后再通过 SPI 发送。
但是、无论何时我写入循环队列或写入 ADC_ISR()内的数组、例程看起来都是挂起的。 有什么想法、为什么会发生这种情况? 我已包含代码片段以供参考。
#define ISR_PULSE_Buffer_LEN 64 中断空 ADC_ISR (空) { PULSE_Ampl_wr = ADC_readResult (myAdc、ADC_ResultNumber_0); PULSE_Ampl[NO_OD_SAMPLES]= ADC_READResult (myAdc、ADC_ResultNumber_1); if (no_of _samples < ISR_PULSE_buffer_LEN) NO_OD_SAM_+; 其他 NO_OD_SAples = false; //清除 ADCINT1 ADC_clearIntFlag (myAdc、ADC_IntNumber_1); //确认 PIE 中断 PI_clearInt (myPie、PI_GroupNumber_10); } void main () { int i = 0; //系统初始化 system_init(); //初始化 ADC 缓冲器 adc_buffer_init (); //延迟系统 DSP28x_usDelay (1000); //主程序循环-持续采样温度 for (;;){ //主循环 if (is_above thrsh =false || no_of _samples >= isr_pulpulate_buffer_LEN) ifo_processed = true; if (is_fifo_processed = true) { 对于(i = no_of _samples; i > 0;i---) { SUM_ADC_PULSE_Val = SUM_ADC_PULSE_Val + PULSE_Ampl[i]; PULSE_Ampl[i]= false; } GPIO_setLow (myGpio、GPIO_Number_19); PULSE_Ampl_rd = SPI_Read (mySpi); SPI_WRITE (mySpi、PULSE_Ampl_wr << 4); GPIO_setHigh (myGpio、GPIO_Number_19); SUM_ADC_PULSE_Val = false; ifo_processed = false; NO_OD_SAples = false; } }
谢谢!
Mansi