এসটিএম 32 এ এন্ডিয়ান সমস্যা


11

আমি একটি এসটিএম 32 এফ 4 ডিস্কোভারি প্রোগ্রাম করার জন্য আর্ম জিসিসি (কোকক্স) ব্যবহার করছি এবং আমি ডাব্লু / এন্ডিয়ান সমস্যা নিয়ে কুস্তি করছি

আমি এসপিআইয়ের মাধ্যমে 24 বিট এডিসি দিয়ে নমুনা দিচ্ছি। যেহেতু তিনটি বাইট আসছে, এমএসবি প্রথমে এগুলি তৈরির জন্য ইউনিয়নে লোড করার ধারণাটি পেয়েছিলাম (আমি আশা করি, যাইহোক!) ব্যবহার করা কিছুটা সহজ।

typedef union
{
int32_t spilong;
uint8_t spibytes [4];
uint16_t spihalfwords [2];} spidata;
spidata analogin0;

আমি স্পি ব্যবহার করে ডেটা লোড করে এনালগিন0.স্পাইবাইটে পড়ি [0] - [2], এমএসবি হিসাবে [0] দিয়ে, তারপর আমি ইউএসআর্টের মাধ্যমে একবারে 8 বিট করে তাদের থুতু দিয়েছি। কোন সমস্যা নাই.

সমস্যাগুলি শুরু হয়েছিল যখন আমি একটি 12 বিট ড্যাকের মধ্যে ডেটাটি দেওয়ার চেষ্টা করেছি। এই এসপিআই ড্যাকটি 16 বিট শব্দ চায়, যা এমএসবি থেকে শুরু করে একটি 4 বিট উপসর্গ নিয়ে থাকে এবং তারপরে 12 বিট ডেটা থাকে।

প্রাথমিক চেষ্টাগুলি ছিল এডিসি আমাকে দ্বিগুণ পরিপূরক হিসাবে বাইনারি অফসেটে রূপান্তরিত করে, xor-ing analogin0.spihalfwords [0] দিয়ে 0x8000 দিয়ে ফলাফলটি নীচে 12 বিটে স্থানান্তরিত করে এবং পরে গাণিতিকভাবে উপসর্গ যুক্ত করে।

অবিশ্বাস্যরূপে হতাশাব্যঞ্জক, যতক্ষণ না আমি খেয়াল করি যে এনালগিন0.স্পাইবাইট [0] = 0xFF এবং এবং এনালগিন0.স্পাইবাইটস [1] = 0xB5, এনালগিন0.এলফवर्डস [0] 0xB5FF এর সমান এবং 0xFFB5 নয় !!!!!

এটি লক্ষ্য করার পরে, আমি গাণিতিক ক্রিয়াকলাপগুলি এবং অর্ধশব্দটি ব্যবহার বন্ধ করে দিয়েছিলাম এবং বিটওয়াইজ যুক্তি এবং বাইটগুলিতে আটকেছি

uint16_t temp=0;
.
.
.


// work on top 16 bits
temp= (uint16_t)(analogin0.spibytes[0])<<8|(uint16_t)(analogin0.spibytes[1]);
temp=temp^0x8000; // convert twos complement to offset binary
temp=(temp>>4) | 0x3000; // shift and prepend with bits to send top 12 bits to DAC A


SPI_I2S_SendData(SPI3,temp); //send to DACa (16 bit SPI words)

... এবং এটি ভাল কাজ করেছে। আমি যখন কোডের প্রথম লাইনের পরে টেম্পে দেখি, তার 0xFFB5, এবং 0xB5FF নয়, তাই সমস্ত ভাল

সুতরাং, প্রশ্নের জন্য ...

  • কর্টেক্স আমার কাছে নতুন। উভয় প্ল্যাটফর্মটি সামান্য এডিয়ান হলেও, আমি পিআইসিকে ইনট 16 এর অদলবদল কখনও স্মরণ করতে পারি না। এটা কি সঠিক?

  • এটি পরিচালনা করার জন্য আরও কি মার্জিত উপায় আছে? এটি দুর্দান্ত হবে যদি আমি কেবল এআরএম 7 বিগ-এন্ডিয়ান মোডে রাখতে পারি। আমি কর্টেক্স এম 4 এর দ্বি-এন্ডিয়ান হিসাবে অনেকগুলি উল্লেখ দেখতে পাচ্ছি, তবে সমস্ত উত্স আসলে কীভাবে আমাকে তা বলার অপেক্ষা রাখে না বলে মনে হয় । আরও সুনির্দিষ্টভাবে, আমি কীভাবে STM32f407 কে বড়-এন্ডিয়ান মোডে রাখি , এটি আরও ভাল যদি এটি জিসিসিতে করা যায় । এটি কি এআইআরসিআর রেজিস্টারে উপযুক্ত বিট স্থাপনের বিষয়? কোনও র‌্যামফিকেশন রয়েছে, যেমন ম্যাচের জন্য সংকলকটি সেট করতে হবে, বা গণিতের স্ক্রুআপগুলি পরে অসামঞ্জস্য লাইব্রেরি সহ ??


2
"যেহেতু তিনটি বাইট আসছেন, এমএসবি প্রথমে" - এটি বিগ-এন্ডিয়ান, আপনি সিপিইউ হ'ল এন্ডিয়ান, সুতরাং আপনার সমস্যাটি শুরু হয়। আমি 16/32-বিট বাই বাইট অদলবদল করতে কম্পাইলার ম্যাক্রো / স্ট্যান্ডার্ড লাইব্রেরি ফাংশনগুলি সন্ধান করব, সাধারণত সেগুলি নির্দিষ্ট সিপিইউ প্ল্যাটফর্মের জন্য সবচেয়ে কার্যকর উপায়ে প্রয়োগ করা হয়। অবশ্যই, বিট-ওয়াইজ শিফটিং / অ্যান্ডিং / ওরিং ব্যবহার করাও ঠিক।
লাস্লোলো

আমি মনে করি যে আমি যে কোনও ক্রমে analogin0.spibytes স্টাফ করতে পারতাম, তবে এটি কিছুটা প্রতারণার মতোই মনে হয়, কারণ আমাকে এটি usart এর মাধ্যমে পাস করার জন্য আনস্টফ করার আদেশটি মনে রাখতে হবে। আমি মনে করি 3 বাইট বিন্যাস জিনিসগুলি কিছুটা মানহীন করে তোলে। যদি এটি সি ++ হত তবে আমি একটি শ্রেণি বিবেচনা করতে পারি।
স্কট সিডম্যান

3
সিএমএসআইএসের রয়েছে __REV()এবং __REV16()বাইটগুলি বিপরীত করার জন্য।
টার্বো জে

3
এটি মোটেও প্রতারণা নয় - আপনি যখন এই স্তরে আই / ও করছেন, তখন আপনাকে অবশ্যই বাহ্যিক বাইট ক্রম এবং অভ্যন্তরীণ বাইট ক্রমের মধ্যকার সম্পর্কের বিষয়ে সচেতন হতে হবে এবং ডিল করতে হবে । আমার নিজস্ব পছন্দটি হ'ল সফ্টওয়্যার শ্রেণিবিন্যাসের নিম্নতম স্তরে "নেটিভ" (অভ্যন্তরীণ) উপস্থাপনাগুলিকে / থেকে রূপান্তর করা এবং উচ্চতর স্তরের সমস্ত সফ্টওয়্যারকে কেবল নেটিভ ফর্ম্যাট দিয়ে ডিল করতে দেওয়া My
ডেভ টুইট করেছেন

যদিও এআরএম কর্পোরেশন দ্বারা ডিজাইন করা কোরটি শেষ পর্যন্ত উভয়ই কাজ করতে সক্ষম হয়েছে, এসটিএম 32F407 এ আরএম কোরটি বাস্তবায়ন কেবল সামান্য-এডিয়ান। রেফারেন্স ম্যানুয়াল আরএম 0090 পৃষ্ঠা See৪ দেখুন A
লাস্লোলো

উত্তর:


6

এম্বেড থাকা সিস্টেমে সর্বদা বিগ-এন্ডিয়ান / লিটল-এন্ডিয়ান সমস্যা থাকবে। আমার ব্যক্তিগত দৃষ্টিভঙ্গিটি সর্বদা অভ্যন্তরীণ মেমরিটিকে দেশীয় অন্তর্নিহিততার সাথে এনকোড করা এবং ডেটা .োকে বা চলে যাওয়ার সাথে সাথে কোনও অদলবদল তৈরি করে।

আমি স্পি ব্যবহার করে ডেটা লোড করি এনালগিন0.স্পাইবাইটে [0] - [2] এমএসবি হিসাবে [0] দিয়ে

[0] এমএসবি হিসাবে লোড করে, আপনি বড়-এন্ডিয়ান হিসাবে মান এনকোড করছেন।

analogin0.spibytes [0] = 0xFF এবং এবং analogin0.spibytes [1] = 0xB5, analogin0.halfwords [0] 0xB5FF এর সমান ছিল

এটি ইঙ্গিত দেয় যে প্রসেসরটি স্বল্প-এন্ডিয়ান।

পরিবর্তে, আপনি প্রথম মানটি [2] এ লোড করে এবং [0] এ ফিরে কাজ করেন, তবে আপনি আগত সংখ্যাটিকে ছোট-এন্ডিয়ান হিসাবে এনকোড করে রেখেছেন, মূলত নম্বরটি প্রবেশ করানোর সাথে সাথে অদলবদল করে। একবার আপনি স্থানীয় প্রতিনিধিত্ব নিয়ে কাজ করার পরে, আপনি গাণিতিক ক্রিয়াকলাপগুলি ব্যবহারের আপনার মূল পদ্ধতির দিকে ফিরে আসতে পারেন। আপনি যখন মানটি প্রেরণ করেন কেবল তখনই এটি বিগ-এন্ডিয়ানগুলিতে ফিরে যাওয়া নিশ্চিত করুন।


5

অনুগ্রহ সম্পর্কে "সত্যই srm32f4 বিগ এন্ডিয়ান মোড সম্পর্কে জানতে চান", এই চিপটিতে কোনও বড় এন্ডিয়ান মোড নেই। STM32F4 সামান্য এডিয়ানতে সমস্ত মেমরি অ্যাক্সেস করে।

ব্যবহারকারী ম্যানুয়াল http://www.st.com/web/en/resource/technical/docament/programming_manual/DM00046982.pdf পৃষ্ঠা 25 এ উল্লেখ করেছে। তবে আরও রয়েছে is পৃষ্ঠাগুলিতে আপনি দেখতে পাচ্ছেন এখানে এন্ডিয়ান অদলবদলের নির্দেশাবলী রয়েছে। বিপরীত ও বিপরীত বিটের জন্য REV এবং REVB। REV 32 বিটের জন্য আধ্যাত্মিকতা পরিবর্তন করবে এবং REV16 এটি 16 বিট ডেটার জন্য করবে।


3

জিসিসি সহ সংকলিত কর্টেক্স এম 4 এর জন্য এখানে একটি কোড স্নিপেট is

/*
 * asmLib.s
 *
 *  Created on: 13 mai 2016
 */
    .syntax unified
    .cpu cortex-m4
    .thumb
    .align
    .global big2little32
    .global big2little16
    .thumb
    .thumb_func
 big2little32:
    rev r0, r0
    bx  lr
 big2little16:
    rev16   r0, r0
    bx  lr

সি থেকে, কলটি হতে পারে:

 extern uint32_t big2little32(uint32_t x);
 extern uint16_t big2little16(uint16_t x);

 myVar32bit = big2little32( myVar32bit );
 myVar16bit = big2little16( myVar16bit );

এর থেকে দ্রুত কীভাবে করবেন তা জানেন না :-)


আপনি এই কোডটি আরও দ্রুত করতে ম্যাক্রো বা একটি ইনলাইন ফাংশন ব্যবহার করতে পারেন
pro

24 বিট তথ্য কি?
পেইজমিট

1

CooCox STM32F429 এর জন্য এটি ঠিক আছে:

typedef union {
  uint8_t  c[4];
  uint16_t   i[2];
  uint32_t  l[1];
}adc;

adc     adcx[8];

...

// first channel ...
    adcx[0].c[3] = 0;
    adcx[0].c[2] = UB_SPI1_SendByte(0x00);
    adcx[0].c[1] = UB_SPI1_SendByte(0x00);
    adcx[0].c[0] = UB_SPI1_SendByte(0x00);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.