ভেরিয়েবল অক্ষরগুলি ইউআআরটিতে মুদ্রণ করা কাজ করে না, ধ্রুবকগুলি ভাল কাজ করে


9

XC8 এর সাথে আমার একটি PIC18F27K40 মাইক্রোকন্ট্রোলারের একটি অদ্ভুত সমস্যা রয়েছে। একটি 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

আমি এমপিএলবিএস এক্সসি 8 সি সংকলক ভি 1.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_pتن (কনস্টের চার্চ এবং সি)" হিসাবে সংজ্ঞায়িত করুন। একে বলা হয় "রেফারেন্স দ্বারা পাসিং"।
রোহাত কলি

1
@ রোহাতকিলি এটি সি ++
টিস্তে আন্ডিই

1
@ টক্রোসলে আমি বোঝাতে চেয়েছি, দুঃখিত। এটি কোনও পার্থক্য করে না (এখনও কাজ করে না)। আমি সব চেষ্টা unsigned char, char, const unsigned charএবং const char

1
আপনার সংশ্লেষ () এর সংজ্ঞা অনুসারে আপনি যুক্তির নাম byteTxবদলে রাখলে কী ঘটে ? আমি উদ্বিগ্ন যে byteডেটা ধরণের হিসাবে অন্য কোথাও সংজ্ঞায়িত হতে পারে। (মনে হচ্ছে এটি একটি সংকলক ডায়াগনস্টিক জেনারেট করবে তবে স্পষ্টতই এখানে কিছু অদ্ভুত ঘটনা চলছে another) এবং অন্য পরীক্ষা putch(0x61)হিসাবে, putch('a')কী একইভাবে দুর্ব্যবহার করা হয় ? আমি ভাবছি যে টেবিল পড়ার নির্দেশটি 8-বিট বা 16-বিট ডেটা পড়ছে। পিআইসি ডাব্লু রেজিস্টার 8 টি বিট যদিও ঠিক আছে?
MarkU

2
@ মারকু তাই আমি একটি পিক 16 এফ 1778 চেষ্টা করেছিলাম এবং সেখানে একই জিনিস ভাল কাজ করে। (যা আমার পক্ষে এটি খুব কম খারাপ সমস্যা করে তোলে কারণ আমি উভয় চিপ দিয়েই ঠিক আছি, তবে তবুও আমি কীভাবে 18F27K40 কাজ করতে পারি তা জানতে আগ্রহী হব ..)

উত্তর:


3

আপনার প্রোগ্রামটি ঠিক আছে, এটি PIC18F27K40 এ একটি বাগ রয়েছে।

Http://ww1.microchip.com/downloads/en/DiviceDoc/80000713A.pdf দেখুন

এক্সসি 8 সংকলক ভি 1.41 এবং এমপ্ল্যাব্যাক্স আইডিই ব্যবহার করুন, এক্সসি 8 গ্লোবাল অপশন / এক্সসি 8 লিঙ্কার নির্বাচন করুন এবং "অতিরিক্ত বিকল্পগুলি" নির্বাচন করুন, তারপরে +nvmregত্রুটি-বিচ্যুতির বাক্সে যুক্ত করুন এবং সমস্ত ঠিক হয়ে যাবে।

লিঙ্কযুক্ত দস্তাবেজ থেকে কিছু অংশ, কীওয়ার্ডগুলি গা bold় হিসাবে চিহ্নিত করা হয়েছে:

টিবিএলআরডি যথাযথ স্মৃতিতে নির্দেশ করার জন্য এনভিএমআরইগ মান প্রয়োজন

PIC18FXXK40 ডিভাইসের ক্ষতিগ্রস্থ সিলিকন সংশোধনগুলির জন্য বিভিন্ন মেমরি অঞ্চলে অ্যাক্সেসের জন্য রেজিস্ট্রে NVMREG<1:0>বিটগুলি ভুলভাবে NVMCONসেট করতে হবে TBLRD। ইস্যুটি সংকলিত সি প্রোগ্রামগুলিতে সর্বাধিক স্পষ্ট হয় যখন ব্যবহারকারী কোনও কনস্টের ধরণ নির্ধারণ করে এবং সংকলক প্রোগ্রাম ফ্ল্যাশ মেমরি (পিএফএম) থেকে ডেটা পুনরুদ্ধার করার জন্য TBLRDনির্দেশাবলী ব্যবহার করে । ব্যবহারকারীটি যখন র‌্যামে একটি অ্যারে সংজ্ঞায়িত করে তখন বিষয়টিও স্পষ্ট হয় যার জন্য কমপ্লায়ার স্টার্ট-আপ কোড তৈরি করে, আগে সম্পাদিত হয়েছিল main(), এটি TBLRDপিএফএম থেকে র‌্যাম শুরু করার নির্দেশাবলী ব্যবহার করে ।


2

কনস্ট অক্ষরগুলি প্রোগ্রাম মেমোরিতে (ফ্ল্যাশ) সঞ্চিত থাকে এবং দেখে মনে হয় যে সংকলকটি দেখছে যে আপনি এটিকে পরিবর্তনশীল হিসাবে ব্যবহার করছেন না (যেহেতু এটি কখনই পরিবর্তন হয় না) এবং কনস্ট ব্যবহার না করে নির্বিশেষে প্রোগ্রাম মেমোরিতে এটি অপ্টিমাইজ করে তুলছেন।

এটি হিসাবে ঘোষণা করার চেষ্টা করুন volatile char c= 'a';। এটি ফ্ল্যাশের পরিবর্তে এসআরএমে সংরক্ষণ করতে বাধ্য করবে।

কেন এই ব্যাপার?

পিআইসি 18 তে, বিজোড় সংখ্যক বাইট (আপনার ক্ষেত্রে যেমন) এর সাথে ডিবি ডাইরেক্টিভ (প্রোগ্রাম মেমোরিতে একটি বাইট সংরক্ষণ করার জন্য ডেটাবাইট) ব্যবহার করে এটি স্বয়ংক্রিয়ভাবে জিরো দিয়ে প্যাড করবে। এই আচরণটি পিআইসি 16 এর থেকে পৃথক হয়, সম্ভবত এটি কারণ এটি অন্যটিতে নয় তবে একটিতে কাজ করে। এই কারণে, ফ্ল্যাশ মেমরিতে সঞ্চিত স্ট্রিংগুলি বা অক্ষরগুলি স্ট্রাইকপি বা প্রিন্টফের মতো স্ট্যান্ডার্ড স্ট্রিং ফাংশনগুলির সাথেও কাজ করবে না। প্রোগ্রাম মেমোরিতে কিছু সঞ্চয় করা স্বয়ংক্রিয়ভাবে নিরাপদ নয়।

সমাবেশের ভিত্তিতে, এটি বেশ স্পষ্ট যে ভুল 8 বাইট লোড করছে is যা 0x00, তাই এটি 0x00 সঠিকভাবে প্রেরণ করছে (যেমন আপনি এটি পুরোপুরি নিশ্চিত করেছেন যে এটি করছে)।

এই দিনগুলিতে সংকলক অপ্টিমাইজেশানের উন্মাদ পরিমাণের সাথে আপনি কী পাবেন তা অনুমান করা কঠিন হতে পারে, সুতরাং আমি নিশ্চিত নই যে এটি কাজ করবে কিনা I অস্থির কৌশলটি কাজ করা উচিত, তবে আপনি যদি সত্যিই এটি ফ্ল্যাশ-এ সঞ্চয় করতে চান তবে এটি চেষ্টা করুন:

TXREG = data & 0xff;

বা সম্ভবত

TXREG = data & 0x0ff;

আমি জানি যে তাত্ত্বিকভাবে, এটি কিছু করা উচিত নয়। তবে আমরা যা করতে চাই তা করতে সংকলকের সমাবেশের আউটপুট পরিবর্তন করার চেষ্টা করছি, এবং সাজানোর মতো নয় তবে আমরা যা চাই তা সত্য নয়।

এমপিএএসএম ব্যবহারকারী গাইড থেকে:

এখানে চিত্র বর্ণনা লিখুন

আমি পিডিএফে এটি নিজের , পাশাপাশি কোড_প্যাকটিও পরীক্ষা করে দেখার পরামর্শ দিই। পৃষ্ঠা 65।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.