这篇来学习下定时器0的配置和应用,通过定时器0来学习,实现1MS定时中断。
一、定时器0时钟
定时器0有两个通道A和B,这里使用定时器0的通道B,时钟选择PCLK1。
PCLK1在主时钟的位置
二、程序部分
2.1、主时钟部分
PCLK1经2分频后得到120MHz频率的时钟。
__WEAKDEF void BSP_CLK_Init(void)
{
stc_clock_xtal_init_t stcXtalInit;
stc_clock_pll_init_t stcPLLHInit;
/* PCLK0, HCLK Max 240MHz */
/* PCLK1, PCLK4 Max 120MHz */
/* PCLK2, PCLK3 Max 60MHz */
/* EX BUS Max 120MHz */
CLK_SetClockDiv(CLK_BUS_CLK_ALL, \
(CLK_PCLK0_DIV1 | CLK_PCLK1_DIV2 | CLK_PCLK2_DIV4 | \
CLK_PCLK3_DIV4 | CLK_PCLK4_DIV2 | CLK_EXCLK_DIV2 | \
CLK_HCLK_DIV1));
GPIO_AnalogCmd(BSP_XTAL_PORT, BSP_XTAL_IN_PIN | BSP_XTAL_OUT_PIN, ENABLE);
(void)CLK_XtalStructInit(&stcXtalInit);
/* Config Xtal and enable Xtal */
stcXtalInit.u8Mode = CLK_XTAL_MD_OSC;
stcXtalInit.u8Drv = CLK_XTAL_DRV_ULOW;
stcXtalInit.u8State = CLK_XTAL_ON;
stcXtalInit.u8StableTime = CLK_XTAL_STB_2MS;
(void)CLK_XtalInit(&stcXtalInit);
(void)CLK_PLLStructInit(&stcPLLHInit);
/* VCO = (8/1)*120 = 960MHz*/
stcPLLHInit.u8PLLState = CLK_PLL_ON;
stcPLLHInit.PLLCFGR = 0UL;
stcPLLHInit.PLLCFGR_f.PLLM = 1UL - 1UL;
stcPLLHInit.PLLCFGR_f.PLLN = 120UL - 1UL;
stcPLLHInit.PLLCFGR_f.PLLP = 4UL - 1UL;
stcPLLHInit.PLLCFGR_f.PLLQ = 4UL - 1UL;
stcPLLHInit.PLLCFGR_f.PLLR = 4UL - 1UL;
stcPLLHInit.PLLCFGR_f.PLLSRC = CLK_PLL_SRC_XTAL;
(void)CLK_PLLInit(&stcPLLHInit);
/* Highspeed SRAM set to 0 Read/Write wait cycle */
SRAM_SetWaitCycle(SRAM_SRAMH, SRAM_WAIT_CYCLE0, SRAM_WAIT_CYCLE0);
/* SRAM1_2_3_4_backup set to 1 Read/Write wait cycle */
SRAM_SetWaitCycle((SRAM_SRAM123 | SRAM_SRAM4 | SRAM_SRAMB), SRAM_WAIT_CYCLE1, SRAM_WAIT_CYCLE1);
/* 0-wait @ 40MHz */
(void)EFM_SetWaitCycle(EFM_WAIT_CYCLE5);
/* 4 cycles for 200 ~ 250MHz */
GPIO_SetReadWaitCycle(GPIO_RD_WAIT4);
CLK_SetSysClockSrc(CLK_SYSCLK_SRC_PLL);
}
2.2、timer0.c
#include "main.h"
#include "led.h"
/* TMR0 unit and channel definition */
#define TMR0_UNIT (CM_TMR0_1)
#define TMR0_CH (TMR0_CH_B)
#define TMR0_CH_INT (TMR0_INT_CMP_B)
#define TMR0_CH_FLAG (TMR0_FLAG_CMP_B)
#define TMR0_INT_SRC (INT_SRC_TMR0_1_CMP_B)
#define TMR0_IRQn (INT006_IRQn)
void init_timer0(void)
{
stc_tmr0_init_t stcTmr0Init;
stc_irq_signin_config_t stcIrqSignConfig;
(void)TMR0_StructInit(&stcTmr0Init);
stcTmr0Init.u32ClockSrc = TMR0_CLK_SRC_INTERN_CLK;
stcTmr0Init.u32ClockDiv = TMR0_CLK_DIV8;
stcTmr0Init.u32Func = TMR0_FUNC_CMP;
stcTmr0Init.u16CompareValue = 15000;
(void)TMR0_Init(TMR0_UNIT, TMR0_CH, &stcTmr0Init);
TMR0_HWStopCondCmd(TMR0_UNIT, TMR0_CH, ENABLE);
TMR0_IntCmd(TMR0_UNIT, TMR0_CH_INT, ENABLE);
stcIrqSignConfig.enIntSrc = TMR0_INT_SRC;
stcIrqSignConfig.enIRQn = TMR0_IRQn;
stcIrqSignConfig.pfnCallback = &TMR0_CompareIrqCallback;
(void)INTC_IrqSignIn(&stcIrqSignConfig);
NVIC_ClearPendingIRQ(stcIrqSignConfig.enIRQn);
NVIC_SetPriority(stcIrqSignConfig.enIRQn, DDL_IRQ_PRIO_DEFAULT);
NVIC_EnableIRQ(stcIrqSignConfig.enIRQn);
TMR0_Start(TMR0_UNIT, TMR0_CH);
}
定时器输入时钟的选择
a> 时钟选择内部的PCLK1时钟
b> 分频选择分频 ,输入时钟的内部时钟=120/8=15MHz
c> 输出比较功能
d> 实现1ms的比较值=15000,15个时钟是1us,15*1000实现1MS;
uint32_t t0_cnt=0;
static void TMR0_CompareIrqCallback(void)
{
t0_cnt++;
if(t0_cnt>99)
{
t0_cnt=0;
BSP_LED_Toggle(LED_BLUE);
}
led1_tog();
TMR0_ClearStatus(TMR0_UNIT, TMR0_CH_FLAG);
}
三、输出波形
测量led1(PE2)的波形:
引用: 秦天qintian0303 发表于 2023-2-23 21:35 通道A和通道B有什么区别吗?为什么要这么分
从资料上看,通道A和通道B有着相同的结构,可以单独配置,不通的中断地址。和之前使用的其他芯片定时器不太一样。
引用: lugl4313820 发表于 2023-2-24 07:50 例子配置非常详细,这示波器非常有特色呀。什么牌子的。
老掉牙的TEK示波器