ATMega328 का उपयोग आंतरिक थरथरानवाला के साथ कैसे करें?


18

मेरे पास एक प्रोजेक्ट है जो मुझे लगता है कि ATMega328P के लिए सबसे उपयुक्त होगा। हालांकि, मैंने देखा है कि हर साधारण परियोजना में, लोग हमेशा 16MHz बाहरी थरथरानवाला को हुक करते हैं। मैं जो देख सकता हूं, उसमें 8MHz आंतरिक थरथरानवाला होना चाहिए। मेरी परियोजना को बहुत अधिक प्रसंस्करण शक्ति की आवश्यकता नहीं है, न ही समय की आवश्यकता बहुत सटीक है (एक UART और I2C के अलावा)। मेरे पास एक प्रोग्रामर भी है, इसलिए मुझे बूटलोडर्स के बारे में चिंता करने की आवश्यकता नहीं है।

क्या मेरे पास बाहरी ऑसिलेटर का उपयोग करने का कोई कारण है?

जवाबों:


20

आप जो नहीं कहते हैं, वह इस आंतरिक दोलक की सटीकता क्या है। पृष्ठ 369 पर इसे डेटशीट में खोजने में मुझे कुछ समय लगा ।

10%। दस प्रतिशत! और कि एक कैलिब्रेटेड थरथरानवाला के लिए? यह भयानक है। इसके लिए 1% से कम त्रुटि की उम्मीद करना अनुचित नहीं है । माइक्रोचिप / Atmel अपने आप को 1% सटीकता के लिए थरथरानवाला अंशांकन के लिए एक दस्तावेज प्रदान करता है ।

I2C एक तुल्यकालिक प्रोटोकॉल है, और समय की सटीकता तब तक प्रासंगिक नहीं है जब तक न्यूनतम और अधिकतम पल्स समय का सम्मान नहीं किया जाता है। दूसरी ओर
UART अतुल्यकालिक है , और फिर समय सटीकता वास्तव में महत्वपूर्ण है। अधिकांश UARTs अंतिम बिट (स्टॉप बिट) में आधे बिट त्रुटि की अनुमति देते हैं, इसलिए 10 बिट ट्रांसमिशन के लिए 5% है।

फैक्ट्री कैलिब्रेटेड ऑसिलेटर यहां नहीं चलेगा। आपको 1% प्राप्त करने के लिए अंशांकन प्रक्रिया से गुजरना होगा। उस स्थिति में आप आंतरिक ऑसिलेटर का उपयोग कर सकते हैं। इसके अलावा, आपको एक क्रिस्टल का उपयोग करना होगा।


1
यहाँ जो कुछ कहा जा रहा है, उसे मैं पुष्ट करूँ। अपने आप को समय और सिरदर्द से बचाएं और बस एक क्रिस्टल प्राप्त करें। यदि शक्ति एक चिंता है, तो स्टार्टअप पर आंतरिक थरथरानवाला को ट्यून करने के लिए 32khz वॉच क्रिस्टल (48/88/168 के लिए 6PF ... 328 के बारे में सुनिश्चित न करें। माइग्रेशन शीट की जांच करें) का उपयोग करें। ऑसिलेटर कैलिब्रेशन रूटीन बहुत बारीक है, इसलिए अगर आप उस रास्ते पर जाते हैं तो ध्यान रखें। मैंने एक और उत्तर के नीचे इसके लिए कुछ उदाहरण कोड पोस्ट किए हैं।
स्नानकर्म ०

6

जैसा कि आप एक UART का उपयोग कर रहे हैं, एक क्रिस्टल थरथरानवाला उचित होगा। यदि यह उस के लिए नहीं था, तो आप आंतरिक थरथरानवाला का उपयोग कर सकते हैं। कुछ MCU में फैक्ट्री-ट्रिम किए गए आंतरिक ऑसिलेटर्स होते हैं, जो UART ऑपरेशन के लिए उपयुक्त हो सकते हैं।


2
यह भी देखें UART के समय पर इस एप्लिकेशन को ध्यान दें: maxim-ic.com/app-notes/index.mvp/id/2141
drxzcl

खैर, UART केवल 9600bps पर चलने वाले एक सुपर सरल सीरियल डिस्प्ले के साथ संचार के लिए है ... मुझे लगता है कि मैं थरथरानवाला और सब कुछ आदेश दे रहा हूं, लेकिन यह देखते हुए कि इसके बिना काम करेगा
अर्लज़

3

"समय संवेदनशील नहीं"। UART बहुत संवेदनशील समय है। यदि यह उचित रूप से सिंक नहीं किया गया है तो आपको पूरा कचरा मिलेगा।

विकल्प 1: एक सामान्य क्रिस्टल का उपयोग करें। बदलें घड़ी उचित रूप से फ्यूज का चयन करें। क्रिस्टल का चयन इस बात पर निर्भर करता है कि आप किस बॉड का उपयोग करना चाहते हैं / कितनी तेजी से आप इस चीज़ को जाना चाहते हैं। "जादू क्रिस्टल" है जो आपको मानक दरों के लिए 0% त्रुटि देगा (यदि वे पूरी तरह से निर्मित हैं)। अधिक जानकारी के लिए धारा 20 [USART0] में तालिकाओं को देखें (आपने डेटाशीट पढ़ी है .... सही ???) :)।

यहां छवि विवरण दर्ज करें

विकल्प 2: यदि पावर चिंता का विषय है, तो आप 32khz क्रिस्टल का उपयोग करके आंतरिक ऑसिलेटर को कैलिब्रेट कर सकते हैं। 32khz के साथ आप स्लीप मोड में यूए करेंट प्राप्त कर सकते हैं (मैंने उन्हें ~ 2uA पर ले लिया है)। आपको एक कैलिब्रेशन रूटीन सेटअप करना होगा, जिसमें टाइमर को शुरू करना / रोकना और टाइमर 2 को एसिंक्रोनस मोड में बदलना शामिल है।

328P कोड अलग हो सकता है ... यह फ़ंक्शन वर्तमान में 48/88 (उपयुक्त F_CPU / बॉड परिभाषाओं के साथ काम करता है। यह थोड़ा बदसूरत है / पूरी तरह से रिफलेक्ट नहीं किया गया है, लेकिन जब आप काम करते हैं तो चीजों के साथ पेंच करना बेहतर समझते हैं। एक समय सीमा पर। "ट्यून 32khz क्रिस्टल" के लिए AVRFreaks फ़ोरम पर खोजें कुछ ऐसा। यह बस एक स्वाद है जो आपको मिल जाएगा ... जरूरी नहीं कि क्या काम हो।

char OSCCAL_calibration(char starting_cal, int cal_value){
//Function calibrates the internal oscillator so usart comms go through.
//Works by continually checking two different timers:
//   (0 -> tied to internal, and 2 -> async to crystal).
//  Recommended cal_value = 5900 for the crystals we're using.
//  Must be running 8MHZ with clkdiv8 fuse enabled.
//  TODO: Make sure to check all the math on this later.
unsigned char calibrate = FALSE;
int temp;
unsigned char tempL;
volatile char osccal_temp=starting_cal;
int cal_bandwidth = 50;

//int cal_value = 6250;
//int cal_value = 5900; //Works.  Need to find out why.

//Dont use clock prescalers.  We're already div8ing.
//CLKPR = (1<<CLKPCE);        // set Clock Prescaler Change Enable
// set prescaler = 8, Inter RC 8Mhz / 8 = 1Mhz
//CLKPR = (1<<CLKPS1) | (1<<CLKPS0);

TIMSK2 = 0;             //disable OCIE2A and TOIE2
ASSR = (1<<AS2);        //select asynchronous operation of timer2 (32,768kHz)

OCR2B = 200;            // set timer2 compare value.  We probably only need to compare A
OCR2A = 200;

TIMSK0 = 0;             // delete any interrupt sources

TCCR2A = (1<<WGM21);    //Normal operation.  Reset timer on hitting TOP (ocr2a).
TCCR2B = (1<<CS20);     // start timer2 with no prescaling

TCCR1B = (1<<CS10);     // start timer1 with no prescaling

//wait for everythnig to mellow out.
while((ASSR & (1<<TCN2UB)) | (ASSR & (1<<OCR2BUB)) | (ASSR & (1<<TCR2BUB)) | (ASSR & (1<<OCR2AUB)) | (ASSR & (TCR2AUB)));       //wait for TCN2UB and TCR2UB to be cleared

//This is specifically for the crystal to stabilize.  Check for better times.
_delay_ms(1000);

while(!calibrate){
    cli();  // disable global interrupt

    TIFR1 = 0xFF;   // delete TIFR1 flags
    TIFR2 = 0xFF;   // delete TIFR2 flags

    TCNT1H = 0;     // clear timer1 counter
    TCNT1L = 0;
    TCNT2 = 0;      // clear timer2 counter

    //Stop timer on compare match.
    while ( !(TIFR2 & (1<<OCF2A)) );
    TCCR1B = 0;

    //Check for overflows (useless if it happens).
    sei();
    if ( (TIFR1 & (1<<TOV1)) ){
        temp = 0xFFFF;      // if timer1 overflows, set the temp to 0xFFFF
    }else{   // read out the timer1 counter value
        tempL = TCNT1L;
        temp = TCNT1H;
        temp = (temp << 8);
        temp += tempL;
        }

    //Check timer value against calculated value.           
    if (temp > (cal_value+(cal_bandwidth/2))){
        //Oscillator is too fast.
        osccal_temp--;
        OSCCAL=osccal_temp;
    }else if (temp < (cal_value-(cal_bandwidth/2))){
        //Oscillator is too slow.
        osccal_temp++;
        OSCCAL=osccal_temp;
    }else{
        //Just right.
        calibrate = TRUE;
        }

    TCCR1B = (1<<CS10); // start timer1
    }

//TODO: Stop timers, ya?
//Now setup timer2 to run "normally" aka async+interrupts.
//Disable interrupt source. Set mask.  Wait for registers to clear.
TIFR2 = (1<<TOV2);
TIMSK2 = (1<<TOIE2);
ASSR = (1<<AS2);        //select asynchronous operation of timer2 (32,768kHz)
TIMSK0 = 0;             // delete any interrupt sources

//Normal Op. 256 prescale.
TCCR2A = 0x00;
TCCR2B = (1<<CS22) | (1<<CS21);

TCCR1B = 0x00;     // turn off timer1

//wait for everythnig to mellow out.
while((ASSR & (1<<TCN2UB)) | (ASSR & (1<<OCR2BUB)) | (ASSR & (1<<TCR2BUB)) | (ASSR & (1<<OCR2AUB)) | (ASSR & (TCR2AUB)));       //wait for TCN2UB and TCR2UB to be cleared

//This is specifically for the crystal to stabilize.  Check for better times.
_delay_ms(1000);
return osccal_temp;
}

2

यह भी ध्यान दिया जाना चाहिए कि एक क्रिस्टल को शुरू होने में लंबा समय लगता है। यह वास्तव में इसकी सटीकता के कारण है: यह केवल एक बहुत ही संकीर्ण आवृत्ति बैंड से ऊर्जा लेता है। यह बैटरी संचालित सामान के लिए एक बोझ हो सकता है, जहां आप हर थोड़े समय के लिए बहुत कम समय के लिए mcu को जगाते हैं: क्रिस्टल के लिए पूर्ण शक्ति ड्रॉ पर एक एमएस की प्रतीक्षा करना एक शुद्ध नुकसान है। सिरेमिक आरसोनेटर्स आंतरिक आरसी थरथरानवाला से अधिक सटीक होते हैं लेकिन एक क्रिस्टल से कम होते हैं, और तदनुसार शुरू होते हैं।

बेशक एक 16 मेगाहर्ट्ज एटमेगा बहुत अधिक रस पीता है और 8MHz एक की तुलना में अधिक वोल्टेज की आवश्यकता होती है, लेकिन 8MHz (या कम, 32kHz तक) क्रिस्टल उपलब्ध हैं; यह मात्र विकल्प ऊर्जा सेवर भी हो सकता है।


0

यदि आपको अधिक या सटीक समय की आवश्यकता नहीं है, तो बाहरी थरथरानवाला की कोई आवश्यकता नहीं है। कुछ पुराने प्रिंटरों को डिसाइड करते हुए, मैं बहुत सारे IC को देखता हूं लेकिन बोर्ड पर एक भी ऑसिलेटर नहीं।


0

मुझे लगता है कि आप पहले से ही इस ऐप नोट को देख चुके हैं: AVR053: आंतरिक आरसी थरथरानवाला का अंशांकन

मैं इससे अनुमान लगाता हूं, और ऊपर @drxzcl की टिप्पणी से ऐप नोट, आपको सैद्धांतिक रूप से तय करने में सक्षम होना चाहिए कि क्या सही है।


जहां पहले से ही है एक स्वीकार किए जाते हैं जवाब, आप और अधिक कुछ कहने के लिए प्रयास करना चाहिए, अन्यथा यह बहुत उपयोगी नहीं है
clabacchio

@clabacchio - यह उत्तर दो दिन पुराना है, और कल से स्वीकृत तिथियां हैं। जब यह पोस्ट किया गया था तो इसे स्वीकार नहीं किया जा सकता था।
स्टीवन्वह

@stevenvh सही, मुझे नहीं पता था कि यह सिर्फ एक संपादन था; हालांकि, यह एक अधूरा जवाब
clabacchio

@clabacchio - "अधूरा जवाब"। माना! मैं "आप तय करने में सक्षम होना चाहिए" बहुत उपयोगी नहीं मिल सकता है।
स्टीवन्वह

@clabacchio - अरे, मेरा भी कहना है "2 दिन पहले" अब। एक मिनट पहले इसने कहा "कल जवाब दिया"। ठीक 48 घंटे हो गए होंगे! :-)
स्टीवन्वह
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.