世俱杯 2025

登录 免费注册 世俱杯 2025 | 行业黑名单 | 帮助
维库电子市场网
技术交流 | 电路欣赏 | 工控天地 | 数字广电 | 通信技术 | 电源技术 | 测控之家 | EMC技术 | ARM技术 | EDA技术 | PCB技术 | 嵌入式系统
驱动编程 | 集成电路 | 器件替换 | 模拟技术 | 新手园地 | 单 片 机 | DSP技术 | MCU技术 | IC 设计 | IC 产业 | CAN-bus/DeviceNe

在定时器1中断中为何必须写入TCNT1L???

作者:hotpower 栏目:单片机
在定时器1中断中为何必须写入TCNT1L???
一直用8MHZ晶振,今天由于产品需要定时准些,就改为7.3728MHZ.芯片M8L.
要求定时2.5mS,采用8分频(TCCR1B = 2),时间常数TCNT1H=0xf7,TCNT1L=0x00.

#define DefTCNT1H 0xf7
#define DefTCNT1L 0x00
//2.5mS定时器
SIGNAL(SIG_OVERFLOW1)
{
  TCNT1L = DefTCNT1L;
  TCNT1H = DefTCNT1H;//2.5mS
//.................................
}

为何不能:
//2.5mS定时器
SIGNAL(SIG_OVERFLOW1)
{
//  TCNT1L = DefTCNT1L;
  TCNT1H = DefTCNT1H;//2.5mS
//.................................
}

TCNT1应该是加一器,那么定时到后TCNT1从0xffff到0,即TCNT1H = 0,TCNT1L = 0.

那么在中断中省略TCNT1L = DefTCNT1L;应该没问题.
就算TCNT1在0xffff时不归零,即TCNT1L = 0xff.

那么中断程序实际为TCNT1L = 0xff.而TCNT1H = DefTCNT1H给出了新值.

依据此判断,定时应该加快才是,但结果却相反!!!

问题即为:
    在定时中断中,若不改写TCNT1L的值,定时将加长,实验结果至少数倍以上!!!


难道我又犯了一个低级错误???

在51时这种省略时间常数低8位的写法可以提高定时精度而且可以少写一条指令.
不知在AVR上为何不行???

郁闷...TCNT1L不就是一个0x00~0xff的数吗???不写应该也有值呀!!!

2楼: >>参与讨论
ipman
TCNT1=0xf7ff直接测试,如果没问题就是低级问题
 
3楼: >>参与讨论
hotpower
不解...
 TCNT1=0xf700~TCNT1=0xf7ff无非差一点点...

我的郁闷在于为何非要在中断中重写TCNT1L...

难道访问TCNT1时,必须高低8位都要访问吗???

估计是个低级错误.难道不访问TCNT1L,就是访问TCNT1H也不管用.

这样进入中断后虽然改写TCNT1H,但实际上TCNT1H不变(实际为0),故延时加长(0x100/(0x100-0xf7))



4楼: >>参与讨论
testcode
必须写入TCNT1L,才能更新TCNT1H!
datasheet:
"Accessing 16-bit Registers"
"TCNT1H is updated with the temporary register VALUE when TCNT1L is written. "

* - 本贴最后修改时间:2005-7-10 6:52:55 修改者:testcode

5楼: >>参与讨论
AVRx007
呵呵! hotpower也犯了个AVR的基本错误。
 
6楼: >>参与讨论
hotpower
基本错误犯多了有好处
"写16 位寄存器时,应先写入该寄存器的高位字节。而读16 位寄存器时应先读取该寄存器的低位字节。"

"访问低字节会触发16位读或写操作。"

"16 位计数器映射到两个8 位I/O存储器位置:TCNT1H为高8 位,TCNT1L 为低8 位。CPU只能间接访问TCNT1H 寄存器。CPU 访问TCNT1H 时,实际访问的是临时寄存器(TEMP)。读取TCNT1L时,临时寄存器的内容更新为TCNT1H的数值;而对TCNT1L执行写操作时,TCNT1H 被临时寄存器的内容所更新。"


#define DefTCNT1H 0xf7
#define DefTCNT1L 0x00

void Timer1Init(void)
{
  TCNT1H = DefTCNT1H;//2.5mS
  TCNT1L = DefTCNT1L;
//.............................
}

//2.5mS定时器
SIGNAL(SIG_OVERFLOW1)
{
volatile unsigned CHAR TEMP;
  TCNT1H = DefTCNT1H;//2.5mS//是否写入TCNT1H的缓冲区???但并非改写TCNT1H
//  TCNT1L = DefTCNT1L;//假如其他中断使定时器1中断滞后使TCNT1L在此远远大于DefTCNT1L但小于0xff
  TEMP = TCNT1L;//读TCNT1L才真正写入TCNT1H???
//.................................
}


为不改写TCNT1L且写入TCNT1H,以上指令不知对否???
TEMP变量实际没用,主要想读TCNT1L激活对TCNT1H的写入.

由于7.3728MHZ在定时2.5mS时理论误差为0,但由于定时中断由于某些原因而不能

及时响应中断,那么就会产生定时误差,选7.3728MHZ就无多大意义.

等有时间做个实验...

7楼: >>参与讨论
testcode
读TCNT1L才真正写入TCNT1H???
应该为:
读取TCNT1L时,
临时寄存器的内容 = TCNT1H的数值;

8楼: >>参与讨论
hotpower
那么哪个次序对呢???
SIGNAL(SIG_OVERFLOW1)
{
volatile unsigned CHAR TEMP;
  TCNT1H = DefTCNT1H
  TEMP = TCNT1L;//读TCNT1L才真正写入TCNT1H???
//.................................
}

还是:

SIGNAL(SIG_OVERFLOW1)
{
volatile unsigned CHAR TEMP;
  TEMP = TCNT1L;//读TCNT1L才真正写入TCNT1H???
  TCNT1H = DefTCNT1H
//.................................
}

周末没开发板无法论证...总之只想写TCNT1H不想写TCNT1L...

如何是好???

9楼: >>参与讨论
AVRx007
用16位,无需担心。
在C语言里面用16位长度的变量(常量只写)对16位寄存器进行读写,AVR的C编译器会自动调整顺序。

10楼: >>参与讨论
hotpower
关键是不想写TCNT1L而读TCNT1L是被逼无奈
 
11楼: >>参与讨论
红日
用8位计数器
7.3728MHZ.芯片M8L.
要求定时2.5mS,采用256分频,用8位计数器T/C0、T/C2,时间常数TCNT0=0xB8。

12楼: >>参与讨论
hotpower
谢谢红日先生
我主要想搞清16位定时器的应用...

主要是想其他中断工作时且cli()时,则T1将无法及时响应中断.

如果延迟大于分频数且在0-TCNT1L的范围内时, TCNT1L的值此时应该是一个非0

的数. 当然不到0xff.

若此时其他中断结束后,由于T1中断标志早被触发,故应该补上中断响应.

如果再将TCNT1L初始为0,则肯定不对.

所以,TCNT1L应该做为"自由人"而不该改写它!!!

这样在一定时间内的中断延迟也不会影响整个定时的准确度...

13楼: >>参与讨论
红日
用16位定时器,选用比效匹配方式。
用16位定时器,选用比效匹配方式(Auto Reload)

7.3728MHZ.芯片M8L.
要求定时2.5mS,采用1分频,用16位定时计数器T/C1,选用比效匹配方式(Auto Reload),时间常数TCNT1=0xB800,时间很准确。



14楼: >>参与讨论
hotpower
再次感谢...
我知道AVR的定时方式很丰富,有很多方法解决...

可能我顶牛想不通吧...

再谢红日先生:

外晶振的问题解决了----原来是双龙的M8开发板插座接触不良所致...
                      而且双龙的ISP成功率太低...小马的100%.

15楼: >>参与讨论
红日
双龙的ISP写入成功率太低
双龙的ISP写入成功率太低:
是选择ISP写入速度过高TURBO档问题,不成功。
选用FAST档或NORMAL档,成功率100%。


16楼: >>参与讨论
hotpower
我选什么都不怎么样
选用FAST档或NORMAL档,成功率不敢说...

17楼: >>参与讨论
testcode
确实要开发板测试才可以
确实要用开发板转转,用avrstudio好像两种结果都一样。
不过datasheet要求必须写入TCNT1L,但TCNT1H倒是可以忽略,如果值不变时。

18楼: >>参与讨论
hotpower
产品中写入了TCNT1L,我只是想不通
我昨天用TCNT1L++都不行...明天看有时间能测试一下...


学习嘛---郁闷多了不是坏事...

19楼: >>参与讨论
athlon64fx
软件重装似乎没有必要,
AVR几乎所有定时器都有 CTC 工作模式(M8T0好像没有), 没有积累误差.

SLISP软件经常校验失败是真的, 而且成功率与速度几乎没有关系, 即使你用Turbo Slow. 至少我用它对 M64 编程还没有一次成功过.

20楼: >>参与讨论
madaha
人非圣贤,孰能无过
看过不如做过,做过不如错过,错过不如错得多.

21楼: >>参与讨论
zhiwei
写TCNT1L才能更新TCNT1H
16位的计数值需要在一次操作中写入,但是实际上分开为H和L写,写H的时候并没有实际写入而是在TEMP里面,写L时,16位计数值同时更新。

22楼: >>参与讨论
qjy_dali
这实际是硬件临界区保护,呵呵
 
参与讨论
昵称:
讨论内容:
 
 
相关帖子
用ICCAVR在main内、外定义变量有何不同?
再次讨论AVR的开发器
mega128I/O扩展及其他?
各位大侠,请问Atmega8怎么使用汇编实现整数除????
那位大侠知道,winarm怎么用,好像和winavr不太一样!


Copyright © 1998-2006 tgdrjb.cn 浙ICP证030469号