// ****************************************************************************************** // Project : STM32VLDISCOVERY Sample Program (STM32F100RB) // Program Name : // Programer : // Create date : Version 1.0 H24.10.09 // History : // Laungage : // ****************************************************************************************** // Description // // ****************************************************************************************** #include #include "stm32f10x.h" void Init_clock(unsigned char); void Timer(void); #define PI_HSI_SYSCLK 1 //HSI clock selected #define PI_HSE_SYSCLK 2 //HSE clock selected #define PI_PLL_SYSCLK 3 //PLL clock selected int main(void) { unsigned int LEDlst=0; // ******************* // 1.Initialize // ******************* // (0)Define Clock Init_clock(PI_HSI_SYSCLK); // HSI clock 8 [MHz] // Init_clock(PI_HSE_SYSCLK); // HSE clock 8.000[MHz] // Init_clock(PI_PLL_SYSCLK); // PLL clock 24.000[MHz] // (1)Define APB2(peripheral clock enable register) RCC->APB2ENR = 0x080D; // APB2ENR[2-3]:IOPAEN,IOPBEN I/O port A,B clock enable // APB2ENR[11]:TIM1EN TIM1 Timer clock enable // Set and cleared by software. 0: I/O portn clock disabled, 1:I/O portn clock enabled // (2)Define I/O Port A GPIOA->CRL = 0x11111111; // Port configuration register low (GPIOn[0-7]) GPIOA->CRH = 0x11111111; // Port configuration register high(GPIOn[8-15]) // CNF=00: General purpose output push-pull, MODE=01:Output mode, max speed 10 MHz // GPIOA->IDR // Port input data register (Read Only) IDR[31-16]:Reserved,@IDR[15-0]:Port output data GPIOA->ODR = 0x00000000; // Port output data register ODR[31-16]:Reserved,@ODR[15-0]:Port output data // GPIOA->BSRR // Port bit set/reset registe // GPIOA->BRR // Port bit reset register // GPIOA->LCKR // Port configuration lock register // (3)Define I/O Port B GPIOB->CRL = 0x11111111; // Port configuration register low (GPIOn[0-7]) GPIOB->CRH = 0x11111111; // Port configuration register high(GPIOn[8-15]) // CNF=00: General purpose output push-pull, MODE=01:Output mode, max speed 10 MHz // GPIOB->IDR // Port input data register (Read Only) IDR[31-16]:Reserved,@IDR[15-0]:Port output data GPIOB->ODR = 0x00000000; // Port output data register ODR[31-16]:Reserved,@ODR[15-0]:Port output data // GPIOB->BSRR // Port bit set/reset registe // GPIOB->BRR // Port bit reset register // GPIOB->LCKR // Port configuration lock register // ******************* // 2.Program main // ******************* LEDlst = 1; while(1){ if(LEDlst == 1){ LEDlst = 2; }else if(LEDlst > 127){ LEDlst = 1; }else{ LEDlst = LEDlst * 2; } GPIOA->ODR = LEDlst | (LEDlst << 8); GPIOB->ODR = LEDlst | (LEDlst << 8); Timer(); } } //****************************************************************************************** // Function Name : Init_clock // Title : Initialized System clock // Input : // Output : // Description : //****************************************************************************************** void Init_clock(unsigned char clk_mode) { // ***************************************** // RCC_CFGR(Clock configuration register) Reset value: 0x0000 0000 // ***************************************** // RCC_CFGR[31:27] Reserved, always read as 0. // RCC_CFGR[26:24] MCO: Microcontroller clock output // Set and cleared by software. // 0xx: No clock // 100: System clock (SYSCLK) selected // 101: HSI clock selected // 110: HSE clock selected // 111: PLL clock divided by 2 selected // This clock output may have some truncated cycles at startup or during MCO clock source switching. // RCC_CFGR[23:22] Reserved. // RCC_CFGR[21:18] PLLMUL: PLL multiplication factor // These bits are written by software to define the PLL multiplication factor. // These bits can be written only when PLL is disabled. // Caution: The PLL output frequency must be in the 16-24 MHz range. // 0000: PLL input clock x 2 // 0001: PLL input clock x 3 // 0010: PLL input clock x 4 // 0011: PLL input clock x 5 // 0100: PLL input clock x 6 // 0101: PLL input clock x 7 // 0110: PLL input clock x 8 // 0111: PLL input clock x 9 // 1000: PLL input clock x 10 // 1001: PLL input clock x 11 // 1010: PLL input clock x 12 // 1011: PLL input clock x 13 // 1100: PLL input clock x 14 // 1101: PLL input clock x 15 // 1110: PLL input clock x 16 // 1111: PLL input clock x 16 // RCC_CFGR[17] PLLXTPRE: LSB of division factor PREDIV1 // Set and cleared by software to select the least significant bit of the PREDIV1 division factor. // It is the same bit as bit 0 in the RCC_CFGR2 register, so modifying bit 0 in the RCC_CFGR2 register changes this bit accordingly. // If bits[3:1] in the RCC_CFGR2 register are not set, the PLLXTPRE bit controls if PREDIV1 divides its input clock by 2 (PLLXTPRE=1) or not (PLLXTPRE=0). // This bit can be written only when the PLL is disabled. // RCC_CFGR[16] PLLSRC: PLL entry clock source // Set and cleared by software to select PLL clock source. // This bit can be written only when PLL is disabled. // 0: HSI oscillator clock / 2 selected as PLL input clock // 1: Clock from PREDIV1 selected as the PLL input clock // RCC_CFGR[15:14] ADCPRE: ADC prescaler // Set and cleared by software to select the frequency of the clock to ADC1. // 00: PLCK2 divided by 2 // 01: PLCK2 divided by 4 // 10: PLCK2 divided by 6 // 11: PLCK2 divided by 8 // RCC_CFGR[13:11] PPRE2: APB high-speed prescaler (APB2) // Set and cleared by software to control the division factor of the APB high-speed clock (PCLK2). // 0xx: HCLK not divided // 100: HCLK divided by 2 // 101: HCLK divided by 4 // 110: HCLK divided by 8 // 111: HCLK divided by 16 // RCC_CFGR[10:8] PPRE1: APB low-speed prescaler (APB1) // Set and cleared by software to control the division factor of the APB low-speed clock (PCLK1). // Warning: the software has to set correctly these bits to not exceed 36 MHz on this domain. // 0xx: HCLK not divided // 100: HCLK divided by 2 // 101: HCLK divided by 4 // 110: HCLK divided by 8 // 111: HCLK divided by 16 // RCC_CFGR[7:4] HPRE: AHB prescaler // Set and cleared by software to control the division factor of the AHB clock. // 0xxx: SYSCLK not divided // 1000: SYSCLK divided by 2 // 1001: SYSCLK divided by 4 // 1010: SYSCLK divided by 8 // 1011: SYSCLK divided by 16 // 1100: SYSCLK divided by 64 // 1101: SYSCLK divided by 128 // 1110: SYSCLK divided by 256 // 1111: SYSCLK divided by 512 // RCC_CFGR[3:2] SWS: System clock switch status // Set and cleared by hardware to indicate which clock source is used as system clock. // 00: HSI oscillator used as system clock // 01: HSE oscillator used as system clock // 10: PLL used as system clock // 11: not applicable // RCC_CFGR[1:0] SW: System clock switch // Set and cleared by software to select SYSCLK source. // Set by hardware to force HSI selection when leaving Stop and Standby mode or in case of // failure of the HSE oscillator used directly or indirectly as system clock (if the Clock Security System is enabled). // 00: HSI selected as system clock // 01: HSE selected as system clock // 10: PLL selected as system clock // 11: not allowed switch (clk_mode){ case PI_HSI_SYSCLK : RCC->CFGR = 0x00000000; break; case PI_HSE_SYSCLK : RCC->CFGR = 0x00000001; break; case PI_PLL_SYSCLK : RCC->CFGR = 0x00000002; break; default: RCC->CFGR = 0x00000000; } } //****************************************************************************************** // Function Name : Timer // Title : Wait 1[S] // Input : // Output : // Description : OSC:8[MHz] // : 8MHz / 800(TIM1 Prescaler) / 10000(ARR register) ==> 1Hz(1S) //****************************************************************************************** void Timer(void) { // ********************************* // TIM1_CNT(TIM1 Counter) // ********************************* TIM1->CNT = 0x0000; // ********************************* // TIM1_PSC(TIM1 Prescaler) // ********************************* // // 8[MHz] / 0d800[0x320](Prescaler) ==> 10[KHz] // TIM1->PSC = 0x0320; // ********************************* // TIM1_ARR(TIM1 Auto-reload register) // ********************************* // // 10KHz / 0d10000[0x2710](ARR) ==> 1[S] // TIM1->ARR = 0x2710; // ********************************* // TIM1_CR1(Control register 1) Reset value: 0x00 // ********************************* // TIM1_CR1[15:10] Reserved, always read as 0 // TIM1_CR1[9:8] CKD[1:0]: Clock division // TIM1_CR1[7] ARPE: Auto-reload preload enable // TIM1_CR1[6:5] CMS[1:0]: Center-aligned mode selection // TIM1_CR1[4] DIR: Direction // 0: Counter used as up-counter // 1: Counter used as down-counter // TIM1_CR1[3] OPM: One-pulse mode // 0: Counter is not stopped at update event // 1: Counter stops counting at the next update event (clearing the CEN bit) // TIM1_CR1[2] URS: Update request source // TIM1_CR1[1] UDIS: Update disable. // TIM1_CR1[0] CEN: Counter enable // 0: Counter disabled // 1: Counter enabled TIM1->CR1 = 0x0001; // ********************************* // TIM1_SR(Status register) // ********************************* // TIM1_SR[15:13] Reserved, always read as 0. // TIM1_SR[12] CC4OF: Capture/Compare 4 overcapture flag refer to CC1OF description // TIM1_SR[11] CC3OF: Capture/Compare 3 overcapture flag refer to CC1OF description // TIM1_SR[10] CC2OF: Capture/Compare 2 overcapture flag refer to CC1OF description // TIM1_SR[9] CC1OF: Capture/Compare 1 overcapture flag // This flag is set by hardware only when the corresponding channel is configured in input // 0: No overcapture has been detected. // 1: The counter value has been captured in TIMx_CCR1 register while CC1IF flag was already set // TIM1_SR[8] Reserved, always read as 0. // TIM1_SR[7] BIF: Break interrupt flag // TIM1_SR[6] TIF: Trigger interrupt flag // TIM1_SR[5] COMIF: Commutation interrupt flag // TIM1_SR[4] CC4IF: Capture/compare 4 interrupt flag // TIM1_SR[3] CC3IF: Capture/compare 3 interrupt flag // TIM1_SR[2] CC2IF: Capture/compare 2 interrupt flag // TIM1_SR[1] CC1IF: Capture/compare 1 interrupt flag // If channel CC1 is configured as output: // This flag is set by hardware when the counter matches the compare value, with some exception in // center-aligned mode (refer to the CMS bits from TIM1_CR1 register description). // It is cleared by software. // 0: No match // 1: The content of the counter register TIM1_CNT matches the content of the TIM1_CCR1 register // If channel CC1 is configured as input: // This bit is set by hardware on a capture. // It is cleared by software or by reading the TIM1_CCR1L register. // 0: No input capture has occurred // 1: The counter value has been captured in the TIM1_CCR1 register (an edge has been detected on // IC1 which matches the selected polarity). // TIM1_SR[0] UIF: Update interrupt flag // This bit is set by hardware on an update event. It is cleared by software. // 0: No update occurred. // 1: Update interrupt pending. This bit is set by hardware when the registers are updated: // -At overflow or underflow regarding the repetition counter value (update if repetition // counter = 0) and if the UDIS=0 in the TIMx_CR1 register. // -When CNT is reinitialized by software using the UG bit in TIMx_EGR register, if URS=0 // and UDIS=0 in the TIMx_CR1 register. TIM1->SR &= 0xFFFE; //Clear UIF bit while((TIM1->SR & 0x0001)==0); //Check UIF flag TIM1->CR1 &= 0xFFFE; //Counter disabled }