#include "stdint.h"
// RCC
#define RCC_APB1ENR *((volatile uint32_t*)0x4002101C)
#define RCC_APB2ENR *((volatile uint32_t*)0x40021018)
// GPIOA
#define GPIOA_CRL *((volatile uint32_t*)0x40010800)
#define GPIOA_ODR *((volatile uint32_t*)0x4001080C)
// TIMER
#define TIM2_CR1 *((volatile uint32_t*) 0x40000000)
#define TIM2_CCMR1 *((volatile uint32_t*) 0x40000018)
#define TIM2_CCMR2 *((volatile uint32_t*) 0x4000001C)
#define TIM2_CCER *((volatile uint32_t*) 0x40000020)
#define TIM2_PSC *((volatile uint32_t*) 0x40000028)
#define TIM2_ARR *((volatile uint32_t*) 0x4000002C)
#define TIM2_CCR1 *((volatile uint32_t*) 0x40000034)
#define TIM2_CCR2 *((volatile uint32_t*) 0x40000038)
#define TIM2_CCR3 *((volatile uint32_t*) 0x4000003C)
#define TIM2_CCR4 *((volatile uint32_t*) 0x40000040)
void delay(uint32_t t)
{
for(uint32_t i=0;i<t*500;i++)
{
__asm("nop");
}
}
void Timx_init (void)
{
//turn on GPIOA
RCC_APB2ENR |=(1<<2);
//turn on TIM2
RCC_APB1ENR |=(1<<0);
// config PA0,1,2 is Alternate Function for TIM2_CH1,2,3,4
/*MODE = 11 (output 50MHz)
CNF = 10 (alternate function push pull)
=>0xB
*/
GPIOA_CRL &=~(0xFFFF);
GPIOA_CRL |= (0xBBBB);
// config prescaler timer
TIM2_PSC = 71; // 1MHZ
// config previous PWM
TIM2_ARR = 255;
// config PWM mode for CH1 CH2 CH3 CH4
/*OC1M = 110 -> PWM mode 1
OC2M = 110 -> PWM mode 1
OC3M = 110 -> PWM mode 1
OC4M = 110 -> PWM mode 1
*/
TIM2_CCMR1 &= ~((7<<4)|(7<<12));
TIM2_CCMR2 &= ~((7<<4)|(7<<12));
TIM2_CCMR1 |= (6<<4)|(6<<12);
TIM2_CCMR2 |= (6<<4)|(6<<12);
// enable output preload
TIM2_CCMR1 |= (1<<3)|(1<<11);
TIM2_CCMR2 |= (1<<3)|(1<<11);
// enable output for CH1 CH2 CH3 CH4
TIM2_CCER |= (1<<0)|(1<<4)|(1<<8)|(1<<12);
// set first duty
TIM2_CCR1 = 0 ;
TIM2_CCR2 = 0 ;
TIM2_CCR3 = 0 ;
TIM2_CCR4 = 0 ;
// turn on Timer
TIM2_CR1 |= (1|(1<<7));
}
void set_duty(uint8_t channel, uint8_t duty)
{
uint32_t CCR_value = (duty * TIM2_ARR) / 100;
switch(channel)
{
case 1:
TIM2_CCR1 = CCR_value;
break;
case 2:
TIM2_CCR2 = CCR_value;
break;
case 3:
TIM2_CCR3 = CCR_value;
break;
case 4:
TIM2_CCR4 = CCR_value;
break;
}
}
int main (void)
{
Timx_init();
while(1)
{
for ( int i=0 ; i<100;i++)
{
// set_duty(1,100-i);
// set_duty(2,i);
// set_duty(3,100-i/2);
TIM2_CCR1 = 255-i;
TIM2_CCR2 = i;
TIM2_CCR3 = 255 - i/2;
delay(20);
}
}
}