36126浏览
查看: 36126|回复: 5

[求助] arduino程序语言中怎么实现两个程序同时运行?

[复制链接]

Rockets  NPC

发表于 2017-8-3 18:32:15

好像不可以,不过我想你大概想要说的是实现两个线程吧。
millis函数应该可以做到你想要的效果。
回复

使用道具 举报

hnyzcj  版主

发表于 2017-8-4 07:19:55

Rockets 发表于 2017-8-3 18:32
好像不可以,不过我想你大概想要说的是实现两个线程吧。
millis函数应该可以做到你想要的效果。 ...

:victory:
回复

使用道具 举报

fats114  初级技师

发表于 2017-8-4 14:55:04

从硬件理论上讲不可能,软件处理上来讲,单核单片机在多任务处理的时候,有以下方式实现多任务:中断、多线程、任务调度,但是说到底都是基于处理器内的堆栈寄存器的硬件中断切换,中断的形式分为外部计时器中断,内部计时器中断等,说到底就是基于计时器定期进行中断,在多个线程上进行轮询切换。
实际操作如下:
首先,Arduino只有一个CPU,要在一个CPU上实现多线程的话,最终都是通过软件实现的。从软件的角度把CPU的时间分成很小的时间片,看起来像是多个任务同时在运行。你可以考虑的是对你的循环做优化来实现你讲的“多线程”。
arduino的多线程问题其实在做相关硬件的时候都会碰到,有以下几种解决方式:
1、用多个arduino,鉴于arduino的cpu处理能力偏弱(特别是328P的uno)还有ALU、寄存器大小(涉及CPU内部结构,不解释),内部能用来做线程堆栈的空间很有限(有多夸张呢,你在一张a4纸上写满字,容量都比它大),uno往往开启第二个线程就会导致堆栈溢出(所以在进行SD卡SPI直读后转发解码器功放输出的时候,UNO卡带,MEGA1280断断续续,2560MEGA才能勉强播放)还有不管是用内部晶振还是外部晶振,计时器都不稳定(时间偏差很大,除非用外部的时钟模块,如ds系列),经常导致轮询出现莫名其妙的错误(很多国内厂商山寨的arduino板子甚至优于晶振对温度过于敏感,导致线程片选出现随机偏差,直观的讲就是应该看起来同时运行的线程感觉有一个特别快一个特别慢)。综上,土豪的解决办法是用多块arduino。
2、楼主的想法应该是使用一个arduino通过软件解决(上面的白写),稍微复杂一点的办法是用arduino IDE配合多线程库,在arduino IDE内部编写程序。现在比较成熟和流行的多线程有:Proto thread(PT)和SCoop(SC),两个库应该都能达到楼主想要的效果,库文件底层用的都是计时器中断(再一次证明了,现有的冯诺依曼架构的单核CPU要多线程只有在中断上做文章),唯一的区别是在Arduino 里的语法不一样。简单的说,一个arduino的程序一般都分为两个基本模块(OOP中称为方法),void setup()和void loop (),当然每个线程的定义都是在之外的独立方法里,程序最终运行的时候,PT是通过arduino的void setup()和void loop ()进行软硬件配置和调用运行,语法上和正常的程序无异,二SC是通过void setup()进行硬件设置并载入SCoop.start()启动任务管理器,运行则是通过void loop ()调用SC库内的yield()方法开干。从程序编写习惯上来讲PT更接近于普通Arduino程序,SC更接近于OOP(python、java)编程,在复杂任务下更稳定。这里新手建议用PT,但是如果线程数大于3个(情况很少,而且几乎把AVR的处理能力用尽了),建议用SC。
3、当然还有更复杂,逼格更高的,用VS、eclipse、AVR studio,在绑定相关硬件的库和查阅主控(一般是328p和2560)的datasheet后,直接用C或者汇编在程序中对寄存器进行中断操作,效率更高,但是对编程要求略高。
综上,楼主只要在论坛搜索Proto thread,马上能得到最有用的资料,论坛已经有大神,做了PT的简单介绍,如有看不懂的,再回复。
回复

使用道具 举报

pATAq  版主

发表于 2017-8-28 16:53:08

好问题~
回复

使用道具 举报

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

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail