1 | /* ... header .... */
|
2 |
|
3 |
|
4 | // masks for setting GPIO bits
|
5 | #define OUT_PP_MASK ((uint32_t)( (0x01 << 1 | 0x01) | 0x00 << 2) )
|
6 | #define IN_ANALOG_MASK ((uint32_t)(0x00 | 0x00 << 2) )
|
7 | #define IN_FLOAT_MASK ((uint32_t)(0x00 | 0x01 << 2) )
|
8 | #define OUT_ALT_PP_MASK ((uint32_t)( ( 0x01 << 1 | 0x01 ) | ((0x01 << 1 | 0x00) << 2) ) )
|
9 |
|
10 | #define CORE_CLOCK ((uint32_t) 64000000)
|
11 |
|
12 |
|
13 | void PCBA_Configuration( void ) // wird vor dem main loop aufgerufen
|
14 | {
|
15 | ConfigureGPIO();
|
16 | ConfigureTimer();
|
17 | ConfigurePWM();
|
18 | }
|
19 |
|
20 | void ConfigureGPIO( void )
|
21 | {
|
22 | RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // clock port a
|
23 | RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; // clock port b
|
24 | RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; // enable alternative function clock
|
25 |
|
26 | GPIOA->CRL = ( GPIOA->CRL & 0x00000000 ) // each half byte for mode and config for each Port. 0x00 = reset state there. here: alter every port
|
27 | | ( IN_ANALOG_MASK << 4 * 0 | OUT_ALT_PP_MASK << 4 * 1 | OUT_ALT_PP_MASK << 4 * 2 | IN_FLOAT_MASK << 4 * 3
|
28 | | IN_ANALOG_MASK << 4 * 4 | IN_ANALOG_MASK << 4 * 5 | OUT_PP_MASK << 4 * 6 | OUT_PP_MASK << 4 * 7 );
|
29 |
|
30 | GPIOB->CRL = ( GPIOB->CRL & 0x00FFFFF0 )// only alter pb0, pb6, pb7
|
31 | | ( OUT_PP_MASK << 4 * 0 | OUT_ALT_PP_MASK << 4 * 6 | IN_FLOAT_MASK << 4 * 7 ) ;
|
32 |
|
33 | // debug pins: pa2, pa3
|
34 | GPIOA->CRL = ( GPIOA->CRL & 0xFFFF00FF ) //
|
35 | | ( OUT_PP_MASK << 4 * 2 | OUT_PP_MASK << 4 * 3 ) ;
|
36 | //GPIOA->BRR = GPIO_Pin_2 | GPIO_Pin_3;
|
37 |
|
38 | AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_1; // trace on
|
39 | }
|
40 |
|
41 |
|
42 | void ConfigurePWM( void )
|
43 | {
|
44 | // output pins are defined in ConfigureGPIO!
|
45 |
|
46 | /* -----------------------------------------------------------------------
|
47 | Time base configuration
|
48 | TIM2CLK = APB1clk = CORE_CLOCK/2 = 32MHz usually, TIM2 counter clock frequency = TIM2CLK/(PSC + 1) = 100Hz => APB1ck / (TimSollClock*ARR) - 1 = PSC
|
49 | TIM2 ARR Register; TIM1 Frequency = TIM1 counter clock frequency/(ARR+1) = x kHz.
|
50 | TIM2 Frequency = 100 Hz.
|
51 | TIM2 Channel2 duty cycle = (TIM2_CCR2/ TIM2_ARR) * 100 = 50%
|
52 | ----------------------------------------------------------------------- */
|
53 |
|
54 | #define ARR_VAL ((uint16_t)4000)
|
55 | #define PWM_FREQ ((uint16_t)100)
|
56 |
|
57 | RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // enable clock for TIM2
|
58 |
|
59 | TIM2->PSC = ( uint16_t )( ( CORE_CLOCK / ( 2 * PWM_FREQ * ARR_VAL ) ) - ( uint32_t )1 ); // 800 kHz counter @ 32 MHz
|
60 | TIM2->ARR = ARR_VAL - 1;
|
61 |
|
62 | TIM2->CCR2 = ARR_VAL / 2; // set channel 2 duty cycle
|
63 | TIM2->CCMR1 = TIM_CCMR1_OC2M | TIM_CCMR1_OC2PE; // set channel 2 PWM mode 2, pre load enabled.
|
64 |
|
65 | TIM2->CCER = TIM_CCER_CC2E; // enable capture and compare, active high
|
66 | TIM2->CR1 = TIM_CR1_ARPE | TIM_CR1_URS; // downcounter, arr preload active, only over/underflow generate interrupt
|
67 | TIM2->DIER = TIM_DIER_UIE; // Enable Update event interrupt
|
68 | NVIC_SetPriority( TIM2_IRQn, 0 ); // set interrupt priority TIM2
|
69 | NVIC_EnableIRQ( TIM2_IRQn ); // enable TIM2 interrupts
|
70 |
|
71 | TIM2->EGR |= TIM_EGR_UG; // generate update event
|
72 | TIM2->CR1 |= TIM_CR1_CEN; // start
|
73 | }
|
74 |
|
75 | void SetPWMOut( float fValue )
|
76 | {
|
77 | float dc, ccr;
|
78 | dc = .028125 * fValue + .5; // 95% = +16mm, 5% = -16mm, 50% = 0mm
|
79 | ccr = dc * ARR_VAL;
|
80 | TIM2->CCR2 = ( uint16_t )ccr;
|
81 | }
|
82 |
|
83 | void TIM2_IRQHandler( void )
|
84 | {
|
85 | if ( TIM2->SR & 0x01 )
|
86 | {
|
87 | TIM2->SR &= ~TIM_IT_Update;
|
88 | }
|
89 | }
|
90 |
|
91 | void ConfigureTimer( void )
|
92 | {
|
93 | RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // enable clock for TIM1
|
94 | /* -----------------------------------------------------------------------
|
95 | Time base configuration
|
96 | TIM1CLK = APB2 clock = 64 MHz, TIM1 counter clock frequency = TIM1CLK/(PSC + 1) = 20 kHz => APB2ck / TimSollClock*ARR - 1 = PSC
|
97 | TIM1 ARR Register = 4 => TIM1 Frequency = TIM1 counter clock frequency/(ARR+1) = 5 kHz.
|
98 | ----------------------------------------------------------------------- */
|
99 | TIM1->PSC = CORE_CLOCK / 20e3 - 1; // set prescaler
|
100 | TIM1->ARR = 4 - 1; // set auto-reload
|
101 |
|
102 | TIM1->CCR1 = 0x0000; //
|
103 | TIM1->CCR2 = 0x7D00; //
|
104 | TIM1->CCR3 = 0x0000; //
|
105 | TIM1->CCR4 = 0x0000; //
|
106 | TIM1->CCMR1 = 0x0100; //
|
107 | TIM1->CCMR2 = 0x0000; //
|
108 | TIM1->CCER = 0x0000; // set capture/compare enable register
|
109 | TIM1->SMCR = 0x0000; // set slave mode control register
|
110 |
|
111 | TIM1->CR1 = 0x0000 & 0xFFFE; // set command register 1
|
112 | TIM1->CR2 = 0x0010; // set command register 2
|
113 |
|
114 | TIM1->DIER = 0x0001; // enable interrupt
|
115 |
|
116 | NVIC_EnableIRQ( TIM1_UP_IRQn );
|
117 | NVIC_SetPriority( TIM1_UP_IRQn, 1 );
|
118 | }
|