با سلام
یک دو سه روزی هست که با کامپایلر IAR دارم کار میکنم ، چیزی که در رابطه با این کامپایلر متوجه شدم این بود که به راحتی کدویژن و بسکام که قبلا باهاشون کار میکردم نمیشه برنامه نوشت ( البته برنامه داریم تا برنامه ، برنامه که من می نویسم مسلما خیلی آماتور هست ) و شاید دلیلش هم نبود کتابخانه های فراوان باشه مثلا توی کدویژن و بسکام کتابخانه هایی مثل LCD.H هست اما این کامپایلر همچین کتابخانه هایی رو نداره !
اما چیزی که من رو بیشتر راغب کرد تا به این نرم افزار دلببندم شکل برنامه نویسیش بود نمیدونم من رو یاد برلندC می ندازه که من باهاش خاطرات خوبی دارم منظورم اینه که آدم تازه احساس میکنه که داره برنامه می نویسه (البته این یک احساس کاملا شخصی هست ) خلاصه مطلب با تعقیب مطالب انجمن XMEGA در رابطه با این کامپایلر چیزی رو که فهمیدم این بود که برای کار با این کامپایلر و اصلا برنامه نویسی اصولی باید اون شکل برنامه نویسی رو ببوسم بزارم کنار تا خودم کنار نرفتم و برای این منظور از آنجا که APPNOTE های ATMEL روش برنامه نویسی استاندارد رو به کاربراش یاد میده تصمیم گرفتم که شروع به مطالعه این APPLICTION ها بکنم .
و حالا قصد دارم تا هر APPNOTE رو که میخونم دریافت هام رو اینجا بنویسم تا دوستان قایل بدوند و اشتباهاتم رو بهم بگند تا این خشتها را بتونم سالم روی هم بزارم :
APPNOTE ای که می خوام باهاش شروع کنم AVR 035 هست :
1.مدهای آدرس دهی : در معماری AVR به چهار نوع اشاره گر حافظه برای استفاده از حافظه داده و حافظه برنامه وجود دارد مثل SP که به محلی که آدرس برگشت از توابع در آن ذخیره می شود اشاره می کنه و اشاره گری که کامپایلر ها به عنوان پارامتر استک اختصاص میدند ( این یعنی چه؟) و اشاره گرهایی که کامپایلر برای بار گزاری و ذخیره داده از اون ها استفاده می کنند .
* تمام اشاره گرها یک کلمه ای(single-word) هستند و در نتیجه برای اجرا به دو سیکل ماشین احتیاج دارند .
مدهای آدرس دهی اشاره گر ها :
1.آدرس دهی مستقیم : برای مقدار دهی مستقیم اشاره گر
مثال :
char i[3];
char *pointer1=&i[0];
*pointer1 =0x00;
2-آدرس دهی غیر مستقیم با جایگزینی : برای آدرس دهی غیر مستقیم اشاره گرها و همچنین مقدار دهی غیر مستقیم متغیر ها
مثال :
char i[3];
char *pointer1=&i[0];
pointer1 =&i[1];
i[2]=*pointer1;
3-آدرس دهی غیر مستقیم اشاره گر و مقدار دهی متغیر ها با افزایش مقدار اشاره گر بعد از انتساب
مثال :
char i[3];
char *pointer1=&i[0];
*pointer1++ =0x00;
i[1]=*pointer1++;
4-آدرس دهی غیر مستقیم اشاره گر و مقدار دهی متغیر ها با کاهش قبل از انتساب
مثال :
char i[3];
char *pointer1=&i[0];
*--pointer1=0x00;
i[1]=*--pointer1;
2.دسترسی به رجیسترهای I/O : تمام رجیسترهای I/O در فایل های هدر مربوط به هر میکرو که به صورت “ioxxxx.h” نام گذاری شده اند تعریف شده است که XXXX به نام میکرو اشاره دارد
مثلا برای مگا 16 داریم : iom16.h
که البته تمام این فایل ها در فایل هدر ioavr.h فراخوانی شده اند که با فراخوانی این هدر در ابتدای برنامه کامپایلر با توجه به تنظیمات انجام شده فایل هدر مورد نظر را به برنامه الحاق مینماید .
1- خواندن رجیستر های I/O :
مثال :
char temp; /* Declare a temporary variable*/
/*To read and write to an I/O register*/
temp = PIND; /* Read PIND into a variable*/
// IN R16,LOW(16) ; Read I/O memory
2-نوشتن در رجیسترهای I/O :
مثال :
TCCR0 = 0x4F; /* Write a value to an I/O location*/
// LDI R17,79 ; Load value
// OUT LOW(51),R17 ; Write I/O memory
3-SET کردن بیت n ام از یک رجیستر :
مثال :
DDRB|=(1<<DDB2);
PORTB |= (1<<PINB2);
// SBI LOW(23),LOW(2)
// SBI LOW(24),LOW(2)
در اینجا PINB2 , DDB2 هر تنها عنوان کننده شماره بیت مورد نظر می باشند از اینرو هر معادل هم و همچنین معادل مثلا PB2,PD2,PIND2,POTRA2,2,... میباشند .
4-clear کردن بیت n ام از یک رجیستر :
مثال :
ADCSR &= ~(1<<ADEN);
// CBI LOW(6),LOW(7)
در اینجا نیز از آنجا که ADEN بیت هفتم از رجیستر ADCSR می باشد میتوان بجای آن از 7,PD7,PINB7,....استفاده نمود البته این کار به جهت از بین رفتن خوانای برنامه انجام نمیشود .
5-SET کردن همزمان چند بیت :
مثال :
DDRD |= 0x0C; /* Set bit 2 and 3 in DDRD register*/
// IN R17,LOW(17) ; Read I/O memory
// ORI R17,LOW(12) ; Modify
// OUT LOW(17),R17 ; Write I/O memory
6-clear کردن همزمان چند بیت:
مثال:
ACSR &= ~(0x0C); /* Clear bit 2 and 3 in ACSR register*/
// IN R17,LOW(8) ; Read I/O memory
// ANDI R17,LOW(243) ; Modify
// OUT LOW(8),R17 ; Write I/O memory
7-چک کردن یک بودن یک بیت از یک رجیستر :
مثال:
if(USR & (1<<TXC)) /* Check if UART Tx flag is set*/
PORTB |= (1<<PB0);
// SBIC LOW(11),LOW(6) ; Test direct on I/O
// SBI LOW(24),LOW(0)
8-چک کردن صفر بودن یک بیت از یک رجیستر :
مثال:
while(!(SPSR & (1<<WCOL))) ;/* Wait for WCOL flag to be set */
// ?0003:SBIS LOW(14),LOW(6); Test direct on I/O
// RJMP ?0003
9-چک کردن یک بودن یا صفر بودن چند بیت از یک رجیستر یا به عبارتی برابر بودن رجیستر با یک سری بیت مرتب شده :
مثال:
if(UDR & 0xF3) /* Check if UDR register "and" 0xF3 is non-zero
{
}
// IN R16,LOW(12) ; Read I/O memory
// ANDI R16,LOW(243) ; "And" value
// BREQ ?0008 ; Branch if equal
//?0008:
}
10-SET ، CLEAR و چک کردن بیت n ام از یک رجیستر با استفاده از ماکرو :
مثال:
#define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define CLEARBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))
/* Macro for testing of a single bit in an I/O location*/
#define CHECKBIT(ADDRESS,BIT) (ADDRESS & (1<<BIT))
/* Example of usage*/
if(CHECKBIT(PORTD,PIND1)) /* Test if PIN 1 is set*/
{
CLEARBIT(PORTD,PIND1); /* Clear PIN 1 on PORTD*/
}
if(!(CHECKBIT(PORTD,PIND1))) /* Test if PIN 1 is cleared*/
{
SETBIT(PORTD,PIND1); /* Set PIN 1 on PORTD*/
}
پایان قسمت اول (دیگه کم آوردم )
یک دو سه روزی هست که با کامپایلر IAR دارم کار میکنم ، چیزی که در رابطه با این کامپایلر متوجه شدم این بود که به راحتی کدویژن و بسکام که قبلا باهاشون کار میکردم نمیشه برنامه نوشت ( البته برنامه داریم تا برنامه ، برنامه که من می نویسم مسلما خیلی آماتور هست ) و شاید دلیلش هم نبود کتابخانه های فراوان باشه مثلا توی کدویژن و بسکام کتابخانه هایی مثل LCD.H هست اما این کامپایلر همچین کتابخانه هایی رو نداره !
اما چیزی که من رو بیشتر راغب کرد تا به این نرم افزار دلببندم شکل برنامه نویسیش بود نمیدونم من رو یاد برلندC می ندازه که من باهاش خاطرات خوبی دارم منظورم اینه که آدم تازه احساس میکنه که داره برنامه می نویسه (البته این یک احساس کاملا شخصی هست ) خلاصه مطلب با تعقیب مطالب انجمن XMEGA در رابطه با این کامپایلر چیزی رو که فهمیدم این بود که برای کار با این کامپایلر و اصلا برنامه نویسی اصولی باید اون شکل برنامه نویسی رو ببوسم بزارم کنار تا خودم کنار نرفتم و برای این منظور از آنجا که APPNOTE های ATMEL روش برنامه نویسی استاندارد رو به کاربراش یاد میده تصمیم گرفتم که شروع به مطالعه این APPLICTION ها بکنم .
و حالا قصد دارم تا هر APPNOTE رو که میخونم دریافت هام رو اینجا بنویسم تا دوستان قایل بدوند و اشتباهاتم رو بهم بگند تا این خشتها را بتونم سالم روی هم بزارم :
APPNOTE ای که می خوام باهاش شروع کنم AVR 035 هست :
1.مدهای آدرس دهی : در معماری AVR به چهار نوع اشاره گر حافظه برای استفاده از حافظه داده و حافظه برنامه وجود دارد مثل SP که به محلی که آدرس برگشت از توابع در آن ذخیره می شود اشاره می کنه و اشاره گری که کامپایلر ها به عنوان پارامتر استک اختصاص میدند ( این یعنی چه؟) و اشاره گرهایی که کامپایلر برای بار گزاری و ذخیره داده از اون ها استفاده می کنند .
* تمام اشاره گرها یک کلمه ای(single-word) هستند و در نتیجه برای اجرا به دو سیکل ماشین احتیاج دارند .
مدهای آدرس دهی اشاره گر ها :
1.آدرس دهی مستقیم : برای مقدار دهی مستقیم اشاره گر
مثال :
char i[3];
char *pointer1=&i[0];
*pointer1 =0x00;
2-آدرس دهی غیر مستقیم با جایگزینی : برای آدرس دهی غیر مستقیم اشاره گرها و همچنین مقدار دهی غیر مستقیم متغیر ها
مثال :
char i[3];
char *pointer1=&i[0];
pointer1 =&i[1];
i[2]=*pointer1;
3-آدرس دهی غیر مستقیم اشاره گر و مقدار دهی متغیر ها با افزایش مقدار اشاره گر بعد از انتساب
مثال :
char i[3];
char *pointer1=&i[0];
*pointer1++ =0x00;
i[1]=*pointer1++;
4-آدرس دهی غیر مستقیم اشاره گر و مقدار دهی متغیر ها با کاهش قبل از انتساب
مثال :
char i[3];
char *pointer1=&i[0];
*--pointer1=0x00;
i[1]=*--pointer1;
2.دسترسی به رجیسترهای I/O : تمام رجیسترهای I/O در فایل های هدر مربوط به هر میکرو که به صورت “ioxxxx.h” نام گذاری شده اند تعریف شده است که XXXX به نام میکرو اشاره دارد
مثلا برای مگا 16 داریم : iom16.h
که البته تمام این فایل ها در فایل هدر ioavr.h فراخوانی شده اند که با فراخوانی این هدر در ابتدای برنامه کامپایلر با توجه به تنظیمات انجام شده فایل هدر مورد نظر را به برنامه الحاق مینماید .
1- خواندن رجیستر های I/O :
مثال :
char temp; /* Declare a temporary variable*/
/*To read and write to an I/O register*/
temp = PIND; /* Read PIND into a variable*/
// IN R16,LOW(16) ; Read I/O memory
2-نوشتن در رجیسترهای I/O :
مثال :
TCCR0 = 0x4F; /* Write a value to an I/O location*/
// LDI R17,79 ; Load value
// OUT LOW(51),R17 ; Write I/O memory
3-SET کردن بیت n ام از یک رجیستر :
مثال :
DDRB|=(1<<DDB2);
PORTB |= (1<<PINB2);
// SBI LOW(23),LOW(2)
// SBI LOW(24),LOW(2)
در اینجا PINB2 , DDB2 هر تنها عنوان کننده شماره بیت مورد نظر می باشند از اینرو هر معادل هم و همچنین معادل مثلا PB2,PD2,PIND2,POTRA2,2,... میباشند .
4-clear کردن بیت n ام از یک رجیستر :
مثال :
ADCSR &= ~(1<<ADEN);
// CBI LOW(6),LOW(7)
در اینجا نیز از آنجا که ADEN بیت هفتم از رجیستر ADCSR می باشد میتوان بجای آن از 7,PD7,PINB7,....استفاده نمود البته این کار به جهت از بین رفتن خوانای برنامه انجام نمیشود .
5-SET کردن همزمان چند بیت :
مثال :
DDRD |= 0x0C; /* Set bit 2 and 3 in DDRD register*/
// IN R17,LOW(17) ; Read I/O memory
// ORI R17,LOW(12) ; Modify
// OUT LOW(17),R17 ; Write I/O memory
6-clear کردن همزمان چند بیت:
مثال:
ACSR &= ~(0x0C); /* Clear bit 2 and 3 in ACSR register*/
// IN R17,LOW(8) ; Read I/O memory
// ANDI R17,LOW(243) ; Modify
// OUT LOW(8),R17 ; Write I/O memory
7-چک کردن یک بودن یک بیت از یک رجیستر :
مثال:
if(USR & (1<<TXC)) /* Check if UART Tx flag is set*/
PORTB |= (1<<PB0);
// SBIC LOW(11),LOW(6) ; Test direct on I/O
// SBI LOW(24),LOW(0)
8-چک کردن صفر بودن یک بیت از یک رجیستر :
مثال:
while(!(SPSR & (1<<WCOL))) ;/* Wait for WCOL flag to be set */
// ?0003:SBIS LOW(14),LOW(6); Test direct on I/O
// RJMP ?0003
9-چک کردن یک بودن یا صفر بودن چند بیت از یک رجیستر یا به عبارتی برابر بودن رجیستر با یک سری بیت مرتب شده :
مثال:
if(UDR & 0xF3) /* Check if UDR register "and" 0xF3 is non-zero
{
}
// IN R16,LOW(12) ; Read I/O memory
// ANDI R16,LOW(243) ; "And" value
// BREQ ?0008 ; Branch if equal
//?0008:
}
10-SET ، CLEAR و چک کردن بیت n ام از یک رجیستر با استفاده از ماکرو :
مثال:
#define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define CLEARBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))
/* Macro for testing of a single bit in an I/O location*/
#define CHECKBIT(ADDRESS,BIT) (ADDRESS & (1<<BIT))
/* Example of usage*/
if(CHECKBIT(PORTD,PIND1)) /* Test if PIN 1 is set*/
{
CLEARBIT(PORTD,PIND1); /* Clear PIN 1 on PORTD*/
}
if(!(CHECKBIT(PORTD,PIND1))) /* Test if PIN 1 is cleared*/
{
SETBIT(PORTD,PIND1); /* Set PIN 1 on PORTD*/
}
پایان قسمت اول (دیگه کم آوردم )
دیدگاه