मैं STM32F303VC डिस्कवरी किट के साथ काम कर रहा हूं और मैं इसके प्रदर्शन से थोड़ा हैरान हूं। सिस्टम से परिचित होने के लिए, मैंने इस MCU की बिट-बैंगिंग स्पीड का परीक्षण करने के लिए एक बहुत ही सरल प्रोग्राम लिखा है। कोड को निम्नानुसार तोड़ा जा सकता है:
- एचएसआई घड़ी (8 मेगाहर्ट्ज) चालू है;
- पीएलएल को एचएसआई / 2 * 16 = 64 मेगाहर्ट्ज प्राप्त करने के लिए 16 के प्रीस्कूलर के साथ शुरू किया गया है;
- PLL को SYSCLK के रूप में नामित किया गया है;
- SYSCLK की निगरानी MCO पिन (PA8) पर की जाती है, और पिन (PE10) में से एक को अनंत लूप में टॉगल किया जाता है।
इस कार्यक्रम का स्रोत कोड नीचे प्रस्तुत किया गया है:
#include "stm32f3xx.h"
int main(void)
{
// Initialize the HSI:
RCC->CR |= RCC_CR_HSION;
while(!(RCC->CR&RCC_CR_HSIRDY));
// Initialize the LSI:
// RCC->CSR |= RCC_CSR_LSION;
// while(!(RCC->CSR & RCC_CSR_LSIRDY));
// PLL configuration:
RCC->CFGR &= ~RCC_CFGR_PLLSRC; // HSI / 2 selected as the PLL input clock.
RCC->CFGR |= RCC_CFGR_PLLMUL16; // HSI / 2 * 16 = 64 MHz
RCC->CR |= RCC_CR_PLLON; // Enable PLL
while(!(RCC->CR&RCC_CR_PLLRDY)); // Wait until PLL is ready
// Flash configuration:
FLASH->ACR |= FLASH_ACR_PRFTBE;
FLASH->ACR |= FLASH_ACR_LATENCY_1;
// Main clock output (MCO):
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
GPIOA->MODER |= GPIO_MODER_MODER8_1;
GPIOA->OTYPER &= ~GPIO_OTYPER_OT_8;
GPIOA->PUPDR &= ~GPIO_PUPDR_PUPDR8;
GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR8;
GPIOA->AFR[0] &= ~GPIO_AFRL_AFRL0;
// Output on the MCO pin:
//RCC->CFGR |= RCC_CFGR_MCO_HSI;
//RCC->CFGR |= RCC_CFGR_MCO_LSI;
//RCC->CFGR |= RCC_CFGR_MCO_PLL;
RCC->CFGR |= RCC_CFGR_MCO_SYSCLK;
// PLL as the system clock
RCC->CFGR &= ~RCC_CFGR_SW; // Clear the SW bits
RCC->CFGR |= RCC_CFGR_SW_PLL; //Select PLL as the system clock
while ((RCC->CFGR & RCC_CFGR_SWS_PLL) != RCC_CFGR_SWS_PLL); //Wait until PLL is used
// Bit-bang monitoring:
RCC->AHBENR |= RCC_AHBENR_GPIOEEN;
GPIOE->MODER |= GPIO_MODER_MODER10_0;
GPIOE->OTYPER &= ~GPIO_OTYPER_OT_10;
GPIOE->PUPDR &= ~GPIO_PUPDR_PUPDR10;
GPIOE->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR10;
while(1)
{
GPIOE->BSRRL |= GPIO_BSRR_BS_10;
GPIOE->BRR |= GPIO_BRR_BR_10;
}
}
कोड को V2 के साथ GNU ARM एंबेडेड टूलचैन का उपयोग करके -O1 ऑप्टिमाइज़ेशन के साथ संकलित किया गया था। एक आस्टसीलस्कप के साथ जांच की गई पीए 8 (मको) और पीई 10 पर संकेत इस तरह दिखते हैं:
SYSCLK सही ढंग से कॉन्फ़िगर किया गया प्रतीत होता है, क्योंकि MCO (नारंगी वक्र) लगभग 64 MHz (आंतरिक घड़ी के त्रुटि मार्जिन पर विचार) का दोलन दिखाता है। मेरे लिए अजीब हिस्सा PE10 (नीला वक्र) पर व्यवहार है। अनंत (1) लूप में प्राथमिक 3-चरण संचालन (यानी बिट-सेट / बिट-रीसेट / रिटर्न) करने के लिए 4 + 4 + 5 = 13 घड़ी चक्र लगते हैं। यह अन्य अनुकूलन स्तरों पर और भी बदतर हो जाता है (जैसे -O2, -O3, ar -Os): सिग्नल के कम भाग में कई अतिरिक्त घड़ी चक्र जोड़े जाते हैं, यानी PE10 के गिरने और उठने वाले किनारों के बीच (LSI को किसी भी तरह से सक्षम करना) इस स्थिति को दूर करने के लिए)।
क्या इस MCU से यह व्यवहार अपेक्षित है? मैं एक कार्य की कल्पना करूँगा, जो 2-4 गुना तेज होने के लिए सेट और रीसेट करने में सरल है। क्या चीजों को गति देने का एक तरीका है?