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.

TMS320F28035: ADCINA1采集电源电压问题,亟待解决

Part Number: TMS320F28035

在使用TMS320F28035芯片的时候遇到了一些问题:

目的:想要使用TMS320F28035芯片(56引脚)的ADCINA1通带进行电源电压测量

工具:已经有了TMS320F28035芯片(64引脚)ADCINA1测量电源电压的代码(经过测试代码正确无误,可以正常读取0-3.3V电压值),具体代码如下:

首先是 main.c代码:

#include "DSP2803x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2803x_Examples.h" // DSP2833x Examples Include Fi

#include "stdio.h"
#include "Battery.h"
#include "leds.h"
#include "Tim.h"
extern Uint16 RamfuncsLoadSize;
/******************************************************************************
*函数原型:		void main(void)
*函数功能:	    飞控主函数
*******************************************************************************/
void main(void)
{
	InitSysCtrl();
	DINT;
	InitPieCtrl();
	IER = 0x0000;
	IFR = 0x0000;
	InitPieVectTable();
	memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (Uint32)&RamfuncsLoadSize);
	LED_Init();              // 初始化LED-
	BatteryCheckInit();    // 初始化电池检测ADC-
	BatteryCheck();        // 检测电池电压;软件触发ADC采集-
	Timer0_init();         // 定时器0初始化,1ms周期中断-
	PieCtrlRegs.PIECTRL.bit.ENPIE = 1;
	EINT;
	ERTM;
    while(1)
	{

/* 电源电压检测及片上温度检测;信号灯提示(100ms为一个周期)*/
    	if(timer0Base.loop10HzCnt >= 1000)
    	{
    		timer0Base.loop10HzCnt=0;
    		BatteryCheck();  	   // 电源电压监控
            TemperatureCheck();   // 片上温度采集
            LED1_TOGGLE;
            LED2_TOGGLE;
    	}
	}
}

Battery.c代码

#include "Battery.h"
#include "stdio.h"

Bat_Typedef Battery;
int adcVal[2]={0};//ADC 采样结果
char adcISRFlag=0;//ADC 中断标识
int16 degC; //temperature in deg. C
interrupt void adc_isr(void);
/*******************************************************************************
* 函 数 名:	    void BatteryCheckInit(void)
* 函数功能:	    AD初始化;将模拟值输入到A1通道
*******************************************************************************/
void BatteryCheckInit(void)
{
	InitAdc();  // 初始化ADC对应的GPIO
	EALLOW;
	PieVectTable.ADCINT3 = &adc_isr;    // AD中断函数映射
	EDIS;
	PieCtrlRegs.PIEIER10.bit.INTx3 = 1;//使能 PIE 的 INT10.3
	IER |= M_INT10;
	EALLOW;
	AdcRegs.ADCCTL2.bit.ADCNONOVERLAP = 1;  //不允许重叠采样
	AdcRegs.ADCCTL1.bit.TEMPCONV  = 1; 		//设置片上温度传感器
	FlashRegs.FOTPWAIT.bit.OTPWAIT = 1;     //设置 flash OTP 等待状态为最小,以保证温度转换函数的性能
	EDIS;
	EALLOW;
	AdcRegs.ADCCTL1.bit.ADCREFSEL	= 0;    //Internal Bandgap//内部带隙产生参考电压
	AdcRegs.ADCCTL1.bit.INTPULSEPOS	= 1;	//ADCINT1 trips 产生中断脉冲, 1 个周期后 ADC 锁存到结果寄存器。
	AdcRegs.INTSEL3N4.bit.INT3E     = 1;	//Enabled ADCINT3
	AdcRegs.INTSEL3N4.bit.INT3CONT  = 0;	//禁止连续转换模,single conversion mode 直到 ADCINTx 标志 (在 ADCINTFLG 寄存器) 由用户清除, 无进一步的 ADCINTx脉冲产生。
	AdcRegs.INTSEL3N4.bit.INT3SEL	= 1;	//创建EOC1,EOC1 为 ADCINTx 的触发。
	AdcRegs.ADCSOC0CTL.bit.TRIGSEL 	= 0x00; //软件触发,没有 ADCINT 触发 SOCx。 TRIGSEL 位域确定 SOCx 触发。
	AdcRegs.ADCSOC1CTL.bit.TRIGSEL 	= 0x00; //软件触发,没有 ADCINT 触发 SOCx。 TRIGSEL 位域确定 SOCx 触发。
	AdcRegs.ADCSOC0CTL.bit.CHSEL 	= 5;	//片上温度采集,SOCx通道选择
	AdcRegs.ADCSOC1CTL.bit.CHSEL 	= 1;	//电源采集,SOCx 通道选择
	AdcRegs.ADCSOC0CTL.bit.ACQPS 	= 6;	//设置窗口,SOCx 采样预定标, 为 SOCx 控制采样保持窗口, 最小值为6
	AdcRegs.ADCSOC1CTL.bit.ACQPS 	= 6;	//设置窗口,采样窗为7 个周期长 (6 + 1 时钟周期)
	EDIS;
	Battery.ADRef   = 3.31;                  // 实际测量的MCU供电电压
	Battery.Bat_K   = 1.0;                   // 电压校准系数
	Battery.overDischargeCnt = 0;
	Battery.Calisum = 0.0;                   // 电池的sum校准系数
	printf("\r\nADC(BATTERY) init...OK");
}

/*******************************************************************************
* 函 数 名:	    void BatteryCheckInit(void)
* 函数功能:	    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
	adcISRFlag = 1;
	adcVal[0]=AdcResult.ADCRESULT0; //温度
	adcVal[1]=AdcResult.ADCRESULT1; //电压
}

/*******************************************************************************
* 函 数 名:	    int GetBatteryAD(u8 ch)
* 函数功能:	    获取电池单次的ADC
*******************************************************************************/
int GetBatteryAD(u8 ch)
{
	AdcRegs.ADCSOCFRC1.all = 0X03; //软件触发AD 的 SOC0--SOC1采样
	if(adcISRFlag == 1)
	{
		adcISRFlag = 0;
	}
	return adcVal[ch];
}

/*******************************************************************************
* 函 数 名:	    int Get_Adc_Average(u8 ch,u8 times)
* 函数功能:	    获取A1通道的AD值
*******************************************************************************/
int Get_Adc_Average(u8 ch,u8 times)
{
	int temp_val=0;
	u8 t;
	for(t=0;t<times;t++)
	{
		temp_val+=(GetBatteryAD(ch));
	}
	return temp_val/times;
}

/*******************************************************************************
* 函 数 名:	    void TemperatureCheck(void)
* 函数功能:	    检测MCU温度
*******************************************************************************/
void TemperatureCheck(void)
{
	degC = GetTemperatureC(Get_Adc_Average(0,5));// 片上温度采样
}

/*******************************************************************************
* 函 数 名:	    void BatteryCheck(void)
* 函数功能:	    检测电池电压;过放报警和过放保护
*******************************************************************************/
void BatteryCheck(void)
{
	Battery.BatteryAD  = Get_Adc_Average(1,5);  // 滤波后的电压值
	//printf("\r\n滤波后的电压值:%d\n",Battery.BatteryAD);
	Battery.BatteryVal = (float)(Battery.Bat_K*((Battery.BatteryAD/4096.0)*Battery.ADRef))+Battery.Calisum;//实际电压值计算
    printf("\r\n实际电压值:%f\n",Battery.BatteryVal);

	if(1)
	{
		if(Battery.BatteryVal <= (BAT_OVERDIS_VAL + 0.03))
		{
			Battery.alarm=1;               // 报警位
		}else{
			Battery.alarm=0;
		}

		if(Battery.BatteryVal <= BAT_OVERDIS_VAL)
		{
			Battery.overDischargeCnt++;    // 过放保护计数
			if(Battery.overDischargeCnt > 3)
			{

			}
		}else
			{
				Battery.overDischargeCnt = 0;
			}
	}
	else
	{
		if(Battery.BatteryVal < BAT_ALARM_VAL) // 3.65V
		{
			Battery.alarm=1;               // 报警位
		}else{
			Battery.alarm=0;
		}
	}
}

Battery.h代码

#ifndef INC_BATTERY_H_
#define INC_BATTERY_H_


#include "DSP2803x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2803x_Examples.h" // DSP2833x Examples Include Fi

#define uint8_t unsigned char
#define uint16_t unsigned short
#define uint32_t unsigned long
#define uint64_t unsigned long long
#define int8_t  signed char
#define int16_t signed short
#define int32_t signed long
#define int64_t signed long long

typedef int8_t s8;
typedef uint8_t u8;
typedef int16_t s16;
typedef uint16_t u16;
typedef int32_t s32;
typedef uint32_t u32;



extern int adcVal[];//ADC 采样结果
extern char adcISRFlag;//ADC 中断标识
extern int16 degC;

#define BAT_CHK_PRD     500
#define BAT_ALARM_VAL   3.65
#define BAT_OVERDIS_VAL 3.15

//电压信息结构体
typedef struct
{
float  ADRef;                 // AD参考源
float  Bat_K;                 // 计算电压值
char   alarm;				  // 电池报警位
char   chargeSta;			  // 充电状态
float  BatteryVal;            // 电压
int    BatteryAD;             // 电压
int    overDischargeCnt;	  // 过放保护计数
float  Calisum;
}Bat_Typedef;
extern Bat_Typedef Battery;

/*函数声明*/
void BatteryCheckInit(void);
int Get_Adc_Average(u8 ch,u8 times);
int GetBatteryAD(u8 ch);
void TemperatureCheck(void);
void BatteryCheck(void);

#endif /* INC_BATTERY_H_ */

经过我的测试,该代码在TMS320F28035(64引脚)中可以通过ADCINA1通道正常采集到电源电压。由于工作需求现在我需要改用TMS320F28035(56引脚)的芯片,同样要采集电源电压,使用同样代码和ADCINA1通道,却没有成功采集得到真实电源电压,采集到的结果显示为0.0V左右, 我有如下问题:

1.TMS320F28035(56引脚)的ADCINA1对应的管脚为12,而(64引脚)的ADCINA1对应的管脚为14,我是否需要在ccs软件中对管脚(或GPIO)进行配置?

2.我画的硬件原理图如下,可以看到ADCINA1的采集线直接连接到电池电源线(1s锂电池供电满电电压4.2v),我并没有采取分压电路进行降压,有没有可能是ADCINA1接口已经被烧坏了?

3.用上述代码在我绘制的控制板中运行程序,ADC采集到的电压值一直在0.055615v左右变换(最大不超过0.1v),这是不是表示ADCINA1采集口接地了?

4.我如果将ADC1采集口放在电容之后(如下图),可以不再增加其他分压电路直接使用吗?

5.如果必须采用分压电路的话,那么分压ADC采集分压电路详细原理图该怎么画?

  • Part Number: TMS320F28035

    在使用TMS320F28035芯片的时候遇到了一些问题:

    目的:想要使用TMS320F28035芯片(56引脚)的ADCINA1通带进行电源电压测量

    工具:已经有了TMS320F28035芯片(64引脚)ADCINA1测量电源电压的代码(代码正确无误),具体代码如下:

    首先是main.c文件:

    #include "DSP2803x_Device.h" // DSP2833x Headerfile Include File #include "DSP2803x_Examples.h" // DSP2833x Examples Include Fi #include "stdio.h" #include "Battery.h" #include "leds.h" #include "Tim.h" extern Uint16 RamfuncsLoadSize; /****************************************************************************** *函数原型: void main(void) *函数功能: 飞控主函数 *******************************************************************************/ void main(void) { InitSysCtrl(); DINT; InitPieCtrl(); IER = 0x0000; IFR = 0x0000; InitPieVectTable(); memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (Uint32)&RamfuncsLoadSize); LED_Init(); // 初始化LED- BatteryCheckInit(); // 初始化电池检测ADC- BatteryCheck(); // 检测电池电压;软件触发ADC采集- Timer0_init(); // 定时器0初始化,1ms周期中断- PieCtrlRegs.PIECTRL.bit.ENPIE = 1; EINT; ERTM; while(1) { /* 电源电压检测及片上温度检测;信号灯提示(100ms为一个周期)*/ if(timer0Base.loop10HzCnt >= 1000) { timer0Base.loop10HzCnt=0; BatteryCheck(); // 电源电压监控 TemperatureCheck(); // 片上温度采集 //LEDFSM(); // 信号灯提示 LED1_TOGGLE; LED2_TOGGLE; } } }

    其次是Battery.c文件:

    #include "Battery.h" //#include "ReceiveData.h" //#include "control.h" //#include "Moto.h" #include "stdio.h" Bat_Typedef Battery; int adcVal[2]={0};//ADC 采样结果 char adcISRFlag=0;//ADC 中断标识 int16 degC; //temperature in deg. C interrupt void adc_isr(void); /******************************************************************************* * 函 数 名: void BatteryCheckInit(void) * 函数功能: AD初始化;将模拟值输入到A1通道 *******************************************************************************/ void BatteryCheckInit(void) { InitAdc(); // 初始化ADC对应的GPIO EALLOW; PieVectTable.ADCINT3 = &adc_isr; // AD中断函数映射 EDIS; PieCtrlRegs.PIEIER10.bit.INTx3 = 1;//使能 PIE 的 INT10.3 IER |= M_INT10; EALLOW; AdcRegs.ADCCTL2.bit.ADCNONOVERLAP = 1; //不允许重叠采样 AdcRegs.ADCCTL1.bit.TEMPCONV = 1; //设置片上温度传感器 FlashRegs.FOTPWAIT.bit.OTPWAIT = 1; //设置 flash OTP 等待状态为最小,以保证温度转换函数的性能 EDIS; EALLOW; AdcRegs.ADCCTL1.bit.ADCREFSEL = 0; //Internal Bandgap//内部带隙产生参考电压 AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; //ADCINT1 trips 产生中断脉冲, 1 个周期后 ADC 锁存到结果寄存器。 AdcRegs.INTSEL3N4.bit.INT3E = 1; //Enabled ADCINT3 AdcRegs.INTSEL3N4.bit.INT3CONT = 0; //禁止连续转换模,single conversion mode 直到 ADCINTx 标志 (在 ADCINTFLG 寄存器) 由用户清除, 无进一步的 ADCINTx脉冲产生。 AdcRegs.INTSEL3N4.bit.INT3SEL = 1; //创建EOC1,EOC1 为 ADCINTx 的触发。 AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 0x00; //软件触发,没有 ADCINT 触发 SOCx。 TRIGSEL 位域确定 SOCx 触发。 AdcRegs.ADCSOC1CTL.bit.TRIGSEL = 0x00; //软件触发,没有 ADCINT 触发 SOCx。 TRIGSEL 位域确定 SOCx 触发。 AdcRegs.ADCSOC0CTL.bit.CHSEL = 5; //片上温度采集,SOCx通道选择 AdcRegs.ADCSOC1CTL.bit.CHSEL = 1; //电源采集,SOCx 通道选择 AdcRegs.ADCSOC0CTL.bit.ACQPS = 6; //设置窗口,SOCx 采样预定标, 为 SOCx 控制采样保持窗口, 最小值为6 AdcRegs.ADCSOC1CTL.bit.ACQPS = 6; //设置窗口,采样窗为7 个周期长 (6 + 1 时钟周期) EDIS; Battery.ADRef = 3.31; // 实际测量的MCU供电电压 Battery.Bat_K = 1.0; // 电压校准系数 Battery.overDischargeCnt = 0; Battery.Calisum = 0.0; // 电池的sum校准系数 printf("\r\nADC(BATTERY) init...OK"); } /******************************************************************************* * 函 数 名: void BatteryCheckInit(void) * 函数功能: 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 adcISRFlag = 1; adcVal[0]=AdcResult.ADCRESULT0; //温度 adcVal[1]=AdcResult.ADCRESULT1; //电压 } /******************************************************************************* * 函 数 名: int GetBatteryAD(u8 ch) * 函数功能: 获取电池单次的ADC *******************************************************************************/ int GetBatteryAD(u8 ch) { AdcRegs.ADCSOCFRC1.all = 0X03; //软件触发AD 的 SOC0--SOC1采样 if(adcISRFlag == 1) { adcISRFlag = 0; } return adcVal[ch]; } /******************************************************************************* * 函 数 名: int Get_Adc_Average(u8 ch,u8 times) * 函数功能: 获取A1通道的AD值 *******************************************************************************/ int Get_Adc_Average(u8 ch,u8 times) { int temp_val=0; u8 t; for(t=0;t<times;t++) { temp_val+=(GetBatteryAD(ch)); } return temp_val/times; } /******************************************************************************* * 函 数 名: void TemperatureCheck(void) * 函数功能: 检测MCU温度 *******************************************************************************/ void TemperatureCheck(void) { degC = GetTemperatureC(Get_Adc_Average(0,5));// 片上温度采样 } /******************************************************************************* * 函 数 名: void BatteryCheck(void) * 函数功能: 检测电池电压;过放报警和过放保护 *******************************************************************************/ void BatteryCheck(void) { Battery.BatteryAD = Get_Adc_Average(1,5); // 滤波后的电压值 //printf("\r\n滤波后的电压值:%d\n",Battery.BatteryAD); Battery.BatteryVal = (float)(Battery.Bat_K*((Battery.BatteryAD/4096.0)*Battery.ADRef))+Battery.Calisum;//实际电压值计算 printf("\r\n实际电压值:%f\n",Battery.BatteryVal); if(1) { if(Battery.BatteryVal <= (BAT_OVERDIS_VAL + 0.03)) { Battery.alarm=1; // 报警位 }else{ Battery.alarm=0; } if(Battery.BatteryVal <= BAT_OVERDIS_VAL) { Battery.overDischargeCnt++; // 过放保护计数 if(Battery.overDischargeCnt > 3) { } }else { Battery.overDischargeCnt = 0; } } else { if(Battery.BatteryVal < BAT_ALARM_VAL) // 3.65V { Battery.alarm=1; // 报警位 }else{ Battery.alarm=0; } } }

    最后是Battery.h文件:

    #ifndef INC_BATTERY_H_ #define INC_BATTERY_H_ //#include "extern_variable.h" #include "DSP2803x_Device.h" // DSP2833x Headerfile Include File #include "DSP2803x_Examples.h" // DSP2833x Examples Include Fi #define uint8_t unsigned char #define uint16_t unsigned short #define uint32_t unsigned long #define uint64_t unsigned long long #define int8_t signed char #define int16_t signed short #define int32_t signed long #define int64_t signed long long typedef int8_t s8; typedef uint8_t u8; typedef int16_t s16; typedef uint16_t u16; typedef int32_t s32; typedef uint32_t u32; extern int adcVal[];//ADC 采样结果 extern char adcISRFlag;//ADC 中断标识 extern int16 degC; #define BAT_CHK_PRD 500 #define BAT_ALARM_VAL 3.65 #define BAT_OVERDIS_VAL 3.15 //电压信息结构体 typedef struct { float ADRef; // AD参考源 float Bat_K; // 计算电压值 char alarm; // 电池报警位 char chargeSta; // 充电状态 float BatteryVal; // 电压 int BatteryAD; // 电压 int overDischargeCnt; // 过放保护计数 float Calisum; }Bat_Typedef; extern Bat_Typedef Battery; /*函数声明*/ void BatteryCheckInit(void); int Get_Adc_Average(u8 ch,u8 times); int GetBatteryAD(u8 ch); void TemperatureCheck(void); void BatteryCheck(void); #endif /* INC_BATTERY_H_ */

    经过我的测试,该代码在TMS320F28035(64引脚)中可以通过ADCINA1通道正常采集到电源电压。由于工作需求现在我需要改用TMS320F28035(56引脚)的芯片,同样要采集电源电压,使用同样代码和ADCINA1通道,却没有成功采集得到真实电源电压,采集到的结果显示为0.0V左右, 我有如下问题:

    1.TMS320F28035(56引脚)的ADCINA1对应的管脚为12,而(64引脚)的ADCINA1对应的管脚为14,我是否需要在ccs软件中对管脚(或GPIO)进行配置?

    2.我画的硬件原理图如下,可以看到ADCINA1的采集线直接连接到电池电源线(1s锂电池供电满电电压4.2v),我并没有采取分压电路进行降压,有没有可能是ADCINA1接口已经被烧坏了?

    3.用上述代码在我绘制的控制板中运行程序,ADC采集到的电压值一直在0.055615v左右变换(最大不超过0.1v),这是不是表示ADCINA1采集口接地了?

    4.如果必须采用分压电路的话,那么分压ADC采集分压电路详细原理图该怎么画?

    5.我如果将ADC1采集口放在电容之后(如下图),可以不再增加其他分压电路直接使用吗?

    本人由于工作原因刚接触这些内容,对电路和dsp均不是很熟悉,问题可能很基础,但还是希望能获得您的帮助!急需解决该问题,谢谢您!

  • Hi,

    Please share the question in English 

    Thanks

    Swathy

  • OK,Thanks

  • Andy, 

    Are you planning to translate the question here or did you start a different thread?

    Best Regards,

    Ben Collier

  • Benjamin Collier,

    I translated Chinese into English and published a new post。Below is a link to the new post:

    TMS320F28035: Problems in using the ADC function of TMS320F28035 to collect the power supply voltage - C2000Tm︎ 微控制器论坛 - C2000 微控制器 - E2ETm 设计支持

    Hope to get your answer, thank you very much!

    Andy

  • Swathy La,

    I translated Chinese into English and published a new post。Below is a link to the new post:

    TMS320F28035: Problems in using the ADC function of TMS320F28035 to collect the power supply voltage - C2000︎ 微控制器论坛 - C2000 微控制器 - E2E 设计支持

    Hope to get your answer, thank you very much!

    Andy

  • Andy,

    Ok, then I will close this thread since it looks like you are being supported in the other thread.

    Best Regards,

    Ben Collier

  • Ben Collier,

    Thank you for your reply.But my problem still hasn't been solved. I hope I can get your help.

    TMS320F28035: Problems in using the ADC function of TMS320F28035 to collect the power supply voltage - C2000︎ 微控制器论坛 - C2000 微控制器 - E2E 设计支持

    My sincere thanks again.

    Best Regards,

    Andy

  • Ok, it looks like Yale has answered these questions.