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采集分压电路详细原理图该怎么画?





