/* ****************************************************************************** File: main.c Info: Generated by Atollic TrueSTUDIO(R) 9.3.0 2021-07-09 The MIT License (MIT) Copyright (c) 2019 STMicroelectronics Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ****************************************************************************** */ /* Includes */ #include #include "stm32l0xx.h" #define PI_MSI_SYSCLK 1 //MSI clock selected #define PI_HSI16_SYSCLK 2 //HSI16 clock selected #define PI_HSE_SYSCLK 3 //HSE clock selected #define PI_PLL_SYSCLK 4 //PLL clock selected void Init_clock(unsigned char); void Timer(void); void Wait(unsigned int); /** **=========================================================================== ** ** Abstract: main program ** **=========================================================================== */ int main(void) { // ******************* // 1.Initialize // ******************* // (1)Define Clock Init_clock(PI_MSI_SYSCLK); // Init_clock(PI_HSI16_SYSCLK); // (2)Setting Timer2 RCC->APB1ENR = 0x0001; // Timer2 clock enabled // (3)Define I/O Port RCC->IOPENR = 0x00000001; // Enable PORTA * GPIOA->MODER = 0x00005400; // Direction output PA7,6,5 // ******************* // 2.Program main // ******************* while (1) { Wait((unsigned int)10); GPIOA->ODR = 0x000000E0; Wait((unsigned int)10); GPIOA->ODR = 0x00000000; } } //****************************************************************************************** // Function Name : Init_clock // Title : Initialized System clock // Input : // Output : // Description : STM32L0x0 Version //****************************************************************************************** void Init_clock(unsigned char clk_mode) { // ***************************************** // RCC_CFGR(Clock configuration register) Address offset: 0x0C / Reset value: 0x0000 0000 // ***************************************** // [31] Reserved, must be kept at reset value. // [30:28] MCOPRE[2:0]: Microcontroller clock output prescaler // These bits are set and cleared by software. // It is highly recommended to change this prescaler before MCO output is enabled. // 000: MCO is divided by 1 // 001: MCO is divided by 2 // 010: MCO is divided by 4 // 011: MCO is divided by 8 // 100: MCO is divided by 16 // Others: not allowed // [27:24] 27:24 MCOSEL[3:0]: Microcontroller clock output selection // These bits are set and cleared by software. // 0000: MCO output disabled, no clock on MCO // 0001: SYSCLK clock selected // 0010: HSI16 oscillator clock selected // 0011: MSI oscillator clock selected // 0100: HSE oscillator clock selected // 0101: PLL clock selected // 0110: LSI oscillator clock selected // 0111: LSE oscillator clock selected // 1000: Reserved // Others: reserved // [23:22] PLLDIV[1:0]: PLL output division // These bits are set and cleared by software to control PLL output clock division from PLL VCO clock. // These bits can be written only when the PLL is disabled. // 00: not allowed // 01: PLL clock output = PLLVCO / 2 // 10: PLL clock output = PLLVCO / 3 // 11: PLL clock output = PLLVCO / 4 // [21:18] PLLMUL[3:0]: PLL multiplication factor // These bits are written by software to define the PLL multiplication factor to generate the PLL VCO clock. // These bits can be written only when the PLL is disabled. // 0000: PLLVCO = PLL clock entry x 3 // 0001: PLLVCO = PLL clock entry x 4 // 0010: PLLVCO = PLL clock entry x 6 // 0011: PLLVCO = PLL clock entry x 8 // 0100: PLLVCO = PLL clock entry x 12 // 0101: PLLVCO = PLL clock entry x 16 // 0110: PLLVCO = PLL clock entry x 24 // 0111: PLLVCO = PLL clock entry x 32 // 1000: PLLVCO = PLL clock entry x 48 // others: not allowed // [17] Reserved, must be kept at reset value. // [16] PLLSRC: PLL entry clock source // This bit is set and cleared by software to select PLL clock source. This bit can be written only // when PLL is disabled. // 0: HSI16 oscillator clock selected as PLL input clock // 1: HSE oscillator clock selected as PLL input clock // Note: The PLL minimum input clock frequency is 2 MHz. // [15] STOPWUCK: Wake-up from Stop clock selection // This bit is set and cleared by software to select the wake-up from Stop clock. // 0: internal 64 KHz to 4 MHz (MSI) oscillator selected as wake-up from Stop clock // 1: internal 16 MHz (HSI16) oscillator selected as wake-up from Stop clock (or HSI16/4 if HSI16DIVEN=1) // [14] Reserved, must be kept at reset value. // [13:11] PPRE2[2:0]: APB high-speed prescaler (APB2) // These bits are set and cleared by software to control the division factor of the APB highspeed 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 // [10:8] PPRE1[2:0]: APB low-speed prescaler (APB1) // These bits are set and cleared by software to control the division factor of the APB low-speed clock (PCLK1). // 0xx: HCLK not divided // 100: HCLK divided by 2 // 101: HCLK divided by 4 // 110: HCLK divided by 8 // 111: HCLK divided by 16 // [7:4] HPRE[3:0]: AHB prescaler // These bits are set and cleared by software to control the division factor of the AHB clock. // Caution: Depending on the device voltage range, the software has to set correctly these bits to ensure that the system frequency does not exceed the maximum allowed // frequency (for more details please refer to the Dynamic voltage scaling management // section in the PWR chapter.) After a write operation to these bits and before // decreasing the voltage range, this register must be read to be sure that the new value has been taken into account. // 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 // [3:2] SWS[1:0]: System clock switch status // These bits are set and cleared by hardware to indicate which clock source is used as system clock. // 00: MSI oscillator used as system clock // 01: HSI16 oscillator used as system clock // 10: HSE oscillator used as system clock // 11: PLL used as system clock // [1:0] SW[1:0]: System clock switch // These bits are set and cleared by software to select SYSCLK source. // Set by hardware to force MSI selection when leaving 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: MSI oscillator used as system clock // 01: HSI16 oscillator used as system clock // 10: HSE oscillator used as system clock // 11: PLL used as system clock switch (clk_mode){ case PI_MSI_SYSCLK : RCC->CFGR = 0x00000000; break; case PI_HSI16_SYSCLK : RCC->CFGR = 0x00000001; break; case PI_HSE_SYSCLK : RCC->CFGR = 0x00000002; break; case PI_PLL_SYSCLK : RCC->CFGR = 0x00080003; break; default: RCC->CFGR = 0x00000000; } } //****************************************************************************************** // Function Name : Wait function // Title : Wait 1[S] * n // Input : // Output : //****************************************************************************************** void Wait(unsigned int i) { unsigned int lp; for(lp=0;lp 1Hz(1S) // Description : STM32L0x0 Version //****************************************************************************************** void Timer(void) { // ********************************* // TIM1_CNT(TIM1 Counter) // ********************************* TIM2->CNT = 0x0000; // ********************************* // TIM1_PSC(TIM1 Prescaler) // ********************************* // // 2[MHz] / 0d600[0x258](Prescaler) ==> 10[KHz] // 8[MHz] / 0d800[0x320](Prescaler) ==> 10[KHz] // 24[MHz] / 0d2400[0x960](Prescaler) ==> 10[KHz] // 64[MHz] / 0d6400[0x1900](Prescaler) ==> 10[KHz] // // TIM2->PSC = 0x0960; // TIM2->PSC = 0x1900; // TIM2->PSC = 0x0320; TIM2->PSC = 0x00C8; // ********************************* // TIM1_ARR(TIM1 Auto-reload register) // ********************************* // // 10KHz / 0d10000[0x2710](ARR) ==> 1[S] // TIM2->ARR = 0x2710; // ********************************* // TIM2_CR1(Control register 1) Reset value: 0x00 * // ********************************* // TIM2_CR1[15:10] Reserved, always read as 0 // TIM2_CR1[9:8] CKD[1:0]: Clock division // TIM2_CR1[7] ARPE: Auto-reload preload enable // TIM2_CR1[6:5] CMS[1:0]: Center-aligned mode selection // TIM2_CR1[4] DIR: Direction // 0: Counter used as up-counter // 1: Counter used as down-counter // TIM2_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) // TIM2_CR1[2] URS: Update request source // TIM2_CR1[1] UDIS: Update disable. // TIM2_CR1[0] CEN: Counter enable // 0: Counter disabled // 1: Counter enabled TIM2->CR1 = 0x0001; // ********************************* // TIM2_SR(Status register) * // ********************************* // TIM2_SR[15:13] Reserved, always read as 0. // TIM2_SR[12] CC4OF: Capture/Compare 4 overcapture flag refer to CC1OF description // TIM2_SR[11] CC3OF: Capture/Compare 3 overcapture flag refer to CC1OF description // TIM2_SR[10] CC2OF: Capture/Compare 2 overcapture flag refer to CC1OF description // TIM2_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 // TIM2_SR[8-7] Reserved, must be kept at reset value. // TIM2_SR[6] TIF: Trigger interrupt flag // TIM2_SR[5] COMIF: Commutation interrupt flag // TIM2_SR[4] CC4IF: Capture/compare 4 interrupt flag // TIM2_SR[3] CC3IF: Capture/compare 3 interrupt flag // TIM2_SR[2] CC2IF: Capture/compare 2 interrupt flag // TIM2_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). // TIM2_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. TIM2->SR &= 0xFFFE; //Clear UIF bit while((TIM2->SR & 0x0001)==0); //Check UIF flag TIM2->CR1 &= 0xFFFE; //Counter disabled }