打印
[51单片机]

几个中断来回交替,如何调整流程?

[复制链接]
935|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
any_014|  楼主 | 2015-6-6 14:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 any_014 于 2015-6-6 16:40 编辑

正在做个单片机控制的双积分ADC电路,原来是这样实现的:正向积分(对被测信号定时积分)->时间到后引发定时器中断,切换通道,反向积分(对基准信号定值积分)->运放输出高或低到一定值引发单片机外部中断,此次反向积分的时间,和输入信号成比例。

后来,加入串口收发部分,将捕获的计时时间发出去;
现在发现,每次上电后,对同一个输入信号,左后捕获的计时时间不一致。现在也没明白是什么引起的?
串口收发中断引起?硬件有问题?

现在是想将串口收发这部分独立出来。主循环里不再一直进行正向积分,反向积分了,而是每完成一次双积分后做一次串口发送。
这样就有了个新问题,第一次积分时,运放输出初始电压不固定,那么第一次积分就不能计时了,需要从第二次积分开始算。
于是有:1.定值积分(计时无效)->2.定时积分(对被测信号的正向积分)->3.定值积分(反向积分,计时器计时有效)。

还有,由于要排除引线电阻干扰,所以要对引线上的带电压信号进行测量,所以由每次运算有3次积分变成5次积分:
1.定值积分1(计时无效)->
2.定时积分1(对被测信号的正向积分)->
3.定值积分2(反向积分,计时器计时有效,结果和被测电压成正比)->
4.定时积分1(对被测导线电压信号的正向积分)->
5.定值积分3(反向积分,计时器计时有效,结果和导线电压成正比)->积分运算结束,开始串口发送。

这个怎么写合适呢?感觉很乱,自己也是整理了下思路才汇总成以上。



相关帖子

沙发
any_014|  楼主 | 2015-6-6 15:31 | 只看该作者
本帖最后由 any_014 于 2015-6-6 15:34 编辑

现在是想设个变量,开始积分时,将其设为0,然后无论定时器中断还是外部中断,中断处理的最后将其加一。
那么在外部中断里,用swith语句判断其值。
      如果是0,表明是第一次定值积分,切换到基准信号通道;
      如果是2,表明是第二次定值积分,将计数器值保存,切换到基准信号通道;
      如果是4,表明是第三次定值积分,计数器值和导线电压成正比,保留。
在定时器中断里,也用switch判断其值。
      如果是1,表明是第一次定时积分,切换到被测信号通道;
      如果是3,表明是第二次定时积分,切换到导线电压测量通道。

void exint1() interrupt 2
{
        TR0 = 0;                                                //¹Ø±Õ¶¨Ê±Æ÷£»
        switch(adc2dac_flag)
        {
                case 00:
                case 02:
                        temp1 = TH0;                        //¼Ç¼ͨµÀ2(µç×èµçѹͨµÀ)·´Ïò»ý·Ö¼Æʱ
                        temp2 = TL0;
                        P1 &= 0xf0;                                //Çл»µ½Ï߶˵çѹͨµÀ¿ªÆô¶¨Ê±Æ÷Æô¶¯20msÑÓʱ
                        P1 |= 0x01;
                        TL0 = T20MS;                        //¶¨Ê±Æ÷¸³³õÖµ£¬20ms¼Æʱ
                        TH0 = T20MS >> 8;
                        TR0 = 1;                                //¿ªÆô¼ÆʱÆ÷
                        break;
                case 04:
                        temp3 = TH0;                        //¼Ç¼ͨµÀ2(µç×èµçѹͨµÀ)·´Ïò»ý·Ö¼Æʱ
                        temp4 = TL0;
                        break;
        }
        RUNLED = 0;
        adc2dac_flag++;
}

void tm0_isr() interrupt 1 using 2
{
        TR0 = 0;                                                //¹Ø±Õ¶¨Ê±Æ÷
        switch(adc2dac_flag)
        {
                case 01:
                        P1 &= 0xf0;                                        //Çл»µ½Í¨µÀ7(»ù×¼µçѹÐźÅͨµÀ)¿ªÆô¶¨Ê±Æ÷¼Æʱ
                        P1 |= 0x07;
                        break;
                case 03:
                        P1 &= 0xf0;                                        //Çл»µ½Í¨µÀ2(±»²âµçѹÐźÅͨµÀ)¿ªÆô¶¨Ê±Æ÷Æô¶¯20msÑÓʱ
                        P1 |= 0x02;
                        break;
        }
        RUNLED = 1;
        TR0 = 1;                                                //¿ªÆô¶¨Ê±Æ÷¼Æʱ
        adc2dac_flag++;
}


使用特权

评论回复
板凳
dirtwillfly| | 2015-6-8 21:46 | 只看该作者
感谢分享

使用特权

评论回复
地板
any_014|  楼主 | 2015-6-9 09:03 | 只看该作者

还没搞成呢...

使用特权

评论回复
5
any_014|  楼主 | 2015-6-10 16:51 | 只看该作者
void exint1() interrupt 2
{
        TR0 = 0;                                                //¹Ø±Õ¶¨Ê±Æ÷£»
        timer_flag = 1;
        switch(adc2dac_flag)
        {
                case 00:
                        P1 &= 0xf0;                                //Çл»µ½±»²âÐźŵçѹͨµÀ¿ªÆô¶¨Ê±Æ÷Æô¶¯20msÑÓʱ
                        P1 |= 0x02;
                        TL0 = T20MS;                        //¶¨Ê±Æ÷¸³³õÖµ£¬20ms¼Æʱ
                        TH0 = T20MS >> 8;
                        TR0 = 1;
                        break;
                case 01:
                        temp1 = TH0;                        //¼Ç¼ͨµÀ2(µç×èµçѹͨµÀ)·´Ïò»ý·Ö¼Æʱ
                        temp2 = TL0;
                        P1 &= 0xf0;                                //Çл»µ½Ï߶˵çѹͨµÀ¿ªÆô¶¨Ê±Æ÷Æô¶¯20msÑÓʱ
                        P1 |= 0x01;
                        TL0 = T20MS;                        //¶¨Ê±Æ÷¸³³õÖµ£¬20ms¼Æʱ
                        TH0 = T20MS >> 8;
                        TR0 = 1;                                //¿ªÆô¼ÆʱÆ÷
                        break;
                case 02:
                        temp3 = TH0;                        //¼Ç¼ͨµÀ2(µç×èµçѹͨµÀ)·´Ïò»ý·Ö¼Æʱ
                        temp4 = TL0;
                        P1 &= 0xf0;                                //Çл»µ½±»²âÐźŵçѹͨµÀ
                        P1 |= 0x02;
                        TL0 = T20MS;                        //¶¨Ê±Æ÷¸³³õÖµ£¬20ms¼Æʱ
                        TH0 = T20MS >> 8;
                        TR0 = 1;
                        timer_flag = 0;
                        break;
                default:
                        SendData(0xFF);
        }
        RUNLED = 0;
}
void tm0_isr() interrupt 1 using 2
{
        TR0 = 0;                                                //¹Ø±Õ¶¨Ê±Æ÷£»
        if(timer_flag)
        {
                TH0 = TL0 = 0;                                        //¶¨Ê±Æ÷ÖµÇåÁ㣻
                P1 &= 0xf0;                                                //Çл»µ½Í¨µÀ7(»ù×¼µçѹÐźÅͨµÀ)¿ªÆô¶¨Ê±Æ÷¼Æʱ£»
                P1 |= 0x07;
                timer_flag = 0;
        }
        else
        {
                P1 &= 0xf0;                                                //Çл»µ½Í¨µÀ7(»ù×¼µçѹÐźÅͨµÀ)¿ªÆô¶¨Ê±Æ÷¼Æʱ£»
                P1 |= 0x02;
        }
        RUNLED = 1;
        TR0 = 1;                                                //¿ªÆô¶¨Ê±Æ÷¼Æʱ£»
        adc2dac_flag++;
}
void Adc2Dac()
{
        SendData(0xBB);
        adc2dac_flag = 0;
        P1 &= 0xf0;                                                //Çл»µ½Í¨µÀ7(»ù×¼µçѹÐźÅͨµÀ)£¬È·¶¨»ý·ÖÁãλ£»
        P1 |= 0x07;       
        while(adc2dac_flag != 3);                //µÈ´ý»ý·Ö½áÊø£»
        temp_value = Adc_Process(temp1, temp2, temp3, temp4);        //½«·´Ïò»ý·Ö¼Æʱֵ»»Ëã³ÉζÈ
        temp2_value = Dac_Process(temp_value);                                        //½«Î¶ÈÖµ»»Ëã³ÉPWM²¨Õ¼¿Õ±È£¬Êä³ö4-20mA
        CCAP1H = temp2_value >> 8;
        CCAP1L = temp2_value;
}
算是能运行一次Adc2Dac()函数,就执行一次双积分运算。

不过每次上电后发送对同一个信号测量,结果每次都不一样。这个问题我再单独开个帖子提问吧。

使用特权

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

本版积分规则

17

主题

132

帖子

3

粉丝