رجیستر ها در STM8 – آموزش stm8 پروژه محور
رجیستر ها در STM8 و برنامه نویسی پایه ها در STM8
پیکربندی و تنظیمات پایه های کاربردی ( پورت های عمومی )
پورتهای عمومی به منظور تبادل داده بین تراشه میکروکنترولر و دنیای واقعی به کار برده می شود در میکروکنترولر های 8 بیتی هر پورت مشتمل بر هشت پین همه منظوره می باشد و هر پین را به تنهایی می توان با پیکربندی مناسب به عنوان خروجی و یا ورودی دیجیتال تعیین نمود و برخی از پین ها را نیز می توان به عنوان ورودی اطلاعات آنالوگ مانند اندازه گیری پارامترهای مورد نظر از سنسورها و یا آشکارسازی وقفه خارجی و یا ورودی خروجی داده از واحد های کاربردی مورد استفاده قرارداد و به خاطر داشته باشید در هر زمان تنها یک عملکرد را میتوان از پین توقع داشت.
نکاتی درباره ی پورتها در میکرو کنترولر STM8 :
- بیت های موجود در پورت (پین) را میتوان بصورت انحصاری (منفرد) پیکربندی نمود.
- به هر پین تنها میتوان یک مسئولیت را تخصیص داد.
- در هنگام پیکربندی بصورت ورودی میتوان اطلاعات سنسورها و یا فرامین خارجی را دریافت نمود (Floating) و یا با فعال نمودن مقاومت بالاکش داخلی اقدام به بررسی وضعیت کلید متصل به پین نمود.
- در هنگام پیکربندی بصورت خروجی میتوان سیگنال و فرامین کنترلی با جریان بالا ، به منظور فعال نمودن و کنترل عملکرد ابزار خارجی و یا کنترل تناوبی و دوره ای فعالیت ابزارهای کاربردی استفاده کرد.
- به منظور وضوح بیشتر هر پین از طریق رجیسترهای متفاوتی پیکربندی می گردد.
- پیکربندی وقفه های خارجی را می توان به تفکیک و با تعیین اولویت بررسی و وقوع برای هر پایه تعیین نمود.
- امکان کنترل سیگنال خروجی بصورت افزاینده و قابل کنترل مقدور گردیده که باعث کاهش نویز در پردازش می گردد.
- قابلیت ورودی سیگنال بصورت اشمیت تریگر در حالت آنالوگ غیر فعال می گردد که باعث کاهش توان مصرفی میگردد.
- پایه های ورودی توان تحمل سیگنال ورودی 5 ولت را دارند.
- پایه ها توان خروجی سیگنال در محدوده 1.6V تا سطح VDDIOmax را دارند.
رجیستر ها در STM8
هر پین به صورت مستقل با 5 رجیستر کنترل می گردد که هر وضعیت از پایه را میتوان از آن طریق به دقت و وضوح بالا و در تناسب با عملکرد پیکری بندی نمود .
بلوک دیاگرام پایه ها در STM8 به شکل زیر است :
چنانچه مشاهده می گردد هر پین 5 رجیستر کاربردی دارد که عملکرد و تنظیمات آن بر حسب نوع کاربرد متغیر است و پین مورد نظر از طریق این رجیسترها با مسیر داده در میکرو کنترولر مرتبط می باشد :
- Port x data direction register (Px_DDR)
- Port x control register 1 (Px_CR1)
- Port x control register 2 (Px-CR2)
- Port x output data register(Px_ODR)
- Port x pin input register (Px_IDR)
و همانگونه که ذکر گردید کلیه تنظیمات لازم به منظور تعیین به عنوان ورودی و خروجی از طریق این رجیسترها انجام می گردد
کانالهای آنالوگ :
کانالهای ورودی و خروجی آنالوگ از طریق واحد مبدل آنالوگ به دیجیتال فعال و کنترل می¬گردند که در جای خود کاملاً بررسی خواهد گردید.
قبلاً گفتیم که ستون اصلی برنامه نویسی در در این خانواده از طریق رجیسترها می باشد بنابراین اطلاعات این بخش را به دقت مطالعه نمایید.
رجیسترهای ورودی و خروجی در STM8
در ابتدا یک توضیح مختصر و سپس با استفاده از آموخته های این بخش چند پروژه ساده را انجام خواهیم داد و اکیداً پیشنهاد می کنم اگر در تمرین ساخت پروژه با IAR مشکل دارید بخش مربوط به این موضوع را دوباره و صدباره تمرین و مطالعه نمایید زیرا در این بخش بسیار به درک مطالب نیاز خواهید داشت.
تنظیم پایه در حالت ورودی یا خروجی
Port x data direction register(Px-DDR)
این رجیستر ستون اصلی تنظیمات وضعیت عملکرد هر پایه را تعیین می نماید ، که این پایه بصورت خروجی مورد استفاده قرار خواهد گرفت و یا ورودی و با توجه به جدول بالا برای هر پایه بصورت مستقل قابل تنظیم است که دو حالت (rw) تنظیم برای این رجیستر قابل تعریف است.
1 2 |
0 : input mode 1 : output mode |
تعیین وضعیت سطح منطقی پایه در حالت خروجی
Port x output data register( Px-ODR )
در صورتی که وضعیت پایه را به عنوان خروجی تعیین کرده اید باید امکان تعیین وضعیت پایه از لحاظ منطقی مقدور گردد و در وضعیت ورودی این رجیستر کاربردی ندارد.
این رجیستر برای هر پایه بصورت مستقل قابل تنظیم است که جدول فوق نحوه تنظیم را نشان می دهد و در هر بار ریست شدن میکرو این رجیستر پاک شده و بر حسب تنظیمات دوباره و بر اساس نوع عملکرد مورد نیاز ما برنامه ریزی می گردد.
خواندن پایه در حالت ورودی
Port x pin input register(Px-IDR)
این رجیستر برای خواندن مقادیر منطقی در پایه مورد نظر بکار برده می شود و یک رجیستر فقط خواندنی می باشد و در هنگام ریست شدن میکرو مقدار منطقی آن را وضعیت مدارات خارجی تعیین می نمایند و دو حالت در هنگام خواندن مقادیر منطقی ممکن است اتفاق بیافتد:
1 2 |
0: low logic level 1: high logic level |
رجیسترهای کنترلی در STM8
این رجیسترها در حالت های تنظیم پایه به عنوان ورودی یا خروجی عملکرد های متفاوتی را از خود نشان می دهند و امکان دارد در صورت عدم دقت هدف مورد نظر کسب نگردد ، دو رجیستر کنترلی برای هر پایه موجود است :
رجیسر کنترلی CR1
Port x control register 1 (Px-CR1)
این رجیستر برای هر پایه بصورت انحصاری قابل کنترل است و بصورت نرم افزاری قابل تنظیم و پاک کردن است و با توجه به عملکرد های چندگانه وضعیت را در هر حالت بصورت تفکیکی بررسی خواهیم نمود:
در وضعیت ورودی ( بستگی به وضعیت تنظیم رجیستر یعنی اگر DDR=0 میباشد)
:0 ورودی در حالت آزاد
:1 ورودی با مقاومت بالاکش
در وضعیت خروجی ( بستگی به تنظیم رجیستر وضعیت پایه DDR=1)
:0 حالت شبه باز با احتمال عملکرد مقطعی
:1 مقاومت کنترل جریان خروجی فعال می شود و وضعیت شیب خروجی اطلاعات در تناسب با رجیستر کنترلی 2 تعیین می گردد
رجیستر کنترلی 2
Port x control register 2 ( Px-CR2)
بیت های این رجیستر کاربردی را نیز می توان بصورت نرم افزاری کنترل نمود و تفاوت عمده عملکرد آن در تعیین ورودی و یا خروجی بودن پورت است که عملکرد های کلی این رجیستر بشرح زیر است:
1. در صورتی که وضعیت پایه بصورت ورودی تنظیم شده باشد.( فعال ویا غیر فعال سازی وقفه خارجی)
• 0 : External Interrupt disabled
• 1 : External Interrupt Enabled
2. در صورتی که پایه بصورت خروجی تنظیم شده باشد.( تعیین سرعت پایه )
• 0 : output speed up to 2 MHz
• 1 : output speed up to 10 MHz
قبل از انجام تمرینات مقدماتی به جدول ذیل توجه نمایید که فرم عمومی استفاده از رجیسترها در تنظیم عملکرد پایه را نشان می دهد:
به عبارات ذکر شده در جدول در تناسب با پین مورد نظر در پورت کاربردی دقت نمایید زیرا در طول برنامه نویسی همین عبارات را باید منظور نمایید.
کلیه رجیسترها باید به درستی و به دقت انتخاب گردند اما شایان ذکر است سه رجیستر که در جدول بالا اشاره شده اند عملکرد کلی پایه را تعیین می¬نمایند و در صورت بروز خطا در تنظیمات این سه جیستر امکان دستیابی به هدف بسیار بعید بوده و حتی امکان بروز صدمات فیزیکی در میکروکنترولر محتمل است.
نکات کاربردی در تنظیمات وضعیت پایه ها:
1-پایه استفاده نشده در طراحی را به حال خود رها نکنید به خصوص پایه NRST زیرا با جریان کشی باعث افزایش توان مصرفی و از سویی باعث افزایش سطح نویز در سیستم خواهد گردید این پایه ها را به اشکال زیر نظیم نمایید:
- اتصال به V_DD و یا V_SS و با استفاده از مقاومت های Pull-Up و یا Pull-down در وضعیت Reset – State ( Input-Floating ) قرار دهید.
- با استفاده از مقاومت بالاکش داخلی بصورت خروجی و در سطح منطقی صفر قراردهید.
- در صورت عدم استفاده از Reset بصورت دستی حتماً با یک مقاومت 10K به VCC متصل گردد .
2-در حالت الزام به استفاده از ارتباط SPI ، پین ها را بصورت Push-Pull و با استفاده از مقاومت بالاکش تنظیم نمایید.
ساختار کلی برنامه در کامپایلر IAR برای میکروکنترولر STM8
ساختار این بخش همانند ساختار کلی در زبان C میباشد.
بعنوان نمونه کد زیر دارای 3 بخش میباشد :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#include<iostm8s003f3.h> #include “delay.h" #define led PD_ODR_bit.ODR3 Void delay_ms(unsigned long int n) { Unsigned long int x=0; Unsigned long fcpu=2000000; X=fcpu/1000; X=x/50; N=n*x; While(n- ->0); } int main(void) { CLK_ICKR=1; CLK_CLKDIVR=24; PD_DDR_DDR3=1; PD_CR1_C13=1; PD_CR2_C23=1; While(1) { led =! Led ; delay_ms(1000); } } |
معرفی پیش پردازنده و کتابخانه های کاربردی مورد نیاز در برنامه:
1 2 |
#include<iostm8s003f3.h> #include “delay.h" |
تنظیمات خاص در خصوص نمایشگر و واحد های کاربردی و زیر تابع های مورد نیاز:
1 2 3 4 5 6 7 8 9 10 |
#define led PD_ODR_bit.ODR3 Void delay_ms(unsigned long int n) { Unsigned long int x=0; Unsigned long fcpu=2000000; X=fcpu/1000; X=x/50; N=n*x; While(n- ->0); } |
تابع اصلی برنامه مشتمل بر تنظیمات پایه های ورودی و خروجی و واحد های عملیاتی و حلقه اصلی برنامه:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
int main(void) { CLK_ICKR=1; CLK_CLKDIVR=24; PD_DDR_DDR3=1; PD_CR1_C13=1; PD_CR2_C23=1; While(1) { led =! Led ; delay_ms(1000); } } |
چند مثال ساده :
تمرین 1:
پایه شماره 2 از پورت D را در وضعیت خروجی قرارداد و سطح منطقی آن را صفر قرار دهید ( وضعیت خاموش )
1 2 |
PD_DDR_DDR2=1; PD_ODR_ODR1=0; |
تمرین 1:
پایه شماره 3 از پورت C را در وضعیت خروجی قرار داده و به منظور اتصال به یک LED ، مقاومت پوش آپ را فعال نموده و سرعت ارتباط با پایه را در بالاترین میزان ممکن قراردهید:
1 2 3 |
PC_DDR_DDR3=1; // PORTC,Bit3 is output PC-CR1_C13=1; // PORTC , Control Register 1,bit3 set to push-Pull PC_CR2_C23=1; // PORTC , Control Register2 , bit3 output speed up to 10MHz |
1 2 3 |
PC_DDR_DDR3=1; // PORTC,Bit3 is output PC-CR1_C13=1; // PORTC , Control Register 1,bit3 set to push-Pull PC_CR2_C23=1; // PORTC , Control Register2 , bit3 output speed up to 10MHz |
یک گام به جلو برداریم در این مثال میخواهیم تمام پایه های یک پورت را روشن یا خاموش کنیم:
1 2 |
PD_ODR=1; // Turn On All pins PC_ODR=0; // Turn off All Pins |
تا اینجا ساده بود اما ذکر چند نکته از همین ابتدا ضروری است:
1. تمام حروف در تنظیمات رجیسترها با حرف بزرگ نوشته شوند.( طبق قوانین الزامی زبان C حروف بزرگ و کوچک متفاوت هستند و در نامگذاری و سایر موارد دو حالت در نظر گرفته می شوند).
2. در انتهای هر خط از فرامین و تنظیمات از علامت سمی کالن ( ; ) حتماً استفاده گردد.
3. حد فاصل بین بلوک ها در تنظیمات و نامگذاری از underline زیرخط استفاده گردد.
حال یک مثال عملی و قابل اجرا را با دقت پیگیری و اجرا نمایید:
مثال یک :
در ابتدا کلیه پایه های موجود در پورت D را صفر کنید و سپس پایه 3 را در زمان توالی 1 ثانیه خاموش و روشن کنید( این مثال در نقش ابتدایی ترین مثال در آموزش کلیه میکروکنترلرها مطرح میشود کدهایی را که متوجه نمی شوید فعلا رها کنید در جای مناسب در این خصوص بررسی خواهیم کرد.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#include <iostm8s003f3.h> void delay_ms(unsigned long int n) { unsigned long int x=0; unsigned long fCPU=2000000; // HSI RC =16 MHz ----- HSIDIV=8 ------CPUDIV=1 fCPU=16 / 8 / 1 Mhz x=fCPU/1000; x=x/50; n=n*x; while (n-- > 0); } //main entry point int main( void ) { CLK_ICKR=1; // High-speed internal RC on = 16 Mhz CLK_CKDIVR = 24; //fHSI RC output/8 & fCPU=fMASTER/1 PD_ODR = 0; //Turn off all pins PD_DDR_DDR3 = 1; //PortD, Bit 3 is output (PD3 - Data Direction Register) PD_CR1_C13 = 1; //PortD, Control Register 1, Bit 3 (PD3) set to Push-Pull PD_CR2_C23 = 1; //PortD, Control Register 2, Bit 3 (PD3) Output speed up to 10 MHz while (1) { PD_ODR_bit.ODR3 = !PD_ODR_bit.ODR3; delay_ms(500); } } |
مثال دوم :
یک عدد LED را به pin3 از PORTD متصل نموده و وضعیت فعالیت آن را با دکمه فشاری که به pin2 از PORTD متصل است کنترل نمایید و از نوسان ساز داخلی 16MHz به عنوان منبع کلاک استفاده نمایید ( با فشردن کلید وضعیت فعالیت LED تغییر حالت دهد، برای دکمه و به منظور جلوگیری از حالت debouncing از مقاومت Pull-Up داخلی استفاده گردد ، برای پایه خروجی از mode fast استفاده گردد):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#include <iostm8s003f3.h> #include "delay.h" #define led PD_ODR_bit.ODR3 #define key PD_IDR_bit.IDR2 int main( void ) { CLK_ICKR=1; // High-speed internal RC on = 16 Mhz CLK_CKDIVR = 24; //fHSI RC output/8 & fCPU=fMASTER/1 PD_DDR_DDR3 = 1; //PortD, Bit 3 is output (PD3 - Data Direction Register) PD_CR1_C13 = 1; //PortD, Control Register 1, Bit 3 (PD3) set to Push-Pull PD_CR2_C23 = 1; //PortD, Control Register 2, Bit 3 (PD3) Output speed up to 10 MHz PD_DDR_DDR2 = 0; //PortD, Bit 2 is INPUT (PD2 - Data Direction Register) PD_CR1_C12 = 0; //PortD, Control Register 1, Bit 2 (PD2) Input with pull-up PD_CR2_C22 = 0; //PortD, Control Register 2, Bit 2 (PD2) External interrupt disabled while (1) { //Turn on and off the output and then key pressure if(key==0){ led = !led; while(key==0); delay_ms(100); } |
• در خطوط سوم و چهارم از دستور define استفاده شده که عبارات led و key را با عنوان نام رجیستر پین های مورد استفاده جایگزین نموده که در کدنویسی از نوشتن عبارات طولانی و گمراه کننده اجتناب گردد.
• در خطوط 7 و 8 تقسیمات و تنظیمات کلاک انجام گردیده که در فصل های بعد بررسی و تشریح خواهد گردید.
• در ادامه تنظیمات پایه های مورد استفاده انجام گردیده.
• در حلقه اصلی برنامه شرطی بررسی میگردد که اگر دکمه متصل شده به گراند متصل گردد ، led تغییر وضعیت داده و اگر روشن بود خاموش و بالعکس و شرطی نیز به منظور بررسی رها نمودن دکمه در انتها بررسی میگردد.
تمرینات و مثال ها را با دقت تمام تحلیل و درک نمایید زیرا که یک پروژه با پیچیدگی بسیار بالا نیز خود از بخش های کوچک و مقدماتی تشکیل یافته است.
حال مرحله اول تمرینات برنامه نویسی و بخش رجیستر ها در STM8 خاتمه یافت.
در بخش بعدی سیستم کلاک و تنظیمات مربوطه بررسی خواهد گردید که در کلیت برنامه نقش بسیار مهمی را دارد.
سلام و عرض ادب
بنده میخواست به عنوان مثال کد هگز 0x3f را در تمام پورت d ایجاد کنم (برای 7 segment ) لطفا راهنمایی بفرمایید
سلام. مخلصیم.
انگلیسی سرچ کنید یک سری پروژه راه اندازی سون سگمنت هست روی نت با همین میکرو stm8s003f3 که توضیح مفصل وجود داره.
سلام
اون فایل (PDF) که عکس های رجیستر ها رو ازش گرفتید رو میشه قرار بدید؟! که تمام ویژگی های مثل UART , SPI رو بشه از توش بدست آورد!
تشکر
سلام
www.st.com/resource/en/reference_manual/cd00190271.pdf
بسیار عالی.
اگر واقعا به تمام موضوعات stm8 تسلط دارین، بی زحمت اگر صلاح میدونین یه پست هم درباره تفاوت ها و شباهت های این میکرو با میکروهای avr بذارین. اینجوری چون مفاهیم تقریبا یکسان هستند هر شخصی که به avr مسلط باشه راحت تر میتونه کار با این میکرو رو یاد بگیره.
به عنوان مثال چیزی که تا به الان خودم میدونم رجیستر های مربوط به پورت های میکرو هستش. در avr فقط دوتا رجیستر DDR و PORT بودن که برای تعیین وضعیت ورودی یا خروجی و مقاومت پول آپ بودن. ولی در stm8 علاوه بر رجیسترهای موجود در avr دو رجیستر دیگه وجود دارند که از آنها میتوان برای تعریف پین به عنوان وقفه خارجی استفاده کرد.
چشم به زودی پستی برای مقایسه اون با avr قرار میدیم روی سایت، در stm8 علاوه بر رجیسترهای موجود در avr فقط 2 رجیستر بیشتر ندارین ! بلکه بیشترن .مثلا در stm8 رجیستر برای تقسیم سیگنال کلاک دارین…رجیستر هایی که این بخش گفته شد برای تعیین ورودی و خروجی بود، برای وقفه ها هم برنامه داریم و اونهارو هم توضیح میدیم در آینده… عجله نکنید 😉
ممنون از پاسخ.
منظورتون از اینکه در stm8 دو رجیستر بیشتر نداریم رو متوجه نشدم. یعنی دو رجیستر بیشتر از avr داریم یا اینکه کلا دو رجیستر مربوط به پورت ها بیشتر نداریم؟
در اینجا بنده 5 رجیستر میبینم:
DDR
ODR
IDR
CR1
CR2
ولی تو AVR فقط 3تا داریم:
DDR
PORT
PIN
اشتباه نوشتاری شد ، اصلاح کردم…
رجیستر های stm8 رو بهتره با Stm32 مقایسه کنید.شباهت بیشتری داره..
مثلا یک مقایسه بخوام در بحث وقفه ها با avr بکنم باید بگم که تمام پین ها میتونن به عنوان درگاه وقفه خارجی استفاده بشن و از طرف دیگه در وضعیت خروجی شما میتونین سرعت رفرش پایه رو تعیین کنین بین دو مقدار 2.60 و 10 مگاهرتز.در حالی که در avr تعداد محدودی وقفه خارجی در دسترسه و از طرف دیگه سرعت رفرش پایه کاملا در تناسب با کلاک تعیین شده داخلی با خارجیه..