اطلاعیه

Collapse
No announcement yet.

اصلاح یک برنامه ساده

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    اصلاح یک برنامه ساده

    وقت همگی بخیر. من تازه کار با ARM رو شروع کردم و خواستم با کتابخونه CMSIS و بدون استفاده از STM32CUBE MX اولین برنامه که 1 کردن پورت PORT.C.13 (یا همون PC13) از ماژول STM32F103C8TC هستش رو بنویسم. اینم برنامه منه که جواب نداده. لطفا راهنمایی کنید:
    کد:
    [FONT=Yekan]#include <stm32f10x.h>[/FONT]
    
    int main()
    {
        RCC -> APB2ENR |= RCC_APB2ENR_IOPCEN;
        GPIOC -> CRH |= GPIO_CRH_MODE11_0;
    }

    #2
    پاسخ : اصلاح یک برنامه ساده

    باسلام.
    دوست عزیز کارکردن مستقیم با ARM به این سادگی نیست.
    نیاز به فایل های استارتر و تنظیمات دیگه داره.اگه با کیوب کد تولید کرده باشید می بینید که کلی فایل تولید کرده.در نتیجه شما اگه بخواین از صفر راهندازی کنید باید کلی تنظیمات اولیه انجام بدید.

    دیدگاه


      #3
      پاسخ : اصلاح یک برنامه ساده

      نوشته اصلی توسط A.I.E نمایش پست ها
      باسلام.
      دوست عزیز کارکردن مستقیم با ARM به این سادگی نیست.
      نیاز به فایل های استارتر و تنظیمات دیگه داره.اگه با کیوب کد تولید کرده باشید می بینید که کلی فایل تولید کرده.در نتیجه شما اگه بخواین از صفر راهندازی کنید باید کلی تنظیمات اولیه انجام بدید.

      دلیل: ادغام دو پست برای جلوگیری از اسپم

      باسلام.
      دوست عزیز کارکردن مستقیم با ARM به این سادگی نیست.
      نیاز به فایل های استارتر و تنظیمات دیگه داره.اگه با کیوب کد تولید کرده باشید می بینید که کلی فایل تولید کرده.در نتیجه شما اگه بخواین از صفر راهندازی کنید باید کلی تنظیمات اولیه انجام بدید.
      درود بر شما. پیش از این با KEIL برای LPC1768 برنامه های متنوعی نوشتم و انجام تنظیمات اولیه رو کم و بیش بلدم و فایلهای لازم رو به پروژه اضافه کردم . در کامپایل هم هیچ خطا یا هشداری وجود نداره. مشکلم الان با STM32 هستش که نمیتونم رجیسترهای GPIO رو پیدا کنم. تو USER MANUAL این میکرو قسمت GPIO رو خیلی ناقص توضیح داده و دریغ از یه مثال. با CUBE MX هم دوست ندارم بنویسم چون به نظرم غیر حرفه ایه و برای کسی که میخاد حرفه ای از همه امکانات و سرعت ARM استفاده کنه باید صاف بره سراغ KEIL و دنبال میانبر نباشه

      دیدگاه


        #4
        پاسخ : اصلاح یک برنامه ساده

        نوشته اصلی توسط soleimani_m نمایش پست ها
        درود بر شما. پیش از این با KEIL برای LPC1768 برنامه های متنوعی نوشتم و انجام تنظیمات اولیه رو کم و بیش بلدم و فایلهای لازم رو به پروژه اضافه کردم . در کامپایل هم هیچ خطا یا هشداری وجود نداره. مشکلم الان با STM32 هستش که نمیتونم رجیسترهای GPIO رو پیدا کنم. تو USER MANUAL این میکرو قسمت GPIO رو خیلی ناقص توضیح داده و دریغ از یه مثال. با CUBE MX هم دوست ندارم بنویسم چون به نظرم غیر حرفه ایه و برای کسی که میخاد حرفه ای از همه امکانات و سرعت ARM استفاده کنه باید صاف بره سراغ KEIL و دنبال میانبر نباشه
        سلام
        لزوما اینطوری که میگید نیست. اکثر کسایی که من میشناسم با همین CubeMX کار میکنن و همچین ادعایی هم ندارن. کار سطح پایین چراغ چشمک زن و اینا هم نمیکنن و دستگاهاشون میلیونی میارزه.
        در مورد برنامه هم تاجایی که فهمیدم اصولا کار خاصی نمیکنه. از چه نظر میگید کار نمیکنه؟

        دیدگاه


          #5
          پاسخ : اصلاح یک برنامه ساده

          نوشته اصلی توسط hossein.m98 نمایش پست ها
          سلام
          لزوما اینطوری که میگید نیست. اکثر کسایی که من میشناسم با همین CubeMX کار میکنن و همچین ادعایی هم ندارن. کار سطح پایین چراغ چشمک زن و اینا هم نمیکنن و دستگاهاشون میلیونی میارزه.
          در مورد برنامه هم تاجایی که فهمیدم اصولا کار خاصی نمیکنه. از چه نظر میگید کار نمیکنه؟
          درود بر شما. ممنون که توجه کردید. من میخام PC13 این میکرو رو 1 کنم. قصدم این بود که با دستور زیر اول کلاک پورت C رو ENABLE کنم
          کد:
          RCC -> APB2ENR |= RCC_APB2ENR_IOPCEN;
          و بعد هم اونو 1 کنم با دستور زیر
          کد:
          [COLOR=#28282B][FONT=monospace]GPIOC -> CRH |= GPIO_CRH_MODE11_0;[/FONT][/COLOR]

          ولی نمیدونم دارم درست جلو میرم یا نه. اگر میتونید لطفا یه برنامه ساده چشمک زن اینجا بذارید.
          جدیدترین ویرایش توسط soleimani_m; ۲۱:۵۱ ۱۴۰۰/۰۷/۱۰.

          دیدگاه


            #6
            پاسخ : اصلاح یک برنامه ساده

            نوشته اصلی توسط soleimani_m نمایش پست ها
            درود بر شما. ممنون که توجه کردید. من میخام PC13 این میکرو رو 1 کنم. قصدم این بود که با دستور زیر اول کلاک پورت C رو ENABLE کنم
            کد:
            RCC -> APB2ENR |= RCC_APB2ENR_IOPCEN;
            و بعد هم اونو 1 کنم با دستور زیر
            کد:
            [COLOR=#28282B][FONT=monospace]GPIOC -> CRH |= GPIO_CRH_MODE11_0;[/FONT][/COLOR]

            ولی نمیدونم دارم درست جلو میرم یا نه. اگر میتونید لطفا یه برنامه ساده چشمک زن اینجا بذارید.
            رجیستر CRH تا جایی که توی رفرنس منوال خوندم فقط ورودی و خروجی بودن و اینجور موارد رو مشخص میکنه. برای نوشتن روی خروجی باید از ODR و BSSR و اینا استفاده کنید.

            دیدگاه


              #7
              پاسخ : اصلاح یک برنامه ساده

              نوشته اصلی توسط soleimani_m نمایش پست ها
              درود بر شما. ممنون که توجه کردید. من میخام PC13 این میکرو رو 1 کنم. قصدم این بود که با دستور زیر اول کلاک پورت C رو ENABLE کنم
              کد:
              RCC -> APB2ENR |= RCC_APB2ENR_IOPCEN;
              و بعد هم اونو 1 کنم با دستور زیر
              کد:
              [COLOR=#28282B][FONT=monospace]GPIOC -> CRH |= GPIO_CRH_MODE11_0;[/FONT][/COLOR]

              ولی نمیدونم دارم درست جلو میرم یا نه. اگر میتونید لطفا یه برنامه ساده چشمک زن اینجا بذارید.
              سلام
              برای انجام اینکار بهتره با توابع HAL کار کنید که خیلی راحت تره
              اگر میخاید از کدهای رجیستر برید دو حالت داره:

              GPIOC->ODR = 0x2000

              پایه C13 رو یک و بقیه رو صفر می کنه
              اگر میخاید بغیه پایه ها تغییر نکنن

              GPIOC->ODR |= 0xEFFF[FONT=Yekan]
              [/FONT]

              این فقط c13 رو یک می کنه و به بقیه کار نداره.
              (اساتید محترم اگر جاییش رو اشتباه گفتم تصحیح بفرمایید چشم پوشی کنید)

              دیدگاه


                #8
                پاسخ : اصلاح یک برنامه ساده

                نوشته اصلی توسط Matin_Mirzadeh نمایش پست ها
                سلام
                برای انجام اینکار بهتره با توابع HAL کار کنید که خیلی راحت تره
                اگر میخاید از کدهای رجیستر برید دو حالت داره:

                GPIOC->ODR = 0x2000

                پایه C13 رو یک و بقیه رو صفر می کنه
                اگر میخاید بغیه پایه ها تغییر نکنن

                GPIOC->ODR |= 0xEFFF[FONT=Yekan]
                [/FONT]

                این فقط c13 رو یک می کنه و به بقیه کار نداره.
                (اساتید محترم اگر جاییش رو اشتباه گفتم تصحیح بفرمایید چشم پوشی کنید)
                ممنونم مهندس. یعنی کد برنامه به صورت زیر میشه:
                کد:
                [COLOR=#28282B][FONT=Yekan]#include <stm32f10x.h>[/FONT][/COLOR]
                int main()
                {
                    RCC -> APB2ENR |= RCC_APB2ENR_IOPCEN;
                    GPIOC -> CRH |= GPIO_CRH_MODE11_0;
                    GPIOC->ODR |= 0xEFFF;
                }

                دیدگاه


                  #9
                  پاسخ : اصلاح یک برنامه ساده

                  خوب خوب خوب
                  ممنونم از دوستانی که در حد توانشون کمک کردن
                  چون نه در اینجا و نه در جای دیگه ای جواب شسته و رفته و ساده و دقیقی برای این مشکلم پیدا نکردم، با کلی وقت و گیر دادن به USER MANUAL این آی سی، تونستم یه پایه رو صفر و یک کنم یا همون چشمک زن ساده رو بصورت رجیستری و بدون استفاده از کتابخونه HAL پیاده سازی کنم. لذا تصمیم گرفتم نتیجه رو به همراه برنامه خودم که نوشتم اینجا بذارم تا اگه کسی دیگه ای هم این مشکل رو داشت جوابشو همینجا بگیره و وقتشو مثل من برای سرچ و سر و کله زدن با کلی DOCUMENT هدر نده. (من از میکروی STM32F103C8 استفاده میکنم)
                  1- یه پروژه توی کیل میسازیم و فایلهای startup و CMSIS رو به پروژه اضافه میکنیم.
                  2- فایل main.c رو هم میسازیم و به پروژمون اضافه میکنیم. (تا اینجاشو همه سایتها به انواع روشهای مختلف توضیح دادن و مشکلی نیست)
                  3- در فایل main.c ابتدا هدر میکروکنترلر خودمونو به صورت زیر به برنامه include میکنیم.
                  کد:
                  #include "stm32f10x.h
                  4- چون میخواهیم چشمک زدن رو ببینیم یه برنامه delay هم اول برنامه بصورت زیر مینویسیم (توضیحاتش تو سایتهای مختلف هست و چون ساده است بیشتر توضیح نمیدم)
                  کد:
                  [FONT=Yekan]void delay(int _delay)[/FONT]{
                      int i;
                      while(_delay--)
                      {
                          for(i=0;i<5000;i++);    
                      }
                  [FONT=Yekan]}[/FONT]
                  5- سپس تابع main و حلقه while خودمونو بصورت زیر مینویسیم:
                  کد:
                  [FONT=Yekan]int main(void)[/FONT]{
                      RCC -> APB2ENR |= (1<<2);
                      GPIOA -> CRL &=~ (0xF);
                      GPIOA -> CRL |= (0x3);
                      
                      while(1)
                      {
                          GPIOA -> BSRR |= (1<<0);
                          delay(1000);
                          GPIOA -> BSRR |= (1<<16);
                          delay(1000);
                      }
                  [FONT=Yekan]}[/FONT]
                  این شد کل برنامه چشمک زن و اگه برنامه رو با f7 کامپایل و با f8 روی میکرو پروگرم کنیم پایه A0 شروع به چشمک زدن میکنه. حالا توضیحات این برنامه :
                  شخصا دوست دارم سریع برم سراغ کدنویسی و با بررسی معماری داخلی میکروها اصلا حال نمیکنم ولی برای نوشتن برنامه بصورت رجیستری توی این میکروها این کار اجتناب ناپذیره. سعی میکنم در حدی که لازمه از جداول و شکلهای user manual این میکرو اینجا استفاده کنم
                  همانطور که تو دیتاشیت میکروکنترلرهای ARM گفته شده، برای راه اندازی هر بخش باید اول کلاک اون بخشو فعال کرد. طبق شکل زیر که از MANUAL همین آی سی گرفتم، برای راه اندازی کلاک بخش مربوط به GPIOها باید کلاک APB2 رو فعال کرد.

                  بنابر این باید رجیستر مربوط به فعال سازی کلاک APB2 رو پیدا و تنظیم کنیم. این رجیستر در این میکروکنترلر به اسم APB2ENR شناخته میشه. این رجیستر کنترلی یک رجیستر 32 بیتی هستش که تو شکل زیر میبینید. برای ENABLE کردن PORTA باید بیت 2 از این رجیستر رو یک کنیم.

                  که برای این کار از شیفت دادن عدد 1 به بیت 2 این رجیستر با دستور زیر استفاده شده است
                  کد:
                  RCC -> APB2ENR |= (1<<2);
                  با اینکار کلاک GPIOA یا همون PORTA فعال میشه و پورت در صورت کانفیگ مناسب آماده دریافت و یا ارسال داده میشه. بعد از اینکار باید پورت رو بصورت خروجی تعریف کنیم. طبق دیتا شیت این میکروکنترلر هر پورت این میکروکنترلر بصورت 16 بیتی تعریف میشه که این 16 بیت به دو دسته 8 بیتی تقسیم میشن که از رجیستر CRL برای 8 بیت کم ارزش و از رجیستر CRH برای 8 بیت با ارزشتر استفاده میشه.

                  برای تعریف ورودی و خروجی هر پایه از پورت یا همون GPIO باید بیت متناظر در این رجیسترها رو یک یا صفر کرد. باز هم طبق دیتاشیت، وقتی این میکرو ریست یا برای اولین بار به منبع تغذیه وصل و روشن میشه، این رجیسترها بصورت شناور با دیتای 0X4444 444 پر میشن. برای اینکه بتونیم این رجیسترها رو کانفیگ کنیم اول باید مقدار صفر رو روی این رجیسترها بریزیم تا بتونیم از حالت شناور خارج و بعد بصورت ورودی یا خروجی تعریفشون کنیم. برای اینکار از دستور زیر استفاده میکنیم:
                  کد:
                  GPIOA -> CRL &=~ (0xF);
                  همانطور که در شکل فوق مربوط به رجیستر CRL میشه دید، پایه های پورتهای بصورت دو به دو و با اسم MODE از MODE0 to MODE7 تقسیم شدن. ما میخواهیم پورت A0 رو بصورت خروجی تعریف کنیم. بنابراین باید MODE0 رو بصورت خروجی تنظیم کنیم. تا یادم نرفته اینم بگم که در این رجیستر (منظور همون CRL) ما بخشای MODE و CNF رو داریم. با بیتهای مربوط به CNF نوع ورودی و خروجی رو طبق شکل زیر تعیین میکنیم و با بیتهای مربوط به MODE فرکانس خروجی رو تعیین میکنیم.

                  من تو این پروژه خروجی رو با ماکزیمم فرکانس یعنی 50MHz راه اندازی کردم. پس باید عدد 11 رو تو بیتهای MODE0 از رجیستر CRL که همون بیتهای 0 و 1 میشن بنویسم. برای اینکار از دستور زیز استفاده میشه:
                  کد:
                  GPIOA -> CRL |= (0x3);
                  تا اینجای کار ما فقط تونستیم پورت A0 رو بصورت خروجی تعریف کنیم حالا میخوایم تو حلقه WHILE این بیت رو 1 و 0 کنیم با یه تاخیر محسوس که چشمک زن ما تکمیل بشه. برای اینکار از رجیستر BSRR استفاده میکنیم. ببینید یه مرضی که این میکروکنترلر داره اینه که برای 1 کردن یه پایه بخصوص از این میکرو از یه بیت رجیستر BSRR استفاده میشه و برای صفر کردنش از یه بیت دیگه رجیستر BSRR (یه روشی هم توی USER MANUAL بود که با استفاده از رجیسترهای ODR و BRR یه پایه یا یه پورت رو 1 و صفر میکرد که درست نفهمیدم فرقش با رجیستر BSRR چیه ).
                  رجیستر BSRR یه رجیستر 32 بیتیه که از 16تا بیت اول یعنی بیتهای 0 تا 15 برای 1 کردن پایه های پورتها و از 16 بیت دوم یعنی بیت های 16 تا 31 برای صفر کردن همون پایه ها استفاده میشه. مثلا برای 1 کردن پایه A5 باید بیت 5 رجیستر BSRR رو 1 کرد و برای صفر کردن پایه A5 باید بیت 21 رجیستر BSRR رو یک کرد (AVR روحت شاد چقدر تو خوب و راحت بودی)
                  اینم برنامه داخل حلقه WHILE برای صفر و یک کردن پایه A0:
                  کد:
                  [FONT=Yekan]while(1)[/FONT]    {
                          GPIOA -> BSRR |= (1<<0);
                          delay(1000);
                          GPIOA -> BSRR |= (1<<16);
                          delay(1000);
                  [FONT=Yekan]}[/FONT]

                  در نهایت کل برنامه به صورت زیر میشه:
                  کد:
                  #include "stm32f10x.h"
                  
                  void delay(int _delay)
                  {
                      int i;
                      while(_delay--)
                      {
                          for(i=0;i<5000;i++);    
                      }
                  }
                  int main(void)
                  {
                      RCC -> APB2ENR |= (1<<2);
                      GPIOA -> CRL &=~ (0xF);
                      GPIOA -> CRL |= (0x3);
                      
                      while(1)
                      {
                          GPIOA -> BSRR |= (1<<0);
                          delay(1000);
                          GPIOA -> BSRR |= (1<<16);
                          delay(1000);
                      }
                  }
                  دوستان و اساتید محترم اگه ایرادی هست لطفا بفرمایید. موفق باشید
                  جدیدترین ویرایش توسط soleimani_m; ۱۰:۰۰ ۱۴۰۰/۰۷/۱۵. دلیل: تکمیل مطلب - ویرایش ایرادات تایپی

                  دیدگاه

                  لطفا صبر کنید...
                  X