- #include "gpio.h"
 
- void led_init(void)
 
- {
 
-     stc_gpio_cfg_t stcGpioCfg;
 
-     Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); 
 
-     stcGpioCfg.enDir = GpioDirOut;
 
-     stcGpioCfg.enPu = GpioPuDisable;
 
-     stcGpioCfg.enPd = GpioPdEnable;
 
-     Gpio_ClrIO(STK_LED_PORT, STK_LED_PIN);
 
-     Gpio_Init(STK_LED_PORT, STK_LED_PIN, &stcGpioCfg);
 
- }
 
 
- void key_init(void)
 
- {
 
-     stc_gpio_cfg_t stcGpioCfg;
 
-     Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); 
 
-     stcGpioCfg.enDir = GpioDirIn;
 
-     stcGpioCfg.enPu = GpioPuDisable;
 
-     stcGpioCfg.enPd = GpioPdDisable;
 
-     Gpio_Init(STK_USER_PORT, STK_USER_PIN, &stcGpioCfg);
 
- }
 
 
- int32_t main(void)
 
- {
 
-     led_init();
 
-     key_init();
 
 
-     while(1)
 
-     {
 
-         if(Gpio_GetInputIO(STK_USER_PORT, STK_USER_PIN) == FALSE)
 
-         {
 
-             delay1ms(10);
 
-             while(Gpio_GetInputIO(STK_USER_PORT, STK_USER_PIN) == FALSE);
 
-             Gpio_WriteOutputIO(STK_LED_PORT, STK_LED_PIN,!Gpio_ReadOutputIO(STK_LED_PORT, STK_LED_PIN));
 
-         }
 
-     }
 
- }
 
3.2按键中断方式
与上面的轮询方法不同,这种方式并不用一直查询GPIO的状态,按键状态改变时会产生中断,程序在检测到中断后再判断按键状态
查看interrupts_hc32l19x.c这个文件,这是官方提供的一个统一中断入口文件
 
可以看到在GPIOA的中断函数里调用了PortA_IRQHandler这个方法,这个方法面用了__WEAK声明
 
按照interrupts_hc32l19x.h的注释说明,可以在需要的地方重新定义这个方法
 
使用这种方式要把这里填上
 
代码示例
- #include "gpio.h"
 
- void led_init(void)
 
- {
 
-     stc_gpio_cfg_t stcGpioCfg;
 
-     Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); 
 
-     stcGpioCfg.enDir = GpioDirOut;
 
-     stcGpioCfg.enPu = GpioPuDisable;
 
-     stcGpioCfg.enPd = GpioPdEnable;
 
-     Gpio_ClrIO(STK_LED_PORT, STK_LED_PIN);
 
-     Gpio_Init(STK_LED_PORT, STK_LED_PIN, &stcGpioCfg);
 
- }
 
 
- void key_init(void)
 
- {
 
-     stc_gpio_cfg_t stcGpioCfg;
 
-     Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); 
 
-     stcGpioCfg.enDir = GpioDirIn;
 
-     stcGpioCfg.enDrv = GpioDrvL;
 
-     stcGpioCfg.enPu = GpioPuDisable;
 
-     stcGpioCfg.enPd = GpioPdDisable;
 
-     Gpio_Init(STK_USER_PORT, STK_USER_PIN, &stcGpioCfg);
 
-     Gpio_EnableIrq(STK_USER_PORT, STK_USER_PIN, GpioIrqFalling);
 
-     EnableNvic(PORTA_IRQn, IrqLevel3, TRUE);
 
- }
 
 
- void PortA_IRQHandler(void)
 
- {
 
-     if(TRUE == Gpio_GetIrqStatus(STK_USER_PORT, STK_USER_PIN))
 
-     {            
 
-         if(Gpio_GetInputIO(STK_USER_PORT, STK_USER_PIN) == FALSE)
 
-         {
 
-             Gpio_WriteOutputIO(STK_LED_PORT, STK_LED_PIN,!Gpio_ReadOutputIO(STK_LED_PORT, STK_LED_PIN));
 
-         }
 
-         Gpio_ClearIrq(STK_USER_PORT, STK_USER_PIN);    
 
-     }
 
- }
 
 
- int32_t main(void)
 
- {
 
-     led_init();
 
-     key_init();
 
 
-     while(1)
 
-     {
 
-         ;
 
-     }
 
- }
 
3.3定时器测试
HC32L196有4个通用定时器、2个低功耗定时器和3个高级定时器,还有一个PCA(可编程计数器阵列)也可作为定时器使用
选用Timer0做一个每1ms触发一次的定时器,用它来控制LED闪烁,按键调节闪烁速度
首先设置一下系统时钟,不做任何更改时用的是内部时4M时钟
 
板子上有个32M的外部晶振,接下来使用它作为时钟源
- void xth_init()
 
- {
 
-     //当使用的时钟源HCLK大于24M:设置FLASH 读等待周期为1 cycle
 
-     Flash_WaitCycle(FlashWaitCycle1);    
 
-     Sysctrl_SetXTHFreq(SysctrlXthFreq24_32MHz);
 
-     Sysctrl_XTHDriverCfg(SysctrlXtalDriver3);
 
-     Sysctrl_SetXTHStableTime(SysctrlXthStableCycle16384);
 
-     Sysctrl_ClkSourceEnable(SysctrlClkXTH, TRUE);
 
-     delay1ms(10);
 
-     Sysctrl_SysClkSwitch(SysctrlClkXTH);
 
- }
 
- void timer0_init()
 
- {
 
-     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      = BtPCLKDiv32;                  //PCLK/32 32M/32=1M
 
-     stcBtBaseCfg.enCntMode  = Bt16bitArrMode;               //自动重载16位计数器/定时器
 
-     stcBtBaseCfg.bEnTog     = FALSE;
 
-     stcBtBaseCfg.bEnGate    = FALSE;
 
-     Bt_Mode0_Init(TIM0, &stcBtBaseCfg);                     //TIM0 的模式0功能初始化
 
-     
 
-     Bt_M0_ARRSet(TIM0, 0x10000-1000);                       //设置重载值
 
-     Bt_M0_Cnt16Set(TIM0, 0x10000-1000);                     //设置计数初值
 
-     
 
-     Bt_ClearIntFlag(TIM0,BtUevIrq);                         //清中断标志   
 
-     Bt_Mode0_EnableIrq(TIM0);                               //使能TIM0中断
 
-     EnableNvic(TIM0_IRQn, IrqLevel3, TRUE);                 //TIM0中断使能
 
-     Bt_M0_Run(TIM0);                                        //TIM0 运行。
 
- }
- uint16_t timecount = 0;
 
- uint16_t timecount_max = 500;
 
- void Tim0_IRQHandler(void)
 
- {
 
-     //Timer0 模式0 溢出中断
 
-     if(TRUE == Bt_GetIntFlag(TIM0, BtUevIrq))
 
-     {
 
-         if(timecount < timecount_max)
 
-             timecount += 1;
 
-         else
 
-         {
 
-             timecount = 0;
 
-             Gpio_WriteOutputIO(STK_LED_PORT, STK_LED_PIN,!Gpio_ReadOutputIO(STK_LED_PORT, STK_LED_PIN));
 
-         }
 
-         Bt_ClearIntFlag(TIM0,BtUevIrq); //中断标志清零
 
-     }
 
- }
 
- void PortA_IRQHandler(void)
 
- {
 
-     if(TRUE == Gpio_GetIrqStatus(STK_USER_PORT, STK_USER_PIN))
 
-     {            
 
-         if(Gpio_GetInputIO(STK_USER_PORT, STK_USER_PIN) == FALSE)
 
-         {
 
-             if(timecount_max == 500)
 
-                 timecount_max = 200;
 
-             else if(timecount_max == 200)
 
-                 timecount_max = 1000;
 
-             else
 
-                 timecount_max = 500;
 
-         }
 
-         Gpio_ClearIrq(STK_USER_PORT, STK_USER_PIN);    
 
-     }
 
 
- }
- int32_t main(void)
 
- {
 
-     xth_init();
 
-     //时钟分频设置
 
-     Sysctrl_SetHCLKDiv(SysctrlHclkDiv1);
 
-     Sysctrl_SetPCLKDiv(SysctrlPclkDiv1);
 
-     led_init();
 
-     key_init();
 
-     timer0_init();
 
-     while(1)
 
-     {
 
-         ;
 
-     }
 
- }
 
3.4PWM输出测试
4个通用定时器3个高级定时器和PCA都有输出PWM的能力,然而开发板上LED所接的PD14这个IO并不能输出PWM
 
因此外接2个LED来测试PWM,选用PA00和PA01作为Timer1的两个PWM通道输出
 
初始化为PWM输出
- void pwm_led_init()
 
- {
 
-     stc_gpio_cfg_t stcLEDPort;
 
-     DDL_ZERO_STRUCT(stcLEDPort);
 
-     
 
-     Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
 
-     stcLEDPort.enDir  = GpioDirOut;
 
-     Gpio_Init(GpioPortA, GpioPin0, &stcLEDPort);
 
-     Gpio_SetAfMode(GpioPortA,GpioPin0,GpioAf5);            //PA00设置为TIM1_CHA
 
-     
 
-     Gpio_Init(GpioPortA, GpioPin1, &stcLEDPort);
 
-     Gpio_SetAfMode(GpioPortA,GpioPin1,GpioAf5);            //PA01设置为TIM1_CHB
 
- }
 
 
这里选用PWM2上计数,锯齿波单点比较,时钟32分频计数周期1000
- void pwm_timer1_init()
 
- {
 
-     stc_bt_mode23_cfg_t        stcBtBaseCfg;
 
-     stc_bt_m23_compare_cfg_t   stcBtPortCmpCfg;
 
 
-     DDL_ZERO_STRUCT(stcBtBaseCfg);
 
-     DDL_ZERO_STRUCT(stcBtPortCmpCfg);
 
-     Sysctrl_SetPeripheralGate(SysctrlPeripheralBaseTim, TRUE);  
 
-     stcBtBaseCfg.enWorkMode    = BtWorkMode2;              //锯齿波模式
 
-     stcBtBaseCfg.enCT          = BtTimer;                  //定时器功能,计数时钟为内部PCLK
 
-     stcBtBaseCfg.enPRS         = BtPCLKDiv32;              //PCLK
 
-     stcBtBaseCfg.enCntDir      = BtCntUp;                  //向上计数,在三角波模式时只读
 
-     stcBtBaseCfg.enPWMTypeSel  = BtIndependentPWM;         //独立输出PWM
 
-     stcBtBaseCfg.enPWM2sSel    = BtSinglePointCmp;         //单点比较功能
 
-     stcBtBaseCfg.bOneShot      = FALSE;                    //循环计数
 
-     stcBtBaseCfg.bURSSel       = FALSE;                    //上下溢更新
 
-     Bt_Mode23_Init(TIM1, &stcBtBaseCfg);                   //TIM0 的模式23功能初始化
 
-     
 
-     Bt_M23_ARRSet(TIM1, 1000-1, TRUE);                  //设置重载值,并使能缓存
 
-     Bt_M23_CCR_Set(TIM1, BtCCR0A, 0);         //设置比较值A
 
-     Bt_M23_CCR_Set(TIM1, BtCCR0B, 0);         //设置比较值B
 
-     
 
-     stcBtPortCmpCfg.enCH0ACmpCtrl   = BtPWMMode2;          //OCREFA输出控制OCMA:PWM模式2
 
-     stcBtPortCmpCfg.enCH0APolarity  = BtPortPositive;      //正常输出
 
-     stcBtPortCmpCfg.bCh0ACmpBufEn   = TRUE;                //A通道缓存控制
 
-     stcBtPortCmpCfg.enCh0ACmpIntSel = BtCmpIntNone;        //A通道比较控制:无
 
-     
 
-     stcBtPortCmpCfg.enCH0BCmpCtrl   = BtPWMMode2;          //OCREFB输出控制OCMB:PWM模式2
 
-     stcBtPortCmpCfg.enCH0BPolarity  = BtPortPositive;      //正常输出
 
-     stcBtPortCmpCfg.bCH0BCmpBufEn   = TRUE;                //B通道缓存控制使能
 
-     stcBtPortCmpCfg.enCH0BCmpIntSel = BtCmpIntNone;        //B通道比较控制:无
 
-     
 
-     Bt_M23_PortOutput_Cfg(TIM1, &stcBtPortCmpCfg);         //比较输出端口配置
 
-                                                             //事件更新周期设置,0表示锯齿波每个周期更新一次,每+1代表延迟1个周期
 
-     Bt_M23_SetValidPeriod(TIM1,0);             //间隔周期设置
 
-     Bt_M23_Cnt16Set(TIM1, 0);                    //设置计数初值
 
-     Bt_M23_EnPWM_Output(TIM1, TRUE, FALSE);    //TIM0 端口输出使能
 
-     Bt_M23_Run(TIM1); 
 
- }
- int32_t main(void)
 
- {
 
-     uint16_t pwm = 0;
 
-     xth_init();
 
-     //时钟分频设置
 
-     Sysctrl_SetHCLKDiv(SysctrlHclkDiv1);
 
-     Sysctrl_SetPCLKDiv(SysctrlPclkDiv1);
 
-     led_init();
 
-     key_init();
 
-     timer0_init();
 
-     pwm_led_init();
 
-     pwm_timer1_init();
 
 
-     while(1)
 
-     {
 
-         if(pwm<2000)
 
-             pwm += 1;
 
-         else
 
-             pwm = 0;
 
-         if(pwm < 1000)
 
-         {
 
-             Bt_M23_CCR_Set(TIM1, BtCCR0A, pwm);
 
-             Bt_M23_CCR_Set(TIM1, BtCCR0B, 1000-pwm);
 
-         }
 
-         else
 
-         {
 
-             Bt_M23_CCR_Set(TIM1, BtCCR0A, 2000 - pwm);
 
-             Bt_M23_CCR_Set(TIM1, BtCCR0B, pwm - 1000);
 
-         }
 
-         delay1ms(2);
 
-     }
 
- }
