2010-02-27 9 views
8

मैं अपनी यूएआरटी लाइब्रेरी को व्यवस्थित करने की कोशिश कर रहा हूं और इसे कुछ # डिफाईन जोड़कर थोड़ा सा प्रमाणित कर रहा हूं, इसलिए मैं बाद में कोड में गहराई से खोदने के बिना इसे कस्टमाइज़ कर सकता हूं, लेकिन मुझे निम्न कोड कोड नहीं मिल रहा है काम कर रहे:सी: चेतावनी के लिए एक इलाज: अभिव्यक्ति में पूर्णांक अतिप्रवाह?

#define FOSC  8000000 
#define BAUDRATE 9600 
#define BRGVAL  (FOSC/2)/(16*BAUDRATE)-1 

void uart_init(){ 
    U1BRG = BRGVAL; 
} 

के बाद गणना BRGVAL २५.०४१६६६७ हो जाता है, और क्योंकि यह एक पूर्णांक मैं इसके लिए निम्न चेतावनी मिलती है, जब मैं आवंटित नहीं है कि U1BRG में:

UART.c: समारोह में ' uart_init ':

UART.c: 24: चेतावनी: पूर्णांक अभिव्यक्ति में अतिप्रवाह

... और कोड लक्ष्य हार्डवेयर पर काम नहीं करता है। (यदि मैं मैन्युअल रूप से U1BRG = 25 में डालता हूं तो यह एक आकर्षण की तरह काम करता है)

क्या संकलक को खुश करने के लिए एक पूर्णांक में निरंतर टाइप करने का कोई तरीका है?

बहुत धन्यवाद, हमज़ा।

+1

यू 1BRG (और उस प्रकार का आकार) का प्रकार क्या है? –

+4

आपको क्यों लगता है कि बीआरजीवीएएल 25.0416667 बन गया है? मैक्रो में अभिव्यक्ति में सभी घटक पूर्णांक होते हैं, इसलिए जब मैक्रो को प्रतिस्थापित किया जाता है तो अभिव्यक्ति के लिए पूर्णांक अंकगणित का उपयोग किया जाएगा। समस्या यह है कि संकलक चेतावनी दे रहा है ओवरफ्लो है, फ्लोटिंग पॉइंट ट्रंकेशन नहीं। –

+0

यू! 1BRG एक हस्ताक्षरित int (16 बिट) है और यह एमपीएलबी सी 30 कंपाइलर – Hamza

उत्तर

22

पूर्णांक अतिप्रवाह मतलब है कि आप एक पूर्णांक मूल्य की ऊपरी सीमा है, जो 32767 होने की संभावना है अगर आपको यह त्रुटि हो रही है पार कर चुके हैं। फ्लोटिंग पॉइंट के साथ इसका कोई लेना-देना नहीं है; आपके द्वारा निर्दिष्ट संचालन वास्तव में पूर्णांक गणित परिचालन हैं, इसलिए विभाजन का आंशिक भाग किसी भी तरह से त्याग दिया जाता है। इस तरह

कोशिश कुछ:

#define FOSC  8000000L 
#define BAUDRATE 9600L 
#define BRGVAL  ((unsigned int)((FOSC/2)/(16*BAUDRATE)-1)) 

void uart_init(){ 
    U1BRG = BRGVAL; 
} 

एल प्रत्यय के बजाय long प्रकार int प्रकार में इन स्थिरांक बदल जाता है। (unsigned int) कास्ट U1BRG के प्रकार में परिवर्तित हो जाता है, और संकलक को यह पता चलता है कि आप समझते हैं कि long मान unsigned int में फिट होगा और इस प्रकार यह आपके द्वारा फेंकने वाली चेतावनियों को छुपाएगा।

आम तौर पर, यह बुरा व्यवहार संकलक चेतावनी मौन करने है, लेकिन इस मामले में, यह स्पष्ट है कि यद्यपि आप long जरूरत गणना में मध्यवर्ती मूल्यों स्टोर करने के लिए, अंतिम परिणाम एक unsigned int में फिट होगा।

+0

पॉप फिलिप, सुझाव के लिए धन्यवाद, कोड का निम्न बिट लगता है मेरे लिए अब काम #define \t FOSC \t \t 8000000L #define \t BAUDRATE \t 9600L #define \t BRGVAL \t \t (FOSC/2)/(16 * BAUDRATE) -1 कुछ अजीब कारण के लिए, तो मुझे लगता है कि जोड़ने (int) बीआरजीवीएएल को डाला गया, मुझे 65536 का मूल्य मिलता है (int की सीमा?), यह सुनिश्चित नहीं है कि ऐसा क्यों होता है। कलाकार के बिना यह काम करता प्रतीत होता है ... – Hamza

+0

@ एडम या तो BAUDRATE लंबा होना चाहिए, या जादू संख्या 16 लंबा होना चाहिए, अन्यथा 16 * BAUDRATE अधिक बह जाएगा। –

+0

@ हम्ज़ा आप कास्ट जोड़ने के लिए किस कोड का उपयोग कर रहे हैं? कलाकारों के लिए सभी कोष्ठक आवश्यक हैं। यदि आप (int) (एफओएससी/2)/(16 * BAUDRATE) -1 या (int) BRGVAL कर रहे हैं तो आप पूरी अभिव्यक्ति कास्टिंग नहीं कर रहे हैं बल्कि आप केवल int (FOSC/2) को int में डाल रहे हैं, जो अतिप्रवाह होगा और कुछ छोटी संख्या बनें। फिर आप इस छोटी संख्या को (16 * BAUDRATE) से विभाजित करते हैं, जो एक बड़ी संख्या है, जो परिणाम 0 देता है। फिर आप 1 घटाते हैं, -1 बनाते हैं। एक हस्ताक्षरित int को -1 असाइन करें और आप चारों ओर लपेटें और 65535 प्राप्त करें। संक्षेप में, यदि आप एक कास्ट करते हैं, तो आप जिस संपूर्ण अभिव्यक्ति को कास्टिंग कर रहे हैं उसके आसपास कोष्ठक जोड़ें। –

0

मैं शायद इस का प्रयोग करेंगे:

#define BRGVAL  ((int)(FOSC/2)/(16*BAUDRATE)-1) 
+0

हैलो सेगफॉल्ट, दुख की बात है कि काम नहीं करता है। – Hamza

0

आप इस बाहर बिंदु में विफल रहे हैं U1BRG के लिए डेटा प्रकार क्या है? यदि यह एक int है, यह दिखाया गया है की तरह डाली

 
#define FOSC  8000000 
#define BAUDRATE 9600 
#define BRGVAL  ((long)(FOSC/2)/(16*BAUDRATE)-1) 

void uart_init(){ 
    U1BRG = BRGVAL; 
} 

संपादित करें: इस संशोधित की टिप्पणी एक अहस्ताक्षरित int बहुत छोटा है कि का परिणाम धारण करने के लिए लिसएडम के ध्यान में रखना करने के लिए मैक्रो, मैं यह है कि यह एक long ... headsup के लिए धन्यवाद एडम ...

आशा इस मदद करता है, सादर, टॉम बनाने के लिए बदल दिया है।

+0

हैलो टॉम, यह 'unsigned int' प्रकार का है, मैंने एक (int) कास्ट करने का प्रयास किया है, लेकिन एक ही त्रुटि अभी भी पॉप अप है ... – Hamza

+0

FOSC/2 अभी भी int में फ़िट होने के लिए बहुत बड़ा है। –

+0

आप अभी भी 16 * BAUDRATE के साथ अतिप्रवाह प्राप्त करते हैं, जो एक int में फिट नहीं होगा। –

0

यह आपके उदाहरण से स्पष्ट नहीं है कि U1BRG एक वैश्विक चर या # परिभाषित स्थिर है या नहीं। किसी भी मामले में, बस एक पूर्णांक के लिए कास्टिंग काम करना चाहिए:

U1BRG = (int)BRGVAL; 
+0

हैलो जेएस, यू 1BRG को किसी अन्य हेज़र फ़ाइल में एक हस्ताक्षरित int के रूप में परिभाषित किया गया है, मैंने एक (int) कास्ट करने का प्रयास किया है, लेकिन एक ही त्रुटि अभी भी – Hamza

8

मैं फिलिप के जवाब पसंद है, लेकिन मुझे लगता है कि एक बेहतर समाधान सूत्र को कम करने और करने के लिए अपने मैक्रो बदलने के लिए है:

#define BRGVAL (FOSC/32/BAUDRATE-1) 

ऐसा करने में, आप कलाकारों को खत्म तो संकलक अगर आप सचेत करने के लिए जारी रख सकते हैं आप कम बॉड दर चुनते हैं जिसके परिणामस्वरूप 16-बिट int के लिए विभाजक मान बहुत बड़ा होता है।

+0

हे टॉम, आपके सुझाव के लिए धन्यवाद। यह एक सम्मोहन की तरह काम करता है! – Hamza

संबंधित मुद्दे