[51单片机] 几个中断来回交替,如何调整流程?

[复制链接]
 楼主| 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,表明是第二次定时积分,切换到导线电压测量通道。

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

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


dirtwillfly 发表于 2015-6-8 21:46 | 显示全部楼层
感谢分享
 楼主| any_014 发表于 2015-6-9 09:03 | 显示全部楼层

还没搞成呢...
 楼主| any_014 发表于 2015-6-10 16:51 | 显示全部楼层
  1. void exint1() interrupt 2
  2. {
  3.         TR0 = 0;                                                //¹Ø±Õ¶¨Ê±Æ÷£»
  4.         timer_flag = 1;
  5.         switch(adc2dac_flag)
  6.         {
  7.                 case 00:
  8.                         P1 &= 0xf0;                                //Çл»µ½±»²âÐźŵçѹͨµÀ¿ªÆô¶¨Ê±Æ÷Æô¶¯20msÑÓʱ
  9.                         P1 |= 0x02;
  10.                         TL0 = T20MS;                        //¶¨Ê±Æ÷¸³³õÖµ£¬20ms¼ÆÊ±
  11.                         TH0 = T20MS >> 8;
  12.                         TR0 = 1;
  13.                         break;
  14.                 case 01:
  15.                         temp1 = TH0;                        //¼Ç¼ͨµÀ2(µç×èµçѹͨµÀ)·´Ïò»ý·Ö¼ÆÊ±
  16.                         temp2 = TL0;
  17.                         P1 &= 0xf0;                                //Çл»µ½Ï߶˵çѹͨµÀ¿ªÆô¶¨Ê±Æ÷Æô¶¯20msÑÓʱ
  18.                         P1 |= 0x01;
  19.                         TL0 = T20MS;                        //¶¨Ê±Æ÷¸³³õÖµ£¬20ms¼ÆÊ±
  20.                         TH0 = T20MS >> 8;
  21.                         TR0 = 1;                                //¿ªÆô¼ÆÊ±Æ÷
  22.                         break;
  23.                 case 02:
  24.                         temp3 = TH0;                        //¼Ç¼ͨµÀ2(µç×èµçѹͨµÀ)·´Ïò»ý·Ö¼ÆÊ±
  25.                         temp4 = TL0;
  26.                         P1 &= 0xf0;                                //Çл»µ½±»²âÐźŵçѹͨµÀ
  27.                         P1 |= 0x02;
  28.                         TL0 = T20MS;                        //¶¨Ê±Æ÷¸³³õÖµ£¬20ms¼ÆÊ±
  29.                         TH0 = T20MS >> 8;
  30.                         TR0 = 1;
  31.                         timer_flag = 0;
  32.                         break;
  33.                 default:
  34.                         SendData(0xFF);
  35.         }
  36.         RUNLED = 0;
  37. }
  1. void tm0_isr() interrupt 1 using 2
  2. {
  3.         TR0 = 0;                                                //¹Ø±Õ¶¨Ê±Æ÷£»
  4.         if(timer_flag)
  5.         {
  6.                 TH0 = TL0 = 0;                                        //¶¨Ê±Æ÷ÖµÇåÁ㣻
  7.                 P1 &= 0xf0;                                                //Çл»µ½Í¨µÀ7(»ù×¼µçѹÐźÅͨµÀ)¿ªÆô¶¨Ê±Æ÷¼ÆÊ±£»
  8.                 P1 |= 0x07;
  9.                 timer_flag = 0;
  10.         }
  11.         else
  12.         {
  13.                 P1 &= 0xf0;                                                //Çл»µ½Í¨µÀ7(»ù×¼µçѹÐźÅͨµÀ)¿ªÆô¶¨Ê±Æ÷¼ÆÊ±£»
  14.                 P1 |= 0x02;
  15.         }
  16.         RUNLED = 1;
  17.         TR0 = 1;                                                //¿ªÆô¶¨Ê±Æ÷¼ÆÊ±£»
  18.         adc2dac_flag++;
  19. }
  1. void Adc2Dac()
  2. {
  3.         SendData(0xBB);
  4.         adc2dac_flag = 0;
  5.         P1 &= 0xf0;                                                //Çл»µ½Í¨µÀ7(»ù×¼µçѹÐźÅͨµÀ)£¬È·¶¨»ý·ÖÁãλ£»
  6.         P1 |= 0x07;       
  7.         while(adc2dac_flag != 3);                //µÈ´ý»ý·Ö½áÊø£»
  8.         temp_value = Adc_Process(temp1, temp2, temp3, temp4);        //½«·´Ïò»ý·Ö¼ÆÊ±Öµ»»Ëã³ÉζÈ
  9.         temp2_value = Dac_Process(temp_value);                                        //½«Î¶ÈÖµ»»Ëã³ÉPWM²¨Õ¼¿Õ±È£¬Êä³ö4-20mA
  10.         CCAP1H = temp2_value >> 8;
  11.         CCAP1L = temp2_value;
  12. }
算是能运行一次Adc2Dac()函数,就执行一次双积分运算。

不过每次上电后发送对同一个信号测量,结果每次都不一样。这个问题我再单独开个帖子提问吧。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

132

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部