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.

TMS320F28027: AD采样的结果数据跳动比较大,转换的结果最大是2020最小是1994 差值大16 ,我的电源采用12V蓄电池,12V通过7805,7805再通过AMS1117-3.3V给芯片供电

Part Number: TMS320F28027


1.现在的电源采用蓄电池按道理应该没有外部电源干扰了,为什么数据差别这么大?

2.我试着按官方例子调用AdcOffsetSelfCal一直卡死在while (AdcRegs.ADCINTFLG.bit.ADCINT1 == 0)

上述两个问题我以前提到过 能否有相关代码关于AD采样的程序尤其是AdcOffsetSelfCal以供参考

我的程序平时下载到FLASH中的 

请问上面两个怎么解决,涉及到上面的两个问题的英文回答我看不懂了 我也试过 麻烦给以中文的详细回答,谢谢!

  • 是使用官方例程测试的还是自己编写的程序?采样频率多少?可以试一下增加一些采样保持时间。另外,下载到flash是否有使用memcpy函数将ADC中断函数搬移到ram运行?

    关于AdcOffsetSelfCal的参考代码,我的理解你已经参考官方例程调用这个函数了?确实没找到相关文档,不过找到一个第三方网站的介绍:bbs.eeworld.com.cn/thread-1069142-1-1.html

    另外,有相关英文回答可以分享一下

  • 按照第三方网站的介绍我试了下还是没有解决即同样的问题卡死在 while (AdcRegs.ADCINTFLG.bit.ADCINT2 == 0){}这条语句

    我把代码贴出来

     #pragma CODE_SECTION(adc_isr, "ramfuncs");
     #pragma CODE_SECTION(AdcConversion, "ramfuncs");
     
     
    void ADC_Config(void)
    {
    
       InitAdc();  // 先调用官方AD默认的配置函数初始化(必须)
    
       EALLOW;
       PieVectTable.ADCINT3 = &adc_isr;// AD中断函数映射
       EDIS;
    
       PieCtrlRegs.PIEIER10.bit.INTx3 = 1;	// Enable INT 10.3 in the PIE
       IER |= M_INT10; 						// Enable CPU Interrupt 10
    
    // Configure ADC
    	EALLOW;
    //	AdcRegs.ADCCTL2.bit.CLKDIV2EN = 0; //ADCclock = CPUclock
    	AdcRegs.ADCCTL1.bit.ADCREFSEL	= 0;    //REF Int
    	AdcRegs.ADCCTL1.bit.INTPULSEPOS	= 1;	//ADCINT1 trips after AdcResults latch //--> P39 HIKE,EOCx产生来自源选择
    	AdcRegs.INTSEL3N4.bit.INT3E     = 1;	//Enabled ADCINT3
    	AdcRegs.INTSEL3N4.bit.INT3CONT  = 0;	//Disable ADCINT3 Continuous mode,single conversion mode
    
    	//HIKE,ADCINTx EOC Source Select, 即哪个 EOCx 触发中断
    	AdcRegs.INTSEL3N4.bit.INT3SEL	= 1;	//setup EOC1 to trigger ADCINT3 to fire , EOC1 is trigger for ADCINTx
    
    //////////////////////////////////////////////////////////////////////////////////////////////////////////
    //ADC勘误表上指出,SOC通道第一个采样的数据不正确,从第二个开始为正确的数据,故这里SOC0 SOC1数据不做处理
    
    //	//P17 P35 同步采样的话,两个SOC的CHSEL设置一样
    //	//Simultaneous sampling enable for SOC0/SOC1
    //	AdcRegs.ADCSAMPLEMODE.bit.SIMULEN0=1;	//SOC0/1 Simultaneous Sampling Enable	,SOC0蚐OC1组合工作
    //	AdcRegs.ADCSOC0CTL.bit.CHSEL 	= 3;	//SOC0 (ADCINA3/ADCINB3 pair),配置模拟通道连接
    //	AdcRegs.ADCSOC1CTL.bit.CHSEL 	= 3;
    
    //SOC 连续采样,赋值与通道连接如下
    //0-7为A0到A7
    //8-16为B0到B7
    	AdcRegs.ADCSOC0CTL.bit.CHSEL 	= 11;	//set SOC0 channel select to ADCINB3
    	AdcRegs.ADCSOC1CTL.bit.CHSEL 	= 11;	//set SOC3 channel select to ADCINB3
    
    //-->HIKE ,AD选择触发源,软件触发 P34
    	AdcRegs.ADCSOC0CTL.bit.TRIGSEL 	= 0x0C;//PWM4B进行ADC的SOCB触发
    	AdcRegs.ADCSOC1CTL.bit.TRIGSEL 	= 0x0C;
    
    	AdcRegs.ADCSOC0CTL.bit.ACQPS 	= 13;
    	AdcRegs.ADCSOC1CTL.bit.ACQPS 	= 13;	//set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
    	EDIS;
    }
    void My_AdcOffsetSelfCal()
    {
        Uint16 AdcConvMean;
        EALLOW;
        AdcRegs.ADCCTL1.bit.ADCREFSEL = 0;					//Select internal reference mode
        AdcRegs.ADCOFFTRIM.bit.OFFTRIM = 80;                //Apply artificial offset (+80) to account for a negative offset that may reside in the ADC core
        AdcRegs.ADCCTL1.bit.VREFLOCONV = 1;                 //Select VREFLO internal connection on B5
        AdcChanSelect(13);                                  //Select channel B5 for all SOC
        AdcConvMean = AdcConversion();                      //Capture ADC conversion on VREFLO
        AdcRegs.ADCOFFTRIM.bit.OFFTRIM = 80 - AdcConvMean;  //Set offtrim register with new value (i.e remove artical offset (+80) and create a two's compliment of the offset error)
        AdcRegs.ADCCTL1.bit.VREFLOCONV = 0;                 //Select external ADCIN5 input pin on B5
        EDIS;
    }
    //-------------------------------------------------------------------------
    //AD 中断处理函数
    //
    //##########################################################################
    interrupt void  adc_isr(void)
    {
    	EALLOW;
    	PieCtrlRegs.PIEACK.all = PIEACK_GROUP10;   // Acknowledge interrupt to PIE
    	EDIS;
    
    	AdcRegs.ADCINTFLGCLR.bit.ADCINT3 = 1;		//Clear ADCINT1 flag reinitialize for next SOC
    	adcISRFlag = 1;
    	adcVal[0] = AdcResult.ADCRESULT0;
    	adcVal[1] = AdcResult.ADCRESULT1;
    }
    
    上面是相关的部分函数 开头是把两个函数定义在flash,期中函数 My_AdcOffsetSelfCal()是我按照第三方网站的描述所建立的函数体
    
    然后在主函数main中程序如下
    void main(void) 
    {
    	uint8_t print_cnt1=0,print_cnt2=0;
    // Step 1. Initialize System Control:b
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the DSP2803x_SysCtrl.c CAN_Node_IDfile.
       InitSysCtrl();
    
    // Step 2. Initalize GPIO:
    // This example function is found in the DSP2803x_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // InitGpio();  // Skipped for this example
    
    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
       DINT;
    
    // Initialize PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the DSP2803x_PieCtrl.c file.
       InitPieCtrl();
    
    // Disable CPU interrupts and clear all CPU interrupt flags:
       IER = 0x0000;
       IFR = 0x0000;
    
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in DSP2803x_DefaultIsr.c.
    // This function is found in DSP2803x_PieVect.c.
       InitPieVectTable();
    
       // Copy time critical code and Flash setup code to RAM
       //实现在RAM中运行代码的搬运,例如使用官方的DELAY_US
       MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
       //-----------------------以上是系统初始化用的,一般不动--------------------------------
    
    
        InitMyGPIO();
    	InitKEY();//按键
    
    	SCI_Init();//波特率128000bps
    	open_uart_debug();
    	printf("\r\n\r\n\r\nDSP is Ready");//标准C的printf输出测试,串口调试助手设置波特率128000bps,ASCII格式显示
    
    	Timer0_init();//定时器0初始化,1ms周期中断
    
    //---------------------TM1650初始化  IIC驱动--------------------------------
    	softResetIIC_BUS(); //软件复位IIC从设备
    	InitI2C_Gpio(); //io 初始化为IIC
    	I2CA_Init();    //HW IIC初始化,100KHz
    	printf("\r\nTM1650 init...");//标准C的printf输出测试,串口调试助手设置波特率128000bps,ASCII格式显示
    
    	//<TM1650.pdf>P4  显示命令设置
    	LigntVal = 0x11; //BIT6到BIT4为亮度调节,BIT0是  1 开启/0关闭
    	TM1650_Send(CMD_SEG, LigntVal); //1级亮度,开启显示
    	TM1650_Send(DIG1, SEG7Table[0]); //GID1
    	TM1650_Send(DIG2, SEG7Table[0]); //GID2
    	TM1650_Send(DIG3, SEG7Table[0]); //GID3
    	TM1650_Send(DIG4, SEG7Table[0]); //GID4
    
      	ADC_Config();
      	My_AdcOffsetSelfCal();
    
    	printf("\r\n开发板左上角的J4排针(3针),用跳线帽短接靠左的2根针,即为将RG接入到模拟输入口B3");
    	printf("\r\nPWM频率为19.6KHZ");
    	InitEPWM_AQ_DB();//PWM初始化 中央对齐模式  , 20K频率 , PWM4A PWM4B为互补输出 ,PWM4B触发AINB组的ADC采样
    
    	//中断配置步骤-----5
    	PieCtrlRegs.PIECTRL.bit.ENPIE = 1;    // Enable the PIE block
    	EINT;                                 // Enable Global interrupt INTM
    	ERTM;//请参看 使用须知 文件夹下的   分享--ERTM、DRTM 在DSP编程中的作用.pdf
    	目前程序就是无法运行 CMD定义代码在flash  谢谢!
    

  • 请教一下 memcpy函数将ADC中断函数搬移到ram运行前提是通过#pragma CODE_SECTION把AD中断函数定义在CODE_SECTION才能 //实现在RAM中运行代码的搬运,例如使用官方的DELAY_US
    MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);