نمایش/عدم نمایش سایدبار
رفتن به بالای صفحه
أَللّهُمَّ ارْزُقْنی شَفاعَةَ الْحُسَیْنِ یَومَ الْوُرُودِ
مهدی دمیرچیلو

پروژه arm ارتباط سریال uart میکروکنترلر lpc1768 ق۱

309

به نام خدا : تو این دو مطلب پروژه آرم، میخاوم یه ۶-۷ تا پروژه قرار بدم، درباره UART میکروکنترلر LPC176X/5X، و یه کتابخونه ایجاد خواهیم کرد و تو هر پروژه ارتقاش میدیم، هر پروژه نسبت به پروژه قبلیش یه سطح بالاتر هستش و مشکل پروژه قبلیش رو حل کرده، و باز خودش مشکلی داره که تو پروژه بعدی حل میشه، روال پروژه های این دو مطلب به همین صورته، بیشتر آموزش پروژه محور هستن، آموزش منظم و کامل رجستر ها هم بعد این دو مطلب در سایت قرار میگیره؛ تمام پروژه های این دو مطلب ( کلا هر چی پروژه و مطلب و … تو سایت هستش ) در عمل تست شده.
پروژه arm ارتباط سریال uart میکروکنترلر lpc1768 ق1

پروژه arm ارتباط سریال uart میکروکنترلر lpc1768 ق۱


 

پروژه آرم با میکروکنترلر LPC17xx – پروژه ۱

این پروژه : تو این پروژه ارسال و دریافت انجام میدیم، بدون استفاده از وقفه.
شماتیک پروژه : 
یه ماژول USB TO TTL میخرید، من از CP2012 استفاده میکنم، اینو گیر بیارید خیلی خوب میشه؛ پایه TX اش رو به پایه P0.3 و پایه RX اش رو به پایه P0.2 میکرو و GND ایش رو به GND میکرو وصل کنید و بعد ماژول فوق رو به کامپیوتر وصل کنید؛ بعد یکی برید لینک بالا و یه نرم افزار برا ارتباط سریال انتخاب کنید و دانلود کنید و شروع کنید به تبادل داده با میکروکنترلر تون ^_^
کد پروژه :

توضیح پروژه بالا رو در زیر به صورت مفصل میدم، خوب بخونید که دیگه دفه های بعد این قدر توضیح نمیدم laugh  :

خب بریم سراغ توضیح تابع initialization که برا راه اندازی اولیه UART0 هستش ( حالا شما برا تمرین میتونید همین پروژه رو با UART1 و یا UART3 انجام بدید – کار خاصی نداره – یعنی اگه نتونستید – با کله برید تو دیوار – از شوخی بگذریم ولی خب سعی کنید انجامش بدید حالا با چند بار تست و خطا کردن زیاد مهم نیست – مهم اینه که آخر سر انجامش بدید)، چیز جالبی که این تابع داره اینه که برا راه اندازی UART فقط Baud Rate رو باید بهش بدی ^_^ این یعنی سادگی کار در برنامه نویسی های آینده  :

۰) تعریف چند تا متغییر که در این تابع نیاز داریم بهشون؛ در هر قسمت که برسیم، کار هر کدوم رو متوجه میشید.

۱) تعیین نقش پایه های P0.2 و P0.3 به عنوان UART0؛ در کد بالا به ساده ترین روش ممکن مقدار دهی کردم، در آینده منظور حرفم رو میفهمید. ^_^
توجه : اگه فراموش کردید به مطلب مقابل برید : آموزش آرم lpc1768 جلسه ۱ pin connect block

۲) با توجه به نکته ای که در جلسات قبل گفتم نباید در پایه دریافت اطلاعات مقاومت داخلی pull-down رو فعال کنید ( اگه فعال کنید، دریافت کننده اطلاعات UART کار نمیکنه -تست کردم که دارم میگم^_^- ) و چون در حالت عادی مقاومت داخلی pull-up تمام پایه ها فعاله و این مورد مشکلی برا ما ایجاد نمیکنه، لذا کاری با ریجستر PINMODE0 نداریم.
توجه مهم : بهتره مقاومت داخلی pull-up پایه های ارسال و دریافت رو بزارید فعال بمونه و غیر فعالش نکنید.

۳) در این مرحله اومدیم حافظه فیفو ارسال و دریافت رو از اطلاعات خالی کردیم، چون ممکنه از آخرین باری که میکرو روشن بوده، اطلاعاتی داخل این بافر ها بوده باشه؛ و همچین FIFO رو هم فعال کردیم.
توجه ۱ : با بیت های RX Trigger Level ( چه تعداد دیتا باید دریافت شود تا وقفه یا درخواست DMA فعال بشه ) هم فعلا کاری نداریم چون از وقفه استفاده نمیکنیم و این مورد برامون مهم نیست؛ یرخی فقط میخوایم اطلاعات رو دریافت کنیم ^_^

۴) در این قسمت اومدم فرمت دیتا رو تعیین کردم، و بیت (Divisor Latch Access Bit (DLAB رو هم ۱ کردم ( تا بتونم به ریجسترهای UnDLL و UnDLM دسترسی داشته باشم و بتونم Baud Rate رو تعیین کنم و بعد که تعیین کردیم، تو ۳ سوت ^_^ مقدارش رو ۰ میکنیم تا بتونیم به ریجستر های RBR و THR  و IER دسترسی داشته باشم – این کارا رو در ادامه انجام میدم و توضیح میدم )

۵) تو این خط کاری به رجیسترش نداشته باشید ( بعد تمام شدن مطالب UART توضیح میدم مبحط کلاک و POWER رو، فعلا بیخیال شید و هر چی من گفتم شما تایید کنید ^_^ )؛ خب تو این خط میایم بررسی میکنیم که مقدار تقسیم کننده کلاک UART0 چند تعیین شده ( در حالت عادی، تمام امکانات میکروکنترلر، تقسیم کننده کلاکشون ۴ هستش، مگر این که تغییرش بدین )؛ این مقدار در ادامه به کار میاد…
توجه : نحوه تعیین تقسیم فرکانسی ها به صورت زیر امکان پذیر هستش ( پیش خودم گفتم بگم تا تو خماری نمونید تو این قسمت O_o میبینید چقدر به فکرتون هستم ^_^ )؛ تو این قسمت ابتدا فایل مربوطه رو باز میکنیم(قسمت قرمز رنگ)، بعد میریم به صفحه مربوطه(قسمت سبز رنگ)، بعد میریم سراغ گزینه مد نظرمون و مقدارش رو تغییر میدیم که این جا UART0 چیزی هستش که ما باهاش کار داریم( قسمت صورتی رنگ )، رو اون ComboBox (دکمه کشویی) کلیک کنید تقسیم فرکانسی های ۱و۲و۴و۸ رو به ما میده و هر کدوم رو دوست داشتیم انتخاب میکنیم، همون طور که میبینید مقدار پیشفرض مقسم (تقسیم کننده!) برای تمام امکانات جانبی میکروکنترلر برابر ۴ هستش.
تعیین تقسیم فرکانسی واحد های جانبی میکروکنترلر LPC17xx

۶) خب تو قسمت قبل مقدار رجیستر مقسم فرکانسی UART0 ( مقدار رجیستر و نه خود مقدار مقسم – ۱و۲و۴و۸ – )؛ حالا تو این قسمت میایم میبینیم که کدوم مقدار مقسم انتخاب شده، به کمکش میایم کلاک اصلی رو بر اون مقدار تقسیم میکنیم و میدیم به متغییر var_UART0Clock_u32 که حاوی فرکانس کاری UART0 هستش و از این متغییر در فرمول محاسبه Baud Rate استفاده میکنیم. ( البته بگم فرمول محاسبه رجیسترهای Baud Rate درست تر هستش. )

۷) اینم از فرمول محاسبه ریجسترهای نرخ داده؛ در ادامه با var_RegValue_u32 کار داریم…

۸) مقدار var_RegValue_u32 رو به رجیسترهای DLL و DLM میدیم.
توجه : از ریجستر U0FDR استفاده نکردم تا کار ساده تر بشه؛ حالا شاید سوال بشه خب چرا مقدار ۰ و ۱ رو هم بهشون ندادی؟ خب اگه مطلب قبل رو خوب یادتون باشه، تو توضیح رجیستر UnFDR گفتم که در حالت عادی این ویژگی غیر فعال هستش و داریم : DIVADDVAL=0 و  MULVAL=1 لذا در فرمول هم این دو رو به همین صورت مقدار دهی میکنیم.

۹) بیت DLAB از رجیستر LCR رو پاک میکنیم ( بنا به دلایلی که در چند خط بالا تر گفتم و الان حال ندارم دوباره تکرار کنم ^_^ )

بریم سراغ تابع بعدی، اسم این تابع write هستش که وظیفش ارسال کاراکتر هستش؛ این تابع به صورت زیر هستش، توضیحات فارسی هم برا هر خط ذکر کردم :

سوال : تو کد بالا، خط ۲ام کد کارش چیه؟ این خط رو نزاریم چی میشه؟
جواب : خب باید صبر کنیم تا رجیتسر U0THR دیتای قبلی که بهش دادم رو به حافظه FIFO ارسال بده، و بعد بیایم بهش دیتای جدید بدیم، حالا چطور متوجه بشیم که U0THR دیتا رو به FIFO داده و الان خالی هستش؟ خب به کمک رجیستر U0LSR و بیت ۵ امش ( THRE ) میتنیم از این موضوع با خبر بشیم؛ حالا اگه رجیستر U0THR هنوز از دیتا خالی نشده، بیایم بهش دیتا بدیم چی میشه؟ خب معلومه دیتای قبلی از بین میره ^_^

تابع بعدی، readData هستش که وظیفش دریافت کاراکتر هستش؛ این تابع به صورت زیر هستش، توضیحات فارسی هم برا هر خط ذکر کردم؛ علت وجود خط ۲ در کد زیر هم معلومه، تا زمانی که در ریجستر U0RBR دیتایی نباشه نمیتونیم مقدارش رو بخونیم ^_^ :

توجه : مشکلی که این جور توابع دارند اینه که تا زمانی که دیتایی دریافت نشده تابع دریافت اطلاعات اجرا میشه، یعنی برنامه تو اون خط ۲ وای میسته و اینطوری CPU و در نتیجه کل پروژه به فنا میره، چون بقیه کارها و کدها رو نمیره اجرا کنه، لذا به همین خاطر معمولا از وقفه برا این کار استفاده میکنن و یا این که خط ۲ رو به صورت if مینویسن که اون داستان خودش رو داره ولی در کل بهترین گزینه معمولا وقفه هستش.

بقیه توابع هم ترکبی از تابع write هستن و بیشتر به بحث برنامه نویسی C مربوط میشن تا به میکروکنترلر!!! این حرفا یعنی ان که توضیح نمیدمشون ^_^ البته فعلا، حالا بعدا ببینیم چی میشه، شاید در مطلب کتابخونه UART میکروکنترلر LPC17xx توضیح دادم، شاید هم ندادم ^_^

پروژه آرم با میکروکنترلر LPC17xx – پروژه ۲

این پروژه : تو این پروژه ارسال و دریافت انجام میدیم، و از وقفه RBR ( اطلاع از دیرافت اطلاعات جدید) استفاده میکنیم.
توجه ۱ : تو این پروژه برا سادگی هرچه بیشتر کار، اومدم توابع مربوط به ارتباط سریال و راه اندازیش و ارسال و دریافت و … رو داخل یه فایل قرار دادم و از این به بعد فقط نام فایل رو تو پروژه فراخونی میکنیم ( یه جورایی اون چند تا تابع رو تبدیل به یه کتابخونه کردم، البته نمیدونم لفظ کتابخونه براش درسته یا نه ولی خب ما میگیم کتاب خونه ^_^ )؛ اینطوری پروژه هم خلوت تر میشه و هم احتمال رخ دادن هر گونه سوتی کاهش پیدا میکنه و … با این فایل کتابخونه UART که فعال برا UART0 هستش و همش ۴-۵ تا تابع داره فعلا کار داریم، در هر قسمت یه توابعی بهش اضافه میکنم و تغییراتی توش میدم.
توجه ۲ : کار دیگه که من کردم اینه که، تابع readData رو اومدم یکم بهبود دادم؛ چون بعضی اطلاعات که دیافت میشه ممکنه خطایی درشون وجود داشته باشه که من این مسئله رو اصلا بررسی نکردم، این مورد رو به تابع اضافه کردم :

توضیحات اضافه برا تابع بالا
میبینید که کلا با تابع قبلی فرق داره، ولی خب همونه ولی به روش دیگه ای نوشتمش، چون با توجه به توضیحاتی که قبلا دادم، اگه یه بار ریجستر UnLSR رو بخونیم بعضی بیت هاش به صورت خودکار مقدارش پاک میشه؛ حالا این یعنی چی؟
ببیند ما باید تا زمانی که دیتایی دریافت نشده صبر کنیم ( تا زمانی که RDR مقدارش ۱ نشده )، حالا به بهونه این موضوع که من میام رجیستر U0LSR رو میخونم، اگه خطایی هم دیتامون داشته باشه من متوجه نمیشم، چرا؟ چون دفعه بعد که میخوام بررسی کنم که خطایی وجود داره یا نه میبینم که بیت ها پاک شده، لذا اومدم متغییری تعریف کردم که مقدار این رجیستر رو داخلش میریزم تا اگه یه وقت دیتا موجود بود، و از حلقه فوق خارج شدم، دوباره مجبور نشم که رجیستر U0LSR رو بخونم چون دیگه فایده نداره، لذا متغییری که میبینید حکمتش اینه، خب حالا داخل اون متغییر اگه خطای رخ داده باشه داخلش ذخیره شده لذا متغییر رو بررسی میکنیم؛ اگه متوجه نشدید برید یکم برنامه نویسیتون رو قوی کنید، حتما متوجه میشید اون وقت.

شماتیک پروژه : دقیقا مثل شماتیک پروژه قبلی هستش.
کد پروژه : حال کنید، میبیند چقدر کد پروژه کوتاه شده ^_^؛ ته مطلب تموم پروژه های این مطلب رو قرار میدم، نگران کدهای فایل serial.h نباشید.

توضیح پروژه بالا : این پروژه رو من این طور نوشتم که هر دیتایی که دریافت بشه، داخل وقفه دریافت، میایم همون دیتا رو +۲ میکنیم و ارسال میکنیم؛ مثلا ۱ دریافت کنه ۳ ارسال میکنه؛ و اگه a دریافت کنه c ارسال میکنه ( اگه متوجه نشدید در باب کد اسکی یکم مطالعه کنید ) خب حالا اگه خطایی رخ بده ( حالا هر نوع خطایی که میخواد باشه )، برنامه میره تو حلقه while و دیگه کاری نمیکنه؛ البته میدونم استفاده از while اونم به این صورت داخل یه وقفه درست نیست ولی خب راه دیگه ای به ذهنم نرسید برا نمایش خطای رخ داده شد. (راه ساده تر از این ^_^ وگرنه میشد یه led هم قرار داد ولی خب حسش نبود جان داش)؛ حالا برای این که دیتایی ارسال کنید که دارای خطا باشه باید چیکار کرد؟ خب نرم افزاری که باهاش دیتا ارسال میکنید رو فرمت دیتاش رو عوض کنید، مثلا بیت توازنش رو تغییر بدید، میبینید که دیگه میکرو دیتایی ارسال نمیکنه ^_^ فیلم زیر رو هم خواستید ببیند؛ توضیحاتی در باب این پروژه، چیز خاصی توش نگفتم ولی خب ببینیدش ظرر نداره :

9.3MB پروژه UART میکرو کنترلر LPC1768 با وقفه RBR
0%
00:00  /  05:06

فعلا یا علی.

تعداد مطالب : 367 تا
جنگ ما فتح قدس را به همراه خواهد داشت. [ امام خمینی (ره) ]
ارسال دیدگاه
28
نظرات این مطلب بسته شده است.
  1. محمد

    مهمان

    محمد

    سلام.لطفا فایل دانلود پروژه arm ارتباط سریال uart میکروکنترلر lpc1768 ق۱ را در این سایت قرار دهید.

    مشاهده پاسخ ها (1)
  2. علی

    مهمان

    علی

    سلام وخسته نباشید.
    ببخشید ارم lpc1768 با 3.3 ولت کار میکنه ولی ماژول سریال با ولت. اتصال اینها به هم مشکلی ایجاد نمیکنه؟

  3. f.m

    مهمان

    f.m

    سلام، ببخشید برا من خط 60 و 63 رو وقتی بیتا رو تعیین میکنم برنامه ارور میگیره،
    // Enable FIFO & Reset Rx/Tx FIFO buffers
    LPC_UART0 -> FCR = (0<<_RxTriggerLevel) | (0<<_DmaModeSelect) | (1<<_TxFifoReset) | (1<<_RxFifoReset) | (1< LCR = (1<<_DLAB) | (0<<_BreakControl) | (0<<_ParitySelect) | (0<<_ParityEnable) | (0<<_StopBitSelect) | (3<<_WordLengthSelect);
    چراا؟

    مشاهده پاسخ ها (1)
    • مهدی دمیرچیلو

      نویسنده این مطلب

      مهدی دمیرچیلو

      سلام
      تو پروژه یه چند تا از عددا انگار فارسی هستن – انگلیسیشون کنید و تست کنید.

  4. NANO

    مهمان

    NANO

    سلام ممنون از آموزش بسیار خوبتون.
    برای شبکه کردن سه تا نود که ماژول ها ارتباط UARTبا میکروها دارند در برنامه بالا چه دستوراتی باید اضافه کنم؟
    تشکر

  5. زهرا نورائی

    مهمان

    زهرا نورائی

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

    مشاهده پاسخ ها (1)
    • مهدی دمرچیلو

      نویسنده این مطلب

      مهدی دمرچیلو

      سلام
      کد پروژه (ها) داخل مطلب هستش.

  6. milad

    مهمان

    milad

    سلام ممکنه یک نگاهی به برنامم بکنی نه warning داره نه error ولی میکروم هیچ عکس العملی نسبت بهش نشون نمیده.
    https://www.dropbox.com/s/wwtjflizkutrfsz/lpc_uart0.rar?dl=0

    مشاهده پاسخ ها (1)
    • مهدی دمرچیلو

      نویسنده این مطلب

      مهدی دمرچیلو

      سلام-برو جلسه دوم همین مطلب و کتابخونه رو از ته مطلب دانلود کن و با اون تست کن.

  7. مهدی

    مهمان

    مهدی

    حل شد smile

  8. مهدی

    مهمان

    مهدی

    تو پروژه اول منظورمه

  9. مهدی

    مهمان

    مهدی

    اون ; بعد از while آخر چه کاری میکنه؟

    مشاهده پاسخ ها (1)
    • مهدی دمرچیلو

      نویسنده این مطلب

      مهدی دمرچیلو

      تو زبان سی بعد از هر دستور باید ; بزاری

  10. مهدی

    مهمان

    مهدی

    اول تشکر می کنم برای زحمتی که کشیدین
    دوم این که برا من کار نکرد
    هیچی نشون نمیده
    وقتی داده میفرستم چراغ مبدل چشمک میزنه ولی وقتی میکرو رو روشن میکنم و یا ریست میکنم هیچی نمیشه. به نظرتون مشکل از کجا میتونه باشه؟

    مشاهده پاسخ ها (1)
    • مهدی دمرچیلو

      نویسنده این مطلب

      مهدی دمرچیلو

      سلام
      برو مطلب جلسه بعد – کتابخونه آماده و آخرین نسخه اشو دانلود کن.
      نمیدونم والا مشکل از کجاس – پروژه باید پیشم باشه ولی فک کنم نرخ داده – اتصالات – اینا رو باید بررسی کنی.

  11. ارش

    مهمان

    ارش

    سلام
    در مورد عملکرد تابعprintNumberخیلی متوجه نشدم چطوری عمل می کنه…میشه یه مقدار توضیحش بدید…. unknw

    مشاهده پاسخ ها (1)
    • مهدی دمرچیلو

      نویسنده این مطلب

      مهدی دمرچیلو

      سلام-ارسال یه عدد
      پارامتر اول – خود عدد
      پارامتر دوم – فرمت ارسال عدد – ۱۰=دسیمال
      ۲=باینری
      ۸=هگزا دسیمال
      و…

  12. حسین عهدی

    مهمان

    حسین عهدی

    void print(char *data) {
    unsigned char i;
    for(i=0; data[i]!=’\0′; i++)
    write( data[i] );
    تو این تابع اشاره گر رو چرا گذاشتی؟ فرقی نداره که گه خود data رو بنویسیم

    مشاهده پاسخ ها (1)
    • مهدی دمرچیلو

      نویسنده این مطلب

      مهدی دمرچیلو

      الان یه رشته میشه گفت دریافت میکنم – اگه * رو نمیزاشتم میشد دریافت کاراکتر!

  13. حسین عهدی

    مهمان

    حسین عهدی

    SystemCoreClock
    این کجاست؟
    تو برنامه تعریف نشده
    آیا این عبارت تو system init هستش؟؟؟

    مشاهده پاسخ ها (1)
    • مهدی دمرچیلو

      نویسنده این مطلب

      مهدی دمرچیلو

      system_LPC17xx.c

  14. حسین عهدی

    مهمان

    حسین عهدی

    char readData(void) {
    while( !((LPC_UART0 -> LSR) & ((1 < RBR; // دادن اطلاعات به بایت بالایی حافظه فیفو دریافت داده
    }
    تو این تابع دریافت، ثبات وضعیت ،برای بررسی خطا بررسی نشده

    مشاهده پاسخ ها (1)
    • مهدی دمرچیلو

      نویسنده این مطلب

      مهدی دمرچیلو

      تو این مطلب من امکانات رو کم کم اضافه کردم – پروژه های بعدی و آخرین ویرایش کتابخونه ته مطلب رو ببینی همچین مشکلی وجود نداره.

  15. حسین عهدی

    مهمان

    حسین عهدی

    تابع بعدی، readData هستش که وظیفش ارسال کاراکتر هستش
    اشتباه تایپی:وظیفش دریافت کاراکتر

    مشاهده پاسخ ها (1)
    • مهدی دمرچیلو

      نویسنده این مطلب

      مهدی دمرچیلو

      good

  16. حسین عهدی

    مهمان

    حسین عهدی

    توجه ۱ : در این رجیستر نیازی نیست حافظه FIFO رو فعال کنیم، چون در حالت پیشفرض خودش فعاله.
    رجیستر FCR مقدار پیش فرضش صفره که فعال نیست پس باید فعالش کنیم.
    البته طبق چیزی که من فهمیدم

    مشاهده پاسخ ها (1)
    • مهدی دمرچیلو

      نویسنده این مطلب

      مهدی دمرچیلو

      ممنون از شما – بله دیتاتشیت رو دیدم و حرف شما رو تایید میکنم – الان تصحیح میکنم good