اطلاعیه

Collapse
No announcement yet.

برنامه نویسی STM32 با مقداردهی رجیسترها در ++C

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

    برنامه نویسی STM32 با مقداردهی رجیسترها در ++C

    من فکر میکنم بیشتر اونهایی که برای کد نویسی ARM سعی در کار کردن مستقیم با رجیسترها دارند، به دو گروه تقسیم میشوند:
    یا خیلی مبتدیند (مثل من) و یا خیلی حرفه ایند (مثل شما که میخواهید بنده و بقیه مبتدیهای این زمینه رو راهنمایی کنید، خدا خیرتون بده).
    ... .
    اساتید محترم، اگه کسی بخواد برای STM32 توی محیط Keil 5 یه پایه از یه پورت رو صفر و یک کنه (همون چشمک زدن LED ، البته برای تأخیر از حلقه تکرار بالا استفاده بشه!) و کمترین استفاده رو از کتابخانه ها و توابع سطح بالا داشته باشه،
    1
    - پوشه پروژه چه شکلی میشه؟ (یعنی حداقل فایلهایی که باید اضافه بشن چی هستند)؟
    2
    -فایل main.c چه شکلی میشه؟ (بدون استفاده از;() system.init و ... )؟
    ... .
    و فکر کنم این سوالات من یه ارتباطی هم به این صفحه از نرم افزار داشته باشه:



    3- و دست آخر اینکه یه جوانمردی لطف کنه و اون گزینه هایی که به component مشخص شده رو یه توضیح اجمالی بده که به چه درد میخورند؟ و مهم اشو باز کنه!
    اجرکم عند الله ... .
    ◙◙◙◙◙ میخوام به دوستان یه کتاب معرفی کنم! وقت کردید، بخونید - اسمش هست قرآن، سال نشر 10، نویسنده: خدا . ◙◙◙◙◙

    #2
    پاسخ : برنامه نویسی STM32 با مقداردهی رجیسترها در ++C

    سلام علیکم شما اگر میخواید وارد مبحث برنامه نویسی با stm32 بشین اول این رو بدونید که کلا سعی کنید فقط با کیوب ام ایکس پروژتون را درست کنید مثل کاری که من انجام میدم برای کنترل کردن یک پین پورت هم بدون توابع سطح بالا میتونید مستقیما با رجیسترها کار کنید مثالش را هم پایین میگذارم
    #define ON_OUT8 GPIOA->BSRR = GPIO_PIN_8; 
    #define OFF_OUT8 GPIOA->BRR = GPIO_PIN_8;
    #define TOGGLE_OUT8 GPIOA->ODR ^= GPIO_PIN_8;

    دیدگاه


      #3
      پاسخ : برنامه نویسی STM32 با مقداردهی رجیسترها در ++C

      نوشته اصلی توسط ubub نمایش پست ها
      اساتید محترم، اگه کسی بخواد برای STM32 توی محیط Keil 5 یه پایه از یه پورت رو صفر و یک کنه (همون چشمک زدن LED ، البته برای تأخیر از حلقه تکرار بالا استفاده بشه!) و کمترین استفاده رو از کتابخانه ها و توابع سطح بالا داشته باشه،
      من هم مثل شما میخواستم از پایین ترین سطح کد نویسی اس تی ام سر در بیارم و شروع به یادگیری کردم -
      ببینید اگه قبلا با رجیسترهای avr کار میکردین و فکر میکنید که با اون روش قبل میتونید برای arm هم کد بزنید باید بگم که کلا رجیسترهای avr شاید همشونو بشه با یکی از رجیسترهای rcc از لحاظ حجم مقایسه کرد.
      پس برنامه نویسی با رجیسترها رو باید بیخیال شی چون خیلی باید برای انجام دادن کار کوچیک با رجیسترها کد بزنی. تازه بیشتر رجیسترها بهم مرتبطن و باید همشونو ست کنی.تازه باید سی رو هم خوب بدونی.حالا من نمونه کد برات برای مقدار دهی رجیستر میزارم. که خودم وقتی فهمیدم چجوری کار میکنه دیگه سمت مقدار دهی رجیستر ها نمیرم . چون خیلیی زیادن و پر دردسر.
      پیشنهاد من اینه که اگه میخای از پایین ترین سطح کد بنویسی بیای از cmsis استقاده کنی . (cmsis رو سرچ کن) و برای استفاده از این کتابخونه برای arm باید بتونی بعضی کارهارو انجام بدی:
      - باید منابع کلاک و بگیری پخش کنی برای قسمت های مختلف میکرو - بنابراین باید اطلاعات خوبی از datasheet va user manul داشته باشی تو این قسمت. که من برای راحتی هردوتارو پرینت گرفتم.
      - یکم داخل این فایل بگرد stm32f10x.h ببین چی به چیه . چون تو مقداردهی رجیسترها باید بدونی این دیفاین ها برای چیه.
      - اگه بیای کتابخونه cmsis یا spl رو از سایت st دانلود کنی همه فایل های مورد نیاز رو داره

      خوب چون داستان خیلی زیاده پراکنده یچیزایی نوشتم . حالا اگه بخوای به رجیستر مقدار بدی باید اینظور کار کنی :
      کد:
      ;  
        address = (int*)(0x40021000 + 0x18); //address of RCC for gpio clock source
       *address = 0x4;
      0x18 : مقدار ofset تو یوزر منوال میتونی ببینیش.
      0x40021000 : آدرس پایه rcc . از رو دیتاشیت میتونی پیداش کنی.

      اینجا داشتم یکی از رجیسترهای rcc رو برای میکرو تنظیم میکردم.


      و حداقل فایل main مورد نیاز برای راه اندازی میکرو :
      کد:
      #include "stm32f10x.h"
      #include "stm32f10x_rcc.h"
      
      
      void init_rcc(void);
      
      
      int main()
      { 
        init_rcc(); 
      
        
        while(1){
         
          
        }
        
      }
      
      
      
      void init_rcc(void){
        RCC_HSEConfig(RCC_HSE_ON);
        RCC_WaitForHSEStartUp();
        FLASH->ACR = 0x1;
        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
        RCC_PLLCmd(ENABLE);  
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);  
        RCC_HCLKConfig(RCC_SYSCLK_Div1);
        RCC_PCLK2Config(RCC_HCLK_Div1);
        
        
      }
      با cmsis نوشتمش.
      موفق باشید.
      به سمت نور خورشيد حرکت کن،تو ميتوني تابش خورشيد رو حس کني ،حتي اگه کور باشي.
      (پيش به سوي هدف)

      دیدگاه


        #4
        پاسخ : برنامه نویسی STM32 با مقداردهی رجیسترها در ++C

        نوشته اصلی توسط hosseinam نمایش پست ها
        میخواستم از پایین ترین سطح کد نویسی اس تی ام سر در بیارم
        جناب مهندس خیلی ممنون از وقتی که گذاشتید.
        کاملا حق با شماست، با این طرز تفکر (کدنویسی از صفر) نمیشه خیلی ادامه داد!
        اما هراس من از اینه که چون موقعی داری از توابع سطح بالا استفاده میکنی و نمیدونی طرف چی نوشته همه شرایط در نظر گرفته نمیشه و میکرو در زمان اجرا و در یک شرایط خاص یه رفتار نامشخص از خودش بروز میده! مخصوصا توی پروژه هایی که از حالت آموزشی و تفننی خارج شده! (گذشته از مسائل بهینه و سبک بودن کد!).
        و از طرفی سر در آوردن از روش کار این کتابخانه ها و مسلط شدن به اونها، دردسرش کم از سروکله زدن با رجیسترها نیست!
        توی بعضی از پروژه ها هم تعداد پریفرالهای استفاده شده اون قدری هست که کد نویسی رجیسترهاش قابل تحمل باشه. چند تا تابع (مثل اون کاری که شما توی کدتون انجام دادید) تعریف میکنی ودیگه رجیسترها رو نمیبینی، ولی به ازاش به کدت و میکروت تسلط داری!
        من آخرین پروژه ام رو که با XMEGA هست با همین رجیسترها کار کردم و تا اینجا 65 کیلوبایت فلش شده، از اونجایی که چیپهاش، وضعیت قیمت و فروش مناسبی ندارند، میخوام به STM32 مهاجرت کنم.
        حالا از اظهار فضل خودم که بگذرم ...
        بابت کدی که زحمت کشیدید ممنون، تستش میکنم اگه مشکلی بود مزاحمتون میشم!
        در مورد او سوال سوم من (توی کامنت 1)اگه امکانش هست یه توضیحی بفرمائید، گزینه هاش و ضروریاش.
        و من توی اون حداقل حالتی که شما فرمودید (استفاده از CMSIS) توی اون شکل چه تیکهایی رو باید فعال کنم؟
        اجرکم عند الله ...
        ◙◙◙◙◙ میخوام به دوستان یه کتاب معرفی کنم! وقت کردید، بخونید - اسمش هست قرآن، سال نشر 10، نویسنده: خدا . ◙◙◙◙◙

        دیدگاه


          #5
          پاسخ : برنامه نویسی STM32 با مقداردهی رجیسترها در ++C

          نوشته اصلی توسط ubub نمایش پست ها
          جناب مهندس خیلی ممنون از وقتی که گذاشتید.
          کاملا حق با شماست، با این طرز تفکر (کدنویسی از صفر) نمیشه خیلی ادامه داد!
          خواهش میکنم دوسته عزیز.
          بله حق با شماست - همین که بدونی چه اتفاقی تو رجیسترها میاوفته خیلی خوبه و به قول شما حرکات نامشخص میکرو رو هم میتونی تشخیص بدین.و همینطور تخصصتون بالا میره. البته خودمم میخوام ببینم منطق فلان تابع چیه و چیکار میکنه میرم داخل تابع رجیستر ها رو میبینم و کارشونو متوجه میشم.
          مهاجرات به stm تصمیم خوبی هست . ولی اگه بیای cmsis یاد بگیری به راحتی میتونید روی lpc و دیگر میکروهای که از معماری arm استفاده میکنن سوپیچ بشید - چون یکی از سیاست های arm برای شرکت ها کتابخونه cmsis هست.
          من بهتون پیشنهاد میدم که بعد اینکه رجیسترها رو فهمیدید بیاید cmsis رو خوب یاد بگیرید که همه ی کارهای مورد نیاز رو داره- حالا میتونید به راحتی با کیوب کار کنید و به راحتی اشکال یابی کنید.
          راستش من مستقیما از avr رفتم arm نمیدونم xmega چطوری هست - اگه خیلی پایه میگم به این دلیل هست وگرنه شما بزرگوارید

          -ما در خدمت شما هستیم اگه بتونیم پاسخ خواهیم داد
          -متاسفانه من با کیل کار نمیکنم . دارم با IAR کار میکنم.ضروری ترین فایل ها برای راه اندازی میکرو که دیفاین ها و آدرس ها رو معرفی کرده باشن اینها هستن که باید در کنار پروژه باشن:
          کد:
          #include "stm32f10x.h"
          #include "stm32f10x_gpio.h"
          #include "stm32f10x_rcc.h"
          فایل stm32f10x_gpio.h هم برای gpio هست (پین میکرو) که مثلا بخای اولین پروژه led blink رو بنویسی .
          مکان فایل core_cm3.h رو هم به کامپایلرتون بشناسونین .تا بقیه فایلها بتونن اینو به خودشون اضافه کنن.البته فایل startup هم ضروری هست ولی من خودم تا قبل اینکه بیام از اینتراپت ها استفاده کنم و ازش استفاده نکردم.چون فقط بردارهای اینتراپت که به اسمبلی نوشتن رو داخلشون دارن.
          من این فایل ها رو براتون گذاشتم که خودم از سایت st گرفته بودم و با هزار دردسر فهمیدم ورژن قدیمی هست و کامپایلر خطا میداد و بعضی فایل های جدید رو جایگذین کردم باهاش.

          خوب اینا همه فایل هایی هستن که cmsis برامون نوشته . ولی اگه خودتون میخایید از پایه و بدونه استفاده از cmsis کد زنی تونو شروع کنید باید زحمت نوشتن این فایل هارو هم بکشید .
          از دیتا شیت و یوزمنوال کمک بگیرید و آدرس ها رو دیفانشونو بنویسید بعد با روش پست قبلیم بیاید دونه دونه رجیسترها رو مقدار دهی کنید . از کلاک و فلش و غیره ... . در این حالت شما به یه فایل main نیاز دارید و حالا به هدرهای مختلفی که قرار کدتون رو داخلش بنویسید و دسته بندی کنید.
          به هیچ فایل کمکی نیاز نخواهی داشت که اضافه کنید به پروژه جز اطلاعاتتون از دیتاشیت و یوزر منوال میکروی مورد نظر و تخصصتون از کد زنی.میتونید روش آدرس دهی رو از فایل include "stm32f10x.h"هم متوجه شید.
          موفق باشید.

          فایل cmsis مورد نیاز:
          Libraries.rar
          جدیدترین ویرایش توسط hosseinam; ۱۱:۵۰ ۱۳۹۶/۰۹/۱۹.
          به سمت نور خورشيد حرکت کن،تو ميتوني تابش خورشيد رو حس کني ،حتي اگه کور باشي.
          (پيش به سوي هدف)

          دیدگاه


            #6
            پاسخ : برنامه نویسی STM32 با مقداردهی رجیسترها در ++C

            عرض سلام یلدایی خدمت همه اساتید،
            مخلص جناب hosseinam هستیم!
            آقا ما در پی پیشرفت شتابان و سریع، حلزون وارمون، به مبحث Interrupt در STM32F10x رسیدیم!
            دوستان و اساتید گرانقدر لطف کنند اگه امکانش هست یه شمای کلی از مکانیزم کنترل وقفه ها در STM32F10x بیان بفرمایند:

            آنچه بنده حقیر سرچ کردم عرض میکنم، اساتید تصحیح بفرمایند :


            (قابل توجه کهنه کارای ATMEL-8 و تازه کارای 32 STM ):
            1- اول عرض کنم که Interrupt ها توی میکروهای ARM خودشون شدند زیر مجموعه بحث جامع تری به نام
            Exception !
            یعنی ما یکسری وضعیت Exception داریم که اگر اتفاق بیافتند، روال اجرای عادی برنامه رو متوقف میکنند و باید توسط پردازنده سرویس دهی شوند و Interrupt ها گروهی از این Exception ها هستند. (البته فکر کنم Exception ها در عمل موضوع جدیدی نیستند! فقط اسمشون عوض شده، شما میتونید فکر کنید یک سری Interrupt خیلی مهم هستند).

            2-طبق روال همه میکروها هر پریفرالی که قابلیت کار با وقفه ها رو داشته باشه، توی بخش رجیسترهای کنترلی مربوط به خودش، چندتا بیت برای تنظیم وقفه هاش داره! مثلا برای USART2 بیتهای 4 تا 8 رجیستر USART2_CR1 (خوب از اینها بگذریم).

            3-بخش کنترل کننده Exception ها و وقفه ها توی STM32 اسمش هست NVIC ،
            که یکسری رجیستر داره که ما میتونیم با تنظیم اونها تعیین کنیم که کدام Exception ها فعال باشند و همچنین Prioroiy هر کدام چقدر باشد!
            الف - فعال و غیر فعال و وضعیت : ISER0-ISER2 _ ICER0-ICER2 _ ISPR0-ISPR2 _ ICPR0-ICPR2 _ IABR0-IABR2
            ب - تعیین سطح اولویت : IPR0-IPR16 _ SHPR1-SHPR3
            پ - گروه بندی اولویتها ... .

            4- هر Exception ( یا هر منبع تولید کننده وقفه ) توی NVIC با یک شماره شناخته میشه (که توی منوال هر قطعه، باید پیدا کنید!) و همچنین مطابق با هر شماره ( شماره Exception مربوطه در NVIC ) یک بیت در رجیسترهای الف جهت فعال و غیر فعال سازی و یک فیلد چهار بیتی در رجیسترهای ب جهت تعیین سطح اولویت وقفه وجود دارد! (از 4 بیت برمی آید که 16 سطح اولویت وقفه قابل تنظیم وجود دارد).
            و مثلا برای USART2 این شماره برابر 38 است.

            5 - همون طور که میدونید قراره پس از وقوع هر کدام از Exception ها، روال عادی اجرای برنامه متوقف بشه و Exception مربوطه سرویس دهی بشه، پس ما به ازای هر Exception نیاز به یک زیر روال مخصوص داریم تا در زمان وقوع، پردازنده به نحوی به اون زیر روال بره و با اجرای اون زیر روال مخصوص، اون Exception رو سرویس دهی کنه و بعد پردازنده دوباره به وضعیت عملکرد عادی خودش برگرده!
            پس ما کلی آدرس رفت داریم و کلی آدرس برگشت (با توجه به وقوع اینتراپتهای تو در تو!).
            خوب در اینجا 4 تا هویت وجود داره:
            5-1- روالهای سرویس دهی Exception ها (که در هر جایی از فضای فلش میتونند باشند فقط باید به نحوی آدرسشون رو بدونیم)
            5-2- فضای پشته سخت افزاری (که محتوی آدرسهای برگشت و متغیرهای محلی مربوط به این زیر روالهاست و در هر جایی از فضای RAM میتونه باشه و فقط ما باید آدرس شروعش رو بدونیم )
            5-3- Vector Table (جدولی که خانه اول آن به آدرس پشته سخت افزاری اشاره میکند و خانه های بعدی آن به ترتیب شماره Exception ها، به آدرس شروع زیر روال مربوطه اشاره دارد!. این جدول در هر جایی از فضای حافظه فلش یا RAM میتواند قرار گیرد)
            5-4- رجیستر SCB_VTOR (رجیستری در هسته آرم که حاوی آدرس Vector Table میباشد (به عبارتی حاوی آفست آدرس نسبت به آدرس پیش فرض 0x000000) که به صورت داینامیک قابل تنظیم میباشد).
            این چها تا رو که به هم وصل کنید میبینید هیچی گم نمیشه!!!

            6- پس باید بعد از انجام همه تنظیمات بالا بیایید برای همه Exception هایی که فعال کردید و مد نظرتون هست زیر روال بنویسد و آدرس اونها رو تک تک، توی جای مخصوص به اون Exception (با توجه به شماره Exception) توی Vector Table وارد کنید، توی C دستوراتش هست!
            و علاوه آدرس بخشی از حافظه RAM رو که به عنوان پشته سخت افزاری در نظر دارید توی خونه اول Vector Table وارد کنید.

            تقریبا دیگه داره کامل میشه!

            البته هنوز یه مقدار رجیستر مربوط به این بخش مونده!
            تازه یک سری فلگ کلی هم، مربوط به فعال و غیر فعال سازی کلی وقفه ها، توی ثبات وضعیت برنامه (SPR توی مغز آرم) داره!

            7- انشا الله به کمک دوستان بقیه ش هم حله!

            به قول اساتید کار کردن با رجیسترهای ARM واقعا درد سر داره!
            البته همش هم به خاطر غول بودن تراشه نیست! یه بخشش هم مربوط به معماری غیر یکپارچه این نوع میکرو هاست!
            ...

            حالا نقدا اساتید لطف کنند و توضیح بدهند که روالهای سرویس دهی وقفه ها رو چطوری و با چه عنوانی توی Keil تعریف کنیم و آدرس دهی به اونها به چه صورت هست؟ (خواهشا اگر به صورت RAW و استفاده از دستورات رایج C باشه بهتره! و به درک بهتر مکانیزم وقفه ها در STM32 کمک میکنه!)
            و یا اگه نشد حداقل CMSIS باشه! ( البته با یه توضیح اجمالی از روش آدرس دهی ).
            ....
            از این که مطلبم یلدایی شد ببخشید!
            جدیدترین ویرایش توسط ubub; ۲۱:۱۸ ۱۳۹۶/۱۰/۰۶.
            ◙◙◙◙◙ میخوام به دوستان یه کتاب معرفی کنم! وقت کردید، بخونید - اسمش هست قرآن، سال نشر 10، نویسنده: خدا . ◙◙◙◙◙

            دیدگاه


              #7
              پاسخ : برنامه نویسی STM32 با مقداردهی رجیسترها در ++C

              نوشته اصلی توسط ubub نمایش پست ها
              و اساتید باید لطف کنند و توضیح بدهند که روالهای سرویس دهی وقفه ها رو چطوری و با چه عنوانی تعریف کنیم و آدرس دهی به اونها به چه صورت هست؟ (خواهشا اگر به صورت RAW و استفاده از دستورات رایج C باشه بهتره! و به درک بهتر مکانیزم وقفه ها در STM32 کمک میکنه!)
              و یا اگه نشد حداقل CMSIS باشه! ( البته با یه توضیح اجمالی از روش آدرس دهی ).
              ...
              بزرگوارید دوسته عزیز.
              اول بیام یکم در مورد رجیستر ها بگم.
              ببینید آرم در واقع یه معماری هست - یعنی یکسایی میآن این معماری رو مینویسن یا طراحی میکنن بعد شرکت هایی مثل st که قطعات نیمه هادی میسازه میآد این معماری رو میخره از شرکت آرم و بعد طبق همون سیاست ها میکرو رو طراحی میکنه .
              خوب یکی از سیاست های آرم اینه که هر میکرویی باید بیاد از این معماری پیروی کنه و یه بخشی از حافظه ی میکروشو رو به هسته ی آرم بده تا آرم بتونه کارهاشو انجام بده . و بخش دیگه از میکرو امکاناتی هست که خود شرکت کننده به میکرو اضافه میکنه . که این بخش رو باید معماری آرم رهبری کنه.
              خوب حالا برای کار کردن سی پی یو و اتصال به دنیای خارج میکرو باید رجیسترهایی باشه دیگه. معماری آرم هم یسری رجیسترهای مخصوص به خودشو داره و همینطور شرکت سازنده هم رجیسترهای مخصوص به خودشو داره.که باید به هسته آرم وصل شن.
              مثلا شما میتونید تو یوزرمنوال رجیسترهای شرکت st رو ببینید . ولی اگه دقت کنید در بخش nvic در یوزرمنوال هیچ رجیستری نیست و لینک میده به راهنمای proggraming . و اگه رجیستر های nvic رو سرچ بزنید شما لینک میگیرید به سایت آرم که باید اطلاعات اونجا رو هم بدونید تا بیایید ادامه بدید کد نویسی رو.
              رجیستر های مخصوص به معماری آرم توی هدر core_cm3.h میتونید پیدا کنید . و رجیسترهای مربوط به شرکت سازنده میکرو (امکانات میکرو) رو میتونید تو هدر stm32f10x.h پیدا کنید.
              اگه از cmsis استفاده نکنید باید هردو راهنمای مربوطه رو بخونید تا با رجیستر ها به خوبی آشنا شید و بتونید با میکرو کار کنید .
              cmsis اومده همه این رجیسترها رو با توجه به معماری آرم و امکانات میکرو به هم ربط داده و با توجه به توابع فراخانی شده از طرف برنامه نویس به خوبی به همه ی رجیستر ها مقدار میده.


              خوب از اینتراپت حرف زدین و شبیه سازی اون به میکرو هشت بیتی اتمل. اصلا یه شما نیا ایندوتارو باهم مقایسه کن چون سطح انتظاراتت نسبت به این میکرو ی آرم پایین میآد و نمیتونید همشو درک کنید .
              خوب شما برای کار کردن با اینتراپت ها نیاز دارین که اولا ازهدر misc.h بیاید واحد nvic رو بگیرید مقدار دهی کنید و اینتراپت مربوطه رو از اینجا معرفی کنید .
              و بعد فایل استارت آپ میکروی مورد نظر رو به پروژه اضافه کنید . و از داخل این فایل بیاید اسم اینتراپت مربوطه رو پیدا کنید و در main یه تابع از نوع ورودی و خروجی void با همون نام مورد نظر بسازید .
              تا با رخ دادن اینتراپت به تابع مربوطه پرش کنه.
              یه مثال از exti که خودم کار کردم با این واحد رو برات میزارم . تا به خوبی موضوع رو درک کنید.
              کد:
              #include "stm32f10x.h"
              #include "stm32f10x_gpio.h"
              #include "stm32f10x_rcc.h"
              #include "LCDlib.h"
              #include "delay.h"
              #include "misc.h" 
              #include "stm32f10x_exti.h"
              
              int i;
              
              void init_rcc(void);
              void gpiob(void);
              void EXTI9_5_config(void);
              
              void EXTI9_5_IRQHandler (void){
                
                GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_SET);
                
                while(1){
                  
                  if( EXTI_GetITStatus(EXTI_Line7) == SET){
                    lcdPutInt(i);
                    i++;
                    delay_ms(200);
                    lcdClear();
                  }
                }
                
              }
              
              int main()
              {
                
                //init_rcc(); 
                gpiob();
                lcd_init();  
                lcdPutString("EXTI test for STM32:");
                
                
                EXTI9_5_config();
                
                while(1){
                  //GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_SET);
                  
                }
                
              }
              
              
              void EXTI9_5_config()
              {
                
                GPIO_InitTypeDef GPIO_EXTI;
                EXTI_InitTypeDef EXTI_INIT;
                NVIC_InitTypeDef NVIC_InitStructure;
                
                
                RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
                GPIO_EXTI.GPIO_Pin = GPIO_Pin_6;
                GPIO_EXTI.GPIO_Mode = GPIO_Mode_IN_FLOATING;
                GPIO_EXTI.GPIO_Speed = GPIO_Speed_10MHz;
                GPIO_Init(GPIOA , &GPIO_EXTI);
                
                RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
                GPIO_EXTILineConfig(GPIO_PortSourceGPIOA , GPIO_PinSource6);
                
                EXTI_INIT.EXTI_Line = EXTI_Line6 ;
                EXTI_INIT.EXTI_Mode = EXTI_Mode_Interrupt;
                EXTI_INIT.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
                EXTI_INIT.EXTI_LineCmd = ENABLE;
                EXTI_Init(&EXTI_INIT);
                
                /* Enable and set EXTI0 Interrupt to the lowest priority */
                NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
                NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
                NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
                NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
                
                NVIC_Init(&NVIC_InitStructure);
                
              }
              
              
              void init_rcc(void){
                RCC_HSEConfig(RCC_HSE_ON);
                RCC_WaitForHSEStartUp();
                FLASH->ACR = 0x1;
                RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
                RCC_PLLCmd(ENABLE);  
                RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);  
                RCC_HCLKConfig(RCC_SYSCLK_Div1);
                RCC_PCLK2Config(RCC_HCLK_Div1);
                
                
              }
              
              
              void gpiob(void){
                
                RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
                
                GPIO_InitTypeDef gpiob;
                gpiob.GPIO_Pin = GPIO_Pin_All;
                gpiob.GPIO_Speed = GPIO_Speed_10MHz ;
                gpiob.GPIO_Mode = GPIO_Mode_Out_PP ;
                GPIO_Init(GPIOB, &gpiob);
                
                
              }
              کد با CMSIS نوشته شد.
              در ضمن شما با میکروتون اولین پروژه که Blink رو انجام دادین ؟واحد های کلاک رو راه انداختین؟ خواسته بودین با رجیستر ها این کارارو انجام بدین. خواشتم ببینم اینارو انجام دادین یا خیر.

              از این لینک هم میتونی از هدر مربوط به LCD که تو این پروژه استفاده کردم رو بگیری:

              https://www.eca.ir/forums/thread78932.html
              به سمت نور خورشيد حرکت کن،تو ميتوني تابش خورشيد رو حس کني ،حتي اگه کور باشي.
              (پيش به سوي هدف)

              دیدگاه


                #8
                پاسخ : برنامه نویسی STM32 با مقداردهی رجیسترها در ++C

                Re. post 7
                مهندس جان خیلی ممنون از وقتی که گذاشتی!
                اول عرض کنم که بنده قصد مقایسه ARM رو با 8051 ندارم که مثل مقایسه فیل و فنجون میمونه!!
                و فقط میخوام یه جورایی مطلبی جمع بشه واسه اونهایی که میخوان با همون تفکر کار با Register ها از AVR به STM32 مهاجرت کنند، (از جمله خودم)،
                واسه همین سعی کردم بگم که لازم نیست همه دونسته هاتون رو راجع به اینتراپتها بیرون بریزید!
                ...
                راجع به نوشته تون باید عرض کنم که من خودم پردازندم 8 بیتی هست و یه خورده طول میکشه تا بفهمم چی نوشتید!
                استفاده میکنم، مشکلی بود، مجدد مطرح میکنم.
                ...
                و فرمودید:
                در ضمن شما با میکروتون اولین پروژه که Blink رو انجام دادین ؟واحد های کلاک رو راه انداختین؟ خواسته بودین با رجیستر ها این کارارو انجام بدین. خواستم ببینم اینارو انجام دادین یا خیر؟

                جناب مهندس من نمیدونم مطابق نظر شما شده یا نه؟
                کد رو میزارم ببینید شده یا نه؟
                ( فقط به جای آدرس از Define نام رجیسترها استفاده کردم - رو سخت افزار هم تست کردم):

                #include "stm32f10x.h"

                int main(void)
                {
                int32_t dly=0;
                while(dly<10000)dly+=1; // Caution wait
                dly=0;

                RCC->CR |= 0X00000081; // enable HSI
                RCC->CR &= 0X0000FF83; // disable all other clock sources
                RCC->CFGR = 0;

                RCC->APB2ENR |= 0X00000010; // ENABLE PORTC CLOCK
                GPIOC->CRL &= 0XFFFFFFF0;
                GPIOC->CRL |= 0X00000002; // Config c.0 as output_push-pull_Low-Freq

                while(1)
                {
                GPIOC->BSRR = 0X00000001; // set c.0
                while(dly<100000)dly+=1;
                dly=0;
                GPIOC->BSRR = 0X00010000; // Reset c.0
                while(dly<100000)dly+=1;
                dly=0;
                }
                }


                اگه که شده، من افزایش فرکانس تا 48MHz رو با PLL و راه اندازی چند تا پریفرال مثل SPI و USART رو هم با مقداردهی رجیسترهاشون راه انداختم. (نه اینکه کار مهمی کرده باشم! واسه تازه کار بودن عرض میکنم!).
                جدیدترین ویرایش توسط ubub; ۲۰:۰۵ ۱۳۹۶/۱۰/۱۵.
                ◙◙◙◙◙ میخوام به دوستان یه کتاب معرفی کنم! وقت کردید، بخونید - اسمش هست قرآن، سال نشر 10، نویسنده: خدا . ◙◙◙◙◙

                دیدگاه


                  #9
                  پاسخ : برنامه نویسی STM32 با مقداردهی رجیسترها در ++C

                  نوشته اصلی توسط ubub نمایش پست ها
                  اگه که شده، من افزایش فرکانس تا 48MHz رو با PLL و راه اندازی چند تا پریفرال مثل SPI و USART رو هم با مقداردهی رجیسترهاشون راه انداختم. (نه اینکه کار مهمی کرده باشم! واسه تازه کار بودن عرض میکنم!).
                  اولا من سعی میکنم توضیحی که تو هر پست میدم تا جایی که میدونم پایه ای و کامل باشه تا بتونم فهم ی که خودم دارم از موضوع رو به دوستان انتقال بدم (هرچند اطلاعات کمی که دارم) پس خدایی ناکرده دوستان از حرفام بد برداشت نکنن -هر چند که خود دوستان استاد بنده هستن.

                  کدتون خانایی خوبی داره و خوب تونستین رجیسترها رو بفهمید.
                  فقط این نکته رو در نظر داشته باشید که وقتی که فرکانس و افزایش میدین- باید فرکانس فلش رو طبق گفته ی دیتاشیت تقسیمش کنید. فک کنم فلش به اونقدر فرکانس بالا نیازی نداره.خودم یکم داستان کشیدم تا این موضوع رو فهمیدم.وگرنه کداتون با فرکانس بالا کار نمیکنه .هرچند فرکانس رو افزایش دادید.
                  FLASH->ACR = 0x1;

                  این خیلی خوبه که درک خوبی از رجیسترها دارید و اول کار تونستین با این ماژول های میکرو کار کنید.

                  در ضمن هرجایی از بحث پست قبلی رو نگرفتید منظورمو- بپرسید تا جایی که میدونم براتون بگم.
                  توضیح کوتاه :
                  اینتراپت ها شبیه اینتراپت های کدویژن هست. ولی قبلش باید فعال کنید اینتراپت مورد نظر رو .
                  اینتراپت ها تو فایل اسمبلی startup_stm32f10x_hd.s تعریف شدن. مثل هدر "stm32f10x.h" . باید به پروژه ها اضافه شن.اینتراپت هایی که میخوایین ازش استفاده کنید باید اسمشو از startup بگیرید و همنامش یه تابع تو main بنویسید.

                  اگه این رجیسترها رو از یوزرمنوال اس تی ام میکروتون گرفتید- هیچ رجیستری از NVIC رو نمیتونید توش پیدا کنید. چون رجیستر NVIC برای معماری آرم هست.نه شرکت سازنده میکرو.

                  چخبر از CMSIS ؟؟ هنوز تصمیم نگرفتین بیاید رو این کتابخونه کار رو شروع کنید؟؟چون کد بالاتون رو CMSIS نوشته . و الان شما غیر مستقیم دارین از سیاست های CMSIS استفاده میکنید.
                  به سمت نور خورشيد حرکت کن،تو ميتوني تابش خورشيد رو حس کني ،حتي اگه کور باشي.
                  (پيش به سوي هدف)

                  دیدگاه


                    #10
                    پاسخ : برنامه نویسی STM32 با مقداردهی رجیسترها در ++C

                    نوشته اصلی توسط hosseinam نمایش پست ها
                    چخبر از CMSIS ؟؟ هنوز تصمیم نگرفتین بیاید رو این کتابخونه کار رو شروع کنید؟؟چون کد بالاتون رو CMSIS نوشته . و الان شما غیر مستقیم دارین از سیاست های CMSIS استفاده میکنید
                    سلام،
                    جناب مهندس بحث پاچه خواری نیست، کلا خیلی آقایی! البته اینجا آقا زیاد داریم، جناب سپهر63 هم بنده رو زیاد راهنمایی فرمودند!
                    خوشحالم که تا حدودی تائید فرمودید که برنامه سطح پائین است! ولی راستش رو بخواهید خودم خیلی مطمئن نیستم!
                    به عکسی که از صفحه برنامه گرفتم توجه فرمائید:

                    موقعی سطح پائین می*بود که اون همه سورس و هدر و ... بهش اضافه نمیشد!
                    البته من حتما اصرار ندارم که همه اونها رو حذف کنم و برنامه رو صفر تا صد خودم بنویسم!
                    همین که سبکه و زود کامپایل میشه خودش خوبه!
                    هرجایی از بحث پست قبلی رو نگرفتید ....
                    راستش رو بخواهید من فعلا چیز زیادی از کد و توضیحاتتون متوجه نشدم، به چند دلیل:
                    1- هنوز فرصت نکردم درست مطالعه شون کنم.
                    2- فکر میکنم شما با IAR نوشتید و من دارم با KEIL کار میکنم ...
                    3- همین که اسم چندتا فایل هدر و تابع رو توی نوشتهتون میبینم، موضع میگیرم و میگم جان رجیسترها به خطر افتاد !! ...
                    ...
                    البته به هر حال من حداکثر استفاده رو از مطالبتون میبرم مخصوصا از طرز نگاه Low Level تون به معماری ARM.
                    و حالا دارم NVIC رو مطالعه میکنم، از رفرنسهای کرتکس و Programming manual استفاده میکنم.
                    و یه کم دیگه کار کنم مورد 5 رو توی پست 6 به همون روش رجیستری تکمیل میکنم، البته به کمک شما!
                    ...
                    و راجع به CMSIS عرض کنم که بهترین استفاده ای که در حال حاضر من میتونم از این کتابخانه داشته باشم،
                    هندل کردن همین بحث Interrupt ها هست، که متأسفانه هنوز موفق به استفاده از اون توی Keil نشدم،
                    حتی هنوز نمیدونم چطوری به کامپایلر بفهمونم که فلان تابعی که نوشتم مربوط به سرویس دهی فلان وقفه هست!!
                    فکر میکنم توی CMSIS یه ربطی به این تابع داشته باشه:
                    void NVIC_SetVector (IRQn_Type IRQn, uint32_t vector)
                    بقیه شون هم اینجان:
                    جدیدترین ویرایش توسط ubub; ۰۱:۳۲ ۱۳۹۶/۱۰/۰۳.
                    ◙◙◙◙◙ میخوام به دوستان یه کتاب معرفی کنم! وقت کردید، بخونید - اسمش هست قرآن، سال نشر 10، نویسنده: خدا . ◙◙◙◙◙

                    دیدگاه


                      #11
                      پاسخ : برنامه نویسی STM32 با مقداردهی رجیسترها در ++C

                      نوشته اصلی توسط hosseinam نمایش پست ها
                      فقط این نکته رو در نظر داشته باشید که وقتی که فرکانس و افزایش میدین- باید فرکانس فلش رو طبق گفته ی دیتاشیت تقسیمش کنید. فک کنم فلش به اونقدر فرکانس بالا نیازی نداره.

                      جناب مهندس سلام،
                      اول تشکر کنم از مطالبتون راجع به اینتراپتها! ،،،،،،،،،، شما به این خوبی توضیح دادید و من ناشکر، دور کلام میچرخیدم!!!!!
                      هم از راهنمایی هاتون و هم از کدتون استفاده کردم و اینتراپتها رو توی CMSIS راه انداختم!
                      و از دیروز بخش اصلی پروژه ام رو به STM32 اکسپورت کردم، فقط یک سری آپشن درشت مونده!
                      ...
                      چندتا نکته:
                      1- اون بخشی از گفته تون رو که نقل قول کردم، جسارتاً مشکل داره (ببخشید، بحث همفکریه):
                      همون طور که میدونید اکثر پردازنده ها زور میزنند که همه دستورالعملهاشون رو توی یه کلاک ساعت انجام دهند، برای این منظور باید توی هر کلاک ساعت به دستور و یا دیتای جدیدی ( در اینجا از حافظه فلش) دسترسی داشته باشند و این به این معنی است که کلاک حافظه فلش باید بزرگتر مساوی کلاک پردازنده باشه!
                      مطابق دستور شما، بخش فلش دیتاشیت رو که مطالعه کردم، گفته بود این wait state هست (Latency)، نه prescaler !
                      یعنی به عبارتی ایجاد تأخیر عمدی در خواندن خروجی حافظه فلش به منظور سپری شدن زمان دستیابی آن! ( همون طور که میدونید access time یکی از مشخصات حافظه های فلش هست)،
                      البته به هر حال من خیلی ازتون ممنونم چون ازش بی خبر بودم!
                      2- قبل از اینکه دیتاشیت رو بخونم گفتم در عمل چک کنم ببینم این گفته درسته یا نه؟!
                      "وگرنه کداتون با فرکانس بالا کار نمیکنه .هرچند فرکانس رو افزایش دادید."
                      ... .
                      برای تست، همون برنامه LED Blink رو که بالا گذاشتم، مقدار 100000 رو تا 10000000 افزایش دادم تا با فرکانس 8 مگ یه تآخیر بزرگ ایجاد شه و بعد من با کرنومتر ثبتش کنم،
                      و مجدد فرکانس رو تا 72 مگ ببرم بالا ببرم و برنامه رو تغییر ندم و دوباره زمان رو ثبت کنم،
                      اگه همه چیز درست باشه، زمان ثبت شده اولی باید 9 برابر زمان ثبت شده دومی باشه، ( که دقیقا 9 برابر بود).
                      حالا این مهم نیست!
                      یه چیز عجیبی که دیدیم این بود:
                      توی 8 مگ، زمان روشنی 17.5 ثانیه شده بود ولی زمان خاموشی 13.7
                      و توی 72 مگ، روشنی 1.9 ثانیه و خاموشی 1.54
                      زمان روشنی و خاموشی برابر نبودند و تفاوت فاحشی دارند ( چند بار تست کردم و هر بار گذاشتم 20 بار نوسان کرد و همه رو ثبت کردم)!!!!!
                      به نظر شما علت چیه؟؟؟
                      (برنامه رو که میبینید، همه چیز مساوی است، وقفه ای چیزی هم فعال نیست!!)
                      ◙◙◙◙◙ میخوام به دوستان یه کتاب معرفی کنم! وقت کردید، بخونید - اسمش هست قرآن، سال نشر 10، نویسنده: خدا . ◙◙◙◙◙

                      دیدگاه


                        #12
                        پاسخ : برنامه نویسی STM32 با مقداردهی رجیسترها در ++C

                        نوشته اصلی توسط ubub نمایش پست ها
                        توی 8 مگ، زمان روشنی 17.5 ثانیه شده بود ولی زمان خاموشی 13.7
                        و توی 72 مگ، روشنی 1.9 ثانیه و خاموشی 1.54
                        زمان روشنی و خاموشی برابر نبودند و تفاوت فاحشی دارند ( چند بار تست کردم و هر بار گذاشتم 20 بار نوسان کرد و همه رو ثبت کردم)!!!!!
                        اولا دلیل دیر پاسخ دادنم بخاطر از دست دادن پدربزرگم بود که درگیر مراسمات ایشون هستیم. به هر حال عذر خواهی میکنم.
                        دقیقا منم همین مشکل رو داشتم رو BLINK که با تاخیر ها شون با هم فرق میکرد. و من 4 روز درگیر این بودم که چرا این اتفاق داره میاوفته.
                        چون وقتی CMSIS میاومد rcc رو کانفیگ میکرد همچی خوب بود - ولی من rcc رو کانفیگ میکردم تاخییر میدیدم تو blink . بعد کلی گشتن فهمیدم از رجیستر flash->asr هست. که باید تو فرکانس های مختلف جداگونه تنظیم شه.کلا منظورم از کدتون کار نمیکنه همین بوده که کد اشتباه و با تاخییر کار میکنه.

                        همون طور که میدونید اکثر پردازنده ها زور میزنند که همه دستورالعملهاشون رو توی یه کلاک ساعت انجام دهند، برای این منظور باید توی هر کلاک ساعت به دستور و یا دیتای جدیدی ( در اینجا از حافظه فلش) دسترسی داشته باشند و این به این معنی است که کلاک حافظه فلش باید بزرگتر مساوی کلاک پردازنده باشه!
                        مطابق دستور شما، بخش فلش دیتاشیت رو که مطالعه کردم، گفته بود این wait state هست (Latency)، نه prescaler !
                        یعنی به عبارتی ایجاد تأخیر عمدی در خواندن خروجی حافظه فلش به منظور سپری شدن زمان دستیابی آن! ( همون طور که میدونید access time یکی از مشخصات حافظه های فلش هست)،
                        البته به هر حال من خیلی ازتون ممنونم چون ازش بی خبر بودم!
                        راستش من از access time که یکی از مشخصات فلش هست خبر ندارم. تو یوزرمنوال دوتا کلمه غیروابسته ترجمش کردم.
                        و دقیقا منظورم همین بود که گفتین/ البته من خیلی کلی فهمیدم و کلی براتون نوشتم.پس این waitstate یه زمان تاخیر برای پردازنده هست که منتظر میمونه تا فلش داده ره مثلا برای پردازنده بیاره . درسته؟
                        اگه منبعی داری برای مطالعه بیشتر ممنونتون میشم.

                        من این مشکل شما رو با تغییر asr حل کردم.دیگه بیشتر از این انگار نیاز نمیدیدم از asr بدونم.حالا شما باعث شدین در اولین فرصت بیشتر مطالعه کنم .
                        جدیدترین ویرایش توسط hosseinam; ۱۰:۱۲ ۱۳۹۶/۱۰/۰۶.
                        به سمت نور خورشيد حرکت کن،تو ميتوني تابش خورشيد رو حس کني ،حتي اگه کور باشي.
                        (پيش به سوي هدف)

                        دیدگاه


                          #13
                          پاسخ : برنامه نویسی STM32 با مقداردهی رجیسترها در ++C

                          نوشته اصلی توسط hosseinam نمایش پست ها
                          وقتی CMSIS میاومد rcc رو کانفیگ میکرد همچی خوب بود - ولی من rcc رو کانفیگ میکردم تاخییر میدیدم تو blink . بعد کلی گشتن فهمیدم از رجیستر flash->asr هست.
                          جناب مهندس سلام،
                          اول درگذشت پدربزرگتون رو تسلیت میگم! یه پیام خصوصی هم در همین رابطه فرستادم، لطفا مطالعه بفرمائید.
                          ... .
                          مهندس جان باز هم جور در نمییاد؟!
                          اگه توجه کنید میبینید که اون عدم تقارن زمان روشنی و خاموشی (Duty != 50%) هم توی کلاک بالا (72M) هست و هم توی کلاک پائیین(8M) ؟؟!!
                          و این درحالیست که دیتا شیت گفته برای کلاک زیر 24 مگ بحث wait state مطرح نیست و باید برابر صفر باشه!!
                          These options should be used in accordance with the Flash memory access time. The wait states represent the ratio of the SYSCLK (system clock) period to the Flash memory access time
                          zero wait state, if 0 < SYSCLK ≤ 24 MHz
                          one wait state, if 24 MHz < SYSCLK ≤ 48 MHz
                          two wait states, if 48 MHz < SYSCLK ≤ 72 MHz
                          من خودم هنوز وقت نکردم روش کار کنم، میگم شاید مال قرار دادن اون اعداد بزرگ (10000000) بدون راهنما برای کامپایلر باشه (یعنی آخرش L ی چیزی اضافه میکردیم)؟؟
                          ...
                          جناب مهندس من همین بین به یه چیز دیگه هم پی بردم!!!
                          و اون اینه که اگه توی این بحث خوب دقیق بشیم مبینیم که گفته:
                          توی فرکانسهای بالا لازمه که پردازنده به اندازه یک یا دو تا wait state منتظر پاسخ Flash بشه!
                          و به احتمال زیاد این wait state ها هر کدومش به اندازه یک کلاک ساعت پردازنده هستند!
                          و یعنی اگر ما یک بلاک دستور داشته باشیم که قرار باشه توی اون بلاک به صورت پشت سر هم از حافظه فلش چیزی بخونیم، لازمه که به ازای هر کدوم از اون خوندنها پردازنده یکی دو کلاک صبر کنه !!!
                          و این چندتا معنی داره:
                          1 - این که حداکثر سرعت Flash توی میکروهای STM32 برابر 24MHz است!
                          2 - این که توی ARM همین که کلاک پردازنده تا 72M رفت بالا نباید انتظار داشته باشیم که سرعت انجام همه کارها (حتی بعضا اجرای دستورات ساده) در داخل اون به همین اندازه باشه (همون طور که توی PC هم کلی از وقت پردازنده معطل هارد میشه!)
                          3 - اینکه اون یکی دو wait state برای Flash خودش مثل تقسیم فرکانس و prescaler عمل میکنه و گفته شما توی پست 9 به لحاظ مفهومی درسته !
                          جدیدترین ویرایش توسط ubub; ۱۱:۱۱ ۱۳۹۶/۱۰/۰۸.
                          ◙◙◙◙◙ میخوام به دوستان یه کتاب معرفی کنم! وقت کردید، بخونید - اسمش هست قرآن، سال نشر 10، نویسنده: خدا . ◙◙◙◙◙

                          دیدگاه


                            #14
                            پاسخ : برنامه نویسی STM32 با مقداردهی رجیسترها در ++C

                            نوشته اصلی توسط ubub نمایش پست ها
                            اول درگذشت پدربزرگتون رو تسلیت میگم! یه پیام خصوصی هم در همین رابطه فرستادم، لطفا مطالعه بفرمائید.
                            ... .
                            مهندس جان باز هم جور در نمییاد؟!
                            اگه توجه کنید میبینید که اون عدم تقارن زمان روشنی و خاموشی (Duty != 50%) هم توی کلاک بالا (72M) هست و هم توی کلاک پائیین(8M) ؟؟!!
                            و این درحالیست که دیتا شیت گفته برای کلاک زیر 24 مگ بحث wait state مطرح نیست و باید برابر صفر باشه!!
                            سلام. ممنونم.
                            پست قبلیتونو خوب نخونده بودم و بد متوجه شدم منظورتون چیه . الان که فهمیدم منظورتون چی بوده.منم با Cmsis این کد شمارو که برای چشمک زن ال ای دی بود رو نوشتم برای عدد 100000000 همین اتفاق افتاد.
                            کد چشمک زن رو تو چهار مرحله پشت هم نوشتم نتایج فرق کرد. حدس زده بودم شاید بخاد حلقه رو برگرده بالا این اتفاق براش میاوفته .
                            راستش دلیلشو منم نفهمیدم چرا اینجوریه.برای همین یه تاپیک زدم تو سایت stm تا ببینم کسی چیزی میگه یا نه.



                            اینم از کد cmsis :
                            کد:
                            #include "stm32f10x.h"
                            #include "stm32f10x_gpio.h"  // for Enable LCD
                            #include "stm32f10x_rcc.h"   //for Enable LCD
                            #include "LCDLib.h"
                            #include "delay.h"
                            
                            
                            void GPIOC_init(void);
                            
                            
                            int main()
                            {
                              long dly=0;
                              GPIOC_init();
                              
                              while(1)
                              {
                                GPIO_WriteBit(GPIOB,GPIO_Pin_0, Bit_SET);
                                while(dly<100000000)dly+=1; 
                                dly=0;
                                GPIO_WriteBit(GPIOB,GPIO_Pin_0, Bit_RESET);
                                while(dly<100000000)dly+=1; 
                                dly=0;
                              }
                              
                            }
                            
                            
                            void GPIOC_init(void)
                            {
                                RCC_APB2PeriphClockCmd  ( RCC_APB2Periph_GPIOB, ENABLE );
                                
                                GPIO_InitTypeDef gpioC;
                                gpioC.GPIO_Mode = GPIO_Mode_Out_PP ;
                                gpioC.GPIO_Pin = GPIO_Pin_All;
                                gpioC.GPIO_Speed = GPIO_Speed_10MHz;  
                                GPIO_Init  (  GPIOB,  &gpioC ); 
                              
                            }
                            اگه شما هم چیزی پیدا کردین در اینباره اینجا بزارید.

                            و اون اینه که اگه توی این بحث خوب دقیق بشیم مبینیم که گفته:
                            توی فرکانسهای بالا لازمه که پردازنده به اندازه یک یا دو تا wait state منتظر پاسخ Flash بشه!
                            آره دیگه منم گفته بودم سرعت فلش به اندازه سی پی یو نیست دیگه.باید کلاک فلش رو براش نسبت به cpu تغییر بدیم دیگه.
                            من فکر میکنم حداکثر سرعت برای حافظه رم میکرو قابل دسترس هست و دیگر بخش های میکرو.مثلا با سرعت بالا داده ها رو تو رم بنویسه یا از رم بخونه برای خودش. ولی از فلش فقط بیاد دستورات رو بخونه ولی برای اجرا از رم کمک بخواد برای سرعت بالا.
                            حالا یه سوال دستورالعمل ها داخل رم هستن یا هردفعه باید بیاد از داخل فلش بخونه؟
                            به سمت نور خورشيد حرکت کن،تو ميتوني تابش خورشيد رو حس کني ،حتي اگه کور باشي.
                            (پيش به سوي هدف)

                            دیدگاه


                              #15
                              پاسخ : برنامه نویسی STM32 با مقداردهی رجیسترها در ++C

                              نوشته اصلی توسط hosseinam نمایش پست ها
                              دستورالعمل ها داخل رم هستن یا هردفعه باید بیاد از داخل فلش بخونه؟
                              مهندس جان سلام
                              خیلی مخلصیم
                              چند وقت نبودید ما دپرس بودیم!
                              دستورالعملها 100 درصد توی Flash هستند
                              و توی اکثر سیستمهای میکروکنترلری دونه به دونه واکشی و دیکد و اجرا میشند
                              فقط توی معماری آرم (هنوز دقیق دقیق مطالعه نکردم) یه سیستم PreFetch (پیش واکشی) داره که اون رو قادر میسازه همزمان با دیکد کردن یه دستورالعمل، دستورالعمل بعدی رو واکشی کنه (فقط واکشی). هنوز نمیدونم این ربطی به سیستم خط لولش داره یا نه؟!
                              و از طرفی فلش مموری تعبیه شده توی STM32 (دقیق مطالعه نکردم) پهنای باند 64 بایت و بافر دوبل PreFetch داره که فعال کردن و استفاده صحیح از اونها هم میتونه این کند بودن فلش رو تا حدودی جبران کنه!
                              راستی راجع به بحث قبلیمون عرض کنم که wait state ها دقیقا prescaler نیستند ولی اینجا تقریبا همچین کاری میکنند
                              و در واقع همون کلاک اصلی CPU به فلش وارد میشه فقط به صورت سخت افزاری Latency ایجاد میشه!
                              ....
                              آقا من دوتا سوال دارم چون ربطی به این بحث نداره توی خصوصی مطرح میکنم، لطفا چک کنید!
                              ◙◙◙◙◙ میخوام به دوستان یه کتاب معرفی کنم! وقت کردید، بخونید - اسمش هست قرآن، سال نشر 10، نویسنده: خدا . ◙◙◙◙◙

                              دیدگاه

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