找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2350|回复: 13
打印 上一主题 下一主题
收起左侧

关于单片机定时器中断程序分析

[复制链接]
跳转到指定楼层
楼主
ID:826204 发表于 2021-3-9 09:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
void clock(void) interrupt 3    //T1
{
  if(e>=10)
  {         
            if((e>=10&&e<80)||(e>=100))
        {
                        
                          if(i>=0&&i<422)
                      {
                                     if(i>=0&&i<25)                                         //z轴
                                  {
                                                                DIR2=1;
                                                                aa++;
                                                                shudu2=!shudu2;
                                                                TH1=(65536-30)/256;             //这里的定时器初始值重置,在指令执行时不执行,而是直接跳过,
                                                                TL1=(65536-30)%256;            //t调到最下面的定时器初始值设置,
                                  }
                                     else if(i>=25&&i<285)
                                 {
                                               if(e>=10&&e<80)
                                           {
                                                                 DIR2=1;
                                                                 shudu2=!shudu2;  
                                            }
                                               else
                                           {
                                                                  DIR2=0;
                                                                  shudu2=!shudu2;
                                           }
                                                                TH1=(65536-600)/256;
                                                                TL1=(65536-600)%256;
                                 }
                                    else
                                {     
                                               if(e>=10&&e<80)
                                            {         
                                                           if(i>=285&&i<310)
                                                      {
                                                                 DIR2=0;
                                                                 shudu2=!shudu2;        
                                                      }
                                                           else if(i>=310&&i<384)
                                                     {
                                                                  DIR=1;
                                                                  shudu=!shudu;
                                                     }
                                                           else
                                                     {
                                                                   DIR1=0;
                                                                   shudu1=!shudu1;
                                                     }
                                                                   aa++;
                                                                   TH1=(65536-30)/256;
                                                                   TL1=(65536-30)%256;
                                           }
                                 }
                         }
                }
             else
         {
                              if(i>=25&&i<310)
                        {
                                          if((i>=25&&i<99)||(i>=118&&i<192)||(i>=211&&i<285))   //y轴
                                     {
                                                       if(i>=118&&i<192)
                                                   {
                                                                   DIR=1;
                                                    }
                                                       else
                                                    {
                                                                   DIR=0;
                                                    }
                                                                   shudu=!shudu;
                                                    }
                                           else if((i>=99&&i<118)||(i>=192&&i<211))  //x轴
                                    {
                                                                   DIR1=1;
                                                                   shudu1=!shudu1;
                                     }  
                                          else
                                   {
                                                                   DIR2=0;
                                                                       shudu2=!shudu2;                                 
                                   }
                                                                    aa++;
                                                                    TH1=(65536-30)/256;                  //直接跳到这里  ,不知道为什么?
                                                                    TL1=(65536-30)%256;
                     }
             }
     }
}
因为控制3个步进电机  需要不同的速度 ,所以定时器的时间有大有小,  而程序直接跳到最下面的定时器初始值设置,这样3个步进电机的速度就一样了,有大佬帮忙看看为什么直接跳到最下面的定时器初始值设置吗
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:367369 发表于 2021-3-9 13:47 | 只看该作者
添加全局计次变量count;在定时器中断中自加

例如:1ms触发一次中;
需要10ms的中断时间就判断count为10的倍数时电机取反
if(count%10==0)
{
    motor1=!motor1;
}
需要3ms的中断时间就判断count为3的倍数时电机取反
if(count%3==0)
{
    motor2=!motor2;
}

然后让count在几种时间的公倍数时清零;上面这两个时间数值就可以让
if(count==3)
    count = 0;

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

板凳
ID:844772 发表于 2021-3-9 14:31 | 只看该作者
你想要30微秒左右的中断,但中断函数又写的特别长,我觉得它不是跳到下边,而是在反复进中断呢。这么短的时间,也就够计个数,还必须使用自动重装功能。

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

地板
ID:826204 发表于 2021-3-9 14:58 | 只看该作者
glinfei 发表于 2021-3-9 14:31
你想要30微秒左右的中断,但中断函数又写的特别长,我觉得它不是跳到下边,而是在反复进中断呢。这么短的时 ...

感谢您的回答
我仿真了一下  它在不符合if else语句的情况下 直接跳到了else的内部语句  也就是最下面我注释的地方
我想做的就是在重置完定时器初始值后 立马调出中断  这样就有30us的时间  进行进入中断的次数计数也是就是程序内的a++
所以  我想不明白的是 为什么在不符合else(e>80&&e<=100)语句的情况下  直接跳到了里面的执行语句
希望大佬费费心  帮忙看看  感谢
回复

使用道具 举报

5#
ID:826204 发表于 2021-3-9 15:05 | 只看该作者
game灬boy 发表于 2021-3-9 13:47
添加全局计次变量count;在定时器中断中自加

例如:1ms触发一次中;

感谢您的回答
我其中是需要一个力传感器来控制其中一个电机的正反向转动   从而达到控制执行机构接触工件的力恒定  不知道该怎么实现才好   
希望大佬帮帮忙
回复

使用道具 举报

6#
ID:844772 发表于 2021-3-9 16:10 | 只看该作者
旅途1 发表于 2021-3-9 15:05
感谢您的回答
我其中是需要一个力传感器来控制其中一个电机的正反向转动   从而达到控制执行机构接触工 ...

要是弄好了,分享一下呗。我觉得你直接上步进电机控制精度太差,不如上个带导杆的气缸,去控制气压来的方便。
回复

使用道具 举报

7#
ID:367369 发表于 2021-3-9 16:17 | 只看该作者
旅途1 发表于 2021-3-9 15:05
感谢您的回答
我其中是需要一个力传感器来控制其中一个电机的正反向转动   从而达到控制执行机构接触工 ...

直接检测力传感器引脚的电平,高电平设置motor=1;低电平设置motor=0;不就行了吗
if(ret==0)
motor=0;
else
motor=1;
直接在main函数的while(1)中写,或者定时器中断中每隔固定时间(如10ms)检测一次传感器状态

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

8#
ID:826204 发表于 2021-3-9 16:35 | 只看该作者
glinfei 发表于 2021-3-9 16:10
要是弄好了,分享一下呗。我觉得你直接上步进电机控制精度太差,不如上个带导杆的气缸,去控制气压来的方 ...

好的  没办法  做实验用 师傅要求
回复

使用道具 举报

9#
ID:826204 发表于 2021-3-9 16:43 | 只看该作者
game灬boy 发表于 2021-3-9 16:17
直接检测力传感器引脚的电平,高电平设置motor=1;低电平设置motor=0;不就行了吗
if(ret==0)
motor=0; ...

传感器是数字式的 不是模拟式的
而且执行机构是有弹性的钢丝刷   
在工作的过程中需要不停的调整电机  
来控制钢丝刷与工件的接触应力
回复

使用道具 举报

10#
ID:844772 发表于 2021-3-9 16:48 | 只看该作者
旅途1 发表于 2021-3-9 16:35
好的  没办法  做实验用 师傅要求

那有个小建议,算一下压力跟脉冲的关系,去几次测的均值打几个脉冲,不能高频率控制电机正反转的,考虑惯性啊,要查一下电机手册。
回复

使用道具 举报

11#
ID:367369 发表于 2021-3-9 17:00 | 只看该作者
旅途1 发表于 2021-3-9 16:43
传感器是数字式的 不是模拟式的
而且执行机构是有弹性的钢丝刷   
在工作的过程中需要不停的调整电机  ...

那就将判断条件改一下,如:
使用ret保存传感器返回值;
if(ret在范围1)//电机正转
motor=0;
else if(ret在范围2)//电机反转
motor=1;
可以放在while(1)中判断;
回复

使用道具 举报

12#
ID:826204 发表于 2021-3-9 17:18 | 只看该作者
glinfei 发表于 2021-3-9 16:48
那有个小建议,算一下压力跟脉冲的关系,去几次测的均值打几个脉冲,不能高频率控制电机正反转的,考虑惯 ...

好的  非常感谢
回复

使用道具 举报

13#
ID:826204 发表于 2021-3-9 17:19 | 只看该作者
game灬boy 发表于 2021-3-9 17:00
那就将判断条件改一下,如:
使用ret保存传感器返回值;
if(ret在范围1)//电机正转

好的  非常感谢
回复

使用道具 举报

14#
ID:367369 发表于 2021-3-9 17:34 | 只看该作者
旅途1 发表于 2021-3-9 17:19
好的  非常感谢

思路:

int count=0;  //计次变量    time = count * 0.1ms
T1_Init()
{
        定时器1初始化;
        设定计时周期 0.1ms ;
}

u8 get_num() //传感器值获取函数()
{
        u8 temp; //保存传感器值
        /*
                在此将传感器值保存于temp;
        */
        if(temp 在正转范围)
                return 0;
        if(temp 在反转范围)
                return 1;
}
int main()
{
        u8 flag_x=0;                //电机正反转标志位
        T0_Init();
        while(1)
        {
                flag_x = get_num();
                if(flag_x==0)
                        motor_x正转; //自行编写正转的条件
                if(flag_x==1)
                        motor_x反转;       
        }
        return 0;
}


void T1_clock(void) interrupt 3    //T1
{
        count++;
        if(count%3 == 0)         //计时时间为0.3ms   电机1 pwm生成
        {       
                motor_z = !motor_z;
                motor_x = !motor_x;
        }
        if(count%6 == 0)         //计时时间为0.6ms   电机2 pwm生成
        {
                motor_y = !motor_y;
                count = 0;
        }       
        else
                return ;
}

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表