一、将前面建立好的工程文件PRINTF文件夹复制一份,命名为TIME. 将PRINTF\MDK\PRINTF.uvprojx,改为TIME.uvprojx.双击这个文件打开工程。
二、修改工程配置
1.组driver下面添加bt.c

2.source下面添加timer.c

timer.h
c
#ifndef __TIMER_H
#define __TIMER_H
#include "ddl.h"
void App_Timer0Cfg(uint16_t u16Period);
void App_Timer1Cfg(uint16_t u16Period);
#endif
定时器0/1//2/3都是通用定时器,定时器3的功能更加强大。模式 0 计数定时器功能,这是定时器最基本的功能,到达一定的计数就产生更新中断。
重载模式计数范围从 ARR 向上计数到 0xFFFF 溢出,然后从 ARR 再开始计数,计数周期为 0Xffff-ARR+1;自由计数模式从设置计数值计数到 0xFFFFFFFF 后溢出,溢出后计数值从 0x0 重新开始计数。这是手册原话,在代码中体现出来了。
timer.c
c
#include "timer.h"
#include "usart.h"
#include "gpio.h"
#include "bt.h"
/*******************************************************************************
* TIM0中断服务函数
******************************************************************************/
void Tim0_IRQHandler(void)
{
static uint8_t flag =0;
//Timer0 模式0 溢出中断
if(TRUE == Bt_GetIntFlag(TIM0, BtUevIrq))
{
Bt_ClearIntFlag(TIM0,BtUevIrq); //中断标志清零
if (flag){
Gpio_SetIO(GpioPortD, GpioPin5); ///< LED关闭
}else{
Gpio_ClrIO(GpioPortD, GpioPin5);
}
flag =!flag;
}
}
/*******************************************************************************
* TIM1中断服务函数
******************************************************************************/
void Tim1_IRQHandler(void)
{
uint8_t read;
//Timer1 模式0 溢出中断
if(TRUE == Bt_GetIntFlag(TIM1, BtUevIrq))
{
Bt_ClearIntFlag(TIM1,BtUevIrq); //中断标志清零
read = Gpio_GetInputIO(GpioPortD, GpioPin5);
Gpio_WriteOutputIO(GpioPortD, GpioPin5,read^1);
}
}
//Timer0配置初始化
void App_Timer0Cfg(uint16_t u16Period)
{
uint16_t u16ArrValue;
uint16_t u16CntValue;
stc_bt_mode0_cfg_t stcBtBaseCfg;
DDL_ZERO_STRUCT(stcBtBaseCfg);
Sysctrl_SetPeripheralGate(SysctrlPeripheralBaseTim, TRUE); //Base Timer外设时钟使能
stcBtBaseCfg.enWorkMode = BtWorkMode0; //定时器模式
stcBtBaseCfg.enCT = BtTimer; //定时器功能,计数时钟为内部PCLK
stcBtBaseCfg.enPRS = BtPCLKDiv256; //PCLK/256
stcBtBaseCfg.enCntMode = Bt16bitArrMode; //自动重载16位计数器/定时器
stcBtBaseCfg.bEnTog = FALSE;
stcBtBaseCfg.bEnGate = FALSE;
stcBtBaseCfg.enGateP = BtGatePositive;
Bt_Mode0_Init(TIM0, &stcBtBaseCfg); //TIM0 的模式0功能初始化
u16ArrValue = 0x10000 - u16Period;
Bt_M0_ARRSet(TIM0, u16ArrValue); //设置重载值(ARR = 0x10000 - 周期)
u16CntValue = 0x10000 - u16Period;
Bt_M0_Cnt16Set(TIM0, u16CntValue); //设置计数初值
Bt_ClearIntFlag(TIM0,BtUevIrq); //清中断标志
Bt_Mode0_EnableIrq(TIM0); //使能TIM0中断(模式0时只有一个中断)
EnableNvic(TIM0_IRQn, IrqLevel3, TRUE); //TIM0中断使能
}
//Timer1配置初始化
void App_Timer1Cfg(uint16_t u16Period)
{
uint16_t u16ArrValue;
uint16_t u16CntValue;
stc_bt_mode0_cfg_t stcBtBaseCfg;
DDL_ZERO_STRUCT(stcBtBaseCfg);
Sysctrl_SetPeripheralGate(SysctrlPeripheralBaseTim, TRUE); //Base Timer外设时钟使能
stcBtBaseCfg.enWorkMode = BtWorkMode0; //定时器模式
stcBtBaseCfg.enCT = BtTimer; //定时器功能,计数时钟为内部PCLK
stcBtBaseCfg.enPRS = BtPCLKDiv256; //PCLK/256
stcBtBaseCfg.enCntMode = Bt16bitArrMode; //自动重载16位计数器/定时器
stcBtBaseCfg.bEnTog = FALSE;
stcBtBaseCfg.bEnGate = FALSE;
stcBtBaseCfg.enGateP = BtGatePositive;
Bt_Mode0_Init(TIM1, &stcBtBaseCfg); //TIM1的模式0功能初始化
u16ArrValue = 0x10000 - u16Period;
Bt_M0_ARRSet(TIM1, u16ArrValue); //设置重载值(ARR = 0x10000 - 周期)
u16CntValue = 0x10000 - u16Period;
Bt_M0_Cnt16Set(TIM1, u16CntValue); //设置计数初值
Bt_ClearIntFlag(TIM1,BtUevIrq); //清中断标志
Bt_Mode0_EnableIrq(TIM1); //使能TIM1中断(模式0时只有一个中断)
EnableNvic(TIM1_IRQn, IrqLevel2, TRUE); //TIM1中断使能
}
要使用有定时器,当然要配置时钟,程序里面使用内部高速时钟,配置为48Mhz
c
#include "gpio.h"
#include "usart.h"
#include "flash.h"
#include "bt.h"
#include "timer.h"
static void App_LedInit(void);
//时钟配置初始化
void App_ClockCfg(void)
{
en_flash_waitcycle_t enWaitCycle;
stc_sysctrl_pll_cfg_t stcPLLCfg;
//结构体初始化清零
DDL_ZERO_STRUCT(stcPLLCfg);
enWaitCycle = FlashWaitCycle1;
Flash_WaitCycle(enWaitCycle);
stcPLLCfg.enInFreq = SysctrlPllInFreq4_6MHz; //RCH 4MHz
stcPLLCfg.enOutFreq = SysctrlPllOutFreq36_48MHz; //PLL 输出48MHz
stcPLLCfg.enPllClkSrc = SysctrlPllRch; //输入时钟源选择RCH
stcPLLCfg.enPllMul = SysctrlPllMul12; //4MHz x 12 = 48MHz
Sysctrl_SetPLLFreq(&stcPLLCfg);
Sysctrl_SetPLLStableTime(SysctrlPllStableCycle16384);
Sysctrl_ClkSourceEnable(SysctrlClkPLL, TRUE);
Sysctrl_SysClkSwitch(SysctrlClkPLL); ///< 时钟切换
}
int32_t main(void)
{
App_ClockCfg();
App_LedInit();
UART0_PortInit();//串口默认配置Pb8 为输出
Uart0Cfg(57600);
//App_Timer0Cfg(48000); //Timer0配置初始化(周期 = 48000*(1/48M)*256 = 256ms)
//Bt_M0_Run(TIM0); //TIM0 运行。
App_Timer1Cfg(18750); //100ms
Bt_M1_Run(TIM1);
printf("Sysctrl_GetHClkFreq : %d \r\n",Sysctrl_GetHClkFreq());
while(1)
{
printf("HC32L136K8TA-MINI......\r\n");
delay1ms(1000);
}
}
static void App_LedInit(void)
{
stc_gpio_cfg_t stcGpioCfg;
///< 打开GPIO外设时钟门控
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
///< 端口方向配置->输出(其它参数与以上(输入)配置参数一致)
stcGpioCfg.enDir = GpioDirOut;
///< 端口上下拉配置->无上下拉
stcGpioCfg.enPu = GpioPuDisable;
stcGpioCfg.enPd = GpioPdDisable;
///< LED关闭
Gpio_SetIO(GpioPortD, GpioPin5);
///< GPIO IO LED端口初始化
Gpio_Init(GpioPortD, GpioPin5, &stcGpioCfg);
}
编译烧录后打印如下,led灯闪烁正常

