打印
[PIC®/AVR®/dsPIC®产品]

加了几行或减掉几行无关的程序,程序效果不一样怎么办

[复制链接]
1530|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
kenan6615|  楼主 | 2013-7-23 14:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
程序调试有点奇怪,用的dsPIC30f3011芯片,有的时候AD采样不对,ADBUF中就不对了,采用的4个通道同时采样,转换有中断,中断读取AD值,有的时候值不对,但是加了几行或减掉几行无关的程序,好像就没有不对的AD值了,这个是为什么呢?我都快疯了
沙发
dgdz2c| | 2013-7-23 15:03 | 只看该作者
看看汇编符不符合你设计意思,PICC总是跟我想的不一样。

使用特权

评论回复
板凳
tianyazhix| | 2013-7-23 15:10 | 只看该作者
上传看看你写的代码

使用特权

评论回复
地板
kenan6615|  楼主 | 2013-7-24 09:23 | 只看该作者
int main (void)
{



       

        init();                //相关外设初始化
        KeyDelay(10);
        LED_PORT = 1;
        while(1)
        {
               
                if(HallIcStart() == 0)                //开启霍尔捕获中断
                {
                        MCPWMStop();        //禁止PWM
                        SlopeTmrStop();
                        CurrSpTmrStop();        //禁止斜坡定时器和电流定时器
       
                        while(1)
                        {
                                ;                                               
                        }

                }
               
       
               
       
                               
       
                        SlopeTmrStart();                        //开启斜坡定时器,暂时固定时间15s
                        CurrSpTmrStart();                //开启电流检测定时器
                        MCPWMStart();                        //开启PWM
                        ADMOD1Start();                        //开始电流采样
                        while(AdcIntBits.NewAdcCap == 0)       
                                ;
                        AdcIntBits.NewAdcCap = 0;

                        while(AdcIntBits.NewAdcCap == 0)       
                                ;
                        AdcIntBits.NewAdcCap = 0;
                        while(AdcIntBits.NewAdcCap == 0)       
                                ;
                        AdcIntBits.NewAdcCap = 0;       
                        HallIntFlagBits.PwmDisableFlag = 0;
                        //WDFEED0--------------------------------------------
                        while(1)
                        {
                                unsigned a = 0;
                                a = AccJudge();
                                if(a == 0)               
                                        ;
                                if(HallIntFlagBits.PwmDisableFlag == 1)
                                {
                                        MCPWMStop();
                                        ADMOD1Stop();
               
                                        SlopeTmrStop();                        //关闭斜坡定时器,暂时固定时间15s
                                        CurrSpTmrStop();                //关闭电流检测定时器
                                        LED_PORT = 1;                //LED亮
                                        LoopContiBits.ClosepLoopConti = 0;
                                        while(1)
                                                ;

                                }

                        }
                               
        }
       

        return(0);
}

使用特权

评论回复
5
kenan6615|  楼主 | 2013-7-24 09:23 | 只看该作者
void IcStart()
{
        T3CONbits.TON = 1;
        _IC1IE = 1;
        _IC2IE = 1;
        _IC7IE = 1;
}
unsigned int HallIcStart()
{
        HallIntFlagBits.HallErrSpFlag = 0;
        HallIntFlagBits.HallErrFlag = 0;
        HallIntFlagBits.PwmDisableFlag = 1;
        HallIntFlagBits.RevOpReqFlag = 0;
        HallIntFlagBits.SpeedFstCal = 1;        //捕获使能后放弃第一次捕获的定时器值
        HallIntFlagBits.HallOfen = 0;

        HallState_Main = ((PORTB&0x0010)>>2)+(PORTD&0x0003);       
//        HallState_Main = ((PORTB&0x0020)>>3)+(PORTD&0x0003);        //调试

        if(HallState_Main>7)
                return 0;
       

        LastHallState_Main = HallState_Main;       
       
        if(HallState_Main == HallErrCode[0] || HallState_Main == HallErrCode[1])
                return(0);
        else               
        {

                SpeedOverFlow = 0;
                SpeedCapValue_Main = 0;
                SpeedCapTime_Main = 0;
                IcStart();
                _T3IE = 1;
                return(1);
        }
       
}

void HallIcStop()
{
        T3CONbits.TON = 0;
        TMR3 = 0;
        _IC1IF = 0;
        _IC2IF = 0;
        _IC7IF = 0;
        _IC1IE = 0;
        _IC2IE = 0;
        _IC7IE = 0;
        _T3IE = 0;

}



void MCPWMStart()
{
        WIDTH = 0;
        PWMCON2bits.UDIS = 1;
        PDC1 = 0;
        PDC2 = 0;
        PDC3 = 0;
        PWMCON2bits.UDIS = 0;                        //占空比为0
        PTCONbits.PTEN = 1;
}

void MCPWMStop()
{
        PTCONbits.PTEN = 0;
        PTMR = 0;
        PWMCON2bits.UDIS = 1;
        PDC1 = 0;
        PDC2 = 0;
        PDC3 = 0;
        PWMCON2bits.UDIS = 0;                        //占空比为0
        WIDTH = 0;
        OVDCON = 0;

}


//三个捕获中断都用一个中断处理函数
void  __attribute__((interrupt,no_auto_psv)) _IC1Interrupt()
{
//清中断标志,暂时没有分具体是哪个中断
        _IC1IF = 0;                //c
        _IC2IF = 0;                //b
        _IC7IF = 0;                //a


}


void  __attribute__((interrupt,no_auto_psv)) _T3Interrupt()
{
        _T3IF = 0;
        if(SpeedOverFlow<0xFFFF)
                SpeedOverFlow ++;
        else
                SpeedOverFlow = 0xFFFF;
        TMR3 = 0;
}

使用特权

评论回复
6
kenan6615|  楼主 | 2013-7-24 09:24 | 只看该作者
//斜坡定时器
void SlopeTmrStop()
{
        _T1IE = 0;
        T1CONbits.TON = 0;
        TMR1 = 0;
        _T1IF = 0;
       
}
//电流定时器
void CurrSpTmrStop()
{
        _T4IE = 0;
        T4CONbits.TON = 0;
        TMR4 = 0;
        _T4IF = 0;
       
}

void T1Start()
{
       
        TMR1 = 0;
        _T1IF = 0;
        _T1IE = 1;
        T1CONbits.TON = 1;
}
void SlopeTmrStart()
{
        SlopeTimeFlagBits.SlopeTimeFlag = 0;
        T1Start();
}

void T4Start()
{
       
        TMR4 = 0;
        _T4IF = 0;
        _T4IE = 1;
        T4CONbits.TON = 1;
}

void CurrSpTmrStart()
{//刚开始运行,各定时器标志位初始化
        TmrIntFlagBits.TempTimeFlag = 0;
        TmrIntFlagBits.AccGivenTimeFlag = 0;
        TmrIntFlagBits.CurrTimeFlag = 0;
        TmrIntFlagBits.OctTimeFlag = 0;

        AccGivenCnt = AccGivenTime;
        TempCalCnt = TempCalTime;       
        OverCurrCnt = OverCurrTime;
        RequestFlagBits.OctReqFlag = 0;
        FaultFlagBits.OverCurrErr = 0;
        FaultFlagBits.OverCurr = 0;       
        TmpFlagBits.sd75 = 0;
        TmpFlagBits.sd50 = 0;

        T4Start();
       
}
void  __attribute__((interrupt,no_auto_psv)) _T4Interrupt()
{
        _T4IF = 0;
        TMR4 = 0;
       

}

//斜坡
void  __attribute__((interrupt,no_auto_psv)) _T1Interrupt()
{
        _T1IF = 0;
        TMR1 = 0;
        SlopeTimeFlagBits.SlopeTimeFlag = 1;

}

使用特权

评论回复
7
kenan6615|  楼主 | 2013-7-24 09:24 | 只看该作者
void KeyDelay(unsigned int N)
{
        unsigned int j;
        while(N--)
                for(j=0;j<MILLISEC;j++);
}


//采样加速器,加速器信号大小判断,太小设置相关标志位返回0,正常返回1
unsigned int AccJudge()
{

        if(_ADIE == 1)
        {

                _ADIE = 0;
                AccVoltAD = (AccVoltAdData[0]+AccVoltAdData[1]+AccVoltAdData[2])/3;       
                _ADIE = 1;
        }
        else
                AccVoltAD = (AccVoltAdData[0]+AccVoltAdData[1]+AccVoltAdData[2])/3;                       
        if(AccSmall)
        {
                RequestFlagBits.NotOperReqFlag = 1;
                HallIntFlagBits.PwmDisableFlag = 1;//关PWM
        //或RequestFlagBits.ReduceRegFlag = 1;
                return(0);
        }
        else
        {
                //或RequestFlagBits.ReduceRegFlag = 0;
                return(1);
        }
}

使用特权

评论回复
8
kenan6615|  楼主 | 2013-7-24 09:25 | 只看该作者
void ADMOD1Start()
{
        ADCON1 = 0x00E8;        //内部计数器结束采样并开始转换,同时采样4通道、转换后自动开始采样

        ADCHS = 0x0003;                //CH0暂时选
        ADCSSL = 0x0000;        //AN6
        ADCON3 = 0x0514;        //可适当加长TAD,
        ADCON2 = 0X0300;

        _ADIF = 0;
        _ADIE = 1;
        _ADON = 1;                //开启A/D
        _SAMP = 1;                //开始采样       

}

void ADMOD1Stop()
{
        _ADIE = 0;                //禁止AD中断
        _ADON = 0;
        _SAMP = 0;
        _ADIF = 0;
       
        _DONE = 0;
        ADCON1 = 0;
        ADCON3 = 0;
        ADCON2 = 0;
}


void  __attribute__((interrupt,no_auto_psv)) _ADCInterrupt()
{
        _ADIF = 0;
        _ADON = 0;

       



        BatVoltAdData[0] = BatVoltAdData[1];
        BatVoltAdData[1] = BatVoltAdData[2];
        BatVoltAdData[2] = ADCBUF0;
//        if(BatVoltAdData[2]>0x1a5||BatVoltAdData[2]<0x195)
//        {
//                BatVoltAdData[2]=BatVoltAdData[2];
//        }

        CurrentAdData[0] = CurrentAdData[1];
        CurrentAdData[1] = CurrentAdData[2];
        CurrentAdData[2] = ADCBUF1;

        TempratureAdData[0] = TempratureAdData[1];
        TempratureAdData[1] = TempratureAdData[2];
        TempratureAdData[2] = ADCBUF2;



        AccVoltAdData[0] = AccVoltAdData[1];
        AccVoltAdData[1] = AccVoltAdData[2];
        AccVoltAdData[2] = ADCBUF3;
//        if(AccVoltAdData[2]>0x0d5|| AccVoltAdData[2]<0x0c0)
//        {
//                AccVoltAdData[2]=AccVoltAdData[2];
//        }

       
        _ADON = 1;                //开启A/D
        _SAMP = 1;





        AdcIntBits.NewAdcCap = 1;
}

使用特权

评论回复
9
kenan6615|  楼主 | 2013-7-24 09:26 | 只看该作者
我把程序精简成这样了,还是有ADBUF不对的地方,其中捕获中断多一点

使用特权

评论回复
10
kenan6615|  楼主 | 2013-7-24 16:19 | 只看该作者
修改ADCON3,即TAD和采样时间,效果不一样,好像和采样时间长短无关,好像采样转换时间短了出现问题倒少了?

使用特权

评论回复
11
yewuyi| | 2013-7-24 17:28 | 只看该作者
采样时间过长或过短都不对。

使用特权

评论回复
12
yewuyi| | 2013-7-24 17:29 | 只看该作者
如果有通道切换,还需要给足够的通道切换时间。

使用特权

评论回复
13
kenan6615|  楼主 | 2013-7-25 10:18 | 只看该作者
没有切换,一个CH上是固定的
看了手册,“由于采样电容最终将放电,大于100 us 的时钟周期将影响线性性能(尤其在温度上升时)”,计算了一下,是大于100us,但是一个CH采样保持上不切换通道的话,电容影响电压变化呗,但是我的外部电路就是电池电压经电阻分压得到的电压,理论上电压不变,但是ADBUF里有时为0,不太可理解啊

使用特权

评论回复
14
XIEYUANBIN| | 2013-7-25 17:00 | 只看该作者
AD的时钟周期过长的话,AD采样电容上的电会漏掉,从而使你的AD结果不准。开始转换之后采样电容就从AD通道断开了。所以你要准确,一直要保证电路连接

使用特权

评论回复
15
kenan6615|  楼主 | 2013-7-26 10:45 | 只看该作者
不改通道,采样电容也会断开啊?

使用特权

评论回复
16
XIEYUANBIN| | 2013-7-26 11:05 | 只看该作者
保持ADON = 1,选择合适的通道,合适的触发方式。

使用特权

评论回复
17
XIEYUANBIN| | 2013-7-26 11:06 | 只看该作者
3011我一直用的,没碰到你这种情况,一般都是程序出问题。

使用特权

评论回复
18
kenan6615|  楼主 | 2013-7-26 12:46 | 只看该作者
弄了好长时间,没发现什么问题啊,出现地址堆栈错误,错误的地方一看堆栈还是中断的第一句,就是是中断没开始时处的错误。把一个函数去掉,好像没有地址堆栈错误了,把函数内容贴到原来地方,好像也没有地址堆栈错误了,我都快疯了

使用特权

评论回复
19
兰天白云| | 2013-7-26 13:38 | 只看该作者
不用中断用查询试试看,仪表这种问题与配置和转换代码有关

使用特权

评论回复
20
kenan6615|  楼主 | 2013-7-26 13:47 | 只看该作者
是的,我改了,好像没有了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

42

帖子

0

粉丝