常常有人用到定时器的中断(或外部中断),
然后想要使用 Serial.print 或 Serial.println 送数据到串口监视器查看,
可是却常常有人发现加了一些 Serial.println 之后可能很快就不动了 !?
官方网站也建议在 ISR( ) 內或是在用 attachInterrupt 连接的中断处理程序內,
最好不要使用 Serial.print 或 Serial.println 这类函数 (function) !
那到底在 中断处理程序內 可不可以用 Serial.print 和 Serial.println 呢 ?
其实答案是勉强可以用 Serial.print( ) 与 Serial.println( ) 的 !
为何说勉强可以, 不是说不可以, 也不说可以 ?
因为, 只要你的中断请求的间隔时间不是太短, 那使用 Serial.print 其实並不会有问题 !
怎样才叫做太短呢? 就是短到 Serial.print 来不及或快要来不及也可能会有问题!
如果你的中断一秒才来一次或更久才来一次, 那用 Serial.println应该没问题
如果你的中断请求是 1ms 来一次,那肯定来不及 !!
原因很简单, 来不及打印 Serial.println( ) 要求送出的字符串。
奇怪!?
不是说 Arduino CPU 在 16MHz 的时脉 (Clock)之下, 最快 1us 可以做 16 个指令,
那 1ms 就可以做 16000 个指令了,怎会小小 Serial.print 一下就来不及呢?
原因当然就是 Serial.print 很慢很慢 !
其实, 所谓 1us (micro second)可以做 16 个指令是指最简单的机器指令,
对於 C/C++ 写的每句指令因为相当於数个到数十个机器指令,
所以 C/C++ 每句指令大多数要 0.5 us 到 1 us甚至更多的时间(例如调用 millis( ) 或调用 micros( ) 就大约要 2 us)。
聪明的你已经算出那这样 1ms 还是可以做大约数百甚至多到两千个 C/C++ 指令 !
没错, 可是, 在 Baud rate (波特率) 9600 的情况下, 打印一个 char 就要大约 1ms = 1000us 的时间。
这是可以算的, 9600bps 意思就是每秒 9600 bit,
一个 char 要用 10 bit,包括內容 8 bit,开始(Start) 1 bit,结束(STOP) 1 bit,
所以,9600bps 意思就是每秒大约 9600/10 = 960 char (Byte);
这意思就是 1 char 大约要 1ms = 1000 us 的时间 (1秒/960 = 1.04ms) !
P.S.
Serial.print 本身要花时间且传送要做一点准备工作也要一点时间,
还有, 1秒 / 960 char 这样 1 char 是 1.04ms, 所以印 100 char 要大约 104.03 ms
|