This is the key line: movlw 0x0A ; [1/(250000/4/256)]*245=1S. Apparently the MCU is operating at 250 kHz, so the time for an instruction cycle is 16 usecs. (16^10-6)*256* 245 = 1.003520 seconds. The 256 comes from the prescale (i.e., only 1 in every 256 clicks of the clock is counted) and the 245 comes from starting the counter at "10" instead of zero (i.e., 255-10 = 245). On PIC MCU's, an instruction cycle requires 4 clock cycles, which is why the clock is divided by 4.
thanks that was really helpful .
So that mean we count down 245 till it reached zero once it reache zero stop counting
or we count 10 till it reach zero.
So this part of program will be executed fro how many time to reach value 00
It means that the counter counts up to 255 and rolls over to 0x00 on the next count. Since the count starts at 10, there are 245 counts before reaching 0xFF and rolling over on the next count. As another example, if you loaded the TMR0 register with 250, the first count would be 251, the fifth count would be 255 and the 6th count would make it roll over, which sets the interrupt flag. Thus, I think the comment has a error of one count of 256 instruction cycles or about 4 msec in calculating the time. I didn't comment on that, as I assumed the instructor just wanted you to see the principle of how to pre-load the TMR0 register.
One thing to remember with these routines is there is always "overhead." That is, the time needed for setting up the delay is added to the delay, but not accounted for in the simple calculation with your code. In your case, that time for set up is 16 microseconds per instruction, which is pretty small compared to the overall delay.
If you are using MPLAB (I use version 8.92, which can still be downloaded free from Microchip.), you might want to simulate the program using MPLAB SIM in the debugger menu. Then you can see using "Stopwatch" what effect adjusting the pre-loaded value in TMR0 has on the actual delay. If you do that, try a value of 0x0B for TMR0 pre-load.
For maybe more than 10 years now, I am using Picloops which you could download to calculate the register values for any delay with any clock. Just few hours ago it took me probably less than two minutes to get the values, add the code and simulate it.
All my delay routines are compiled conditionally, acccording to the current clock.
For short delays, like less than 100 to 300 ms depending on the clock speed, I use a macro that Mike McLaren ((K8LH) has posted here. Here's the version for 14-bit processors: https://www.electro-tech-online.com/threads/help-with-serial-echo-16f628.145969/#post-1235251 It is cycle-accurate and easily adjusted. For this homework, however, I think the teaching goal was how to use a timer, not loops.
I will be clocking my reads of an encoder the same way. Unfortunately, the encoder died a quick death. DigiKey is sending a replacement. Drats. Now I need to finish getting ready for our Winter instead of having fun. John
I have downloaded MPLAB IDE v3.10 i dont have any PIC kit to check this code of application. what is the best meathos of debugging this assembly language code. I read the guide book on simulator but it is old version i want understant it step by step to learn do you guys have any particular book or site to refer me that will be helpful
For JPANHALT do you have any youtube videos on learning MPLAB simulator or its functions I am kinda new to this learning process please give me basics learning guidance too.
Hi,
You really need a later version of MPLab IDE. Version 8.92 is the current and last version. There are probably some tutorials for the earlier version still on the Internet.
As for counting machine cycles, that is most easily done by using the stopwatch function in MPLab SIM debugger. It can be done manually, and the instruction set summary will give the number of cycles for each instruction. Simply put, most instructions are one cycle; instructions that require changing the program counter (PC) (e.g., "goto" ) take 2 cycles. Programs that can branch (e.g., btfss) take 1 cycle unless they branch/skip, which then takes 2 cycles as the PC is changed.
Here is some simple code based on a PIC datasheet for clearing RAM:
Code:
Clear_RAM ;clears 0x20 through 0x30
movlw 0x20 ;begining GPR register |B0
movwf FSR ; |B0
RAM_loop
clrf INDF ; |B0
incf FSR,f ; |B0
movlw 0x30 ;ending GPR register, i.e., 16 GPR's are used |B0
xorwf FSR,w ; |B0
btfss STATUS,2 ; |B0
goto RAM_loop ;continue to Start if zero |B0
To use the StopWatch, you need to be in debug mode. Place a breakpoint where you want to start and where you want to stop. You cannot put a breakpoint on a label, so I put the two breakpoints at the first step (movlw 0x20) and at the very next step after the loop is exited. If you put a breakpoint at "goto RAM_loop" you will only time one pass through the look. The default mode for putting a breakpoint is to double click on the line. Here is the StopWatch:
Here is what the first line looks like with a breakpoint:
Actually, I find using StopWatch fun and sometimes use it just to amuse myself.