진폭과 주파수가 다른 사인파의 주파수를 측정해야하는 비교적 "간단한"프로젝트를 진행하고 있습니다. 일을 단순화하기 위해 지금은 고정 주파수 (27Hz) 사인파 입력 (비교기의 음의 입력) 만 얻었으며 진폭은 전위차계를 사용하여 다양 할 수 있습니다. 비교기의 양의 입력은 Vcc / 2로 설정됩니다. 그런 다음 비교기의 출력은 atmega2560 마이크로 컨트롤러의 입력 캡처 레지스터로 공급되어 주파수를 측정합니다.
문제는 입력 신호의 특정 진폭에서 다음과 같이 출력에서 매우 강렬한 토글 (또는 때로는 불감 대)을 얻는다는 것입니다.
예상되는 출력이 다음과 같이 보이는 곳 :
내가 지금까지 시도한 것 :
내부 atmega2560의 내부 비교기를 사용합니다. 외부 비교기 사용. 소프트웨어 및 슈미트 트리거 회로를 사용한 히스테리시스를 소개합니다. 고정 참조 설정 및 데이터 슬라이서 설정을 포함한 다양한 입력 설정을 시도했습니다. 다른 atmega2560을 시도합니다. 다른 클럭 속도를 시도 중입니다.
일부 솔루션은 다른 솔루션보다 안정적이지만 어느 곳도 수용 할 수있는 곳은 없었습니다. 지금까지 가장 안정적인 구성으로 정착했습니다.
이 설정을 사용하면 특정 사항이 안정성을 개선 / 변경하지만 여전히 완벽한 곳은 없습니다.
히스테리시스를 높이기 위해 R5의 값을 변경합니다. C2를 완전히 제거합니다 (아무 이유가 없습니다). 브레드 보드의 전선을 만지십시오 (몇 개는 서로 옆에 있습니다). 외부에서 USB로 또는 그 반대로 전원 공급 장치 전환
이 시점에서 그것은 사인파를 생성하는 데 사용되는 DAC 인 노이즈이거나 매우 근본적으로 잘못된 일을하고 있습니다. 이 회로는 다른 사람들에게 아무런 문제없이 작동했기 때문에 구성이나 환경에 문제가 있어야합니다.
누구든지 제안 사항이 있으면 시간을 내 주셔서 감사합니다.
여기 내 최소한의 소스가 있습니다 :
#include <avr/io.h>
void init(void);
void init(void) {
/* Setup comparator */
ACSR = (1 << ACIE) | (1 << ACIS1);
/* Initialize PORTD for PIND5 */
DDRD = 0x00;
PORTD = 0x00;
/* Enable global interrupts */
sei();
}
int main(void) {
init();
while (1) {}
}
ISR(ANALOG_COMP_vect) {
if (!(ACSR & (1<<ACIS0))) { //comparator falling edge
/* Set PIND5 to 0V */
PORTD &= ~(1 << PIND5);
ACSR |= (1<<ACIS0); //set next comparator detection on rising edge
}
else {
ACSR &= ~(1<<ACIS0); //set next comparator detection on falling edge
/* Set PIND5 to 5V */
PORTD |= (1 << PIND5);
}
}
또한 회로도 및 라이브러리 자체에 대한 링크는 다음과 같습니다.
http://interface.khm.de/index.php/lab/interfaces-advanced/frequency-measurement-library/
최신 정보:
나는 당신의 모든 제안을 시도했지만 그중 하나도 효과가 없었습니다. ISR 내부 또는 외부에서 인터럽트 플래그를 지우거나 인터럽트를 비활성화해도 실제로 효과가 없었습니다. 칩의 비교기 레지스터가 실제로 어떻게 작동하는지 오해하는 것 같습니다.
처음에 언급했듯이 입력 캡처를 사용하여 사인파에서 파생 된 구형파의 주파수를 측정하려고했습니다. 비교기의 출력은 입력 캡처 핀으로 공급 된 다음 타이머를 사용하여 간단하고주기를 측정합니다.
여기 ATMEGA2560의 아날로그 비교기도이다 http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2549-8-bit-AVR-Microcontroller-ATmega640-1280-1281-2560-2561_datasheet.pdf 페이지 265 :
보시다시피, 비교기에는 ACO 및 ACIS0 + ACIS1의 두 가지 출력이 있습니다. ACO는 + 입력>-입력시 설정되고 + 입력 <-입력시 해제됩니다. ACIS0 + ACIS1은 에지 선택 비트입니다.
처음에 내가 한 일은 ISR에서 엣지 유형을 확인하는 것이 었습니다. 대신 ISR을 다음과 같이 변경했습니다.
ISR(ANALOG_COMP_vect) {
if (!(ACSR & (1<<ACO))) { // + < -
/* Set PIND5 to 0V */
PORTD &= ~(1 << PIND5);
}
else {
/* Set PIND5 to 5V */
PORTD |= (1 << PIND5);
}
}
그리고 출력은 완벽하게 작동했습니다 (두 번째 그림에서와 같이). 그런 다음 펄스 폭을 측정했지만 결과는 좋지 않았습니다. 신호가 깨끗 해지더라도 LCD 디스플레이에서 강렬한 토글, 숫자가 임의의 값으로 점프하거나 0에 머물러 있습니다. 다른 조건을 사용하여 코드를 여러 번 다시 작성했습니다. 지금까지 얻은 유일한 반 안정 솔루션은 다음과 같습니다.
#include <avr/io.h>
#include <util/delay.h>
#include "UART.h"
void init(void);
volatile uint16_t y = 0;
volatile uint16_t x = 0;
volatile uint16_t current_value = 0;
volatile uint16_t previous_value = 0;
volatile uint16_t total = 0;
void init(void) {
/* Normal mode, 64 prescaler, Rising Edge trigger, Input Capture */
TCCR1A = 0;
TCCR1B = (1 << CS10) | (1 << CS11) | (1 << ICES1);
TIMSK1 = (1 << ICIE1);
ACSR = (1 << ACIC);
ADCSRB = 0x00;
/* This port is used for simulating comparator's output */
DDRC = 0xFF;
PORTC = 0xFF;
DDRD = 0x00;
PORTD = 0x00;
USART_Init(UBRR_VALUE);
sei();
}
int main(void) {
init();
while (1) {
if (TCNT1 == 60000) {
/* Display the values on the LCD */
USART_Transmit(0xFE);
USART_Transmit(0x01);
USART_Transmit_Double(x+y);
}
}
}
ISR(TIMER1_CAPT_vect) {
//ACSR &= ~(1<<ACIC);
if (!(ACSR & (1 << ACO))) {
if (!(TCCR1B & (1 << ICES1))) { // check for falling edge
PORTD |= (1 << PIND5);
PORTC &= ~(1 << PINC1);
TCCR1B |= (1 << ICES1);
current_value = ICR1;
x = current_value - previous_value;
previous_value = current_value;
}
}
else {
if (TCCR1B & (1 << ICES1)) { // check for rising edge
PORTD &= ~(1 << PIND5);
PORTC |= (1 << PINC1);
TCCR1B &= ~(1 << ICES1);
current_value = ICR1;
y = current_value - previous_value;
previous_value = current_value;
}
}
//ACSR |= (1<<ACIC);
}
반-안정적으로 나는 1/3의 정확한 값을 얻습니다. 다른 시간의 2/3는 올바른 값의 절반이거나 임의의 값입니다. ISR에서 비교기의 레지스터 비트뿐만 아니라 조건문에 타이머의 레지스터 비트를 사용해 보았습니다. 이것은 일종의 작동하는 유일한 구성입니다.
나중에 내가 한 일은 동일한 설정 및 소스 (비교기와 관련된 모든 행 제외) 대신 외부 비교기를 사용하는 것입니다. 출력은 입력 캡처 핀에 공급되었으며 의도 한대로 작동했습니다 (히스테리시스가 필요하지 않음).
이 시점에서 외부 비교기를 사용하여 문제를 해결했다고 말할 수는 있지만 내부 이유 자체가 왜 작동하지 않는지 잘 모르겠습니다. 나는 이것에 대한 많은 게시물과 가이드를 읽었고, 다른 라이브러리를 읽었으며, 수용 가능한 결과없이 모방하려고했습니다. 데이터 시트에는 전체 비교기 장치에 5 페이지 만 있으며 여러 번 다시 읽었으며 내가 뭘 잘못하고 있는지 알 수 없습니다.
제대로 사용하는 방법을 찾고 싶지만 실패하면 백업이 있습니다. 더 이상의 의견이 있으시면 대단히 감사하겠습니다.