آموزش میکروکنترلر STM32 قسمت دهم: واحد DMA در رابط سریال UART

آموزش میکروکنترلر STM32 قسمت دهم: واحد DMA در رابط سریال UART

آموزش میکروکنترلر STM32 قسمت دهم: واحد DMA در رابط سریال UART
آموزش میکروکنترلر STM32 قسمت دهم: واحد DMA در رابط سریال UART

آموزش میکروکنترلر STM32 ; سیسوگ در قسمت نهم از آموزش میکروکنترلر STM32  طریقه کار با وقفه رابط سریال را با استفاده و بدون استفاده از توابع کتابخانه hal  آموزش داد. در این قسمت از آموزش میکروکنترلر STM32 قصد دارد وارد قسمت آموزش کار با DMA رابط سریال UART شود. در مجموعه آموزشی ” آموزش میکروکنترلر STM32 ” با سیسوگ همراه باشید.

 

DMA در رابط سریال UART

اول از همه بهتر است در چند جمله کوتاه کار و قابلیت این امکان در این رابط سریال را توضیح دهیم. فرض کنید برنامه‌ای داریم که میخواهیم 500 بایت اطلاعات را به رابط سریال ارسال کنیم، بدون اینکه دست از کارهای دیگرمان بکشیم و وقتی صرف نماییم و یا اینکه مثلا 500 بایت از رابط سریال دریافت کنیم بدون اینکه بخواهیم وقتی صرف کنیم و منتظر دریافت باشیم. در موارد یاد شده ما از واحد DMA استفاده خواهیم کرد، به علاوه این قابلیت که وقتی عملیات به پایان رسید از طریق یک وقفه با خبر خواهیم شد و کدهای مناسب را در ادامه اجرا خواهیم کرد. ما برای شروع در این قسمت ابتدا آموزش کار با DMA را در قسمت دریافت قرار می‌دهیم. برای شروع دوباره به نرم افزار CubeMX می‌رویم و در قسمت تنظیمات UART1 به پنجره DMA settings می‌رویم و طبق عکس زیر تنظیمات را انجام می‌دهیم.

 تنظیمات UART1 پنجره DMA settings

آموزش میکروکنترلر STM32

بعد از انتخاب گزینه مورد نظر حالا می‌توانیم از طریق گزینه Mode در پایین سمت چپ مشخص کنیم دیتا به چه صورت دریافت شود، بصورت عادی Normal یا به صورت Circular و چرخشی. در حالت عادی ما هر بار باید بعد از اتمام دریافت اطلاعات دوباره پیکره‌بندی را انجام دهیم ولی در حالت چرخشی این عمل لازم نیست و بصورت خودکار بعد از اتمام دریافت دوباره آماده دریافت اطلاعات می‌شویم.

تنظیمات UART1 پنجره DMA settings

و در قسمت Data width هم نوع اطلاعاتی را که می‌خواهیم منتقل کنیم، مشخص می‌کنیم:

تنظیمات UART1 پنجره DMA settings

توجه داشته باشید در اینجا Byte به معنی 8 بیتی و Half Word به معنی 16 بیتی و Word به معنی دیتا از نوع 32 بیتی می‌باشد. ما در اینجا چون اطلاعاتی که جابجا می‌کنیم هشت بیتی است همان Byte را انتخاب می‌کنیم. بعد از ok کردن تنظیمات از CubeMX خروجی می‌گیریم و به محیط نرم افزار keil می‌رویم.

حال به توضیح فرمان‌های کتابخانه hal در این قسمت می‌پردازیم. برای ارسال یک آرایه اطلاعات به رابط سریال uart ما از فرمان زیر استفاده خواهیم کرد:

 

در آرگومان *huart تابع نام uart مورد استفاده ما قرار می‌گیرد و در آرگومان *pData رشته ای که قرار است اطلاعات دریافتی از رابط سریال در داخل آن قرار بگیرد. در آرگومان Size سایز یا تعداد بایتی که قرار است دریافت شود تعیین می‌شود. در نتیجه ما باید در ابتدای محلی که می‌خواهیم دریافت اطلاعات شروع شود از این فرمان استفاده کنیم. برای فهم بیشتر مسئله به عکس زیر توجه کنید.

 ارسال اطلاعات به رابط سریال uart

همانطور که میبینید در قسمت مشخص شده از عکس بالا، ما قرار است 20 بایت از رابط سریال huart1 دریافت کنیم و بایت‌های دریافتی هم داخل آرایه str ریخته شود. خوب تا اینجا مشکلی نیست، ولی می‌خواهیم بدانیم چطور از نتیجه عملیات باخبر شویم. یعنی اولا از کجا بفهمیم عملیات انتقال تا کجا پیش رفته یعنی چند بایت تا الان دریافت شده و دوم اینکه نصف بایت‌هایی که می‌خواستیم دریافت شده و سوم اینکه چطور بفهمیم همه 20 بایتی که می‌خواستیم کاملا دریافت شده است. در جواب سوال اول، ما می‌توانیم با چک کردن وضعیت رجیستر CNDTR از رجیستر‌های واحد DMA مورد استفاده خودمان متوجه شویم تا الان چند بایت دیگر از 20 بایت برای دریافت باقیمانده برای فهم بیشتر به کد زیر توجه کنید:

 

 

بر طبق کد‌نویسی بالا 20 بایتی که می‌خواستیم در یک مرحله دریافت شود، از تعداد بایتی که برای دریافت باقیمانده کم می‌شود و نتیجه می‌شود تعداد بایتی که تا الان دریافت شده بواقع عملکرد رجیستر CNDTR دقیقا مشابه عملکرد همان رجیستر RxXferCount است که پیش از این ذکر کردیم. یعنی با هر بار استفاده از فرمان HAL_UART_Receive_DMA این رجیستر با تعداد بایت درخواستی که ما در اینجا همان 20 است پر می‌شود و با هر واحد (در اینجا بایت) دریافت اطلاعات یکی از مقدار آن کم می‌شود تا به صفر برسد و بواقع عملیات دریافت پایان پذیرد.

راه حل دیگری که می‌توان از طریق آن متوجه شد آیا واحد DMA هنوز در حال تبادل اطلاعات است یا کار آن به پایان رسیده، چک کردن وضعیت State واحد DMA مورد نظر است. برای فهم بیشتر مسئله به عکس کدنویسی زیر توجه کنید.

چک کردن وضعیت State واحد DMA

همانطور که در عکس بالا میبینید ما چک می‌کنیم اگر وضعیت State در حالت HAL_DMA_STATE_READY است، یعنی عملیات تمام شده و واحد مورد نظر دوباره آماده پذیرش است و در خط 133 هم اطلاعات دریافتی را نمایش می‌دهیم . در خط 134 بافر دریافت را پاک میکنیم، در خط 135 بدلیل اینکه در مد عادی هستیم و از حالت چرخشی استفاده نکردیم دوباره پیکره بندی را انجام می‌دهیم. توجه داشته باشید که State در ابتدای شروع متن تابع HAL_UART_Receive_DMA به حالت HAL_UART_STATE_BUSY_RX می‌رود و تا پایان عملیات دریافت در همین وضعیت باقی می‌ماند و اصولا تابع HAL_UART_Receive_DMA هم تنها زمانی اجرا می‌شود که State در وضعیت ازاد یا همان HAL_DMA_STATE_READY باشد. برای فهم بیشتر متن تابع مورد نظر را در برگه مربوطه مطالعه نمائید. بیاد داشته باشید این قائده تنها مخصوص این تابع نمی‌باشد، بلکه خیلی توابع دیگر از کتابخانه hal از این رویه پیروی می‌کنند. خوب حالا بسراغ توابع وقفه رابط DMA می‌رویم که این وقفه به اجبار در همان نرم افزار CubeMX انتخاب شده بوده بدنه روتین وقفه در همان برگه stm32f1xx_it.c وجود دارد که در عکس زیر مشاهده مینمائید.

توابع وقفه رابط DMA

در اینجا ما می‌خواهیم از دو وقفه مختلف برای دریافت رابط DMA استفاده کنیم و از توابع Callback که می‌توانیم در  برگه main.c برنامه خود ان را جاسازی کنیم استفاده می‌کنیم. اولین تابع Callback وقفه دریافت کامل است و دیگری مربوط به دریافت نیمی از اطلاعات درخواستی یعنی وقتی 20 بایت می‌خواهیم از رابط سریال دریافت کنیم بعد از دریافت 10 بایت که نیمی از اطلاعات درخواستی ماست به این تابع می‌رویم. در عکس زیر می‌توانید این توابع را به همراه کدهای مورد نظرمان که می‌خواهیم داخل این توابع اجرا شود در برگه main.c برنامه ببنید.

تابع Callback وقفه رابط DMA

همانطور که در کدنویسی‌ها مشخص است تابع بالا مربوط می‌شود به دریافت کامل و تابع پایینی مربوط می‌شود به دریافتی نیمی از اطلاعات. و در عکس هم توضیح داده شده است که فرمان خط 251 تنها باید زمانی نوشته شود که از حالت معمولی استفاده شده و در حالت چرخشی یا Circular احتیاجی به دوباره نوشتن این فرمان برای دریافت دوباره نیست. برای فهم بیشتر مسئله به تصویری از محیط نرم افزار terminal برای ارتباط سریال با کامپیوتر توجه کنید.

 محیط نرم افزار terminal برای ارتباط سریال با کامپیوتر

ارسال از طریق DMA

بعد از آموزش طریقه دریافت بوسیله واحد DMA وارد آموزش ارسال از طریق DMA می‌گردیم. برای این منظور دوباره به محیط CubeMX برمی‌گردیم و باز به سراغ پنجره DMA settings می‌رویم و طبق عکس زیر تنظیمات را انجام می‌دهیم.

 پنجره DMA settings در محیط CubeMX

بعد از ok کردن تنظیمات از CubeMX خروجی می‌گیریم و به محیط نرم افزار keil وارد می‌شویم. حال می‌خواهیم ببنیم از طریق چه فرمانی از کتابخانه hal می‌توانیم محتوای یک بافر را از طریق واحد DMA به رابط سریال ارسال کنیم.

 

 

در آرگومان *huart تابع نام uart مورد استفاده ما قرار می‌گیرد و در آرگومان *pData رشته‌ای که قرار است اطلاعات آن به رابط سریال ارسال شود. در آرگومان Size سایز یا تعداد بایتی که قرار است ارسال شود را تعیین می‌شود. بعنوان مثال فرمان زیر را تحیلیل می‌کنیم.

 

 

از طریق این فرمان ما 20 بایت از آرایه str به درگاه سریال huart1 ارسال می‌کنیم. حال اگر حالت عادی را انتخاب کرده باشیم این ارسال یکبار صورت می‌گیرد و اگر حالت چرخشی را انتخاب کرده باشید بصورت مداوم اطلاعات به رابط سریال ارسال می‌گردد . توجه داشته باشید برای حالت ارسال هم دو وقفه مشابه حالت دریافت بصورت Callback بکار گرفته می‌شود. یکی بعد از اتمام نیمی از بافر با نام HAL_UART_TxHalfCpltCallback و دومی بعد از اتمام همه محتویات بافر با نام HAL_UART_TxCpltCallback منتها در حالت عادی تنها وقفه ارسال نیمی از بافر قابل دسترسی است، منتها شما خودتان می‌توانید با دستکاری تابع UART_DMATransmitCplt در برگه stm32f1xx_hal_uart.c می‌توانید برای حالت عادی هم از آن وقفه استفاده کنید.

تنظیملت DMA در رابط سریال UART

توجه داشته باشید در حالت ارسال هم می‌توانیم با چک کردن رجیستر CNDTR  متوجه شویم چند بایت تا الان ارسال شده و همچنین با چک کردن وضعیت State به مانند حالت دریافت میتوانیم از اتمام عملیات باخبر شویم ، بعد از توضیح و اموزش دریافت و ارسال توسط DMA توسط رابط UART بد نیست به چند دستور دیگر از کتابخانه hal که معمولا کاربرد دارند اشاره شود.

 

 

متوقف کردن ادامه انتقال

 

 

ادامه انتقالی که قبلا متوقف شده بود

 

 

توقف کلی انتقال

 

 

برای توقف انتقال‌های جاری که البته در حالت چرخشی مجاز نیست و باعث می‌شود برنامه بعضا بعد از مدتی قفل کند.

برای بخش UART توابع hal زیادی وجود دارد که تحقیق و بررسی آن خارج از وقت و زمان ماست به اضافه اینکه این رابط سریال خیلی امکانات دیگری هم دارد که ان شا الله در آموزشهای بعدی به آنها اشاره خواهیم کرد.

 

سیسوگ در قسمت یازدهم از مجموعه آموزش میکروکنترلر STM32 به آموزش تنظیمات نرم‌افزار CubeMX برای رابط RTC  در خانواده CORTEXM3 می‌پردازد. در مجموعه آموزش میکروکنترلر STM32 با سیسوگ همراه باشید.

 

 

 

حمایت از مهدی عبدالهی

خوشحال میشیم برای تداوم و کیفیت ما رو حمایت کنید.

1 نفر

پــــســنــدیـده انـد

توجه

مهدی عبدالهی
مهدی عبدالهی

کانال میکروالکترونیک @microstm32

دیدگاه ها

27 دیدگاه

  • سینا مختاری
    سینا مختاری
    ۲۸ خرداد ۱۴۰۱

    خیلی خوب بود ممنونم

    • Sisoog Os
      Sisoog Os
      ۲۹ خرداد ۱۴۰۱

      سلام خواهش میکنم دوست عزیز

  • محمد احمدلو
    ahmadlou.mo
    ۲۷ فروردین ۱۴۰۱

    با سلام
    ممنونم از مطلب بسیار عالی شما
    یه سوال داشتم. بعد از اولین ارسال توسط تابع HAL_UART_Transmit_DMA چگونه باید تابع را از حالت Busy خارج کرد و به حالت Ready برد تا برای ارسال دیگر آماده شود ؟

    با تشکر

    • سیاوش ایرانپاک
      سیاوش
      ۲۸ فروردین ۱۴۰۱

      سلام دوست عزیز، خوشحالیم که آموزش‌ها مورد توجه شماست.
      در مورد سوالتون (البته اگر من درست متوجه شده باشم)، خب DMA به مقدار مشخص شده پکت به UART میده برای ارسال، UART هم بعد از هر ارسال اعلام میکنه که منتظر ارسال بعدیه.
      حالا اگه DMA توی حالت Normal تنظیم شده باشه بعد اتمام ارسال داده‌ها خود به خود آماده ارسال مجدد میشه و اگه شما قصدتون اینه قبل از ارسال کامل داده‌ها مجددا دستور ارسال بدین(به همین واحد UART) باید از دستور HAL_UART_DMAStop استفاده کنید.

  • محمد عزیز
    محمد عزیز
    ۲۳ فروردین ۱۴۰۱

    سلام و وقت بخیر
    سپاس از آموزش خوبتان
    من یک مشکلی دارم موقع تحلیل پیام دریافتی از sim800 با DMA مدل پردازنده Stm32f103rb و Keil
    طبق آموزش شما پیش رفتم، دستور رو در تابع اصلی قبل از حلقه while(1) نوشتم با این تفاوت که رو مد circular گذاشتم و بازفراخوانی رو انجام ندادم و فقط بدنه تابع recal رو نوشتم اما توش خالیه چون با stmstudio نظاره گر اطلاعات بافر هستم.
    اما مشکل !
    پس از تحلیل پیام بافر 100 آرایه ایم رو با دستور memset بازنشانی میکنم به صفر .
    اما در شروع دریافت پیام بعد متوجه روی هم افتادگی اطلاعات شدم ، سایز رو کردم 150 و دیدم اطلاعات داره دقیقا از آخرین آرایه ای که در سری قبل دریافت شده رایت میشه روی بافرم!
    یعنی بجای اینکه بیاد از آرایه صفر شروع به نوشتن کنه از همون آرایه مثلا 100 میره جلو تا 117 مثلا هنگام دریافت پیام.
    و تراژدی اونجا غمناک تر میشه که حتی با یک تماس بافر چند خانه اش (مثلا تا خانه 8 پر میشه طبق رشته ring !!!) پر میشه و پس از پاک کردن با memset باز موقع دریافت پیام از همون خانه 8 شروع به پر کردن میکنه بجای آرایه صفر.
    خیلی تلاش کردم و متاسفانه حرفه ای هم نیستم و هنوز علی رغم دست و پاهایی که زدم نتونستم این مشکلو حل کنم که پس از بازنشانی خانه های بافر بیاد از آرایه صفر شروع به نوشتن کنه.
    کارهایی که خودم تابحال کردم استفاده از توایع دیگر hal مثل hal_abort , hal_init_, hal_deinit و غیره بوده که هیچکدام جواب نداده.
    ممنون میشم به من بی نوا کمک کنید

    • سیاوش ایرانپاک
      سیاوش
      ۲۳ فروردین ۱۴۰۱

      خب طبق چیزی که من متوجه شدم شما میخواید مثلا 100 خونه از حافظه که توسط بافرتون مشخص شده، به وسیله DMA پر بشه و بعد برای عملیات دوم دوباره از ابتدای این بافر شروع به نوشتن کنه. برای این منظور شما باید آدرس ابتدای بافر و تعداد خونه‌هایی که قصد نوشتن توشون رو دارید یک برای عملیات اول و بعد هم یک بار برای عملیات دوم به حافظه بدین. بسته به پروژه و نوع میکروکنترلر ممکنه نیاز باشه که DMA رو هم غیر فعال و دوباره فعال کرد.

      • محمد
        ۲۴ فروردین ۱۴۰۱

        سلام بله مشکل اینه که آرایه های بافر بدون ترمز بصورت افزایشی پر میشند تا سرریز شند و از ابتدا شروع کنند نه از صفر.
        در روش ریجستری تو بعضی منابع مبحثی هست برای رسیت کانتر داخلی تابع دریافت DMA با کتابخوانه CMSIS اما اینکه وسط کتابخونه HAL با CMSIS ریجستری بنویسیم احتمال زیاد ارور میده چون اون داره یک تابع کامل رو اجرا میکنه مگر اینکه از خود کتابخونه HAL مجدد استفاده شه.
        من با دستورات دیگش کار کردم و تست کردم اما هنوز جوابی نگرفتم متاسفانه برای رفع این مشکل که خیلی هم بده.
        HAL_Abort_DMA ، HAL_Init_DMA , HAL_DeInit_DMA , HAL_Stop_DMA
        اینها رو که در انتها استفاده میکنم کلا ارتباط قطع میشه چون HAL_Receive_DMA قبل از While تو تابع اصلی نوشته شده.
        البته امروز هم قراره با کد ور برم نتیجه رو حتما اینجا اعلام میکنم که کسی این مشکل رو نداشته باشه البته اگر حل شد 😅

    • محمد عزیز
      محمد عزیز
      ۲۴ فروردین ۱۴۰۱

      حل شد !
      باید برای جلوگیری از مشکل فوق ابتدا دستور را بازنشانی و سپس مجدد استارت کنید.

      • Zeus ‌
        Zeus ‌
        ۲۴ فروردین ۱۴۰۱

        بسیار عالی
        ممنونم که تجربه خودتون با ما به اشتراک گذاشتید 🙂

        • محمد
          ۲۴ فروردین ۱۴۰۱

          خواهش میکنم، من از سیسوگ بهم رسیده و کم سعادتم بخاطر مشغله که نمیتونم فعال باشم انشا… در آینده زکات علم ناچیزمو همینجا خواهم داد.
          حالا که حضرت زئوس از المپ تشریف آوردند تکمیل ترش میکنم :
          HAL_DeInit_DMA جهت بازنشانی مقادیر به صفر و
          HAL_UART_START_RECEIVE_DMA جهت استارت مجدد دستور

          باید در انتها قبل از شروع بررسی بافر جدید اجرا شود تا شاهد تکمیل شدن از آرایه صفر در بافر باشید ، در غیر اینصورت ادامه فرایند تکمیل شدن از همونجایی ادامه پیدا میکنه که قبلا پر شده بوده تا جایی که سرریز اتفاق بیفته.
          با تشکر از سیسوگ

          • Zeus ‌
            Zeus ‌
            ۲۷ فروردین ۱۴۰۱

            سلام و درود
            بسیار سپاسگذارم 🙂

            0
  • مصطفی
    ۱۵ دی ۱۴۰۰

    من چند سایت رو برای موضوع DMA بررسی کردم , توضیحات شما بسیار کاربردی و مناسب بود.
    ممنون

  • علی
    ۳۰ مهر ۱۴۰۰

    سلام
    اگر در حالت چرخشی از فرمان
    HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
    برای دریافت دوباره استفاده بشه چه اتفاقی می افته؟

    • Zeus ‌
      Zeus
      ۱۴ آبان ۱۴۰۰

      اگر به موقع بافر رو نخونید آور رایت میشه اطلاعات و اطلاعات از دست میره

  • hamid
    ۲۶ اردیبهشت ۱۴۰۰

    با سلام.
    در زمانی ک دریافت اطلاعات در DMA به پایان نرسیده است(مثلا قرار است 200 دیتا دریافت شود ولی تنها 25 تا دریافت شده است) میتوان ب اطلاعاتی ک تا آن زمان دریافت شده است(مثلا دیتا 24) دسترسی داشت یا خیر؟
    با تشکر

    • Zeus ‌
      zeus
      ۱ خرداد ۱۴۰۰

      سلام بله منطقا میشه
      چون دیتا توی همون بافری که به dma معرفی شده ذخیره میشه به سادگی میتونید بهش دسترسی داشته باشید.

  • amir
    ۱۹ خرداد ۱۳۹۹

    با عرض خسته نباشید خدمت شما
    چنتا سوال داشتم از خدمتتون ممنون میشم بهم جواب بدین
    سوال اول:بخش size در دستور ارسال یا دریافت بر اساس حجم کلی یا چیز دیگه من زمانیی که کاراکتری که مقدار ان 255 میفرستادم زمانی که به جای size عدد 3 میگزاشتم عدد رو کامل میفرستاد ولی زمانی که 1 میزاشتم 2 رو فقط میفرسستاد در صورتی که گفته بودین size تعداد byte هایی که میفرستمی و 1 هست یعن یهمون یه کاکتر
    سوال دوم: من با استفاده از ارتباط uart بین دو عدد stm32f103 ارتباط بر قرار کردم در حالت uart بدون استفاده از dma ارتباط درست بود ولی بین برنامه هام تداخل ایجاد میکرد برای همین از dma استفاده کردم ولی مشکل این است که دیتایی که میفرستم بادیتا که میاد تفاوت داره وخیلی عجیبه ارسالم رو چک کردم به وسیله ttl به usb درست بود ولی دیتای دریافتیم درست نیست چه کنم
    سوال سوم :سرعت انتقال دیتای من کمه با مولتی متر که گرفتم 42khz بود ولی خیلی بیشتر از این ها باید باشه

    ممنون

    • Zeus ‌
      زئوس Zeus
      ۲ تیر ۱۳۹۹

      ج۱ – خوب size در واقع طولی بایت هایی هست که قراره از طریق واحد uart ارسال بشه – فرض کنید شما میخواید عبارت salam رو در خروجی ظاهر کنید – برای این باید مقدار size رو برابر ۵ قرار بدید.
      ج۲ – اگه با مبدل چک کردید باس رو و دیتای درستی ارسال میشه – مشکل توی فرایند دریافت است واگر باز بدون dma دریافت درسته مشکل از تنظیمات dma است. چک کنید آیا بافری که قراره دیتا رو بخونه به اندازه لازم طولانی باشه
      ج۳ – متوجه منظورتون نشدم ؟ یعنی چی سرعت انتقال کمه ؟ باوود رو روی چه عددی گذاشتید ؟

  • َAmir
    ۲۷ آذر ۱۳۹۸

    سلام
    خسته نباشید
    سوالی داشتم:
    DMA در حالت ارسال بدون تاخیر ارسال میکنه ؟ اگه بخواهیم مثلا 10 بایت را بصورت مداوم اما بین هر ارسال مثلا 100 میلی ثانیه تاخیر باشه باید چکار کنیم ؟
    واینکه وقتی ارسال تکمیل بشه تابع HAL_UART_TxCpltCallback اجرا میشه ؟

    ممنون

    • Zeus ‌
      زئوس Zeus
      ۱ دی ۱۳۹۸

      خوب این کار رو صد در صد با dma نمیتونید هندل کنید – در واقع dma هیچ تنظیمی برای زمان دادن نداره و بافر ورودی رو با سریعترین حالت ممکن توی خروجی ظاهر میکنه !!
      برای زمان دادن میتونید از تایمر و cpu رو کمک بگیرید که دیگه هیچ ربطی به dma نداره

  • سروش
    ۳۱ شهریور ۱۳۹۷

    با عرض سلام و احترام
    سوالی از آموزشتون برام پیش اومده بود که ممنون خواهم شد اگر جواب بدین.
    در قسمت پنجره Dma setting یه قسمت هست به نام priority که Low گذاشتین . از کجا می شه فهمید باید High گذاشت یا Low . چون من در مثال های دیگه ای که مثل همین بود حالتهای مختلفی دیدم.یک جا هر دو را Low گذاشته بودند یک جای دیگه High برای RX و Low برای TX گذاشته بودند.
    از جناب آقای زئوس بزرگ هم کمال تشکر را دارم . موفق و سربلند باشید!

    • Zeus ‌
      زئوس Zeus
      ۳۱ شهریور ۱۳۹۷

      سلام دوست عزیز، ممنون از لطف شما
      خوب همونطور که از اسم priority برمیآد ، برای مشخص کردن اولویت کاربرد داره ، اما اولویت چی بر چی ؛ ببینید توی میکروکنترلر یه باس RAM در هر لحظه میتونه میزبان تراکنش باشه (البته باس رم خیلی سریعه و فکر میکنم سرعتی در حدود گیگاهرتز داره تو مدل m4) ولی به هر حال ، حالا فرض کنید هم زمان شما دوتا کانال Dma رو فعال کردید ، و شرایطی پیش میآد که دقیقا نیاز در یک لحظه مشخص به حافظه RAM دسترسی پیدا بکنند ، چه اتفاقی می تونه بیفته ؟
      شما میتونید با دادن اولویت مشخص کنید که کدام کانال DMA از اولویت بالاتری برخورداره و زودتر به RAM دسترسی پیدا بکنه ! البته میگم فقط توی چنین شرایطی !

    • سروش
      ۳۱ شهریور ۱۳۹۷

      با سلام و عرض ادب
      واقعا ممنون توضیحتون مشکلم رو حل کرد.
      یک دنیا ممنون.
      موفق و سربلند باشید.

      • Zeus ‌
        زئوس Zeus
        ۳۱ شهریور ۱۳۹۷

        ممنونم
        خوشحال میشم اگر تونسته باشم کمکی بکنم
        شما هم موفق و پیروز باشید.

  • سروش
    ۲۷ شهریور ۱۳۹۷

    سلام آقا مهدی
    خسته نباشید . امیدوارم همینطور به آموزشتون ادامه بدید.
    خیلی خیلی ممنون.
    از سایت سیسوگ هم تشکر ویژه – علم برای همه رایگان –
    می خواستم اگه امکانش هم بود در مورد حالت mem to mem واحد dma هم یه قسمت آموزشی بزارید.
    موفق و سر بلند باشید.

    • Zeus ‌
      زئوس Zeus
      ۲۷ شهریور ۱۳۹۷

      خواهش میکنم دوست عزیز
      خوشحالیم اگر توانسته باشیم کمکی هر چند کوچک کرده باشیم

پر بحث ترین ها

مسابقه دوم : چالش برنامه نویسی به زبان C

مسابقه اول سیسوگ (مسابقه اول: درک سخت افزار) انتقادهای زیادی رو در پی داشت تا جایی که حتی خودمم به نتیجه مسابقه...

Zeus ‌ Zeus ‌
  • 2 سال پیش

راه اندازی LCD گرافیکی Nokia 1661 و دانلود کتابخانه آن

LCD گرافیکی یکی از مهم ترین پارامترهای موجود در طراحی انواع مدارات الکترونیکی پیچیده و حتی ساده است ، نمایش وضعیت و...

Zeus ‌ Zeus ‌
  • 4 سال پیش

ریموت کدلرن و چکونگی دکد کردن آن به همراه سورس برنامه

ریموت کنترل امروزه کاربرد زیادی پیدا کرده است؛ از ریموت‌های درب بازکن تا ریموت‌های دزدگیر و کنترل روشنایی همه از یک اصول اولیه پیروی می‌کنند و آن‌هم ارسال اطلاعات به‌صورت بی‌سیم است....

Zeus ‌ Zeus ‌
  • 5 سال پیش

مسابقه سوم: استخراج داده از رشته ها در زبان C

نزدیک به 5 ماه از مسابقه دوم سیسوگ می‌گذره و فکر کردم که بد نیست یک چالش جدید داشته باشیم! البته چالش‌ها...

Zeus ‌ Zeus ‌
  • 2 سال پیش

همه چیز درباره ریموت کنترل‌های هاپینگ

امنیت همیشه و در همه‌ی اعصار، مقوله‌ی مهم و قابل‌توجه‌ ای بوده و همیشه نوع بشر به دنبال امنیت بیشتر، دست به ابداعات و اختراعات گوناگونی زده است. ریموت کنترل یکی از این اختراعات است. در این مقاله، به بررسی امنیت انواع ریموت‌های کنترل خواهیم پرداخت....

Zeus ‌ Zeus ‌
  • 5 سال پیش

مسابقه ششم: بزن میکروکنترلر را بسوزون!

بزنم میکروکنترلر را بسوزونم اونم تو  این شرایط!، طراحی مسابقه از اون چیزی که به نظر می‌رسه سخت‌تر است، باید حواست باشه...

Zeus ‌ Zeus ‌
  • 9 ماه پیش

آموزش قدم به قدم راه اندازی +NRF24L01

آموزش قدم به قدم راه اندازی +NRF24L01  با کتابخانه سازگار با انواع میکروکنترلرها و کامپایلرها قبل از اینکه قسمت بشه با ماژول...

رسول خواجوی بجستانی رسول خواجوی بجستانی
  • 3 سال پیش

ساخت ماینر با FPGA و ARM

چند ماهی هست که تب بیت کوین و ارزهای دیجیتال خیلی بالا رفته! چه شد که این پست را نوشتم همانطور که...

Zeus ‌ Zeus ‌
  • 3 سال پیش

مسابقه چهارم: کدام حلقه سریع‌تر است؟

حدود ۷ ماه پیش، مسابقه سوم سیسوگ رو برگزار کردیم و کلی نکته در مورد خواندن رشته‌های ورودی را بررسی کردیم. فکر...

Zeus ‌ Zeus ‌
  • 1 سال پیش

کار با ماژول تمام عیار mc60 – قسمت دوم – راه اندازی OpenCPU

در قسمت اول به یکسری اطلاعات کلی ماژول mc60 پرداختیم، با نرم افزار QNavigator کار کردیم و یک هدربرد هم برای کار...

Mahdi.h   Mahdi.h  
  • 2 سال پیش
سیـــســـوگ

مرجع متن باز آموزش الکترونیک