// ****************************************************************************************** // Project : STM32VLDISCOVERY Sample Program (STM32F100RB) // Program Name : // Programer : // Create date : Version 1.0 H24.10.10 // History : // Laungage : Atollic TrueSTDIO C Launguage // ****************************************************************************************** // Description // PWM(TIMER1) TIM1-CH1(A8), TIM1-CH2(A9), TIM1-CH3(A10), TIM1-CH4(A11) : Define OC1-4 // TIM1-CH1N(B13),TIM1-CH2N(B14),TIM1-CH3N(B15) : Define OC1N-3N // Output Frequency:10KHz, duty cycle: 75%,50%,25%,10% // ****************************************************************************************** #include #include "stm32f10x.h" void Init_clock(unsigned char); void Init_PWM(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) { // ******************* // 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 = 0x44444444; // Port configuration register low (GPIOn[0-7]) GPIOA->CRH = 0x4444BBBB; // Port configuration register high(GPIOn[8-15]) // B: CNF=10:Alternate function output Push-pull, MODE=11:Output mode, max speed 50 MHz. // 4: CNF=01:Floating input (reset state), MODE=00:Input mode (reset state) // GPIOA->IDR // Port input data register (Read Only) IDR[31-16]:Reserved,@IDR[15-0]:Port output data // GPIOA->ODR // 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 = 0x44444444; // Port configuration register low (GPIOn[0-7]) GPIOB->CRH = 0xBBB44444; // Port configuration register high(GPIOn[8-15]) // B: CNF=10:Alternate function output Push-pull, MODE=11:Output mode, max speed 50 MHz. // 4: CNF=01:Floating input (reset state), MODE=00:Input mode (reset state) // GPIOB->IDR // Port input data register (Read Only) IDR[31-16]:Reserved,@IDR[15-0]:Port output data // GPIOB->ODR // 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 // (4)Initialized PWM Init_PWM(); // ******************* // 2.Program main // ******************* while(1); } //****************************************************************************************** // Function Name : Init_PWM // Title : Initialized PWM // Input : // Output : // Description : //****************************************************************************************** void Init_PWM(void) { // ********************************* // TIM1_ARR(TIM1 Auto-reload register) // ********************************* // TIM1_ARR[15:0] ARR[15:0]: Prescaler value // Output Frequency F[Hz] : TIM1_ARR = ( SystemCoreClock / F[Hz] ) - 1 // // (Examples 1) Output 10KHz, SystemCoreClock:24[MHz] // TIM1_ARR = ( 24000000 / 10000 ) - 1 ===> 0d2399 ==> 0x095F TIM1->ARR = 2399; // ********************************* // TIMx_CCRx (TIM1 capture/compare register x) // ********************************* // TIMx_CCRx[15:0] CCR1[15:0]: Capture/Compare 1 value // duty cycle N[%] : TIMx_CCRx = N[%] * ( TIM1_ARR - 1 ) / 100 // // (Examples 1) duty cycle:75[%], TIM1_ARR: 0d2399 // TIMx_CCRx = 75[%] * ( 2399 - 1 ) / 100 ===> 0d1799 // (Examples 2) duty cycle:50[%], TIM1_ARR: 0d2399 // TIMx_CCRx = 50[%] * ( 2399 - 1 ) / 100 ===> 0d1199 // (Examples 3) duty cycle:25[%], TIM1_ARR: 0d2399 // TIMx_CCRx = 25[%] * ( 2399 - 1 ) / 100 ===> 0d600 // (Examples 4) duty cycle:10[%], TIM1_ARR: 0d2399 // TIMx_CCRx = 15[%] * ( 2399 - 1 ) / 100 ===> 0d240 TIM1->CCR1 = 1799; TIM1->CCR2 = 1199; TIM1->CCR3 = 600; TIM1->CCR4 = 240; // ********************************* // 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 // This bit-field indicates the division ratio between the timer clock (CK_INT) frequency and the // dead-time and sampling clock (tDTS)used by the dead-time generators and the digital filters (ETR, TIx), // 00: tDTS=tCK_INT // 01: tDTS=2*tCK_INT // 10: tDTS=4*tCK_INT // 11: Reserved, do not program this value // TIM1_CR1[7] ARPE: Auto-reload preload enable // 0: TIMx_ARR register is not buffered, 1: TIMx_ARR register is buffered // 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; // ********************************* // TIMx_CCER (TIM1 capture/compare enable register) // ********************************* TIM1->CCER = 0x0000; //CC4P-CC1E Reset // ********************************* // TIM1_CR2(Control register 2) Reset value: 0x00 // ********************************* // TIM1_CR2[15] Reserved, always read as 0 // TIM1_CR2[14] OIS4: Output Idle state 4 (OC4 output) refer to OIS1 bit // TIM1_CR2[13] OIS3N: Output Idle state 3 (OC3N output) refer to OIS1N bit // TIM1_CR2[12] OIS3: Output Idle state 3 (OC3 output) refer to OIS1 bit // TIM1_CR2[11] OIS2N: Output Idle state 2 (OC2N output) refer to OIS1N bit // TIM1_CR2[10] OIS2: Output Idle state 2 (OC2 output) refer to OIS1 bit // TIM1_CR2[9] OIS1N: Output Idle state 1 (OC1N output) // 0: OC1N=0 after a dead-time when MOE=0 // 1: OC1N=1 after a dead-time when MOE=0 // This bit can not be modified as long as LOCK level 1, 2 or 3 has been programmed (LOCK bits in TIMx_BDTR register). // TIM1_CR2[8] OIS1: Output Idle state 1 (OC1 output) // 0: OC1=0 (after a dead-time if OC1N is implemented) when MOE=0 // 1: OC1=1 (after a dead-time if OC1N is implemented) when MOE=0 // This bit can not be modified as long as LOCK level 1, 2 or 3 has been programmed (LOCK bits in TIMx_BDTR register). // TIM1_CR2[7] TI1S: TI1 selection // 0: The TIMx_CH1 pin is connected to TI1 input // 1: The TIMx_CH1, CH2 and CH3 pins are connected to the TI1 input (XOR combination) // TIM1_CR2[6:4] MMS[1:0]: Master mode selection // 100: Compare - OC1REF signal is used as trigger output (TRGO) // 101: Compare - OC2REF signal is used as trigger output (TRGO) // 110: Compare - OC3REF signal is used as trigger output (TRGO) // 111: Compare - OC4REF signal is used as trigger output (TRGO) // TIM1_CR2[3] CCDS: Capture/compare DMA selection // 0: CCx DMA request sent when CCx event occurs // 1: CCx DMA requests sent when update event occurs // TIM1_CR2[2] CCUS: Capture/compare control update selection // 0: When capture/compare control bits are preloaded (CCPC=1), they are updated by setting the COMG bit only // 1: When capture/compare control bits are preloaded (CCPC=1), they are updated by setting the COMG bit or when an rising edge occurs on TRGI // This bit acts only on channels that have a complementary output. // TIM1_CR2[1] Reserved, always read as 0 // TIM1_CR2[0] CCPC: Capture/compare preloaded control // 0: CCxE, CCxNE and OCxM bits are not preloaded // 1: CCxE, CCxNE and OCxM bits are preloaded, after having been written, they are updated only when TIM1->CR2 = 0x7F70; // ********************************* // TIMx_CCMR1 (TIM1 capture/compare mode register 1) Define OC2 - OC1 // TIMx_CCMR2 (TIM1 capture/compare mode register 2) Define OC4 - OC3 // ********************************* // TIMx_CCMR1[15] OC2CE: Output Compare 2 clear enable // TIMx_CCMR1[14:12] OC2M[2:0]: Output Compare 2 mode // TIMx_CCMR1[11] OC2PE: Output Compare 2 preload enable // TIMx_CCMR1[10] OC2FE: Output Compare 2 fast enable // TIMx_CCMR1[9:8] CC2S[1:0]: Capture/Compare 2 selection // This bit-field defines the direction of the channel (input/output) as well as the used input. // 00: CC2 channel is configured as output // 01: CC2 channel is configured as input, IC2 is mapped on TI2 // 10: CC2 channel is configured as input, IC2 is mapped on TI1 // 11: CC2 channel is configured as input, IC2 is mapped on TRC. // This mode is working only if an internal trigger input is selected through the TS bit (TIMx_SMCR register) // CC2S bits are writable only when the channel is OFF (CC2E = e0f in TIMx_CCER). // TIMx_CCMR1[7] OC1CE: Output Compare 1 clear enable // OC1CE: Output Compare 1 Clear Enable // 0: OC1Ref is not affected by the ETRF Input // 1: OC1Ref is cleared as soon as a High level is detected on ETRF input // TIMx_CCMR1[6:4] OC1M: Output Compare 1 mode // These bits define the behavior of the output reference signal OC1REF from which OC1 and OC1N are derived. // OC1REF is active high whereas OC1 and OC1N active level depends on CC1P and CC1NP bits. // 000: Frozen - The comparison between the output compare register TIMx_CCR1 and the counter TIMx_CNT has no // effect on the outputs. (this mode is used to generate a timing base). // 001: Set channel 1 to active level on match. OC1REF signal is forced high when the counter TIMx_CNT matches // the capture/compare register 1 (TIMx_CCR1). // 010: Set channel 1 to inactive level on match. OC1REF signal is forced low when the counter TIMx_CNT matches // the capture/compare register 1 (TIMx_CCR1). // 011: Toggle - OC1REF toggles when TIMx_CNT=TIMx_CCR1. // 100: Force inactive level - OC1REF is forced low. // 101: Force active level - OC1REF is forced high. // 110: PWM mode 1 - In upcounting, channel 1 is active as long as TIMx_CNTTIMx_CCR1 else active // (OC1REF=f1f). // 111: PWM mode 2 - In upcounting, channel 1 is inactive as long as TIMx_CNTTIMx_CCR1 else inactive. // These bits can not be modified as long as LOCK level 3 has been programmed (LOCK bits in TIMx_BDTR register) // and CC1S=f00f (the channel is configured in output). // In PWM mode 1 or 2, the OCREF level changes only when the result of the comparison changes or when the output // compare mode switches from gfrozenh mode to gPWMh mode. // TIMx_CCMR1[3] OC1PE: Output Compare 1 preload enable // 0: Preload register on TIMx_CCR1 disabled. // TIMx_CCR1 can be written at anytime, the new value is taken in account immediately. // 1: Preload register on TIMx_CCR1 enabled. // Read/Write operations access the preload register. // TIMx_CCR1 preload value is loaded in the active register at each update event. // These bits can not be modified as long as LOCK level 3 has been programmed (LOCK bits in TIMx_BDTR register) // and CC1S=f00f (the channel is configured in output). // The PWM mode can be used without validating the preload register only in one pulse mode (OPM bit set in // TIMx_CR1 register). Else the behavior is not guaranteed. // TIMx_CCMR1[2] OC1FE: Output Compare 1 fast enable // This bit is used to accelerate the effect of an event on the trigger in input on the CC output. // 0: CC1 behaves normally depending on counter and CCR1 values even when the trigger is ON. // The minimum delay to activate CC1 output when an edge occurs on the trigger input is 5 clock cycles. // 1: An active edge on the trigger input acts like a compare match on CC1 output. // Then, OC is set to the compare level independently from the result of the comparison. // Delay to sample the trigger input and to activate CC1 output is reduced to 3 clock cycles. // OCFE acts only if the channel is configured in PWM1 or PWM2 mode. // TIMx_CCMR1[1:0] CC1S: Capture/Compare 1 selection // This bit-field defines the direction of the channel (input/output) as well as the used input. // 00: CC1 channel is configured as output // 01: CC1 channel is configured as input, IC1 is mapped on TI1 // 10: CC1 channel is configured as input, IC1 is mapped on TI2 // 11: CC1 channel is configured as input, IC1 is mapped on TRC. // This mode is working only if an internal trigger input is selected through TS bit (TIMx_SMCR register) // CC1S bits are writable only when the channel is OFF (CC1E = e0f in TIMx_CCER). TIM1->CCMR1 = 0x7070; TIM1->CCMR2 = 0x7070; // ********************************* // TIMx_CCER (TIM1 capture/compare enable register) // ********************************* // TIMx_CCER[15:14] Reserved, always read as 0. // TIMx_CCER[13] CC4P: Capture/Compare 4 output polarity refer to CC4P description // TIMx_CCER[12] CC4E: Capture/Compare 4 output enable refer to CC4E description // TIMx_CCER[11] CC3NP:Capture/Compare 3 complementary output polarity refer to CC3NP description // TIMx_CCER[10] CC3NE:Capture/Compare 3 complementary output enable refer to CC3NE description // TIMx_CCER[9] CC3P: Capture/Compare 3 output polarity refer to CC3P description // TIMx_CCER[8] CC3E: Capture/Compare 3 output enable refer to CC3E description // TIMx_CCER[7] CC2NP: Capture/Compare 2 complementary output polarity refer to CC2NP description // TIMx_CCER[6] CC2NE: Capture/Compare 2 complementary output enable refer to CC2NE description // TIMx_CCER[5] CC2P: Capture/Compare 2 output polarity refer to CC2P description // TIMx_CCER[4] CC2E: Capture/Compare 2 output enable refer to CC2E description // TIMx_CCER[3] CC1NP: Capture/Compare 1 complementary output polarity refer to CC1NP description // TIMx_CCER[2] CC1NE: Capture/Compare 1 complementary output enable refer to CC1NE description // TIMx_CCER[1] CC1P: Capture/Compare 1 output polarity refer to CC1P description // CC1 channel configured as output: // 0: OC1 active high, 1: OC1 active low // TIMx_CCER[0] CC1E: Capture/Compare 1 output enable refer to CC1E description // TIM1->CCER = 0x3333; TIM1->CCER = 0x3FFF; // ********************************* // TIMx->BDTR(TIM1 break and dead-time register) // ********************************* // TIMx->BDTR[15] MOE: Main output enable // 0: OC and OCN outputs are disabled or forced to idle state. // 1: OC and OCN outputs are enabled if their respective enable bits are set (CCxE, CCxNE in TIMx_CCER register). // TIMx->BDTR[14] AOE: Automatic output enable // 0: MOE can be set only by software // TIMx->BDTR[13] BKP: Break polarity // TIMx->BDTR[12] BKE: Break enable // TIMx->BDTR[11] OSSR: Off-state selection for Run mode // TIMx->BDTR[10] OSSI: Off-state selection for Idle mode // TIMx->BDTR[9:8] LOCK[1:0]: Lock configuration // TIMx->BDTR[7:0] DTG[7:0]: Dead-time generator setup TIM1->BDTR = 0xC000; } //****************************************************************************************** // 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; } }