STM8S903K3基于ST Visual Develop开发定时器1中断示例
Posted perseverance52
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM8S903K3基于ST Visual Develop开发定时器1中断示例相关的知识,希望对你有一定的参考价值。
STM8S903K3基于ST Visual Develop开发定时器1中断示例
- 🎉在基于STVP环境下和IAR环境下,如果都使用寄存器操作,那么差异不大,主要在中断函数的书写上有差异。
📝本示例基于定时器1定时,产生中断来控制闪烁间隔时间,led引脚在PD7上。
🚩重装载值说明
如果是基于STVD寄存器开发,那么在写重装载寄存器的值时推荐将高低寄存器分开写,具体为什么,可以查看头文件寄存器地址具体位置就可以知道。
TIM5_ARRH = 0x00; // 自动重载寄存器ARR=0x007c
TIM5_ARRL = 0x7c; // 每1ms中断一次
TIM5_ARR = 0x7c;//自动重装的值,变成了每隔524ms一次了达不到预期。
- 头文件寄存器地址:
例如TIM5重装载寄存器,的高8位寄存器的地址和
TIM5_ARR
是相同的,如果直接赋值那相当于将重装载值直接赋值给了高8位的寄存器TIMx_ARRH
。这一点特别需要注意!
/* TIM5 Auto-reload register */
DEF_16BIT_REG_AT(TIM5_ARR,0x530f);
/* Data bits High */
DEF_8BIT_REG_AT(TIM5_ARRH,0x530f);
/* Data bits Low */
DEF_8BIT_REG_AT(TIM5_ARRL,0x5310);
- ⚡TIM1也是如此
/* TIM1 Auto-reload register */
DEF_16BIT_REG_AT(TIM1_ARR,0x5262);
/* Data bits High */
DEF_8BIT_REG_AT(TIM1_ARRH,0x5262);
/* Data bits Low */
DEF_8BIT_REG_AT(TIM1_ARRL,0x5263);
🌼示例一
🔖使用外部8MHz时钟源定时,500ms,让PD7引脚led状态翻转。
#include"stm8s903k3.h"
unsigned char i=0;
void Init_Timer1(void)
CLK_ECKR = 0x01; //开启外部时钟寄存器
CLK_SWR = 0xb4; //HSE外部时钟源作为主时钟源
CLK_CKDIVR = 0x00;//不分频
TIM1_CR1=0x01;//enable 使能计数器
//TIM1_IER=0x00;//disable TIMER
TIM1_IER=0x01;//更新中断使能
TIM1_EGR=0x01;
TIM1_CNTR=255;//计数器值
TIM1_ARR=255;//自动重装的值,相当于**TIM1_ARRH**高位是0xff
TIM1_PSCR=0x07;//分频值:2^7=128分频;T=128/8MHz=16us,16us*255*122=500ms
void Init_GPIO(void)
PD_DDR |=0x80;
PD_CR1 |=0x80;
PD_CR2 |=0x00;
void main()
Init_GPIO();
Init_Timer1();
_asm("rim");
while (1);
@far @interrupt void TIM1_UPD_OVF_IRQHandler (void)
i++;
TIM1_SR1=0x00;// 清除更新中断标记,这步不能漏掉
if(i==122)
PD_ODR ^= 0x80;
i=0;
return;
- 📈逻辑分析仪采集的波形
🌻示例二
🍁使用内部16MHz时钟源,定时1s,,让PD7引脚led状态翻转。
/* MAIN.C file
*
* Copyright (c) 2002-2005 STMicroelectronics
*/
#include"stm8s903k3.h"
unsigned char i=0;
void Init_Timer1(void)
// CLK_ECKR = 0x01; //开启外部时钟寄存器
// CLK_SWR = 0xb4; //HSE外部时钟源作为主时钟源
// CLK_CKDIVR = 0x00;//不分频
CLK_ICKR |= 0X01; //使能内部高速时钟 HSI
CLK_CKDIVR = 0x08; // 2分频
while(!(CLK_ICKR&0x02)); //HSI准备就绪
CLK_SWR =0xE1;//HSI内部时钟源作为主时钟源(复位值)
//TIM1_IER=0x00;//disable TIMER
CLK_PCKENR1 |=0x80; //外设时钟门控寄存器
TIM1_EGR=0x01;//计数器更新,可省略
TIM1_PSCR=0x07;//分频值:8
TIM1_CNTR=255;//计数器值
TIM1_ARR=255;//自动重装的值
TIM1_CR1=0x01;//enable 使能计数器
TIM1_IER=0x01;//更新中断使能
void Init_GPIO(void)
PD_DDR |=0x80;
PD_CR1 |=0x80;
PD_CR2 |=0x00;
void main()
_asm("sim"); //disable all interrupt
Init_GPIO();
Init_Timer1();
_asm("rim");//enable all interrupt
while (1);
@far @interrupt void TIM1_UPD_OVF_IRQHandler (void)
i++;
TIM1_SR1=0x00;// 清除更新中断标记,这步不能漏掉
if(i==122)
PD_ODR ^= 0x80;
i=0;
return;
-
📈逻辑分析仪采集的波形
-
两个示例中的
stm8_interrupt_vector.c
代码相同,都是采用的TIM1
,中断号:11
typedef void @far (*interrupt_handler_t)(void);
struct interrupt_vector
unsigned char interrupt_instruction;
interrupt_handler_t interrupt_handler;
;
@far @interrupt void NonHandledInterrupt (void)
/* in order to detect unexpected events during development,
it is recommended to set a breakpoint on the following instruction
*/
return;
extern @far @interrupt void TIM1_UPD_OVF_IRQHandler (void);
extern void _stext(); /* startup routine */
struct interrupt_vector const _vectab[] =
0x82, (interrupt_handler_t)_stext, /* reset */
0x82, NonHandledInterrupt, /* trap */
0x82, NonHandledInterrupt, /* irq0 */
0x82, NonHandledInterrupt, /* irq1 */
0x82, NonHandledInterrupt, /* irq2 */
0x82, NonHandledInterrupt, /* irq3 */
0x82, NonHandledInterrupt, /* irq4 */
0x82, NonHandledInterrupt, /* irq5 */
0x82, NonHandledInterrupt, /* irq6 */
0x82, NonHandledInterrupt, /* irq7 */
0x82, NonHandledInterrupt, /* irq8 */
0x82, NonHandledInterrupt, /* irq9 */
0x82, NonHandledInterrupt, /* irq10 */
0x82, TIM1_UPD_OVF_IRQHandler, /* irq11 */
0x82, NonHandledInterrupt, /* irq12 */
0x82, NonHandledInterrupt, /* irq13 */
0x82, NonHandledInterrupt, /* irq14 */
0x82, NonHandledInterrupt, /* irq15 */
0x82, NonHandledInterrupt, /* irq16 */
0x82, NonHandledInterrupt, /* irq17 */
0x82, NonHandledInterrupt, /* irq18 */
0x82, NonHandledInterrupt, /* irq19 */
0x82, NonHandledInterrupt, /* irq20 */
0x82, NonHandledInterrupt, /* irq21 */
0x82, NonHandledInterrupt, /* irq22 */
0x82, NonHandledInterrupt, /* irq23 */
0x82, NonHandledInterrupt, /* irq24 */
0x82, NonHandledInterrupt, /* irq25 */
0x82, NonHandledInterrupt, /* irq26 */
0x82, NonHandledInterrupt, /* irq27 */
0x82, NonHandledInterrupt, /* irq28 */
0x82, NonHandledInterrupt, /* irq29 */
;
示例二效果方式二(推荐)
与上面的主要的差异在于将分配寄存器进行高8位低8位进行了拆解。
#include"stm8s903k3.h"
void Init_Timer1(void)
// CLK_ECKR = 0x01; //开启外部时钟寄存器
// CLK_SWR = 0xb4; //HSE外部时钟源作为主时钟源
// CLK_CKDIVR = 0x00;//不分频
CLK_ICKR |= 0X01; //使能内部高速时钟 HSI
CLK_CKDIVR = 0x08; // 16M,2分频后8MHz
while(!(CLK_ICKR&0x02)); //HSI准备就绪
CLK_SWR =0xE1;//HSI内部时钟源作为主时钟源(复位值)
//TIM1_IER=0x00;//disable TIMER
CLK_PCKENR1 |=0x80; //外设时钟门控寄存器
TIM1_EGR=0x01;//计数器更新,可省略
TIM1_PSCRH = 0x1F; // 8M系统时钟经预分频f=fck/(PSCR+1)
TIM1_PSCRL = 0x3F; // PSCR=0x1F3F,f=8M/(0x1F3F+1)=1000Hz,每个计数周期1ms
TIM1_ARRH = 0x03; // 自动重载寄存器ARR=0x01F4=500;0X03E8=1000
TIM1_ARRL = 0xE8; // 每记数500次产生一次中断,即500ms
TIM1_RCR = 0x00; //重复计数器值
TIM1_SR1 = ( ~0x01 ); //清除更新中断标志
TIM1_CR1=0x01;//enable 使能计数器
TIM1_IER=0x01;//更新中断使能
void Init_GPIO(void)
PD_DDR |=0x80;// 配置PD端口的方向寄存器PD7输出
PD_CR1 |=0x80;// 设置PD7为推挽输出
PD_CR2 |=0x00;
void main()
_asm("sim"); //disable all interrupt
Init_GPIO();
Init_Timer1();
_asm("rim");
while (1);
@far @interrupt void TIM1_UPD_OVF_IRQHandler (void)
TIM1_SR1 =0x00;// 清除更新中断标记,这步不能漏掉
PD_ODR ^= 0x80;
以上是关于STM8S903K3基于ST Visual Develop开发定时器1中断示例的主要内容,如果未能解决你的问题,请参考以下文章
STM8S903K3基于ST Visual Develop开发定时器1中断示例
STM8S903K3T6C基于ST Visual Develop开发串口数据收发示例
STM8S903K3基于ST Visual Develop开发定时器5中断示例
STM8S903K3T6C基于ST Visual Develop开发输入输出按键检测示例