UART में परिवर्तनशील वर्ण प्रिंट करना काम नहीं करता है, स्थिरांक ठीक काम करते हैं


9

मैं एक PIC18F27K40 माइक्रोकंट्रोलर पर XC8 के साथ एक बल्कि अजीब मुद्दा है। PIC16F1778 पर यह काम करता है । मैंने परिभाषित किया है:

void uart_putch(unsigned char byte) {
    while (!PIR3bits.TX1IF);
    TX1REG = byte;
}

जब, मेरे mainपाश में, मैं कहता हूं uart_putch('a');, यह ठीक काम करता है। हालांकि, जब मैं परिभाषित करता हूं const char c = 'a';और कॉल uart_putch(c);करता हूं , तो यह काम नहीं करता है। यह कुछ प्रिंट करता है, हालांकि नहीं a- मुझे लगता है कि वे 0x00चरित्र हैं, जो मुझे मिलता है hexdump -x /dev/ttyUSB0। यह मेरे कंप्यूटर पर सीरियल पोर्ट के साथ कोई समस्या नहीं है; मैंने एक गुंजाइश के साथ देखा और संकेत अलग है (बाएं काम करता है, दाएं नहीं करता है):

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

कोड सरल है:

void main(void) {
    init(); // Sets up ports and UART control registers
    while (1) {
        uart_putch('a'); // or c
    }
}

जो काम नहीं करता है वह या तो किसी भी स्ट्रिंग फ़ंक्शंस ( puts, printfआदि) का उपयोग कर रहा है, जो मुझे लगता है कि संबंधित है - इसलिए इस प्रश्न में मैंने पात्रों के साथ एक न्यूनतम काम करने का उदाहरण बनाया।

जब मैं एक चर cका उपयोग करता है तो उत्पन्न विधानसभा :

_c:
    db  low(061h)
    global __end_of_c

_main:
    ; ...
    movlw   low((_c))
    movwf   tblptrl
    if  1   ;There is more than 1 active tblptr byte
    movlw   high((_c))
    movwf   tblptrh
    endif
    if  1   ;There are 3 active tblptr bytes
    movlw   low highword((_c))
    movwf   tblptru
    endif
    tblrd   *
    movf    tablat,w
    call    _putch

और एक स्थिर के साथ _mainब्लॉक में है:

    movlw   (061h)&0ffh 
    call    _putch

मैं MPLAB XC8 C कंपाइलर V1.41 (जनवरी 24 2017) का उपयोग कर रहा हूं, जिसमें पार्ट सपोर्ट वर्जन 1.41 है।

मेरे मेकफाइल के प्रासंगिक भाग:

CC:=xc8
CFLAGS:=-I. --chip=18F27K40 -Q -Wall

SRC:=main.c uart.c
DEP:=uart.h
PRS:=$(subst .c,.p1,$(SRC))
OBJ:=main.hex

all: $(OBJ)

$(OBJ): $(PRS)
    $(CC) $(CFLAGS) $^

$(PRS): %.p1: %.c $(DEP)
    $(CC) $(CFLAGS) -o$@ --pass1 $<

इस काम को पाने के लिए किसी भी मदद की बहुत सराहना की जाएगी।


1
अपने uart_putch को "uart_putch (const char & c)" के रूप में परिभाषित करें। इसे "संदर्भ से गुजरना" कहा जाता है।
Rohat Kılıç

1
@ RohatKılıç यह C ++
SoreDakeNoKoto

1
@tcrosley मेरा मतलब था कि इसे शामिल करना, क्षमा करें। इससे कोई फर्क नहीं पड़ता (अभी भी काम नहीं करता है)। मैं सभी की कोशिश की unsigned char, char, const unsigned charऔर const char

1
पुट की अपनी परिभाषा में (), यदि आप byteTxइसके स्थान पर तर्क का नाम लेते हैं तो क्या होता है ? मुझे चिंता है कि byteडेटा प्रकार के रूप में कहीं और परिभाषित किया जा सकता है। (ऐसा लगता है कि एक संकलक नैदानिक ​​उत्पन्न करेगा, लेकिन स्पष्ट रूप से कुछ अजीब चल रहा है।) और एक अन्य परीक्षण के रूप में, putch(0x61)उसी तरह से दुर्व्यवहार करता है putch('a')? मैं सोच रहा हूं कि क्या तालिका पढ़ा गया निर्देश 8-बिट या 16-बिट डेटा पढ़ रहा है। PIC W रजिस्टर केवल 8 बिट्स ही है, है ना?
मार्कयू

2
@MarkU तो मैंने एक PIC16F1778 पर कोशिश की और वहां भी वही काम ठीक है। (जो यह मेरे लिए बहुत कम बुरी समस्या है क्योंकि मैं या तो चिप के साथ ठीक हूं, लेकिन फिर भी मुझे यह जानने में दिलचस्पी होगी कि 18F27K40 को कैसे काम किया जाए ..)

जवाबों:


3

आपका कार्यक्रम ठीक है, यह PIC18F27K40 पर एक बग है।

Http://ww1.microchip.com/downloads/en/DeviceDoc/80000713A.pdf देखें

XC8 कंपाइलर V1.41 और mplabx IDE का उपयोग करें, XC8 ग्लोबल विकल्प / XC8 लिंकर का चयन करें और "अतिरिक्त विकल्प" चुनें, फिर +nvmregइरेटा बॉक्स में जोड़ें और सब ठीक हो जाएगा।

लिंक किए गए दस्तावेज़ से अंश, बोल्ड चिह्नित कीवर्ड:

TBLRD को उपयुक्त मेमोरी को इंगित करने के लिए NVMREG मान की आवश्यकता होती है

PIC18FXXK40 उपकरणों के प्रभावित सिलिकॉन संशोधनों को अनुचित रूप से विभिन्न मेमोरी क्षेत्रों की पहुंच के लिए रजिस्टर NVMREG<1:0>में बिट्स की आवश्यकता होती है । संकलित सी कार्यक्रमों में यह मुद्दा सबसे अधिक स्पष्ट है जब उपयोगकर्ता एक कास्ट प्रकार को परिभाषित करता है और संकलक प्रोग्राम को मेमोरी फ्लैश (पीएफएम) से डेटा प्राप्त करने के लिए निर्देशों का उपयोग करता है । जब उपयोगकर्ता RAM में किसी सरणी को परिभाषित करता है तो वह समस्या स्पष्ट होती है, जिसके लिए कंप्लीट स्टार्ट-अप कोड बनाता है, जिसे पहले निष्पादित किया गया है , जो PFM से RAM को इनिशियलाइज़ करने के लिए निर्देशों का उपयोग करता है ।NVMCONTBLRDTBLRDmain()TBLRD


2

const chars को प्रोग्राम मेमोरी (फ्लैश) में संग्रहित किया जाता है, और ऐसा लगता है कि कंपाइलर देख रहा है कि आप इसे एक वेरिएबल के रूप में उपयोग नहीं कर रहे हैं (क्योंकि यह कभी नहीं बदलता है) और प्रोग्राम मेमोरी में इसे ऑप्टिमाइज़ करना चाहे आप कांस्ट का उपयोग करें या नहीं।

इसे घोषित करने का प्रयास करें volatile char c= 'a';। यह इसे फ्लैश के बजाय SRAM में संग्रहीत करने के लिए मजबूर करेगा।

यह बात क्यों है?

PIC18s पर, db निर्देश (डेटाइम को प्रोग्राम मेमोरी में बाइट को स्टोर करने के लिए) का उपयोग करके, विषम संख्या में बाइट्स (जैसे आपके मामले में) स्वचालित रूप से इसे शून्य के साथ पैड कर देगा। यह व्यवहार PIC16 से भिन्न होता है, जो शायद इसलिए एक पर काम करता है लेकिन दूसरे पर नहीं। इस कारण से, फ्लैश मेमोरी में संग्रहीत स्ट्रिंग्स या चार्ट भी मानक स्ट्रिंग फ़ंक्शंस में से किसी के साथ काम नहीं करेंगे, जैसे कि स्ट्रॉपी या प्रिंटफ। प्रोग्राम मेमोरी में कुछ स्टोर करना स्वचालित रूप से सुरक्षित नहीं है।

विधानसभा के आधार पर, यह स्पष्ट है कि गलत 8 बाइट्स लोड हो रहा है। जो 0x00 है, इसलिए यह 0x00 को सही तरीके से भेज रहा है (जैसा कि आपने पूरी तरह से पुष्टि की है कि यह कर रहा है)।

इन दिनों कम्पाइलर ऑप्टिमाइज़ेशन की पागल राशि के साथ आपको क्या मिलेगा, इसका अनुमान लगाना मुश्किल हो सकता है, इसलिए मुझे यकीन नहीं है कि यह काम करेगा। वाष्पशील चाल काम करना चाहिए, लेकिन अगर आप वास्तव में चाहते हैं कि यह फ्लैश में संग्रहीत हो, तो यह कोशिश करें:

TXREG = data & 0xff;

या संभवतः

TXREG = data & 0x0ff;

मुझे पता है कि सिद्धांत रूप में, यह कुछ नहीं करना चाहिए। लेकिन हम संकलक के असेंबली आउटपुट को बदलने की कोशिश कर रहे हैं, जो हम चाहते हैं, और ऐसा नहीं है लेकिन वास्तव में हम जो चाहते हैं वह नहीं है।

MPASM उपयोगकर्ता गाइड से:

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

मैं पीडीएफ में अपने आप को , साथ ही कोड_पैक की भी जाँच करने की सलाह देता हूँ । पृष्ठ ६५।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.