完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我用time0和一个32 kHz的内部低频振荡器作为光源(在定时器上)在一个电路板上闪烁一个LED。我最初使用了高频振荡器用于系统时钟(32 MHz和1MHz),一切都正常工作。如果我把它设置到LFET,但是定时器显然停止了它的中断。我能把LED通过主线闪烁,但不能被中断。有什么原因我不能使用低频振荡器两者?这是我正在使用的代码:
以上来自于百度翻译 以下为原文 I am blinking a led on a breadboard using timer0 and the 32kHz internal low frequency oscillator as source (for the timer). I initially used the high frequency oscillator for the system clock (both 32MHz and 1MHz), and everything works. If I set it to the LFINT as well however the timer apparently stops launching its interrupt. I am able to blink the led through the main thread, but not with interrupts. Is there any reason I can't use the Low Frequency oscillator for both? This is the code I'm using: #if defined(__XC) #include #elif defined(HI_TECH_C) #include #endif #include // CONFIG1 #pragma config FEXTOSC = OFF // External Oscillator mode selection bits->Oscillator not enabled #pragma config RSTOSC = LFINT // Power-up default value for COSC bits->HFINTOSC with OSCFRQ= 32 MHz and CDIV = 1:1 #pragma config CLKOUTEN = OFF // Clock Out Enable bit->CLKOUT function is disabled; i/o or oscillator function on OSC2 #pragma config CSWEN = OFF // Clock Switch Enable bit->Writing to NOSC and NDIV is allowed #pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable bit->FSCM timer enabled // CONFIG2 #pragma config MCLRE = ON // Master Clear Enable bit->MCLR pin is Master Clear function #pragma config PWRTE = OFF // Power-up Timer Enable bit->PWRT disabled #pragma config LPBOREN = OFF // Low-Power BOR enable bit->ULPBOR disabled #pragma config BOREN = ON // Brown-out reset enable bits->Brown-out Reset Enabled, SBOREN bit is ignored #pragma config BORV = LO // Brown-out Reset Voltage Selection->Brown-out Reset Voltage (VBOR) set to 1.9V on LF, and 2.45V on F Devices #pragma config ZCD = OFF // Zero-cross detect disable->Zero-cross detect circuit is disabled at POR. #pragma config PPS1WAY = OFF // Peripheral Pin Select one-way control->The PPSLOCK bit can be set and cleared repeatedly by software #pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable bit->Stack Overflow or Underflow will cause a reset // CONFIG3 #pragma config WDTCPS = WDTCPS_31 // WDT Period Select bits->Divider ratio 1:65536; software control of WDTPS #pragma config WDTE = OFF // WDT operating mode->WDT Disabled, SWDTEN is ignored #pragma config WDTCWS = WDTCWS_7 // WDT Window Select bits->window always open (100%); software control; keyed access not required #pragma config WDTCCS = SC // WDT input clock selector->Software Control // CONFIG4 #pragma config BBSIZE = BB512 // ->512 words boot block size #pragma config BBEN = OFF // ->Boot Block disabled #pragma config SAFEN = OFF // ->SAF disabled #pragma config WRTAPP = OFF // ->Application Block not write protected #pragma config WRTB = OFF // ->Boot Block not write protected #pragma config WRTC = OFF // ->Configuration Register not write protected #pragma config WRTSAF = OFF // ->SAF not write protected #pragma config LVP = OFF // Low Voltage Programming Enable bit->High Voltage on MCLR/Vpp must be used for programming // CONFIG5 #pragma config CP = OFF // UserNVM Program memory code protection bit->UserNVM code protection disabled void PIN_MANAGER_Initialize(void) { TRISCbits.TRISC4 = 0; TRISCbits.TRISC2 = 0; ANSELCbits.ANSC4 = 0; ANSELCbits.ANSC2 = 0; LATCbits.LATC2 = 0; /* disable weak pull up for PORTC */ WPUC = 0x00; /* disable open drain for PORTC */ ODCONC = 0x00; } void initTimer() { /* Low Frequency internal oscillator, 32 kHz*/ T0CON1bits.T0CS = 0b100; /* Prescaler 1:1 */ T0CON1bits.T0CKPS = 0b0000; T0CON0bits.T016BIT = 0; /* By running 32 times the timer should be 1 ms */ TMR0H = 32-1; T0CON0bits.T0EN = 1; PIE0bits.TMR0IE = 1; INTCONbits.GIE = 1; } void interrupt isr(void) { static int count_1s = 0; if (PIR0bits.TMR0IF) { if (count_1s++ >= 1000) { count_1s = 0; LATCbits.LATC2 = ~LATCbits.LATC2; } PIR0bits.TMR0IF = 0; } } void SYSTEM_Initialize(void) { PIN_MANAGER_Initialize(); initTimer(); } void main(void) { // initialize the device SYSTEM_Initialize(); while (1) { int i = 0, x; for (i = 0; i < 1000; i++) { } LATCbits.LATC2 = ~LATCbits.LATC2; } } |
|
相关推荐
13个回答
|
|
|
|
|
|
|
|
|
|
好的,我已经理解了同步模式和异步模式的区别。如果我设置T0ASYNC位为1,虽然我似乎无法改变TMR0H寄存器。如果我理解正确:-我目前使用的低频振荡器,运行在31千赫-我在8位模式(T016BIT=0),所以TMR0H是可自由写入的,TMR0L在每一个时钟上升沿递增(所以每秒31000次(?))每当TMR0L==TMR0HBY写入31到TMR0H时,触发一个中断,我希望中断每毫秒(31000/1000)被触发一次,但它似乎比它慢大约4倍。此外,改变TMR0H似乎没有任何影响,所以也许我不理解一切正确?
以上来自于百度翻译 以下为原文 Ok, I've kinda understood the difference between SYNC and ASYNC mode. If I set the T0ASYNC bit to 1 though I seem to be unable to change the TMR0H register. If I understand correctly: - I'm currently using the Low Frequency Oscillator, which runs at 31 kHz - I'm in 8-bit mode (T016BIT = 0), so TMR0H is freely writable and TMR0L is incremented at each clock rising edge (so 31000 times per second (?)), firing an interrupt whenever TMR0L == TMR0H By writing 31 to TMR0H I'd expect the interrupt to be fired once every millisecond (31000/1000), but it seems to be about 4 times slower than that. Also, changing TMR0H doesn't seem to have any effect, so maybe I don't understand everything correctly? |
|
|
|
8位模式是TMR0L,你写的是错误的寄存器。1/32000=0.00万31251毫秒=0.001/0.00万31,25=32 TMR0(TMR0L)=32—1。
以上来自于百度翻译 以下为原文 8bit mode is TMR0L only, you are writing to the wrong register. 1 / 32,000 = 0.000,031,25 1ms = 0.001 / 0.000,031,25 = 32 TMR0 (TMR0L) = 32 - 1 |
|
|
|
8位模式增加了TMR0L,但是数据表表示,当TMR0L匹配TMR0HOLL时,计时器触发了良好的测量结果,并且设置TMR0L似乎没有任何效果。此外,当我使用高频振荡器作为系统时钟源时,我的计算工作(虽然仍有LFoSC作为Time0源),这更令人困惑,因为我没有改变Time0源。
以上来自于百度翻译 以下为原文 8bit mode increases the TMR0L, but the datasheet says the timer fires when TMR0L matches TMR0H Just for good measure I tried, and setting TMR0L seems to have no effect. Also, my calculations work when I use the High Frequency Oscillator as system clock source (while still having LFOSC as timer0 source), which is even more confusing since I'm not changing the timer0 source. |
|
|
|
您是正确的:在这个芯片上,TMR0H在8位模式下作为一个周期寄存器,在TMR0H中设置周期3-1,在启动时清除TMR0L。当TMR0L=TMR0H时,中断应该发生。通常当计时器达到周期值时,定时器被复位为零。复位)其他芯片有自己的独立周期寄存器。
以上来自于百度翻译 以下为原文 You are correct: On this chip TMR0H operates as a period register in 8 bit mode. Set the period 32-1 in TMR0H and clear TMR0L on start. The interrupt should happen when TMR0L = TMR0H. Normally when a timer reaches the period value the timer is reset to zero. (This will have to be cleared if it does not reset) Other chips have their own separate period registers. |
|
|
|
你没有显示你的所有代码,但是使用了A*PrimaMaungRSTOSC=LFIFT,FoSC/4是T0时钟输入的1/4,这就是为什么它以1/4的预期速率递增。这就是为什么中断不起作用的原因。这就是为什么我再说一遍第25.1.6节。
以上来自于百度翻译 以下为原文 You didn't show all your code, but with #pragma config RSTOSC = LFINT, FOSC/4 is 1/4 the T0 clock input which is why it is incrementing at 1/4 the expected rate. And probably why the interrupt isn't working. Which is why I say again read section 25.1.6. |
|
|
|
请原谅我晚些时候来参加晚会,但是……在编写代码之前,我总是做一个需求分析,也许还有一些期望调整。现在,你正在运行系统时钟在31千赫(标称频率的LFIFTSC)。你建议创建一个“计数器事件”(设置TMR0IF)。每一毫秒,我认为你已经做了很多。但是……你想每毫秒做点什么。在你的情况下,“某物”是重置TMR0IF标志,增加一个16位计数器,并且,如果计数器达到某个值,则切换一个LED。在31 kHz系统频率下,指令速率是31 kHz / 4=7.75千赫。你只有七个指令来完成这项工作,回到一个你可以检测到下一个计数器事件的地方。如果你接受超过七条指令,你会错过计数器事件,并且你的LED闪烁会比你预想的慢(希望)。所以我的问题是:你能写一个循环来完成上面所有的测试,这样在测试一个计数器事件和测试下一个EV之间只有七条指令吗?在毫秒之前,ENT已经过去。也许有人可以,但我肯定黑客可以。写一个中断服务程序,所有的事情,你必须做的每毫秒是更不可能用一个31千赫系统时钟(有这样一件事是不可能比不可能吗?)由于中断潜伏期(三到五个指令周期),一些上下文保存和恢复,以及ReFiEE指令,除了要做的实际工作。底线:你可以整天用寄存器值来摆放屁,用汇编语言代替C来试试。或者什么,但是我不认为你可以在每毫秒内为计数器事件服务,只要系统时钟是31 KHZI,建议你调整你的期望和方法。也许使用FoC/ 4来计时计时器和/或使用预分频器/后标器值,例如中断EV的最终结果。八毫秒,那么你可以有62个指令周期来完成这个动作。因为你唯一的真正目标是每秒切换一个LED,我认为这是可以做到的。事实上,我知道这是可以做到的,因为我只是用我的PIC16F15355(同样的MPU核心和TMR0模块作为您的设备)。
以上来自于百度翻译 以下为原文 Pardon me for coming to the party a little late, but... Before writing code I always do a requirements analysis, and, perhaps, some expectations adjustment. Now, you are running the system clock at 31 kHz (the nominal frequency of the LFINTOSC). You propose to create a "counter event" (setting TMR0IF) every millisecond, and I think you have pretty much done it. However... You want to do "something" every millisecond. In your case,the "something" is to reset the TMR0IF flag, increment a 16 bit counter, and, if the counter has reached a certain value, then toggle an LED. At 31 kHz system frequency, the instruction rate is 31kHz / 4 = 7.75 kHz. You have only seven instructions to do the work and get back to a place where you can detect the next counter event. If you take more than seven instructions, you will miss counter event, and your LED will blink slower than you had expected (hoped). So here's my question: Can you write a loop that does all of the above so that there are only seven instructions between testing a counter event and testing the next event before a millisecond has elapsed. Maybe someone can, but I sure as hack can't. Writing an interrupt service routine that does all of the things you have to do every millisecond is even more impossible with a 31 kHz system clock (is there such a thing as more impossible than impossible?) due to interrupt latency (three to five instruction cycles), some kind of context saving and restoring, and the retfie instruction in addition to the actual work to be done. Bottom line: You can fiddle-fart around with register values all day and all night, try it in assembly language instead of C, or whatever, but I don't think you can service the counter event every millisecond as long as the system clock is 31 kHz I suggest that you adjust your expectations and methodology. Maybe use Fosc/4 to clock the timer and/or use prescaler/postscaler values with the end result of, say, an interrupt every eight milliseconds Then you can have something like 62 instruction cycles to do the deed. Since your only real goal is to toggle an LED every second, I think it can be done. In fact, I know it can be done, since I just did it with my PIC16F15355 (same MPU core and TMR0 module as your device). Regards, Dave |
|
|
|
是的。也许你没有读过,但是这超出了我的影响。第25.1.2节,8位模式:再一次,第25.1.5节:因为我设置了T016BIT=0和T0ASYNC=1,我再次问你,为什么它不应该每隔毫秒发射我的定时器?和往常一样,欢迎你再重复一遍,如果我没有设置这样的寄存器,读第25.1.6节,会发生什么,但是除了浪费你的时间,我也看不出它会实现什么。至于戴夫,我相信你是命中注定的。“小提琴放屁”正是我一直在做的事情,我在代码中没有看到大象:LED确实每5到8秒切换一次,可能是由于中断时间重叠造成的。显然,这样一个缓慢的执行不是我想要的,我只是在测试我能用多少低功率,为了它的缘故,我通过将TMR0H设置为31和后缩放器到1:1024,一眨眼就成功了。多谢,希望从现在起我会更加了解我的MCU频率。
以上来自于百度翻译 以下为原文 Yes I did. Maybe you didn't read it, but that's beyond my influence. Section 25.1.2, 8-BIT mode: and again, section 25.1.5: Since I set T016BIT = 0 and T0ASYNC = 1 I ask you again, is there any reason why it shouldn't fire my timer every millisecond? As always, you're welcome to repeat me again what would happen if I hadn't setup those registers like that and to read section 25.1.6, but beside wasting your time I fail to see what it would accomplish. As for Dave, I believe you hit the spot. "Fiddle-farting" was exactly what I was doing this whole time, and I failed to see the elephant in my code: the led was indeed switching state once every 5~8 seconds, probably due to the interrupt times overlapping. Obviously such a slow execution is not what I want, I was merely testing how much low power I could go with; and just for the sake of it I succeded in blinking once a second by setting TMR0H to 31 and the postscaler to 1:1024. Many thanks, hopefully from now on I'll be more aware of my MCU frequency! |
|
|
|
在我的经验中,如果使用快速时钟来处理/中断,处理器在中断之间休眠,则使用较少的功率。
以上来自于百度翻译 以下为原文 In my experience less power is used if a fast clock is used to handle the/an interrupt and the processor sleeps in between interrupts. |
|
|
|
对不起的。我的眼睛可能坏了,所以我看不出你在哪里初始化T0ASYNC,这意味着默认值是同步的。您的最后一个帖子表明您认为您处于异步模式,但似乎不是。
以上来自于百度翻译 以下为原文 Sorry. My eyes may be going bad, so I can’t see where you initialize t0async at all which means it defaults to synchronize. Your last post indicates you think you are in async mode but it seems not. |
|
|
|
|
|
|
|
|
|
|
|
只有小组成员才能发言,加入小组>>
5223 浏览 9 评论
2024 浏览 8 评论
1949 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3198 浏览 3 评论
请问电源和晶体值之间有什么关系吗?PIC在正常条件下运行4MHz需要多少电压?
2252 浏览 5 评论
769浏览 1评论
655浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
583浏览 1评论
PIC Kit3出现目标设备ID(00000000)与预期的设备ID(02c20000)不匹配。是什么原因
667浏览 0评论
569浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-16 19:08 , Processed in 1.719823 second(s), Total 100, Slave 84 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号