تحلیل کتابخانه

تحلیل و بررسی کتابخانه STDIO.h در زبان C و ++C

نوشته شده توسط علی زاهدی

کتابخانه STDIO.h یکی از کتابخانه هایی است که تقریبا در اکثر کد هایی به به زبان C یا ++C نوشته می‌شوند کاربرد بسیار زیادی دارد. این کتابخانه در میکروکنترلر ها قابلیت برقراری ارتباط بین میکروکنترلر ها، ارتباط با ماژول های مختلف و یا ارتباط بین کامپیوتر با میکروکنترلر ها را ایجاد می‌کند. این کتابخانه دارای دستورات و توابع مختلفی است. در این آموزش، همانند سلسله آموزش های تحلیل کتابخانه، به تشریح و تحلیل توابع کتابخانه STDIO.h می پردازیم. در ادامه با مرجع تخصصی آردوینو به زبان فارسی، دیجی اسپارک همراه باشید.

 


نکات فنی کتابخانه STDIO.h


این کتابخانه برای آسان تر کردن کار با ورودی و خروجی های استاندارد استفاده می‌شود ( در میکروکنترلر ها این ورودی و خروجی ها میتواند ارتباط سریال و LCD باشد) توابعی را فراهم کرده است. این کتابخانه نیاز به نصب ندارد و تقریبا در همه کامپایلر هایی که بر پایه زبان های C و ++C هستند نصب می‌شود. برای استفاده از این کتابخانه ها در کامپایلر و یا IDE هایی مثل KEIL ،CodeVison ،Arduino IDE و … بایستی فایل هدر مربوط به کتابخانه را به برنامه خود اضافه کنید. با نوشتن دستور زیر در ابتدای برنامه این کتابخانه به کد شما اضافه می شود.

#include <stdio.h>

بسته به کامپایلری که استفاده می‌کنید. ممکن است برخی از دستورات قابل استفاده باشند و یا نیاز به انجام تنظیماتی داشته باشند. برای مثال در کامپایلر Codevision تابع printf بصورت پیش فرض برای ارسال رشته از طریق USART تعریف شده است. اما در کامپایلر KEIL برای استفاده از این دستور بایستی ابتدا مشخص شود که این دستور بایستی از طریق کدام USART عملیات ارسال رشته را انجام دهد. در بخش سوم میکروکنترلر های STM32 ارسال از طرق USART نحوه تنظیم و استفاده از تابع printf توضیح داده شده است.

کتابخانه stdio.h قابل استفاده در انواع میکروکنترلر ها

 


توابع کلیدی کتابخانه STDIO.h


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

  • (char getchar (void

این تابع  با استفاده از روش Polling عملیات دریافت را از USART را انجام می‌دهد. این تابع ورودی ندارد. و پس از دریافت کارکتر از UART در خروجی آن قرار خواهد گرفت. برای استفاده از این تابع بایستی متغیری را برابر این تابع قرار دهید.

char receive;

receive = getchar();
  • (void putchar (char c

این تابع با استفاده از روش Polling عملیات ارسال از طریق USART را انجام می‌دهد. این تابع عکس تابع قبلی است و تنها یک ورودی از نوع char دارد. با استفاده از این تابع میتوانید یک کاراکتر را از سمت USART ارسال کنید. در صورتی کاراکتری که در ورودی این تابع قرار می‌گیرد، داخل ‘ ‘ باشد. کد اسکی آن ارسال می‌شود. برای مثال اگر در قسمت ورودی عدد ۱ را قرار دهید. همان عدد ۱ ارسال می‌شود. ولی در صورتی که ‘۱’ را در قسمت ورودی قرار دهید. عدد ۴۹ یا همان کد اسکی کاراکتر ۱ ارسال می‌شود.

putchar('A');
  • (void puts (char *str

این تابع رشته ای از کاراکتر ها را که در حافظه SRAM ذخیره شده است را در USART ارسال می‌کند. این تابع دارای یک ورودی است که در این قسمت بایستی رشته ای از نوع char در آن قرار گیرد. این تابع در بیت آخر رشته قرار گرفته در قسمت ورودی کاراکتر NULL یا ‘۰\’ را قرار می‌دهد. با استفاده از این دستور می‌توانید به ۲ صورت رشته ای را به USART ارسال کنید. روش اول ارسال رشته یا بافری که از قبل تعریف شده است. و روش دوم ارسال رشته ای ثابت است که عبارت مورد نظر بایستی داخل ” ” قرار بگیرد.

// روش اول
char buffer[] = "Hello";
puts(buffer);
// روش دوم
puts("Hello");
  • (void putsf (char flash *str

این دستور کاملا شبیه به دستور puts است با این تفاوت که این دستور رشته ای که در حافظه Flash ذخیره شده باشد را به سمت USART ارسال می‌کند. ورودی این تابع و نحوه استفاده از این دستور کاملا مشابه دستور قبل است.

flash char buffer[] = "Hello";
putsf(buffer);
  • (char *gets (char *str , unsigned char len

این تابع عملیات دریافت رشته ای با طول مشخص از USART را انجام می‌دهد. این تابع دارای دو ورودی است که ورودی اول برای متغیری است که رشته ی دریافت شده در آن ذخیره خواهد شد. و ورودی دوم اندازه رشته یا ب عبارت دیگر تعداد کاراکتر هایی که قصد دارید دریاف کنید، است. برای درک بهتر به مثال زیر توجه کنید. در این مثال یک رشته با طول ۵ کاراکتر را دریفت و در متغیر buffer ذخیره می‌کنیم.

char buffer[10];
gets(buffer,10);

 

  • ([… , void printf (char flash *fmtstr [,arg1 , arg2

تابع printf یک از مهم ترین و پرکاربرد ترین دستور های کتابخانه STDIO.h است. این تابع داده های قالب بندی شده را از طریق ارتباط سریال USART ارسال می‌کند. فرمت کلی رشته قالب بندی شده به صورت زیر است.

%[Flags] [width] [.precision] [l] type-char
    • Flags : این یک پارامتر اختیاری است و میتواند به صورت ‘-‘ و ‘+’ و ” باشد.
        • در حالت ‘-‘ نتایج از سمت چپ مرتب می‌شوند. در غیر این صورت نتایج از سمت راست با اضافه کردن صفر و جای خالی به سمت چپ مرتب می‌شوند.
        • در حالت ‘+’ نتایج همیشه دارای علامت ‘+’ و ‘-‘ نمایش داده می شوند.
        • در حالت ” اگر نیتجه یک عدد منفی باشد با علامت ‘-‘ نمایش داده خواهد شد و در غیر این صورت با فضای خالی نمایش داده خواهد شد.
    • width : این پارامتر نیز یک پارامتر اختیاری است که حداقل پهنای خروجی را مشخص می‌کند. اگر نتیجه  تبدیل بزرگتر از width باشد، رشته به اندازه‌ای افزایش می‌یابد تا تمام نتیجه را نمایش دهد. پارامتر width میتواند به دو صورت n و ۰n (که حداقل طول رشته است) باشد.
        • اگر پارامتر به صورت n تعریف شده باشد و خروجی کوچیکتر از n کاراکتر باشد با فضای خالی تکمیل خواهد شد.
        • در صورتی که به صورت ۰n تعریف شده باشد. در صورت کوچکتر بودن از n کاراکتر با صفر تکمیل خواهد شد.
    • precision : این پارامتر اختیاری  حداکثر تعداد کاراکتر ها و یا حداقل تعداد ارقام صحیح را در خروجی مشخص می‌کند. برای کاراکتر های تبدیل ‘e’ ، ‘E’ و ‘F’ ، این پارامتر تعداد ارقامی را که باید از سمت راست عدد دسیمال نشان داده شوند، مشخص میکند. این پارامتر می‌تواند به صورت ۰٫ ، n. و یا none باشد.
    • type-char : و بلاخره کاراکتر تبدیل type-char که طریقه نمایش کاراکتر خروجی را مشخص می‌کند و می‌تواند مقادیر زیر را داشته باشد:
        • i: نشان می دهد که داده خروجی باید به صورت یک عدد دسیمال علامت دار به نمایش در آید.
        • d: نشان می دهد که داده خروجی باید به صورت یک عدد دسیمال علامت دار به نمایش در آید.
        • u: نشان می دهد که داده خروجی باید به صورت یک عدد دسیمال علامت دار به نمایش در آید.
        • e: نشان می دهد آرگومان خروجی تابع، یک عدد float است که به صورت e[-]dd [-]d.dddd نمایش داده می شود.
        • E: نشان می دهد آرگومان خروجی تابع، یک عدد float است که به صورت E[-]dd [-]d.dddd نمایش داده می شود.
        • f: نشان می دهد آرگومان خروجی تابع، یک عدد float است که به صورت [-]d.dddd نمایش داده می شود.
        • x: نشان می دهد آرگومان خروجی تابع، یک عدد هگزادسیمال است، که با حروف کوچک نمایش داده می شود.
        • X: نشان می دهد آرگومان خروجی تابع، یک عدد هگزادسیمال است، که با حروف بزرگ نمایش داده می شود.
        • c: نشان می دهد آرگومان خروجی باید به صورت یک کاراکتر واحد نمایش داده شود.
        • s: نشان می دهد آرگومان تابع یک اشاره‌گر به رشته وجود در حافظه SRAM است.
        • p: نشان می دهد آرگومان تابع یک اشاره‌گر به رشته وجود در حافظه Falsh است.

برای در بهتر این تابع بهتر است به مثال زیر توجه کنید. در مثال زیر با فرض این که زمان از ماژول ساعت دریافت شده و در متغیر های Min ، Sec و Hour ذخیره شده است. و ما قصد ارسال این مقادیر را با استفاده از USART به سمت کامپیوتر را داریم.

printf("Time = %02d:02d:02d",Hour,Min,Sec);
  • ([… , void sprintf (char * str, char flash *fmtstr [,arg1 , arg2

این تابع نیز تا حدودی شبیه به دستور printf است. با این تفاوت که رشته قالب بندی شده در رشته str ذخیره می‌شود. یکی از کاربرد های مهم این تابع برای نمایش عداد متغیر در LCD است. برای درک بهتر این تابع به مثال زیر توجه کنید.

char buffer[15];
sprintf(buffer,"Time = %02d:02d:02d",Hour,Min,Sec);
  • ([… ,  signed char scanf (char flash *fmtstr [,arg1 address , arg2 address

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

 


لوازم مورد نیاز


این کتابخانه نیاز به ماژول خاصی ندارد. همانطور که گفته شد تقریبا تمامی میکروکنترلر های موجود در بازار که با زبان C برنامه نویسی می‌شوند از این کتابخانه پشتیبانی می‌کنند. برای تهیه میکروکنترلر مود نظر خود می‌توانید از طریق لینک زیر اقدام کنید.

خرید انواع میکروکنترلر ها

 


جمع بندی


در این آموزش تحلیل و بررسی توابع موجود در کتابخانه stdio.h که یکی از مهم ترین کتابخانه های زبان C و ++C به شمار می آید، پرداختیم. همانطور که در ابتدای آموزش گفته شد این کتابخانه به برد و یا کامپایلر خاصی محدود نمی‌شود. و در تمامی کامپایلر و یا IDE هایی که مبتنی بر زبان های C و ++C باشند، مورد استفاه قرار میگیرد. ابتدا با این کتابخانه و نکات مهم استفاده از این کتابخانه آشنا شده و پس از آن به بررسی توابع موجود در این کتابخانه پرداختیم. در این قسمت پارامتر های مختلف دستور های printf، sprintf و scanf توضیح داده شد.

 

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

 

در پایان نظرات و پیشنهادات خود را با ما درمیان بگذارید و با اشتراک گذاری این آموزش در شبکه های اجتماعی , از وبسایت دیجی اسپارک حمایت کنید.

 

درباره نویسنده

علی زاهدی

برنامه نویس و طراح سیستم های مبتنی بر میکروکنترلر

دانسته هایتان را مانند یک ساعت مچی در دست کنید، نه صرفا به این خاطر که نشان دهید آن را دارید. بلکه به این خاطر که اگر کسی از شما ساعت را پرسید، برایش بگویید.
لرد چسترفیلد

تبادل نظر و رفع عیب با ثبت دیدگاه

۶ دیدگاه

  • سلام و خدا قوت
    آقا من میخوام از کتابخونه برای میکرو کنترلر های avr استفاده کنم و با اتمل استودیو کار میکنم اما توابع این کتابخونه کار نمیکنن…یعنی دارم روانی میشم…نه ارسال میکنه نه دریافت میکنه…چه تنظیماتی باید انجام بدم که پورت سریال میکرو رو به عنوان ورودی و خروجی استاندارد بشناسه؟ خداوکیلی کمک کنید گیرم بدجووووووووور

  • مهندس جان عرض سلام
    ارتباط یک طرفه روی میکرو اعمال کردم و ۱۶ led رو سمت گیرنده و ۱۶ کلید رو سمت فرستنده رو بریدبرد نصب کردم
    از کامپایلر کدویژن استفاده میکنم ودر برنامه ای که نوشتم از دستور UDR استفاده کردم و مشکلی برام پیش اومده که هرچقدر تحقیق و سرچ میکنم نمیتونم رفع عیب کنم واقعا حالمو بد کرده..
    ۸ پین PORTAو ۸ پین PORTC در فرستنده به عنوان ورودی و PULLUP مقدار دهی کردم
    ۸پورت PORTA و ۸پورت PORTC در گیرنده نیز به عنوان خروجی و ۰ درنظر گرفته و مقدار دهی کردم
    زمانی که برنامه رو کامپایل و رو میکروکنترلر لود میکنم و تست میکنم هر کلید بعد از چند بار فشرده شدن از سمت گیرنده پورت خروجیش عوض میشه
    مثال کلید ۱ در جروجی ۴ بار PORTA. 1 رو روشن می‌کند
    دفعه ۶ به بعد PORTC. 1 رو روشن میکند و همینطور ادامه دارد

    ترو خدا کمک کنید‍♂️؟؟

    • با سلام
      از دستور Printf برای این کار استفاده کنید. داده ی ارسالی را به صورت یک رشته مشخص ارسال کنید. در صورتی که تنها یک عدد از گیرنده ارسال شود چنین مشکلاتی ممکن است پیش بیاید.