یه سوال: الان در مورد خود رجیستری مثل FIOSET0، خود همین رجیستر ادرس در کجا تعریف شده؟ مثلا در مورد lpc2148 توی هدر فایل ادرس هر رجیستر این شکلی تعریف شده بود
#define IO0DIR (*((volatile unsigned long *) 0xE0028008))
خب توی غیر کرتکس ها که ممکنه هر میکرو و هر شرکت یه چیزی زده باشه. ولی توی کرتکس ها که استاندارد هست توی چند مرحله هر رجیستر تعریف میشه. مثلا برای GPIO0 داریم:
کد:
#define LPC_GPIO0 ((LPC_GPIO_TypeDef *) LPC_GPIO0_BASE )
خب اینجا اومده LPC_GPIO0_BASE رو به LPC_GPIO_TypeDef کست(cast) کرده. حالا داریم:
کد:
#define LPC_GPIO0_BASE (LPC_GPIO_BASE + 0x00000)
خب از اینجا اون روند چند مرحله ای شروع میشه. اینجا اومده LPC_GPIO0_BASE رو تعریف کرده که آدرسش هست 0x00000 به اضافه LPC_GPIO_BASE.
کد:
#define LPC_GPIO_BASE (0x2009C000UL)
خب حالا اینجا در واقع شروع آدرس مربوط به GPIO هاست.
پس اگه مراحل رو به عقب بریم برای GPIO0 آدرسش میشه: 0x2009C000UL + 0x00000
حالا می ریم سراغ رجیستر ها. رجیستر ها توی یه استراکت تعریف شده بودن دیگه. خب الان طبق کد زیر استراکت GPIO0 آدرس شروعش میشه 0x2009C000UL + 0x00000. حالا توی استراکت اومده به ترتیب رجیستر هارو تعریف کرده. مثلا:
کد:
__IO uint32_t FIODIR;
بعدش هم مثلا هست:
کد:
__IO uint32_t FIOMASK;
از اونجایی که هر رجیستر 4 بایته پس در واقع الان FIODIR میشه از 0x2009C000UL تا 0x2009C080UL + 0x
حالا باز دوباره FIODIR0 ~ FIODIR4 رو تعریف کرده هر کدوم از نوع uint8_t هست که میشه یک بایت. حالا اصل مطلب توی اون union هست. اگه اینا با هم union نمی شدن هر کدوم از FIODIRL و FIODIR0 و... برای خودشون حافظه اشغال می کردن و کلا آدرس رجیستر از محدودش خارج می شد. ولی دستور union به کامپایلر می گه که آقا اینایی که اینجا تعریف شدن همه یه آدرس دارن و همه با هم هستن و فقط اسماشون فرق داره.
یه نکته دیگه هم که الان یوزر منوال رو ببینی ترتیبی که برای رجیستر ها هست با ترتیب این کد یکیه. چون کد خط به خط اجرا میشه. اولین رجیستر که FIODIR باشه اول از آدرس 0x2009C000UL (که مربوط به GPIO0 هست) 4 بایت رو می گیره. بعد FIOMASK میاد 4 بایت بعدی رو می گیری و الا آخر. پس ترتیب تعریف اینا هم توی استراکت GPIO_TypeDef مهمه و اگه جاشون عوض آدرساشون هم عوض شده پس مثلا اگه جای FIODIR و FIOMASK رو عوض کنی وقتی توی LPC_GPIO0->FIODIR می نویسی در واقع توی آدرس FIOMASK می نویسه.