打印
[STM8]

第一次用 定时器3,总结

[复制链接]
5746|45
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
明月小厨|  楼主 | 2012-12-9 12:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
定时器部分的头绪比较多;我用了T3;这个比T1要省事些;
任务:产生定时器T3中断,然后翻转PD0;(接了LED灯)
沙发
明月小厨|  楼主 | 2012-12-9 12:11 | 只看该作者
任务A:时钟部分先确定下来;
//下面设置相关的时钟参数,使用HIS = 16MHZ;
//使能T1,T2,T3,T4,I2C,ADC时钟;
void init_clk(void)
{
  CLK_CKDIVR = 0;//内部HSI时钟16MHZ全速运行
CLK_PCKENR1 = 0xF1;//TIM1,2,3,4有效;I2C有效;
  CLK_PCKENR2 = 0x08;//仅ADC有效;
}

使用特权

评论回复
板凳
明月小厨|  楼主 | 2012-12-9 12:13 | 只看该作者
本帖最后由 明月小厨 于 2012-12-9 12:20 编辑

任务B:让定时器T3跑起来;(在主程序里这是最后一步)
void init_T3(void)
{
  TIM3_PSCR = 0x09;//主频16MHZ,产生32uS的基准;
  TIM3_IER = 1;
  TIM3_ARRH = (1*1000000/32)>>8; //约1秒
  TIM3_ARRL = (unsigned char)(1000000/32);
  TIM3_CR1 = 1;//开启
}

使用特权

评论回复
地板
明月小厨|  楼主 | 2012-12-9 12:14 | 只看该作者
任务C:PD端口设置
//PD推拉输出模式,初值为0;(SWIM端口调试占用)
void init_PD(void)
{
  PD_ODR = 0;//输出数据寄存器
  PD_DDR = 0xFF;//方向寄存器 = 1表示输出模式
  PD_CR1 = 0xFF;//输出时为推拉模式
  PD_CR2 = 0;//输出速度最大为2MHZ;
}

使用特权

评论回复
5
明月小厨|  楼主 | 2012-12-9 12:15 | 只看该作者
任务D:
//这就是T3溢出中断,在这里点灯关灯
#pragma vector=0x11
__interrupt void TIM3_UPD_OVF_BRK_IRQHandler(void)
{
  PD_ODR++;//PD0位反相
  TIM3_SR1=0;//必须清中断标志位;
}

使用特权

评论回复
6
明月小厨|  楼主 | 2012-12-9 12:17 | 只看该作者
任务E:把所有的任务一个一个串起来;注意要开系统中断允许;
main()
{
asm("rim");//开中断
  init_clk();
  init_PD();
  Init_T3();
  while(1);//死循环体开始
}

使用特权

评论回复
7
明月小厨|  楼主 | 2012-12-9 12:18 | 只看该作者
上面这个例程在ST的开发板上跑;主要是PD0外接了灯;
CPU型号:STM8S105xx;

使用特权

评论回复
8
明月小厨|  楼主 | 2012-12-9 12:24 | 只看该作者
本帖最后由 明月小厨 于 2012-12-9 12:25 编辑

我从半夜开始搞,搞到天亮都没搞好,一觉起来接着干,现在通了;回顾一下.
把任务分解为ABC...,

希望对初学者有所帮助,少走点弯路,省出来的时间多睡觉;
(用的是IAR;如果是STVD相关的工具,中断函数的声明也许有些不同;)

使用特权

评论回复
9
明月小厨|  楼主 | 2012-12-9 12:44 | 只看该作者
本帖最后由 明月小厨 于 2012-12-9 12:45 编辑

下一步要做的测试项目:注意PD0的端口就是TIM3_CH2;
可以用这个做超低速的PWM测试;
点灯关灯将自动进行;这个不急,有空再做.

上例用的是溢出;pwm用的应该是比较;
pwm周期,极性,占空比三样;(推测)

使用特权

评论回复
10
Regsen| | 2012-12-9 14:05 | 只看该作者
楼主是使用库文件写的吧。我想要问一下,sam(“rim”)该语句是对哪里进行操作。我是使用寄存器操作的。现在中断无法产生

使用特权

评论回复
11
明月小厨|  楼主 | 2012-12-9 16:59 | 只看该作者
本帖最后由 明月小厨 于 2012-12-9 17:08 编辑

asm("rim");//开中断
是在IAR FOR STM8 C语言里嵌入最原始的汇编语句;意思是开系统中断;
如果是COSMIC
_asm("rim"); 意思一样,格式稍有差异.

使用特权

评论回复
12
明月小厨|  楼主 | 2012-12-9 17:11 | 只看该作者
中断的几个概念:
1)全局中断允许;
2)对应的外设有相应的寄存器;要设为允许中断;
3)中断服务程序里要清中断的标志位;

使用特权

评论回复
13
Regsen| | 2012-12-9 21:17 | 只看该作者
对的,楼主。在库文件内部有说明。我这里有一个很奇怪的问题,查不到问题的所在。我使用定时器1,捕获通道1 来计算某个电机的转速,在仿真的时候,一旦进入了中断就会一直在该中断中反复的循环运行。当然我是用寄存器操作的。手册上说读取CCR1L的时候,中断标志位清除。我不放心,还手动清除了一遍。依旧不停的从中断第一个语句开始往下走。。。回不到主程序了。实在是没想法了

未命名.jpg (26.59 KB )

未命名.jpg

使用特权

评论回复
14
明月小厨|  楼主 | 2012-12-9 22:14 | 只看该作者
Regsen 发表于 2012-12-9 21:17
对的,楼主。在库文件内部有说明。我这里有一个很奇怪的问题,查不到问题的所在。我使用定时器1,捕获通道1 ...

你输入端的电平是怎么设的?不能悬浮;
你的问题其实就是中断的条件一直成立;所以中断处理完成后,退出中断,然后又进去了;

使用特权

评论回复
15
明月小厨|  楼主 | 2012-12-9 22:18 | 只看该作者
测试方法:
设一全局变量,每处理一次中断你就计数一次;这样可以观察,一段时间内中断发生过多少次;
在中断处理程序里把总的中断允许关掉,所有的中断都不响应,这下总可以出来了吧;
读写某些寄存器有可能触发新的事件,而从产生了新的中断;在退出中断服务前,清理中断标志位;
一定是自己在某个环节没注意;一个点一个点怀疑.

使用特权

评论回复
16
明月小厨|  楼主 | 2012-12-9 22:20 | 只看该作者
在退出中断前你把中断标志寄存器复制一份出来;看看是那一位又有新的请求;
复制完关全局中断,然后你再分析;

使用特权

评论回复
17
明月小厨|  楼主 | 2012-12-9 22:30 | 只看该作者
8个中断源挂在二个中断向量上,这是多么不好的事情啊;

使用特权

评论回复
18
明月小厨|  楼主 | 2012-12-10 02:18 | 只看该作者
TIM3 H2通道,PWM测试一次性成功(调整LED灯的亮度);没费什么事;比较轻松;

使用特权

评论回复
19
Regsen| | 2012-12-10 09:06 | 只看该作者
贺喜楼主,这么晚还在奋战。

使用特权

评论回复
20
明月小厨|  楼主 | 2012-12-10 11:00 | 只看该作者
本帖最后由 明月小厨 于 2012-12-10 11:14 编辑

/*TIM3第2通道(PD0),控制LED灯亮度;*/
/*自动进行*/
/*和IO端口对应的寄存器好象不需要设置,以TIM的设置为准*/

void T3_PWM_CH2_init(unsigned char t)
{
  //任务A:设PWM周期;
  TIM3_PSCR = 0x00;//预分频器;主频HSI = 16MHZ,产生(1/16)uS的基准;
  TIM3_IER = 0;       //中断使能寄存器;不允许中断
  TIM3_ARRH = 0x10;  //自动装载寄存器;16*256/16 = 256uS;周期是256uS;
  TIM3_ARRL = 0;
  
  //任务B:设PWM的模式,有效电平定义并接至外部引脚;
  //CC2为比较输出,PWM2模式;(CNT>CCR时为有效电平:低:亮灯)
  TIM3_CCMR2 = 0x70; //H2通道的比较模式寄存器
  TIM3_CCER1 = 0x30; //比较使能寄存器;OC2有效时低电平,OC2输出到引脚;
  
  //任务C:占空比和ARR及CRR2有直接关系;  
  TIM3_CCR2H  =  t;  //和ARR对应,影响占空比,不能超过ARRH;
  TIM3_CCR2L  =  0;
  
  //任务D:清理战场并点火启动;
  TIM3_EGR=0X01;//事件产生寄存器;产生一次更新事件,计数器分频器归零;
  TIM3_SR1=0;//状态寄存器
  TIM3_SR2=0;//状态寄存器  
  TIM3_CR1 = 0X81;//各项参数初始化完毕,开启TIM3
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:爱你一万年

35

主题

1072

帖子

2

粉丝