मैं एक अपेक्षाकृत "सरल" परियोजना पर काम कर रहा हूं जहां मुझे एक साइन लहर की आवृत्ति को मापने की आवश्यकता है जो आयाम और आवृत्ति में भिन्न होती है। चीजों को सरल बनाने के लिए, अब तक, मुझे केवल एक निश्चित आवृत्ति (27 हर्ट्ज) साइन वेव इनपुट (तुलनित्र का नकारात्मक इनपुट) मिला है, जो केवल आयाम (एक पोटेंशियोमीटर का उपयोग करके) में भिन्न हो सकता है। तुलनित्र का धनात्मक इनपुट Vcc / 2 पर सेट है। तुलनित्र का उत्पादन फिर आवृत्ति को मापने के लिए atmega2560 माइक्रोकंट्रोलर के इनपुट कैप्चर रजिस्टर में फीड किया जाता है।
समस्या यह है कि इनपुट सिग्नल के कुछ आयामों पर मुझे इस पर लगने वाले आउटपुट पर काफी तीव्र टॉगल (या कभी-कभी मृत बैंड) मिलते हैं:
जहां अपेक्षित आउटपुट कुछ इस तरह दिखना चाहिए:
मैंने अब तक जिन चीजों की कोशिश की है:
आंतरिक atmega2560 के आंतरिक तुलनित्र का उपयोग करना। बाहरी तुलनित्र का उपयोग करना। सॉफ्टवेयर और श्मिट ट्रिगर सर्किट का उपयोग करके हिस्टैरिसीस का परिचय। निश्चित संदर्भ सेटअप और डेटा स्लाइसर सेटअप सहित विभिन्न इनपुट सेटअप की कोशिश की। अलग atmega2560 की कोशिश कर रहा है। अलग-अलग घड़ी की गति की कोशिश करना।
कुछ समाधान दूसरों की तुलना में अधिक स्थिर थे, लेकिन उनमें से कोई भी स्वीकार्य नहीं था। मैंने अब तक के सबसे स्थिर विन्यास के साथ समझौता किया है:
इस सेटअप के साथ, कुछ चीजें स्थिरता में सुधार / परिवर्तन करती हैं, हालांकि अभी भी बिल्कुल सही नहीं हैं:
हिस्टैरिसीस बढ़ाने के लिए R5 का मूल्य बदलना। पूरी तरह से C2 को हटाना (पता नहीं क्यों)। ब्रेडबोर्ड पर तारों को छूना (एक-दूसरे के बगल में काफी कुछ)। बाहरी से यूएसबी और इसके विपरीत बिजली की आपूर्ति स्विचिंग।
इस बिंदु पर, यह या तो शोर है, मेरा डीएसी जिसके साथ मैं साइन लहर उत्पन्न कर रहा हूं या मैं गलत तरीके से कुछ मौलिक काम कर रहा हूं। इस सर्किट ने अन्य लोगों के लिए बिना किसी समस्या के काम किया है, इसलिए मेरे कॉन्फ़िगरेशन या वातावरण में कुछ गलत होना चाहिए।
अगर किसी के पास कोई सुझाव है, तो मैं आपके समय की बहुत सराहना करूंगा।
यहाँ मेरा न्यूनतम स्रोत है:
#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/
अपडेट करें:
मैंने आपके सभी सुझावों की कोशिश की है, उनमें से किसी ने भी काम नहीं किया है। आईएसआर के भीतर या बाहर इंटरप्ट झंडे को साफ करना या बाधित करना वास्तव में कोई प्रभाव नहीं था। मुझे गलतफहमी हो रही है कि चिप का तुलनित्र रजिस्टर वास्तव में कैसे काम करता है।
जैसा कि मैंने शुरू में उल्लेख किया था, मैं साइन लहर से निकले वर्ग तरंग की आवृत्ति को मापने के लिए इनपुट कैप्चर का उपयोग करने वाला था। तुलनित्र का आउटपुट इनपुट कैप्चर पिन में खिलाया जाता है, फिर समयावधि को मापने के लिए टाइमर का उपयोग करें, सरल।
यहाँ atmega2560 के अनुरूप तुलनित्र आरेख http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2549-8-bit-AVR-Microcontroller-ATmega440-1280-1281-25-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);
}
}
और आउटपुट ने स्वयं त्रुटिपूर्ण व्यवहार किया (जैसे दूसरी तस्वीर में)। फिर मैं दालों की चौड़ाई मापने के लिए आगे बढ़ा, लेकिन परिणाम बहुत अच्छे नहीं थे। स्वच्छ संकेत होने के बावजूद, मेरे एलसीडी डिस्प्ले पर भीख माँगना, यादृच्छिक मूल्यों पर कूदना या 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 पृष्ठ हैं, मैं इसे कई बार फिर से पढ़ता हूं और मैं यह नहीं देखता कि मैं क्या गलत कर रहा हूं।
मैं यह पता लगाना चाहूंगा कि इसका सही उपयोग कैसे किया जाए, लेकिन अगर वह विफल हो जाता है तो मुझे बैकअप मिल गया है। यदि आपके पास कोई और इनपुट है तो इसकी बहुत सराहना की जाती है।