초당 800 번 함수를 호출하기 위해 타이머를 설정하고 싶습니다. 프리스케일러가 1024 인 Arduino Mega 및 Timer3을 사용하고 있습니다. 프리스케일러 요소를 선택하려면 다음 단계를 고려했습니다.
- CPU 주파수 : 16MHz
- 타이머 해상도 : 65536 (16 비트)
- 선택한 프리스케일러로 CPU 주파수를 나눕니다 : 16x10 ^ 6 / 1024 = 15625
- 나머지를 원하는 주파수 62500 / 800 = 19로 나눕니다 .
- 결과 + 1을 OCR3 레지스터에 넣습니다.
다음 표를 사용하여 TCCR3B의 레지스터를 설정했습니다.
오류
코드를 컴파일하는 것은 불가능합니다. 이것은 컴파일러가 반환 한 오류입니다.
서보 \ Servo.cpp.o : 함수 '__vector_32'에서 : C : \ Program Files (x86) \ Arduino \ libraries \ Servo / Servo.cpp : 110 : '__vector_32'의 다중 정의 AccelPart1_35.cpp.o : C : \ 프로그램 파일 (x86) \ Arduino / AccelPart1_35.ino : 457 : 여기에 처음 정의 된 c : / 프로그램 파일 (x86) / arduino / hardware / tools / avr / bin /../ lib / gcc / avr / 4.3.2 /. ./../../../avr/bin/ld.exe : 완화 비활성화 : 여러 정의에서 작동하지 않습니다.
코드
volatile int cont = 0;
unsigned long aCont = 0;
void setup()
{
[...]
// initialize Timer3
cli(); // disable global interrupts
TCCR3A = 0; // set entire TCCR3A register to 0
TCCR3B = 0; // same for TCCR3B
// set compare match register to desired timer count: 800 Hz
OCR3A = 20;
// turn on CTC mode:
TCCR3B |= (1 << WGM12);
// Set CS10 and CS12 bits for 1024 prescaler:
TCCR3B |= (1 << CS30) | (1 << CS32);
// enable timer compare interrupt:
TIMSK3 |= (1 << OCIE3A);
// enable global interrupts:
sei();
}
void loop()
{
// Print every second the number of ISR invoked -> should be 100
if ( millis() % 1000 == 0)
{
Serial.println();
Serial.print(" tick: ");
Serial.println(contatore);
contatore = 0;
}
}
[...]
// This is the 457-th line
ISR(TIMER3_COMPA_vect)
{
accRoutine();
contatore++;
}
void accRoutine()
{
// reads analog values
}
서보 라이브러리와의 충돌을 해결하는 방법은 무엇입니까?
해결책
다음 코드를 사용하여 충돌을 해결했습니다. 컴파일되지만 800Hz 타이머와 관련된 카운터는 값을 증가시키지 않습니다.
volatile int cont = 0;
void setup()
{
Serial.begin(9600);
// Initialize Timer
cli(); // disable global interrupts
TCCR3A = 0; // set entire TCCR3A register to 0
TCCR3B = 0; // same for TCCR3B
// set compare match register to desired timer count: 800 Hz
OCR3B = 20;
// turn on CTC mode:
TCCR3B |= (1 << WGM12);
// Set CS10 and CS12 bits for 1024 prescaler:
TCCR3B |= (1 << CS30) | (1 << CS32);
// enable timer compare interrupt:
TIMSK3 |= (1 << OCIE3B);
// enable global interrupts:
sei();
Serial.println("Setup completed");
}
void loop()
{
if (millis() % 1000 == 0)
{
Serial.print(" tick: ");
Serial.println(cont);
cont = 0;
}
}
ISR(TIMER3_COMPB_vect)
{
cont++;
}
주요 문제가 해결 되었기 때문에, 나는 또 다른 질문 만들었습니다 여기에 카운터 점진의 문제와 관련이 있습니다.