خب . حالا می خایم از گذرگاه AHB که شروع ورود به امکانات محیطی میکرو هست به سمت مقصد نهایی که GPIO هست حرکت کنیم . عبارت
کد:
#define PERIPH_BASE ((uint32_t)0x40000000)
رو داخل این هدر پیدا کنید . پس مشخص شد که آدرس باس AHB در بانک رجیستر مقدار فوق هست . خب این باس به دو شاخه APB1,APB2 تقسیم میشه . حالا عبارت
کد:
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
رو پیدا کنید . این میرسونه که اگه از بانک رجیستر AHB به اندازه 0x10000 بریم جلو به محدوده APB2 وارد میشیم . این عدد رو میتونید با آدرسهای جدول بالا مقایسه کنید . عدد قبلی با عدد فعلی جمع شده و عبارت 0x4001xxx بینشون مشترکه . حالا یه مرحله جلوتر میریم . مثلا وارد GPIOA میشیم . عبارت
کد:
#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)
v رو پیدا کنید . حالا اگر نتیجه رو با جدول بالا مقایسه کنید معلوم میشه که آدرس شروع واحد GPIOA عدد 0x40010800هست که از جمع مقادیر از ابتدا تا اینجا بدست اومد . عبارت
کد:
#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
رو هم مشاهده کنید . حالا تازه وارد محدوده GPIOA شدیم و می تونیم به رجیسترهای اون دسترسی داشته باشیم .
این جدول و رجیسترهای اون برای پورت های دیگه GPIO تکرار میشه . فقط باید بیس آدرس ما عدد بدست اومده باشه و با افست دادن به اون عدد (اضافه کردن عدد های سمت چپ جدول متناظر با هر رجیستر میتونیم به رجیستر مربوطه دسترسی داشته باشیم . مثلا آدرس مطلق دسترسی به این هفت رجیستر برای GPIOA به ترتیب برابر :
0X40010818 - 0X40010814-0X40010810-0X4001080C-0X40010808-0X40010804-0X40010800
هست . حالا با رفتن به این آدرس میشه 32 بیت داخلش نوشت یا خواند . بعضی جاهاش هم که رزرو هست . تو کتابخانه دنبال عبارت :
کد:
typedef struct
{
__IO uint32_t CRL;
__IO uint32_t CRH;
__IO uint32_t IDR;
__IO uint32_t ODR;
__IO uint32_t BSRR;
__IO uint32_t BRR;
__IO uint32_t LCKR;
} GPIO_TypeDef;
بگردید . در اینجا اومدن این جدول رو بصورت یک ساختار یا STRUCTURE تعریف کردن و عناصر این جدول رو هم همانند manual جاگذاری کردند . این ساختار یک جدول رو روی حافظه تشکیل میده به این شکل عمل میکنه که وقتی به نام ساختار که GPIO_TypeDef هست یه آدرس نسبت بدیم ( در اینجا آدرس GPIOA=0x40010800) از این آدرس میاد و 7 رجیستر 32 بیتی رو تو حافظه میچینه . حالا ما خیلی راحت میتونیم با فراخوانی اسم ساختار و یکی از اعضای اون بشکل زیر یه مقدار مثلا تو رجیستر BSRR بنویسیم :
GPIOA->BSRR=0x00000001
از این به بعد دیگه کتابخانه مخصوص stm32f10x_gpio.c و هدرش stm32f10x_gpio.h وارد کار میشه . تعریفهای پین 0 تا 15 فقط در واقع مقدار 1 دادن به بیتهای 0و1و... است و فرقی با نوشتن عدد نمی کنه . حالا اگه یک تابع مثلا
کد:
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
رو نگاه کنیم میبینیم که اونم از همین راه رفته و راه دیگه ای در واقع نیست .
یه عکس هم براتون میزارم که مقدار پورت رو تو رجیستر ODR در آدرس حافظه مورد نظر بوسیله ابزار Memory در Keil نشون میده .
پس معلوم شد چیزی که مهمه آدرس رجیستر هست و همون طوری که می دونیم اسامی فقط نام گذاری ما هستن . حالا تو manual مثلا نوشته GPIOx_ODR و تو کتابخانه به یه طریقی دیگه (structure) و اسمی دیگه .... مهم اینه که آدرس ها با هم میخونه .
خب امیدوارم تا حدی تونسته باشم سر نخ رو دستتون بدم و امیدوارم مفید بوده باشه .....
در ضمن برای نوشتن این پست حدود 2 ساعت وقت صرف شده
یا حق