به نام خدا!

سلام دوستان!

یه بحث هست توی میکرو های Cortex-m که میشه کلاک رو توی هرجای برنامه کم و زیاد کرد تا به نتیجه دلخواه رسید!

این کار برای کاهش مصرف باتری هم خیلی کاربرد داره! شما میتونید کلاک رو تا 1 مگاهرتز پایین بیارید یا تا سقف 100 مگاهرتز بالا ببرید!

البته این نکته هم بگم! که این کلاک 100 مگاهرتز حداکثر کلاکی هست که کارخونه سازنده پشتیبانی میکنه! واگرنه میشه کلاک رو 120 مگاهرتز کرد و بیبشتر و... ولی مشکلاتی که برای پردازنده هنگام اجرای برنامه رخ میده یا به عبارتی درصد خطا میره بالا! بنابراین کمتر از سقف کلاک رد میزنیم!


خوب برای تعیین کلاک میشه از خود برنامه Keil استفاده کرد بدون اینکه درگیر رجیستر ها شد! ولی این کار، کار درستی نیست و ما باید همه چیز رو بلد باشیم!

به هرحال برای اینکار میتونید فایل system_LPC17XX.c که جزو فایل های startup هست و هر پروژه ای باز کنید این فایل توشه توشه!

بعد اونجا پایینش یه گزینه هست به نام Text Editor و یه گزینه بغلش هست به نام configuration Wizard که اونو بزنید میتونید تنظیمات رو انجام بدید!


خوب!

شروع میکنیم!


Clock Source Selction انتخاب منبع کلاک

یه رجیستر هست به نام CLKSRCSEL که تعیین کننده منبع کلاک هست!

سه نوع منبع کلاک داریم!

  1. نوسان ساز داخلی: این منبع کلاک 4مگاهرتز هست و زیاد به درد کار ما نمیخوره چون دقت کافی رو نداره
  2. نوسان ساز اصلی: این منبع کلاک یه کریستال خارج از میکرو هست که معمولا 12 مگاهرتزه (البته اگه هدر بورد دارید)
  3. نوسان ساز RTC: این منبع کلاک مخصوص بلوک RTC هست و فرکانسش 32khz هست که خیلی کمه و به درد کار ما نمیاد
خوب برای استفاده از این رجیستر ما فقط به دو بیت اول یعنی بیت های 0 و 1 احتیاج داریم! برای دسترسی به این رجیستر میتوانید از کد زیر استفاده کنید!
LPC_SC->CLKSRCSEL=0X00000000;

شما باید به جای 0X00 عدد خودتون رو قرار بدید که اونو در زیر اوردیم!

  1. برای استفاده از منبع کلاک داخلی بیت 00 رو قزار بدید! (باینری)
  2. برای استفاده از منبع کلاک اصلی (کریستال ) بیت 01 رو قرار بدید
  3. برای استفاده از RTC بیت 10 رو قرار بدید
مثلا شما میخواید از منبع کلاک خارجی استفاده کنید تکه کد مربوطه به شکل زیر است!
LPC_SC->CLKSRCSEL=0X1;

خوب حالا که اومدیم و کریستال خارجی یا همون نوسان ساز اصلی رو منبع کلاک قرار دادیم باید بیایم و یه خورده از ویژگی هاش رو هم مشخص کنیم!

مثلا بگیم کریستال خارجی در چه محدوده ای کار میکنه! چند مگاهرتز؟؟!

حالا پای یه رجیستر دیگه میاد وسط


  • رجیستر وضعیت و کنترل سیستم

خوب برای اینکه ویژگی های منبع نوسان ساز اصلی یا همون کریستال خارجی رو بیان کنیم از این رجیستر استفاده میکنیم!

در این رجیستر چهار بیت اول (بیت صفرم تا سوم) رزرو شده یعنی ما بهش کاری نداریم! بقیه بیت ها به صورت زیره!

  • بیت چهارم
    • در صورت استفاده از کریستال خارجی در محدوده 1MHZ تا 2MHZ این بیت 0 باشد
    • در صورت استفاده از کریستال خارجی در محدوده ی 15تا 20 مگاهرتز این بیت 1 شود

  • بیت پنجم
    • برای فعال سازی نوسان ساز اصلی این بیت 1 شود
    • برای غیر فعال سازی نوسان ساز اصلی این بیت 0 شود

  • بیت ششم - تعیین وضعیت نوسان ساز اصلی (فقط خواندنی)
    • اگر این بیت 1 باشد یعنی منبع کلاک آماده است
    • اگر این بیت 0 باشد یعنی منبع کلام آماده نیست
برای دسترسی به این رجیستر از کد زیر استفاده کنید!
LPC_SC->SCS=0X00000000;

مثلا اگر بخواهیم نوسان ساز اصلی رو که همون کریستال خارجی هست رو با فرکانس 12 مگاهرتز فعال کنیم از کد زیر استفاده میکنیم!

LPC_SC->SCS=0X20;


خوب بحص تعیین کلاک سیستم تموم شد! حالا یه بحثی شروع شد به نام PLL0 که وظیفه ی اون ضرب و تقسیم فرکانس نوسان ساز هست!

مثلا برای رسیدن به فرکانس 100 مگاهرتز که نمیتونیم یه کریستال 100 مگاهرتز بزاریم! بنابراین از طریق این واحد فرکانس رو کم و زیاد میکنیم!


حالا چندتا قانون وجود داره که باید اونارو رعایت کنیم!

  1. فرکانس ورودی PLL0 باید بین 32 کیلوهز تا 50مگاهرتز باشه (که از ما 12 مگاهرتزه)
  2. ما باید عدد فرکانس اسیلاتور رو بر عدد N تقسیم کنیم
  3. و همچنین عدد فرکانس اسیلاتور رو باید در M ضرب کنیم
  4. عددی که از ضرب و تقسیم فرکانس اسیلاتور به وجود میاید باید بین 275 تا 550 مگاهرتز باشه!
  5. فرمول بدست آوردن PLL0 در زیر آورده شده که N و M مقادیر ضرب و تقسیم و عدد 2 ثابت می باشد همچنین F فرکانس اسیلاتور هست که اینجا 12 میشه
PLL0=2*F(OSC)*M / N


چهار تا رجیستر مهم در بلوک PLL0 وجود داره که در پائین شرح دادم

  1. رجیستر PLL0CON برای فعالسازی و اتصال PLL0 به بلوک های دیگر استفاده می شود و تا رجیستر PLL0FEED بروز نشود این رجیستر بی تاثیر است
  2. رجیستر PLL0CFG مقادیر ضرب و تقسیم را در خود نگه میدارد و تا رجیستر PLL0FEED مقدار دهی نشود بی تاثیر است
  3. رجیستر PLL0STST که یک رجیستر فقط خواندنی است! که وضعیت PLL0 را بر میگرداند!
  4. رچیستر PLL0FEED که رجیستر های PLL0CON و PLL0CFG را اعمال میکنند و باید نخت مقدار 0XAA و سپس 0X55 در آن قرار کیرد
خوب حالا به توضیح هریک از این رجیستر های pll0 میپردازیم!

رجیستر (PLL0CON (PLL0 Control Register

این رجیستر وظیفه کنترل PLL0 رو داه!
بیت صفرم این رجیستر (PLLE0) وظیفه فعال کردن واحد PLL0 رو داره و بیت یکم (PLLC0) وظیفه اتصال PLL0 به بلوک ها و واحد های داخلی رو داره
برای دسترسی به این رجیستر از کد زیر استفاده میکنیم!
LPC_SC->PLL0CON=0X0000000;

رجیستر (PLL0CFG (PLL Configuration Register

وظیفه این رجیستر همونطور که از اسمش پیداست. ذخیره کننده ی ضرایب تقسیم و ضرب هست! یعنی برای اینکه به میکرو بفهمونیم منبع کلاک یا همون نوسان ساز اصلی رو در عدد M ضرب و بر عدد N تقسیم کن!
15 بیت اول یعنی از بیت صفرم تا چهاردهم (14:0) برای ذخیره ی عدد ضرب شونده (M) هست و باید بین 6 تا 512 باشه
 و بیت بعدی یعنی بیت پونزدهم (15) رززو شده هست و شما نمیتونید به اون عددی نسبت بدید! بنابراین بزارید این بیت یک باشه!
بیت های شونزدهم تا بیست و سوم (23:16) هم برای نگه داری ضریب تقسیم کننده (N) هست که باید عددی بین 1 تا32 باشه 
بیت های بعدی هم رزرو شده هست!
N و M با 1 جمع می شوند سپس مورد استفاده میکرو قرار میگیرد!

برای دسترسی به این رجیستر از کد زیر استفاده میکنیم!
LPC_SC->PLL0CFG=0X0000000;
رجیستر PLL0STAT (PLL Status Register)

وظیفه ی این رجیستر مشاهده وضعیت PLL0 هست!

15 بیت اول یعنی از بیت صفرم تا چهاردهم (14:0) برای نمایش عدد ضرب شونده (M) هست
 و بیت بعدی یعنی بیت پونزدهم (15) رززو شده هست!
بیت های شونزدهم تا بیست و سوم (23:16) هم نشون دهنده ی ضریب تقسیم کننده (N) هست
بیت بیست و چهارم (24) وضعیت PLL0 رو نشون میده! اگه 0 باشه یعنی غیر فعاله و اگه 1 باشه یعنی PLL0 فعاله!
بیت بیست و ششم (26) این بیت نشان دهنده ی فرکانس قفل شده است! یعنی اگه 1 باشه PLL0 روی فرکانس مورد نظر قفل شده! و اگه صفر باشه بلعکس
جهت دسترسی به این رجیستر از کد زیر استفاده کنید
inr d = LPC_SC->PLL0STAT;

رجیستر PLL0FEED (PLL Feed Register)

از این رجیستر جهت تازه کرن مقادیر PLL0CFG و PLL0CON است و تا این رجیستر مقدار دهی نشود آن دو رجیستر اعمال نمیشود!

جهت استفاده از این رجیستر ابتدا باید مقادیر 0XAA و سپس مقدار 0X55 رو در این رجیستر قرار دهید!

دسترسبه این رجیستر از کد زیر امکان پذیره!

LPC_SC->PLL0FEED=0XAA;

تنظیم کلاک سی پی یو


و در آخر میتونیم کلاک CPU رو تنظیم کنیم

برای بدست آوردن کلاک CPU از فرمول زیر استفاده کنید

CPU=PLL0(CLK)/CCLKSEL+1

یعنی شما باید عدد بدست آمده را بر عددی تقسیم کنید تا کلاک CPU بدست بیاید!

توجه کنید این عدد با 1 جمع می شود سپس مورد استفاده قرار میگیرد!

برای دسترسی به این رجیستر از کد زیر استفاده میکنیم!

LPC_SC->CCLKSEL=0X0000000;


این یه برنامه کمک آموزشی

		LPC_SC->CLKSRCSEL=0X01;
	 LPC_SC->SCS=0X20;
	 while (!(LPC_SC->SCS & 1<<6));
		LPC_SC->PLL0CFG = 0X0E; // M=15  N=0  CLK=360
		LPC_SC->CCLKCFG=0X7; //CPU CLOCK == 360/8 = 45MHZ
	 
	 LPC_SC->PLL0FEED=0XAA;
	 LPC_SC->PLL0FEED=0X55;
	 
	 LPC_SC->PLL0CON=0X1;
	 
	 LPC_SC->PLL0FEED=0XAA;
	 LPC_SC->PLL0FEED=0X55;	

		while(!(LPC_SC->PLL0STAT & 1<<26));
	 LPC_SC->PLL0CON=0X3;
	 
	 LPC_SC->PLL0FEED=0XAA;
	 LPC_SC->PLL0FEED=0X55;	


فعلا برای ظهور آقا امام زمان (عج) یه صلوات بفرستید!

یا علی مدد...!