完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
嗨,PIC16F1937中的time0模块是一个8位的计数器。这意味着要发生溢出,需要2 ^ 8(256)个指令周期。有没有办法绕过这256个指令周期?改为200个周期。谢谢
以上来自于百度翻译 以下为原文 Hi, the Timer0 module in pic16f1937 is an 8bit when used as a counter. That means it will take 2^8 (256) instruction cycles for an overflow to happen. Is there any way to bypass this 256 instruction cycle? Make it 200 cycles instead. Thanks |
|
相关推荐
13个回答
|
|
最好的方法是不使用TMR0,而是使用TMR2/4等,这些寄存器具有周期寄存器,可以实现你想要的。
以上来自于百度翻译 以下为原文 The best way to do that is to not use TMR0, but use TMR2/4/etc. which have period register that does exactly what you want. |
|
|
|
|
|
|
|
谢谢你的回复。另一个NOOB问题,如何将Time0的计数从0到255设置为中断?我怎么知道这个计数的持续时间?
以上来自于百度翻译 以下为原文 Thanks for the replies. Another noob question, how can I set the count of timer0 from 0 - 255 to enable the interrupt? How would I also know the duration of this count? |
|
|
|
注意,“每个指令循环一个计数”不是一个给定的值。如果预分频器没有启用,这是唯一正确的。您只是通过写入TMR0寄存器预先设置计数值。如果您向寄存器写入56,那么它将溢出256 - 56=200个计数。如果您希望它中断每200个。计数,然后你的中断服务例程必须立即重新加载TMR0寄存器。如果你不使用预分频器,那么你需要抵消由多少个指令写的值进入中断服务例程和写一个新的值到寄存器。这就是为什么使用硬件在定时器2/4/6中做它是一个更好的解决方案。为什么你坚持使用TMR0?
以上来自于百度翻译 以下为原文 Note, the "one count per instruction cycle" is not a given. That is only true if the prescaler is not enabled. You are just pre-setting the count value by writing to the TMR0 register. If you write 56 to the register, then it will overflow in 256 - 56 = 200 counts. If you want it to interrupt every 200 counts, then your interrupt service routine must immediately reload the TMR0 register. If you are not using the prescaler, then you need to offset the value written by how many instructions it takes to enter the interrupt service routine and write a new value to the register. That is why using the hardware to do it in timer 2/4/6 is a much better solution. Why are you insisting on using TMR0 ? |
|
|
|
为了获得更精确的计数,您还必须考虑在写入TMR0时受到抑制的两个指令周期。
以上来自于百度翻译 以下为原文 To get a more accurate count, you'll also have to account for the two instruction cycles that are inhibited when TMR0 is written. TMR0 += 256 - 200 + 2; |
|
|
|
事实上,1+0合并了另一个我忘了提到的技巧,而不是直接将新的值写入TMR0寄存器,而是将它添加到寄存器中(使用“+=”运算符),这就自动地允许了从中断开始到指令的许多指令。UCIT更新寄存器。
以上来自于百度翻译 以下为原文 Actually, 1and0 incorporated another trick I forgot to mention. Rather than writing the new value directly to the TMR0 register, you add it into that register (by using the "+=" operator). This automatically allows for however many instructions it took to get from the interrupt starting, to the instruction which updates the register. |
|
|
|
我只想知道这些指令循环是如何工作的,我如何使用这些计时器来计算传感器的脉冲数量,如果我听起来像是在坚持使用TMR0,我很抱歉。不管怎样,如果我要使用Time2/4/6,你能给我一步一步的关于如何进行阅读的概述吗?
以上来自于百度翻译 以下为原文 I just want to understand how these instruction cycles work and how could I employ these timers in counting the number of pulses from a sensor, I'm sorry if I sounded like I am insisting using TMR0. Anyway, if I am to use timer2/4/6 can you give me a step by step overview on how to do the reading? |
|
|
|
啊,你在第一篇文章中说的是“计数器”而不是“计时器”,但后来你开始讨论指令周期,混淆了这个问题。如果你想计算外部脉冲,指令周期是无关的。你到底想做什么?获得定时器产生一个中断后,你已经收到了200个脉冲在该引脚?只有Time0和Time1可以被外部信号计时,所以2/4 / 6在这里是无济于事的。
以上来自于百度翻译 以下为原文 Ahh you did say "counter" rather than "timer" in your first post, but then you started talking about instruction cycles, confusing the issue. If you want to count external pulses, the instruction cycles are irrelevant. What do you really want to do? Get the timer to generate an interrupt after you have received 200 pulses on that pin? Only Timer0 and Timer1 can be clocked by external signals, so 2/4/6 are of no help here. |
|
|
|
好吧,我应该把它包括在原来的帖子里。我可以再发表一个主题吗?无论如何,我想做的是计数来自外部来源的信号脉冲。为什么我问的指令周期是因为:说一个脉冲已经进来了,我想验证它是否是一个有效的脉冲(有些只是来自弹跳的尖锐脉冲)。要说它是一个有效的,我必须完成我想要的周期(200)在这个脉冲的持续时间,这样我就可以产生一个中断并增加一个值。
以上来自于百度翻译 以下为原文 Okay, I should've included it in the original post. Shall I post another topic? Anyway. What I want to do is count the signal pulse coming from an external source. Why I asked about the instruction cycles is because: Say a pulse has came in, and I want to verify if it's a valid pulse or not (some are just sharp pulses coming from bounces). To say it is a valid one, I must complete the cycles I want (200) during the duration of that pulse so I can generate an interrupt and increment a value. |
|
|
|
显然,一种选择是在外部过滤脉冲,然后可以将滤波器输出馈给时钟输入引脚。否则,如果您想以数字方式进行这一过程,则称为“去抖动”,但通常应用于较慢的信号。如果要检测信号变高,则验证T。它仍然是高200指令周期后,那么你不使用计时器外设来计数脉冲在所有。您可以使用外围设备来检测时间间隔何时已经过去,但它随后充当“计时器”,而不是“计数器”。在“过窄”脉冲和有效脉冲之间,您的阈值(微秒)是多少?脉冲本身会发生多快?每毫秒?一秒钟十次?快多了?[编辑-加法]你是否需要做其他事情,同时等待一个脉冲是否有效,或者PIC能专注于观察脉冲吗?例如,一旦检测到脉冲的开始,就可以将计时器初始化为56(通过写入TMR寄存器56),然后只需仔细检查输入,检查计时器是否溢出。如果计时器在脉冲变低之前溢出,那么您就知道它是一个有效脉冲。当然,你不能同时做任何其他事情。
以上来自于百度翻译 以下为原文 Plainly one option is to filter the pulses externally. Then you can just feed the filter output to the clock input pin. Otherwise, if you want to do this digitally, it's a process known as "debouncing", but usually applied to much slower signals. If you want to detect a signal going high, and verify that it is still high 200 instruction cycles later, then you don't use the timer peripheral to count the pulses at all. You may use the peripheral to detect when the time interval has elapsed, but that is then acting as a "timer", not a "counter". What is your threshold (in microseconds) between a "too narrow" pulse, and a valid one? How rapidly could the pulses themselves occur? Every millisecond? ten times a second? Much faster? [Edit - addition] Do you need to be doing anything else while waiting to see if a pulse is valid, or can the PIC be dedicated to watching the pulse? e.g. once you detect the start of a pulse, you could initialise a timer to 56 (by writing 56 to the TMR register), then just sit in a tight loop checking the input, and checking if the timer has overflowed. If the timer overflows before the pulse goes low, then you know it was a valid pulse. Naturally you can't be doing anything else at the same time though. |
|
|
|
由于我使用的是8MHz的FoSC,所以我期待128次的这些周期结束。当然,低于这些周期将被过滤掉,因为不会有中断周期的机会。它将是这样的,检测脉冲的下降沿。一旦检测到,开始计数。如果微处理器还没有完成,那么中断计数不会被启用,如果它完成了,那么激活中断并增加值。我设法为它写了一个代码,没有运气。如果我设置TMR0CS=0,它只增加1,并且不关心输入脉冲是否到来。如果把它设置为1,即使已经有脉冲,显示器也会被显示为0。如果你能回忆起来,这和我以前的帖子是一样的:HTTP://www. McCHIP.COM/FUMMS/M1041450.ASPX,但这次,我使用的是计时器模块。对不起,我有很多问题。
以上来自于百度翻译 以下为原文 Since I'm using 8Mhz FOSC, I'm expecting a 128us of these cycles to finish up. And of course lower than these cycles will be filtered out since there will be no chance that the interrupt for the cycle is enabled. It will be like this, detect the pulse's falling edge. Once, detected, start the count. If the micro hasn't finished then interrupt for the count isn't enabled, if it's finished, then activate interrupt and increment the value. I managed to write a code for it and got no luck. If I set the TMR0CS = 0, it just increments by 1 and doesn't care whether the input pulse is coming or not. If I set it to 1, the display is stucked to 0, even if there are pulses already. If you can recall, this is the same principle as that of my previous post: http://www.microchip.com/forums/m1041450.aspx But this time, I'm using the timer module. I'm sorry to have a lot of questions // CONFIG1 #pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin) #pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled) #pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled) #pragma config MCLRE = ON // MCLR Pin Function Select (MCLR/VPP pin function is MCLR) #pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled) #pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled) #pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled) #pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin) #pragma config IESO = ON // Internal/External Switchover (Internal/External Switchover mode is enabled) #pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled) // CONFIG2 #pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off) #pragma config VCAPEN = OFF // Voltage Regulator Capacitor Enable (All VCAP pin functionality is disabled) #pragma config PLLEN = OFF // PLL Enable (4x PLL disabled) #pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset) #pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.) #pragma config LVP = ON // Low-Voltage Programming Enable (Low-voltage programming enabled) #include #include #include #define _XTAL_FREQ 8000000 //*********************Definitions********************************// #define RS LATD2 /*PIN 2 of PORTD is assigned for register select Pin of LCD*/ #define EN LATD3 /*PIN 3 of PORTD is assigned for enable Pin of LCD */ #define LDATA LATD /*PORTD(PD4-PD7) is assigned for LCD Data Output*/ #define LCD_PORT TRISD /*define macros for PORTD Direction Register*/ #define PULSE_IN LATA4 /*Square Wave pulses from Generator*/ #define HIGH 1 #define LOW 0 //*********************PROTOTYPE DECLARATION***************************// //------------------------------LCD------------------------------------// void initialize_LCD(); /*Initialize LCD*/ void LCD_command(unsigned char ); /*Send command to LCD*/ void LCD_char(unsigned char x); /*Send data to LCD*/ void LCD_string(const char *); /*Display data string on LCD*/ void LCD_string_xy(char, char , const char *); //-----------------------------PULSE-----------------------------------// void initialize_ports(void); void interrupt timer0_ISR(); void enable_interrupts(void); //**************************Global Variable****************************// unsigned int counter = 0; char buffer[16] = 0; int main(void){ OSCCON = 0x70; //8MHz(70), 16MHz(7A) Freq OSCTUNE = 0x20; //Minimum Freq initialize_LCD(); initialize_ports(); enable_interrupts(); while(1){ itoa(buffer, counter, 10); LCD_string_xy(1,1, "Pulse Counted:"); LCD_string_xy(2,1, buffer); } return 0; } void interrupt timer0_ISR(){ if(TMR0IF && TMR0IE){ TMR0IF = 0; counter++; } } void enable_interrupts(void){ TMR0IF = 0; TMR0IE = 1; PSA = 0; TMR0SE = 1; GIE = 1; } void initialize_ports(void){ TRISA4 = 1; TRISD = 0x00; ANSELA = 0x00; ANSELD = 0x00; TMR0CS = 1; T0XCS = 0; } |
|
|
|
你已经计算了256 /(FoSC/4)=128U。我不确定你说的“128US的这些周期结束”是什么意思,抱歉,不能理解你在这里想说什么。你希望激活什么样的中断?我不觉得它不起作用,因为整个概念听起来很糟糕。我怀疑你不理解计时器是如何工作的。
以上来自于百度翻译 以下为原文 You have calculated that 256/(Fosc/4) = 128us. I'm not sure what you mean by "128us of these cycles to finish up" Sorry, can't understand what you are trying to say here. What do interrupts have to do with this? What interrupt exactly are you expecting to activate? I'm not surprised that it doesn't work, as the whole concept sounds screwy. I suspect you don't understand how a timer works. |
|
|
|
我必须同意,Q,很难理解你的目标。请给出更多关于你拥有什么和你想要什么的信息(例如外部信号发生器和测量它的脉冲频率)。你的PIC提供诸如捕获和比较的硬件模块。R,它可以用于在一定条件下产生中断。我不想让事情变得过于复杂。如果你给我们一些关于你的目标的更高质量的信息,那是最好的了。正如之前所问的:你必须马上做这个吗?或者这是你项目的唯一工作?问候,Fabian
以上来自于百度翻译 以下为原文 I must agree to qɥb, it is very difficult if not impossible to understand what you are aiming for. Please give some more information about what you have and what you want (e.g. external signal generator and measuring its pulse frequency). Your PIC offers hardware modules such as Capture and Comparator, which can be used to generate interrupts under certain conditions. I don't want to over complicate things for now. It would be best if you give us some more quality information about your goal. Also as has been asked before: Do you have to do this 'on the fly' or is it the only job of your program? Regards, Fabian |
|
|
|
只有小组成员才能发言,加入小组>>
5237 浏览 9 评论
2027 浏览 8 评论
1950 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3202 浏览 3 评论
请问电源和晶体值之间有什么关系吗?PIC在正常条件下运行4MHz需要多少电压?
2253 浏览 5 评论
772浏览 1评论
662浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
590浏览 1评论
PIC Kit3出现目标设备ID(00000000)与预期的设备ID(02c20000)不匹配。是什么原因
672浏览 0评论
572浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-21 17:17 , Processed in 1.617549 second(s), Total 102, Slave 85 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号