TrmerM.c 13.9 KB
Newer Older
时昊's avatar
时昊 committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403
/*
 * TrmerM.c
 *
 *  Created on: 2024年2月21日
 */
#include <stdint.h>
// #include "gpio.h"
// #include "timm.h"
// #include "isr.h"

#include "TrmerM.h"

typedef struct
{
  TIMERM_PWM_Counter_en_t counter;  //定时器选择
}Display_mode_Struct;




/*-------------------PWM相关-------------------------------------*/
// extern void TimerB_PWM_Init(void);
// extern uint8_t TimerB_PWM_Channel_Init(TIMERB_Channel_en_t enTimerBChannel, TIMERB_Clock_en_t enTimerBClock, TIMERB_Polarity_en_t enTimerBPolarity);
// extern uint32_t TimerB_PWM_Channel_Fre_Set(TIMERB_Channel_en_t enTimerBChannel, uint16_t u16Fre, uint16_t u16Duty);
// /*占空比精度千分之一*/
// extern void TimerB_PWM_Channel_Duty_Set(TIMERB_Channel_en_t enTimerBChannel, uint16_t u16Duty);
// extern void TimerB_PWM_Channel_Start(TIMERB_Channel_en_t enTimerBChannel);
// /*调用该函数后,仅重新调用开始函数功能即可正常使用*/
// extern void TimerB_PWM_Channel_Stop(TIMERB_Channel_en_t enTimerBChannel);
// /*仅休眠时可调用,调用该函数后需要重新初始化相关通道才可以正常使用。*/
// extern void TimerB_PWM_Channel_Sleep(TIMERB_Channel_en_t enTimerBChannel);


TMM_InitTypeDef TIMM_InitStructure[2] = {0};
static uint32_t cycle_pulse[2];              //一个周期的时钟数  //频率
static uint32_t high_level_Pulse[2][3];      //高电平时钟数      //占空比
static uint32_t pwm_duty[2][3];

/**
 * @brief 设置TimerM的定时器x的模式为比较输出
 * 
 * @param counter 定时器
 * @param freq 比较输出频率
 * @return uint8_t 返回0成功,非0失败
 */
uint8_t TimerM_PWM_counter_Output_Init(TIMERM_PWM_Counter_en_t counter, uint16_t freq, uint32_t PWM_Clock)//, uint32_t PWM_Clock //SystemCoreClock
{
    if (counter == TIMERM_COUNTER0)
    {
        TIMM_InitStructure[counter].TMM_Select  = TMM0;
    }
    else if (counter == TIMERM_COUNTER1)
    {
        TIMM_InitStructure[counter].TMM_Select  = TMM1;
    }
    else
    {
        return 1;
    }
    
    TIMM_InitStructure[counter].TMM_Channel	                    = TMM_Channel_A|TMM_Channel_B|TMM_Channel_C|TMM_Channel_D;
    TIMM_InitStructure[counter].TMM_Mode		                = TMM_Mode_PWM;  
    TIMM_InitStructure[counter].TMM_CounterClear                = TM_Clear_Match_TMGRA;  //when TM is matched with TMGRA, TM0 is cleared
    TIMM_InitStructure[counter].TMM_Intp                        = TMM_Int_IMIA; ///compare match interrupt enable A (IMIEA)
	
    if (freq > 2000)
    {
        TIMM_InitStructure[counter].TMM_Clk                     = TMM_FCLK_Div1; // specify the operation clk of tim
        cycle_pulse[counter] = PWM_Clock / freq;
    }
    // else if(freq >= 500)
    // {
    //     TIMM_InitStructure[counter].TMM_Clk                     = TMM_FCLK_Div8; // specify the operation clk of tim
    //     cycle_pulse[counter] = PWM_Clock / 8 / freq;
    // }
    else if(freq >= 50)
    {
        TIMM_InitStructure[counter].TMM_Clk                     = TMM_FCLK_Div32; // specify the operation clk of tim
        cycle_pulse[counter] = PWM_Clock / 32 / freq;
    }
    else
    {
        return 1;
    }
    
    TIMM_InitStructure[counter].TMM_CHA_Pulse                   = cycle_pulse[counter] & 0x0FFFF;//这里需要计算,调试下 period;  //周期设置为period
    
    
    
    // TMM_Init(&TIMM_InitStructure[counter]);

    // if (counter == TIMERM_COUNTER0)
    // {
    //     TMM0_Start(ENABLE);
    // }
    // else if (counter == TIMERM_COUNTER1)
    // {
    //     TMM1_Start(ENABLE);
    // }

    return 0;
}

//uint8_t TimerM_PWM_counter_Output_Init(TIMERM_PWM_Counter_en_t counter, uint16_t freq)//, uint32_t PWM_Clock //SystemCoreClock
//{
//    if (counter == TIMERM_COUNTER0)
//    {
//        TIMM_InitStructure[counter].TMM_Select  = TMM0;
//    }
//    else if (counter == TIMERM_COUNTER1)
//    {
//        TIMM_InitStructure[counter].TMM_Select  = TMM1;
//    }
//    else
//    {
//        return 1;
//    }
//    
//    TIMM_InitStructure[counter].TMM_Channel	                    = TMM_Channel_A|TMM_Channel_B|TMM_Channel_C|TMM_Channel_D;
//    TIMM_InitStructure[counter].TMM_Mode		                = TMM_Mode_PWM;  
//    TIMM_InitStructure[counter].TMM_CounterClear                = TM_Clear_Match_TMGRA;  //when TM is matched with TMGRA, TM0 is cleared
//    TIMM_InitStructure[counter].TMM_Intp                        = TMM_Int_IMIA; ///compare match interrupt enable A (IMIEA)
//	
//    if (freq > 2000)
//    {
//        TIMM_InitStructure[counter].TMM_Clk                     = TMM_FCLK_Div1; // specify the operation clk of tim
//        cycle_pulse[counter] = SystemCoreClock / freq;
//    }
//    // else if(freq >= 500)
//    // {
//    //     TIMM_InitStructure[counter].TMM_Clk                     = TMM_FCLK_Div8; // specify the operation clk of tim
//    //     cycle_pulse[counter] = SystemCoreClock / 8 / freq;
//    // }
//    else if(freq >= 50)
//    {
//        TIMM_InitStructure[counter].TMM_Clk                     = TMM_FCLK_Div32; // specify the operation clk of tim
//        cycle_pulse[counter] = SystemCoreClock / 32 / freq;
//    }
//    else
//    {
//        return 1;
//    }
//    
//    TIMM_InitStructure[counter].TMM_CHA_Pulse                   = cycle_pulse[counter] & 0x0FFFF;//这里需要计算,调试下 period;  //周期设置为period
//    
//    
//    
//    // TMM_Init(&TIMM_InitStructure[counter]);

//    // if (counter == TIMERM_COUNTER0)
//    // {
//    //     TMM0_Start(ENABLE);
//    // }
//    // else if (counter == TIMERM_COUNTER1)
//    // {
//    //     TMM1_Start(ENABLE);
//    // }

//    return 0;
//}



/**
 * @brief 设置timerM定时器x通道x的占空比
 * 
 * @param counter 定时器
 * @param ch 通道
 * @param duty 占空比 xxxx/1000 千分之
 * @param ActiveLevel 0负占空比 1正占空比
 * @return uint8_t 返回0成功,非0失败
 */
uint8_t TimerM_PWM_CH_Output_init(TIMERM_PWM_Counter_en_t counter, TIMERM_PWM_Channel_en_t ch,TIMERM_PWM_ActiveLevel_en_t ActiveLevel)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    
    switch (ch)
    {
    case TIMERM_CHB:
        TIMM_InitStructure[counter].TMM_CHB_Pulse = ((cycle_pulse[counter]) ) & 0x0FFFF;  	//TM计数达到TMGRB. 占空比:duty2/period
        TIMM_InitStructure[counter].TMM_PWM.TMM_CHB.TMM_PWMInitLevel = TMM_PWMInitLevel_High;
        TIMM_InitStructure[counter].TMM_PWM.TMM_CHB.TMM_PWMActiveLevel = ActiveLevel;
        if (counter == TIMERM_COUNTER0)
        {
            GPIO_PinAFConfig(GPIO_PORT1,GPIO_Pin_4,GPIO_P14,GROUP_AF_ODEFAULT);  //P14 used as TMIOB0 output(default function)
            GPIO_InitStruct.GPIO_Pin	= GPIO_Pin_4 ;
        }
        else if (counter == TIMERM_COUNTER1)
        {
            GPIO_PinAFConfig(GPIO_PORT1,GPIO_Pin_0,GPIO_P10,GROUP_AF_ODEFAULT);  //P14 used as TMIOB1 output(default function)
            GPIO_InitStruct.GPIO_Pin	= GPIO_Pin_0 ;
        }
        break;
    
    case TIMERM_CHC:
        TIMM_InitStructure[counter].TMM_CHC_Pulse =  ((cycle_pulse[counter]) ) & 0x0FFFF;  	//TM计数达到TMGRC. 占空比:duty2/period
        TIMM_InitStructure[counter].TMM_PWM.TMM_CHC.TMM_PWMInitLevel = TMM_PWMInitLevel_High;
        TIMM_InitStructure[counter].TMM_PWM.TMM_CHC.TMM_PWMActiveLevel = ActiveLevel;
        if (counter == TIMERM_COUNTER0)
        {
            GPIO_PinAFConfig(GPIO_PORT1,GPIO_Pin_6,GPIO_P16,GROUP_AF_ODEFAULT);  //P16 used as TMIOC0 output(default function)
            GPIO_InitStruct.GPIO_Pin	= GPIO_Pin_6;
        }
        else if (counter == TIMERM_COUNTER1)
        {
            /* code */
        }
        break;
    
    case TIMERM_CHD:
        TIMM_InitStructure[counter].TMM_CHD_Pulse = ((cycle_pulse[counter]) ) & 0x0FFFF;  	//TM计数达到TMGRD. 占空比:duty3/period
        TIMM_InitStructure[counter].TMM_PWM.TMM_CHD.TMM_PWMInitLevel = TMM_PWMInitLevel_High;//TMM_PWMInitLevel_High;//
        TIMM_InitStructure[counter].TMM_PWM.TMM_CHD.TMM_PWMActiveLevel = ActiveLevel;//TMM_PWMActiveLevel_Low;//TMM_PWMActiveLevel_High;//
        if (counter == TIMERM_COUNTER0)
        {
            GPIO_PinAFConfig(GPIO_PORT1,GPIO_Pin_7,GPIO_P17,GROUP_AF_TMIOD0);  //P15 used as TMIOD0 output(default function)
            GPIO_InitStruct.GPIO_Pin	=  GPIO_Pin_7 ;	
        }
        else if (counter == TIMERM_COUNTER1)
        {
            /* code */
        }
        break;
    
    default:
        return 1;
        //break;
    }

	GPIO_InitStruct.GPIO_Mode	= GPIO_Mode_OUT;	
	GPIO_InitStruct.GPIO_Level  = GPIO_Level_LOW;	
	GPIO_InitStruct.GPIO_OType	= GPIO_OType_PP;
	GPIO_InitStruct.GPIO_PuPd	= GPIO_PuPd_NOPULL;	

	TMM_Init(&TIMM_InitStructure[counter]);
    if (counter == TIMERM_COUNTER0)
    {
        TMM0_Start(ENABLE);
    }
    else if (counter == TIMERM_COUNTER1)
    {
        TMM1_Start(ENABLE);
    }
    else
    {
        return 1;
    }
    
	GPIO_Init(GPIO_PORT1,&GPIO_InitStruct);

    high_level_Pulse[counter][ch] = ((cycle_pulse[counter]) ) & 0x0FFFF;
    pwm_duty[counter][ch] = 1000;

    return 0;
}



extern void TMM0_Set_Counter(uint8_t ch,uint16_t value);
extern void TMM1_Set_Counter(uint8_t ch,uint16_t value);
/**
 * @brief 改变TimerM PWM输出的占空比
 * 
 * @param counter 定时器x
 * @param ch 通道x
 * @param duty 占空比 千分之一
 * @return uint8_t 返回0成功,非0失败
 */
uint8_t TimerM_PWM_set_duty(TIMERM_PWM_Counter_en_t counter, TIMERM_PWM_Channel_en_t ch, uint16_t duty )
{
    if (duty >= 1000)
    {
        duty = 0;
    }
    else if (duty <= 0)
    {
        duty = 1000;
    }

    if (counter == TIMERM_COUNTER0) 
    {
        high_level_Pulse[counter][ch] = (((cycle_pulse[counter] * duty) / 1000) & 0x0FFFF);
        TMM0_Set_Counter(1 << (ch + 1), high_level_Pulse[counter][ch]);
    }
    else if (counter == TIMERM_COUNTER1)
    {
        high_level_Pulse[counter][ch] = (((cycle_pulse[counter] * duty) / 1000) & 0x0FFFF);
        TMM1_Set_Counter(1 << (ch + 1), high_level_Pulse[counter][ch]);
    }
    else
    {
        return 1;
    }

    pwm_duty[counter][ch] = duty;
    return 0;
}

/**
 * @brief 改变TimerM 定时器x的PWM输出频率
 * 
 * @param counter 定时器x
 * @param freq PWM频率
 * @return uint8_t 0成功 非0失败
 * 
 * @note 频率范围有两种,50~2000 2001~最大,如果初始话的频率和目标频率在一个区间可以使用TimerM_PWM_set_freq2函数来优雅的切换频率,
 *                                          如果不在一个频率区间就需要使用TimerM_PWM_set_freq来不优雅的切换频率,
 *                                           如果看不懂注释也使用TimerM_PWM_set_freq来切换频率。
 */
uint8_t TimerM_PWM_set_freq(TIMERM_PWM_Counter_en_t counter, uint16_t freq )
{
    if (counter < TIMERM_COUNTER_MAX)
    {
        if (freq > 2000)
        {
            TIMM_InitStructure[counter].TMM_Clk                     = TMM_FCLK_Div1; // specify the operation clk of tim
            cycle_pulse[counter] = SystemCoreClock / freq;
        }
        // else if(freq >= 500)
        // {
        //     TIMM_InitStructure[counter].TMM_Clk                     = TMM_FCLK_Div8; // specify the operation clk of tim
        //     cycle_pulse[counter] = SystemCoreClock / 8 / freq;
        // }
        else if(freq >= 50)
        {
            TIMM_InitStructure[counter].TMM_Clk                     = TMM_FCLK_Div32; // specify the operation clk of tim
            cycle_pulse[counter] = SystemCoreClock / 32 / freq;
        }
        else
        {
            return 1;
        }

    }
    else
    {
        return 1;
    }
    
    high_level_Pulse[counter][TIMERM_CHB] = (((cycle_pulse[counter] * pwm_duty[counter][TIMERM_CHB]) / 1000) & 0x0FFFF);
    high_level_Pulse[counter][TIMERM_CHC] = (((cycle_pulse[counter] * pwm_duty[counter][TIMERM_CHC]) / 1000) & 0x0FFFF);
    high_level_Pulse[counter][TIMERM_CHD] = (((cycle_pulse[counter] * pwm_duty[counter][TIMERM_CHD]) / 1000) & 0x0FFFF);

    TIMM_InitStructure[counter].TMM_CHB_Pulse = high_level_Pulse[counter][TIMERM_CHB];
    TIMM_InitStructure[counter].TMM_CHC_Pulse = high_level_Pulse[counter][TIMERM_CHC];
    TIMM_InitStructure[counter].TMM_CHD_Pulse = high_level_Pulse[counter][TIMERM_CHD];

    
    TIMM_InitStructure[counter].TMM_CHA_Pulse = cycle_pulse[counter] & 0x0FFFF;

    TMM_Init(&TIMM_InitStructure[counter]);

    if (counter == TIMERM_COUNTER0)
    {
        TMM0_Start(ENABLE);
    }
    else if (counter == TIMERM_COUNTER1)
    {
        TMM1_Start(ENABLE);
    }
    return 0;
}


uint8_t TimerM_PWM_set_freq2(TIMERM_PWM_Counter_en_t counter, uint16_t freq )
{
    if (counter == TIMERM_COUNTER0) 
    {
        cycle_pulse[counter] = SystemCoreClock / freq;
        high_level_Pulse[counter][TIMERM_CHB] = (((cycle_pulse[counter] * pwm_duty[counter][TIMERM_CHB]) / 1000) & 0x0FFFF);
        high_level_Pulse[counter][TIMERM_CHC] = (((cycle_pulse[counter] * pwm_duty[counter][TIMERM_CHC]) / 1000) & 0x0FFFF);
        high_level_Pulse[counter][TIMERM_CHD] = (((cycle_pulse[counter] * pwm_duty[counter][TIMERM_CHD]) / 1000) & 0x0FFFF);
        TMM0_Set_Counter(1 << 1, high_level_Pulse[counter][TIMERM_CHB]);
        TMM0_Set_Counter(1 << 2, high_level_Pulse[counter][TIMERM_CHC]);
        TMM0_Set_Counter(1 << 3, high_level_Pulse[counter][TIMERM_CHD]);
        TMM0_Set_Counter(1, cycle_pulse[counter]);
    }
    else if (counter == TIMERM_COUNTER1)
    {
        cycle_pulse[counter] = SystemCoreClock / freq;
        high_level_Pulse[counter][TIMERM_CHB] = (((cycle_pulse[counter] * pwm_duty[counter][TIMERM_CHB]) / 1000) & 0x0FFFF);
        high_level_Pulse[counter][TIMERM_CHC] = (((cycle_pulse[counter] * pwm_duty[counter][TIMERM_CHC]) / 1000) & 0x0FFFF);
        high_level_Pulse[counter][TIMERM_CHD] = (((cycle_pulse[counter] * pwm_duty[counter][TIMERM_CHD]) / 1000) & 0x0FFFF);
        TMM1_Set_Counter(1 << 1, high_level_Pulse[counter][TIMERM_CHB]);
        TMM1_Set_Counter(1 << 2, high_level_Pulse[counter][TIMERM_CHC]);
        TMM1_Set_Counter(1 << 3, high_level_Pulse[counter][TIMERM_CHD]);
        TMM1_Set_Counter(1, cycle_pulse[counter]);
    }
    else
    {
        return 1;
    }
    
    return 0;

}

void TimerM_PWM_Init(void)
{
    
}