arduino定时器pdf_【图片】【经验分享】atmega 328p的定时器1的精确定时【arduino吧】_百度贴吧...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

我花了一个星期在学习使用atmega 328p的定时器来精确定时,最后成功学会使用。(稍后送上视频)过程中有很多问题,下面我将给大家总结一下我的经验:

使用的材料就只有Arduino uno r3(atmega 328p), Arduino IDE 1.0.5环境

501d61510e5c5f39c59e550a4325a841.png

首先,我的目的是使板子上的13管脚的LED灯隔一秒亮一次。

原理是计数器1/(晶振频率*分频数) 秒会自加1,最后从初值加到65535(0xFFFF)再加一就溢出,计数器清零,计数器一溢出就可以调用溢出中断程序,程序里来改变管脚状态。

开始:

1) 初始化,需要配置相关的寄存器,使用定时器1(Timer/Counter1),因为只有它是16位的定时器,能定时超过一秒。

代码如下:

cli();关全局中断

TCCR1A=0; //寄存器A是配置PWM的,这里我们只是使用定时功能,其实不需要配置

TCCR1B=(1<

TCNT1=0XC2F6; //计数器初值,1s定时

TIMSK1=(1<

DDRB|=(1<

PORTB|=(0<

sei(); //开全局中断

大家的疑问是这个计数器TCNT1怎么设置?

根据技术文档是这样计算的: TCNT1=0Xffff - 定时时间/(分频数* (1/晶振频率))

分频数是调整计数的,越大计数越慢,一般有1、8、64、256、1024分频。

晶振频率就是板子上那个晶振,我的是16M,虽然这里说的是内部晶振,但这里不是这个实验的重点所以有疑问的请查看技术文档。

所以:TCNT1= 0XFFFF - 1 / (1024 *(1/16000000))= 0xFFFF –0x3D09=0XC2F6;

2) 接下来就是中断程序,网上很多写中断的例子,我都试过但失败了,最后去查看interrupt.h才找到中断程序的定义使用(仅限Arduino IDE),格式:

ISR(中断向量){

中断程序;

}

代码如下:

ISR(TIMER1_OVF_vect){ // TIMER1_OVF_vect是中断溢出向量,不同芯片具体定义还是要去头文件定义和技术文档查看,执行溢出中断程序后,溢出标志位自动清零,不需要置零

TCNT1=0XC2F6; //设置计数器为初值重新技术

PORTB=(~PORTB)&(1<

}

3) 试编译,修改语法错误。

完整程序代码:

#include

#include

#define FOCS 16000000

void DEVICE_INIT(void){

cli();

TCCR1A=0;

TCCR1B=(1<

TCNT1=0XC2F6;

TIMSK1=(1<

DDRB|=(1<

PORTB|=(0<

sei();

}

ISR(TIMER1_OVF_vect){

TCNT1=0XC2F6;

PORTB=(~PORTB)&(1<

}

void setup(){

DEVICE_INIT();

}

void loop(){

}

注意:

1)#include,要的,不然ISR就提示出错!

2)不同的模式计算计数器TCNT1值有不同,需要查询技术文档!

3)中断程序不执行的情况先看第一条,否则就是你晶振频率弄错或者分频数太小,导致灯闪频率太快,看不出变化,其实已经执行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值