打印
[技术问答]

n76e003 一个想不通的问题请教

[复制链接]
693|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 dfbb123wef 于 2020-9-27 09:03 编辑

用n76e003 控制 一个 直流电机出现怪事 程序简单描述如下
if(a){//如果有串口接收就运行以下程序
  if(x>b){
    f1();//这里放电机正转
      while(1)
        if(x<b)break;//电机已经转到位了
  }else {
    f2();/这里放/电机反转
      while(1)
        if(x>b)break;//电机已经转到位了
    }
  f3();//这里放电机停止程序
}
x为串口输入产生,b为编码器数值,由 200us的定时器 通过检测A,B线 加加减减产生
现在问题是有一定概率电机没转到x处就停了,为什么?
我把if(x<b)break;  改为if(x<b)if(x<b)break;       if(x>b)break;  改为if(x>b)if(x>b)break;
就正常了,谁能帮我分析下,谢谢!!

使用特权

评论回复
沙发
dfbb123wef|  楼主 | 2020-9-27 09:10 | 只看该作者
我自己猜,是否跟原子操作有关吗?但那不是指中断和主程序对同一个变量写操作时才发生的吗?我在主程序只是读,难道也会出问题?想不通,但我描述的现象确实存在。望有高手帮我分析下,谢谢。

使用特权

评论回复
板凳
gaoyang9992006| | 2020-9-27 12:52 | 只看该作者
看不明白你是想让电机转到哪儿停。
x大于b时候正转,一直转到小于b, 然后呢执行f3停止。
下一轮,
x已经小于b了,这个时候执行f2,一直到大于b,然后停止。。
如果你的a一直为真就会这么不停的正反转下去。
那么你考虑当等于b的情况没。不知道你这到底干啥啊。

使用特权

评论回复
地板
dfbb123wef|  楼主 | 2020-9-27 15:34 | 只看该作者
本帖最后由 dfbb123wef 于 2020-9-27 15:35 编辑
gaoyang9992006 发表于 2020-9-27 12:52
看不明白你是想让电机转到哪儿停。
x大于b时候正转,一直转到小于b, 然后呢执行f3停止。
下一轮,

a为真就进入函数,在函数最后面有清零a。(忘了加,抱歉!)
程序过程是接收到有串口数据,就进一次,然后退出,等下一次串口发送数据。
程序没有完整贴出来,不好意思,但这不是重点。重点是为什么if判断2次就正常,1次就会概率性的电机提前停止?

使用特权

评论回复
5
pigluffy| | 2020-9-27 15:39 | 只看该作者
因為是中斷的關係,b定義成Volatile比較保險

使用特权

评论回复
6
dfbb123wef|  楼主 | 2020-9-27 15:44 | 只看该作者
当电机提前停止时,用串口输出查看x,b都为正常,编码器b数值并没有错误,也就是说 if(x<b)break;  x>b时确执行了break;怪事就在这里。

使用特权

评论回复
评论
mailshichao 2020-9-27 16:58 回复TA
那就说应该跟程序没有关系, 程序是根据正确的数据进行运行的;那就是跟数据的来源有关系了,是不是编码器识别有问题呢? 
7
dfbb123wef|  楼主 | 2020-9-27 17:01 | 只看该作者
pigluffy 发表于 2020-9-27 15:39
因為是中斷的關係,b定義成Volatile比較保險

试了下,x和b都加了 volatile  现象依旧。

使用特权

评论回复
8
dfbb123wef|  楼主 | 2020-9-27 17:12 | 只看该作者
又试了下,魔法棒里的c51里的,那是不是叫优化等级的一项,里面有10个等级,试了几个,还是失望,但只要if来2次就正常,我真是奇了怪了。

使用特权

评论回复
9
pigluffy| | 2020-9-27 17:35 | 只看该作者
dfbb123wef 发表于 2020-9-27 17:12
又试了下,魔法棒里的c51里的,那是不是叫优化等级的一项,里面有10个等级,试了几个,还是失望,但只要if ...

不然選擇不優化看有解決嗎

使用特权

评论回复
10
dfbb123wef|  楼主 | 2020-9-27 17:45 | 只看该作者
pigluffy 发表于 2020-9-27 17:35
不然選擇不優化看有解決嗎

选0是吧,试过,编译代码增加了些,现象依旧。
虽然我知道解决办法,这办法也不增加多少代码量,也不拖慢系统,算得上是完美,只是我想知道为什么这样?

使用特权

评论回复
11
sjnh| | 2020-9-27 17:59 | 只看该作者
难道是16位的原因,x,b定义的是8位,还是16位?

使用特权

评论回复
12
dfbb123wef|  楼主 | 2020-9-27 18:00 | 只看该作者
sjnh 发表于 2020-9-27 17:59
难道是16位的原因,x,b定义的是8位,还是16位?

都是16位的,什么意思?

使用特权

评论回复
评论
dfbb123wef 2020-9-27 18:27 回复TA
@sjnh :有道理啊,牛人一个,多谢解答!!! 
sjnh 2020-9-27 18:09 回复TA
就是8位机操作16位数,内部汇编实际分成很多步,例如你原来的数是00ff,中断里面加1就变成0100,但主程序有可能已经把低字节已经读到acc里面了,结果退出中断后主程序再读高字节,则主程序实际操作的是01ff,而不是0100、 参考单片机定时器读操作 
13
dfbb123wef|  楼主 | 2020-9-27 18:40 | 只看该作者
结贴,答案以由sjnh给出,再次感谢,豁然开朗的感觉真的很好。

使用特权

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

本版积分规则

3

主题

21

帖子

0

粉丝