我在 Arduino Nano 板上使用 Servo.h 和 SoftwareSerial.h 时遇到计时器冲突问题。现在我需要 2 对串行引脚,通过在我的笔记本电脑上使用 NFC 模块和 Arduino 的串行监视器。
如果我得到的信息没有错的话,Nano board 中提供了三个定时器(timer0、timer1、timer2)。我听说 timer1 是 16 位定时器,Servo.h 和 SoftwareSerial.h 在 Nano 板上同时使用该 timer1,这就是他们无法避免定时器冲突问题的原因。
然而,我需要在没有计时器冲突的情况下使用这两个头文件。在这种情况下,我该怎么办?我是否必须修改 Servo.h 文件才能不使用 timer1?
因为我对伺服电机所做的只是控制角位置。
因此,除非我使用 PWM 控制,否则在我正在进行的这个项目中使用 16 位定时器是没有用的。
所以,此时,我想使用 timer0 或 timer2(都是 8 位定时器)而不是使用 timer1。否则,Servo 和 Software 头文件中的 timer1 将发生冲突。以下是我使用的源代码。
const unsigned char wake[24]={
0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0xfd, 0xd4, 0x14, 0x01, 0x17, 0x00};//wake up NFC module
const unsigned char firmware[9]={
0x00, 0x00, 0xFF, 0x02, 0xFE, 0xD4, 0x02, 0x2A, 0x00};//
const unsigned char tag[11]={
0x00, 0x00, 0xFF, 0x04, 0xFC, 0xD4, 0x4A, 0x01, 0x00, 0xE1, 0x00};//detecting tag command
const unsigned char std_ACK[25] = {
0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x0C,
0xF4, 0xD5, 0x4B, 0x01, 0x01, 0x00, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x00};
unsigned char old_id[5];
unsigned char receive_ACK[25];//Command receiving buffer
//int inByte = 0; //incoming serial byte buffer
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#define print1Byte(args) mySerial.write(args)
#define print1lnByte(args) mySerial.write(args),mySerial.println()
#else
#include "WProgram.h"
#define print1Byte(args) mySerial.print(args,BYTE)
#define print1lnByte(args) mySerial.println(args,BYTE)
#endif
#include <Servo.h>
#include <NeoSWSerial.h>
NeoSWSerial mySerial(5,6);
volatile uint32_t newlines = 0UL;
Servo sv;
int pos1=0; //initial value = 93 degree
int pos2=180;
int sw1 = 4;
static void handleRxChar( uint8_t c )
{
if (c == '\n')
newlines++;
}
void setup(){
mySerial.attachInterrupt( handleRxChar );
pinMode(sw1, INPUT_PULLUP);
sv.attach(9);
Serial.begin(9600); // open serial with PC
mySerial.begin(9600); //open serial1 with device
//Serial2.begin(115200);
wake_card();
delay(100);
read_ACK(15);
delay(100);
display(15);
}
void loop(){
send_tag();
read_ACK(25);
delay(100);
if (!cmp_id ()) { //nfc tag
if (test_ACK ()) {
display (25);
sv.write(pos1);
delay(2500);
sv.write(pos2);
}
}
else if (cmp_id()){ // switch
if(digitalRead(sw1) == LOW){
sv.write(pos1); // waits 15ms for the servo to reach the position
}
else if(digitalRead(sw1) == HIGH){
sv.write(pos2);
}
}
copy_id ();
}
void copy_id (void) {//save old id
int ai, oi;
for (oi=0, ai=19; oi<5; oi++,ai++) {
old_id[oi] = receive_ACK[ai];
}
}
char cmp_id (void){//return true if find id is old
int ai, oi;
for (oi=0,ai=19; oi<5; oi++,ai++) {
if (old_id[oi] != receive_ACK[ai])
return 0;
}
return 1;
}
int test_ACK (void) {// return true if receive_ACK accord with std_ACK
int i;
for (i=0; i<19; i++) {
if (receive_ACK[i] != std_ACK[i])
return 0;
}
return 1;
}
void send_id (void) {//send id to PC
int i;
Serial.print ("ID: ");
for (i=19; i<= 23; i++) {
Serial.print (receive_ACK[i], HEX);
Serial.print (" ");
}
Serial.println ();
}
void UART1_Send_Byte(unsigned char command_data){//send byte to device
print1Byte(command_data);
#if defined(ARDUINO) && ARDUINO >= 100
mySerial.flush();// complete the transmission of outgoing serial data
#endif
}
void UART_Send_Byte(unsigned char command_data){//send byte to PC
Serial.print(command_data,HEX);
Serial.print(" ");
}
void read_ACK(unsigned char temp){//read ACK into reveive_ACK[]
unsigned char i;
for(i=0;i<temp;i++) {
receive_ACK[i]= mySerial.read();
}
}
void wake_card(void){//send wake[] to device
unsigned char i;
for(i=0;i<24;i++) //send command
UART1_Send_Byte(wake[i]);
}
void firmware_version(void){//send fireware[] to device
unsigned char i;
for(i=0;i<9;i++) //send command
UART1_Send_Byte(firmware[i]);
}
void send_tag(void){//send tag[] to device
unsigned char i;
for(i=0;i<11;i++) //send command
UART1_Send_Byte(tag[i]);
}
void display(unsigned char tem){//send receive_ACK[] to PC
unsigned char i;
for(i=0;i<tem;i++) //send command
UART_Send_Byte(receive_ACK[i]);
Serial.println();
}
概括
我在使用 Servo.h 和 SoftwareSerial.h 时遇到计时器冲突问题。
他们都同时共享 timer1。为了避免这种碰撞问题并使这两个工作正常,我应该怎么做?我应该对源代码做一些事情,比如添加几行代码或修改那些头文件吗?