gpt4 book ai didi

WDT, TIMER0 16F676 delay calculation problem. Pre-scaling issue in MPASM(WDT,TIMER0 16F676延迟计算问题。MPASM中的预缩放问题)

转载 作者:bug小助手 更新时间:2023-10-24 19:16:06 27 4
gpt4 key购买 nike



One more question on Delays. Since I'm a starter my head aching around the calculations of delay. I understand delay when somebody explaining it in their code. But when it comes to my code Im totally a mess. (Calculating a delay for 2 days). this is the code; I want to blink-Led in every 1 second on any port pin on pic16f676:

还有一个关于延迟的问题。因为我是个新手,所以一想到延误,我就头疼。我理解当有人在他们的代码中解释它时的延迟。但当涉及到我的代码时,我完全是一团糟。(计算延迟2天)。这是代码;我想在pic16f676上的任何端口引脚上每1秒闪烁一次LED:



#include "p16F676.inc"

; CONFIG
; __config 0xFFFC
__CONFIG _FOSC_INTRCIO & _WDTE_ON & _PWRTE_OFF & _MCLRE_ON & _BOREN_ON & _CP_OFF & _CPD_OFF

usec EQU 0x20

sec EQU 0x23

UNKNOWN EQU 0x5F

org H'0000' ;Origem no endereço 00h de memória
goto INIT ;Desvia para a label início

; --- Vetor de Interrupção ---
org H'0004'

isr:
MOVWF 0x5E
; Reinit TMR0 : TMR0 = 8
MOVLW 8
MOVWF TMR0
; CLEAR TMR FLAG T0IF : T0IF=0
BCF INTCON, 2
; increase 1 microsec
; usec++; increase
;-----------------------------------------------------------------------------------------------------
MOVLW 0x1
ADDWF usec, F

MOVLW 0x0F
SUBWF usec, 0
MOVWF 0x51
BTFSS STATUS, 0
GOTO mangata
lalaind:
BCF STATUS, RP0 ; RA0=~RA0; // togle RA0
MOVLW 0x01
(MOVWF PORTA ); XORWF PORTA, F ==> replaced both
MOVLW 0
MOVWF usec

mangata:
BCF STATUS, 0x5

RETFIE

INIT:
BSF STATUS, 5
CLRF TRISA
; TRISA = 0x00;
CLRF TRISC

BCF STATUS, 5
CLRF PORTA
; PORTC = 0;
CLRF PORTC
; GIE = 1;
BSF INTCON, 7
; T0IF = 0;
BCF INTCON, 2
; T0IE = 1;
BSF INTCON, 5
; T0CS = 0;
BSF STATUS, 5
BCF OPTION_REG, 5 ;(INternal instruuction cycle clock) (clkout)
; PSA = 1;
BSF OPTION_REG, 3 ;Prescalar applied to WDT
; TMR0 = 8;
MOVLW 8
BCF STATUS, 0x5
MOVWF TMR0
CLRF usec
; while(1);

loop:
GOTO loop

end

The code works fine except delay(In MPLAB(MPASM)).after normal 255 counts timer0 call interrupt. there usec is subtracted with 15: to check is it ignited (i think status carry will toggle when usec > 15) and led on on pin RA0. I assumed the DELAY = 255*(15*10) = 38250cycles(Sorry if im wrong).

代码工作正常,但延迟(在MPLAB(MPASM)中)。正常后255计时器0调用中断。在这里,USEC减去15:以检查它是否被点燃(我认为当USEC>15时状态进位将切换),并在引脚RA0上发光。我假设延迟=255*(15*10)=38250个周期(抱歉,如果我错了)。


更多回答
优秀答案推荐

Let's start with the calculation for your existing code.

让我们从现有代码的计算开始。


The figure 4-1 on page 31 of the data sheet shows the relevant details:

数据手册第31页的图4-1显示了相关细节:


enter image description here



  • You set T0CS (timer 0 clock select) to 0, selecting Fosc/4 as input frequency. As you commented in your other question, the oscillator frequency is 4 MHz, thus CLKOUT is 1 MHz. This is one clock tick per cycle.

  • You set PSA (prescaler assignment) to 1, assigning the prescaler to the watchdog. We can see in the schematic, that this routes the input clock undivided to the timer.

  • The SYNC block is for the cases if you clock the timer from pin T0CKI. In this case, it does not change the frequency, so the timer is clocked by 1 MHz. The only "visible" consequence is a start delayed by 2 cycles after writing to the TMR0 register, according to the data sheet.

  • Now when the timer overflows from 0xFF to 0x00 (decimal 255 to 0), it sets its interrupt flag T0IF. You have enabled the interrupts by setting T0IE and GIE accordingly.

  • Initializing you write 8 to TMR0 and 0 to usec.

  • In the interrupt service routine you reset TMR0 with 8. With the interrupt latency of 3 cycles, 3 instructions of 1 cycle each, and the mentioned synchronization delay of 2 cycles, this adds up to 8 cycles. By chance (or by purpose?) this is exactly the value you write into TMR0.

  • To the next overflow triggering the interrupt, it will count additional 256 - 8 = 248 cycles. So the interrupts come in at a rate of:

    FT0int = CLKOUT / 256 = 1,000,000 Hz / 256 = = 3906.25 Hz

    Or you can think of 256 cycles per interrupt trigger.

  • Next, you have the variable usec counting from 0 to 14. The PIC has a kind of "inverted" carry logic, setting C to 0 if it has a borrow. In contrast to your analysis, the carry flag is cleared as long as usec is smaller than 15. subwf subtracts W from the variable, and C is set if usec is 15 (or greater).

  • Anyway, it takes 15 interrupts until you detect that overflow. So the complete toggle time is:

    256 cycles per interrupt * 15 interrupts = 3840 cycles.

    Or as frequency:

    Ftoggle = FT0int / 15 = 260,4166... Hz


Now to your goal, you want a 1 second toggle. For this you have several alternatives. These are some:

现在到你的目标,你想要一个1秒的切换。对于这一点,你有几种选择。以下是其中一些内容:



  1. Add another divider by 260 in an additional variable.

  2. Assign the prescaler to the timer. Set PS2:PS0 to 111, selecting 1:256. The input frequency of the timer is divided by 256.


The result is not exactly 1 second, but quite near. A human will not note a difference on a first glance.

结果不是准确的1秒,但非常接近。人类不会第一眼就注意到有什么不同。


Notes:

备注:


You might want to postpone the enabling of the interrupts until everything is prepared. Else depending on the situation, an unwanted interrupt might occur.

您可能想要推迟启用中断,直到一切准备就绪。否则,根据情况,可能会发生不想要的中断。


Since you write 8 to TMR0 at each overflow, you can consider to avoid this and let the timer run through. It will generate the same overflow rate.

由于您在每次溢出时向TMR0写入8,因此可以考虑避免这种情况,并让计时器超时。它将产生相同的溢出率。


If you want exact times (as much as the crystal allows), change the reload value of the timer so that it interrupts for example every 200 cycles. Then divide by variables for another 5000 (200 * 5000 = 1000000). Or use a prescaler of 1:64 and let the timer divide by 125. With a software divider of another 125 you reach the same goal (64 * 125 * 125 = 1000000). The secret is in integer factors that multiply to 1000000.

如果你想要准确的时间(在水晶允许的范围内),改变计时器的重载值,使其例如每200个周期中断一次。然后除以变量得到另一个5000(200x5000=1000000)。或者使用1:64的预分频器,让计时器除以125。使用另一个125的软件分割器,您可以达到相同的目标(64*125*125=1000000)。秘诀在于乘以1000000的整数倍。



Albpy,

阿尔比,


The code you posted will fail in a number of weird ways in the PIC16F676 because this is a crap controller.

您发布的代码将在PIC16F676中以许多奇怪的方式失败,因为这是一个糟糕的控制器。


This is a solution for your homework that does work with MPLABX v6.15, pic-as(v2.41) assembler and the simulator:

这是一个适用于您的家庭作业的解决方案,适用于MPLABX v6.15、PIC-AS(v2.41)汇编程序和模拟器:


;
; File:     main.S
; Target:   PIC16F676
; Author:   dan1138
; Date:     2023-09-10
; Compiler: pic-as(v2.41)
; IDE:      MPLABX v6.15
;
; Description:
;
;   Example project for the PIC16F676 controller using the pic-as(v2.41) tool chain.
;
; This application uses the TIMER0 interrupt to toggles the RA0 output once per second.
;
; Add this line in the project properties box, pic-as Global Options -> Additional options: 
; -Wa,-a -Wl,-pPor_Vec=0h,-pIsr_Vec=4h,-pFacConst=3ffh
;
; PIC16F676
; +------------:_:------------+
; GND -> 1 : VDD VSS : 14 <- 5v0
; <> 2 : RA5/T1CKI PGD/AN0/RA0 : 13 <> PGD
; <> 3 : RA4/AN3 PGC/AN1/RA1 : 12 <> PGC
; VPP -> 4 : RA3/VPP INT/AN2/RA2 : 11 <>
; <> 5 : RC5 AN4/RC0 : 10 <>
; <> 6 : RC4 AN5/RC1 : 9 <>
; <> 7 : RC3/AN7 AN6 RC2 : 8 <>
; +---------------------------:
; DIP-14

PROCESSOR 16F676
PAGEWIDTH 132
RADIX DEC


; PIC16F676 Configuration Bit Settings

; Assembly source line config statements

; CONFIG
CONFIG FOSC = INTRCIO ; Oscillator Selection bits (INTOSC oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
CONFIG WDTE = OFF ; Watchdog Timer Enable bit (WDT disabled)
CONFIG PWRTE = OFF ; Power-up Timer Enable bit (PWRT disabled)
CONFIG MCLRE = ON ; RA3/MCLR pin function select (RA3/MCLR pin function is MCLR)
CONFIG BOREN = OFF ; Brown-out Detect Enable bit (BOD disabled)
CONFIG CP = OFF ; Code Protection bit (Program Memory code protection is disabled)
CONFIG CPD = OFF ; Data Code Protection bit (Data memory code protection is disabled)

// config statements should precede project file includes.
#include <xc.inc>

#define _XTAL_FREQ 4000000
#define FCY (_XTAL_FREQ/4)

#define TMR0_RELOAD_VALUE (256-250+TMR0_RELOAD_OVERHEAD)
#define TMR0_RELOAD_OVERHEAD 3
#define BLINK_TIMEOUT_VALUE (FCY/250)-1

;
; Power-On-Reset entry point
;
PSECT Por_Vec,global,class=CODE,delta=2
global resetVec,start,start2
resetVec:
pagesel start
btfsc STATUS,STATUS_RP0_POSITION ; skip if we have not tried to get the calibration value
goto start2 ; branch if calibration value not availablee
goto start ;jump to the start up routine

;
; Data space use by interrupt handler to save context
PSECT Isr_Data,global,class=RAM,space=1,delta=1,noexec
;
GLOBAL WREG_save,STATUS_save
;
WREG_save: DS 1
STATUS_save: DS 1
PCLATH_save: DS 1
PORTA_shadow: DS 1
BlinkTimeout: DS 2
;
; Interrupt vector and handler
PSECT Isr_Vec,global,class=CODE,delta=2
GLOBAL IsrVec
;
IsrVec:
movwf WREG_save
swapf STATUS,W
banksel STATUS_save
movwf STATUS_save
movf PCLATH,W
movwf PCLATH_save
pagesel IsrVec
;
TMR0_IsrHandler:
btfsc INTCON,INTCON_TMR0IE_POSITION
btfsS INTCON,INTCON_TMR0IF_POSITION
goto TMR0_IsrHandlerExit
bcf INTCON,INTCON_TMR0IF_POSITION
movlw TMR0_RELOAD_VALUE
addwf TMR0,F
movf BlinkTimeout+0,W
iorwf BlinkTimeout+1,W
btfsc STATUS,STATUS_Z_POSITION
goto TMR0_Blink
movlw 1
subwf BlinkTimeout+0,F
btfss STATUS,STATUS_C_POSITION
subwf BlinkTimeout+1,F
goto TMR0_IsrHandlerExit
TMR0_Blink:
movlw BLINK_TIMEOUT_VALUE
movwf BlinkTimeout+0
movlw BLINK_TIMEOUT_VALUE>>8
movwf BlinkTimeout+1
movf PORTA_shadow,W
xorlw (1<<PORTA_RA0_POSITION)
movwf PORTA
movwf PORTA_shadow
TMR0_IsrHandlerExit:
;
movf PCLATH_save,W
movwf PCLATH
swapf STATUS_save,W
movwf STATUS
swapf WREG_save,F
swapf WREG_save,W
retfie ; Return from interrupt
;
; Get the factory Fosc calibration constant
start:
bsf STATUS,STATUS_RP0_POSITION
call GetFactoryCal ; get the calibration value
movwf OSCCAL ; calibrate internal oscillator
start2:
PAGESEL main ; Start main application
goto main
;
;
; Initialize main application
PSECT MainCode,global,class=CODE,delta=2
main:
clrf INTCON ;starting point
BANKSEL TRISA
movlw 0xFF
movwf TRISA ; Make PORTA inputs
movwf TRISC ; Make PORTC inputs
bsf OPTION_REG,OPTION_REG_PSA_POSITION ; assign prescaker to WDT
bcf OPTION_REG,OPTION_REG_T0CS_POSITION ; assign Fosc/4 as TIMER0 clock source
BANKSEL ANSEL
clrf ANSEL ; Trun off ADC analog inputs
BANKSEL CMCON
movlw 0x07
movwf CMCON ; Turn off comparator analog inputs

banksel PORTA_shadow
clrf BlinkTimeout+0
clrf BlinkTimeout+1

banksel TMR0
movlw TMR0_RELOAD_VALUE
movwf TMR0
bcf INTCON,INTCON_TMR0IF_POSITION
;
; Application process init
;
BANKSEL TRISA
bcf TRISA,PORTA_RA0_POSITION
BANKSEL PORTA
movlw 0
bsf INTCON,INTCON_T0IE_POSITION
bsf INTCON,INTCON_GIE_POSITION
;
; Application process loop
;
loop:
goto loop
;
;
; The factory Fosc calibration value is in a RETLW instruction
; located as the last instruction in code space. When this opcode
; is not present and the XC8 calibration method is used the
; PIC16F676 will loop indefinitely after a reset when a call
; to get this value is executed.
PSECT FacConst,global,class=CODE,delta=2
GLOBAL GetFactoryCal
GetFactoryCal:

END resetVec ; Tell the linker the entry point

It is up to you to discover why this implementation seems so complex.

这取决于您来发现为什么这个实现看起来如此复杂。


Microchip hates developers using assembly language so the tool chain sucks.

MicroChip讨厌开发人员使用汇编语言,所以工具链很糟糕。


Assembly language coding for the PIC16F is not for the weak willed. The IDE is buggy, the assembler is stupid, documentation is incomplete and support is nonexistent.

PIC16F的汇编语言编码不适合意志薄弱的人。IDE有错误,汇编程序很愚蠢,文档不完整,支持也不存在。


更多回答

Due with heaviness of datasheet, I never noticed that diagram. and I understand the relevance of it now. Your answer lead me into a ton of questions regarding the diagram. But i understand that the main trouble in my code is there is not much delay in my code to show an led blinking. So i created another variable sec with 255 and decremented it to 0 and led is now respecting my eye's speed.

由于数据表太重,我从来没有注意到那个图表。我现在明白了这一点的相关性。你的回答让我产生了一大堆关于图表的问题。但我明白,我的代码中的主要问题是,我的代码中没有太多延迟来显示LED闪烁。所以我用255创建了另一个变量秒,并将其减为0,LED现在考虑到了我的眼睛的速度。

Glad to be of help! Anyway, you should take the tour to learn how this site works. For example, if an answer fits you, you are supposed to accept it by setting the mark. This way other visitors (and your future self) with the same or similar issue can navigate right from the list to the relevant posts.

很高兴能帮上忙!无论如何,你应该参加参观,了解这个网站是如何工作的。例如,如果一个答案适合你,你应该通过设置标记来接受它。这样,其他有相同或相似问题的访问者(以及你未来的自己)就可以从列表直接导航到相关帖子。

Well, Dan, I don't share your position towards the PIC and its "infrastructure." It all depends on the goal you try to reach, and a PIC is not an ARM. -- I used to build several projects especially with PIC16C84 years ago, and I was quite satisfied in the end. It is always the same, using my skills to read and understand helped a lot. I'm afraid that apparently this art is going to be lost these days...

丹,我不同意你对PIC和它的“基础设施”的看法。这完全取决于你试图达到的目标,而PIC不是一只手臂。--84年前,我曾专门用PIC16C84建造过几个项目,最后我相当满意。它总是一样的,用我的阅读和理解的技能帮助很大。我担心这些天这件艺术品显然会消失……

@thebusybee, Your view of Microchip controllers and support seems fond memories of when it was good. The current experience has gotten a lot less pleasant. That said, my specific issue is with the PIC16F676. It has too many traps that will frustrate new developers. Any other Microchip controller is a better choice.

@thebusybee,你对微芯片控制器和支持的看法似乎是对它好的时候的美好回忆。目前的体验已经变得不那么愉快了。也就是说,我的具体问题是PIC16F676。它有太多的陷阱,会让新开发人员感到沮丧。任何其他微芯片控制器都是更好的选择。

@thebusybee, The code I posted in this answer addresses the major issues with the way the PIC16F676 works with the available Microchip tools along with some of the things that the OP left out of the code posted in the original question.

@thebusybee,我在这个答案中发布的代码解决了PIC16F676与可用的微芯片工具一起工作的主要问题,以及OP在原始问题中发布的代码中遗漏的一些内容。

Thanks for clarification! I appreciate that you gave reasons. Now I worry about the future of the AVRs. =-O

感谢您的澄清!我很感激你给出了理由。现在我担心自动取款机的未来。=-O

@Dan1138 your right, It some times work in contradiction to my code. I tried to light up an led using bounce button(using polling). but led turns off after some times as not desired in the coode: [i had a weird problem ](stackoverflow.com/q/77096231/20787426) I think PIC-as is difficult than MPASM. There is a whole bunch of thinks like delta, reloc,... section errrors soon. So i downgraded to mplab lower versions.

@Dan1138你的权利,它有时工作与我的代码相矛盾。我试着用弹跳按钮(使用轮询)点亮一个LED。但在Coode中,LED在一段时间后熄灭:[我有一个奇怪的问题](Stackoverflow.com/Q/77096231/20787426)我认为PIC-AS比MPASM更难。有一大堆的想法,像Delta,reloc,..。很快就会出现章节错误。所以我降级到了mplab的较低版本。

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com