PIC18f8722 (given delay and clocked by oscillator)

Thread Starter

xiandra park

Joined Jul 26, 2018
9
How do I write a program to count from 0 to 300 repeatedly at a delay of 200ms. I want to run this program on PIC18F8722 clocked by a 48MHz crystal oscillator. using NOP or whatever method appropriate for it.

Delay: 200ms
Frequency: 48MHz
Total Instruction: 1.2M
 

jpanhalt

Joined Jan 18, 2008
11,087
Welcome to AAC.

That chip will not operate at 48 MHz. It will operate at 40 MHz, if the supply voltage>4.2V

Assume 40 MHz = 0.1 us per instruction. An easy way (not necessarily best) is to use TMR0 in 16-bit mode with its prescale. TMR0 has an 8-bit prescale (up to 1:256). Using a 1:32 prescale, then 200 ms/32 = 6.25 ms per rollover. Pre-load TMR0 with approximately decimal 3036. Then, when it rolls over at 65535, you will have 6.5536 ms - 0.3036 ms = 6.25 ms x32 = 200 ms. For TMR0, you need to reload each time with the starting value. Its interrupt will give you the "clock" ticks you need to increment another timer, such as TMR1. Since there is "housekeeping" to do (e.g., interrupt latency, loading registers) you will need to adjust the pre-load values a little to get exact intervals.
 

Thread Starter

xiandra park

Joined Jul 26, 2018
9
How will it be if I want to use NOP instructions or Macro for this question:-

Write a program to count from 0 to 200 repeatedly at a rate of 100ms delay. This program is to be run on PIC18F8722 demo board clocked by a 28MHz crystal oscillator.

delay: 100ms
frequency: 28MHz
Total instructions: 700k (I need to divide this until it becomes less than 256)
 
Last edited:

jpanhalt

Joined Jan 18, 2008
11,087
How will it be if I want to use NOP instructions or Macro?
let say I changed the given:

delay: 100ms
frequency: 28MHz
Total instructions: 700k (I need to divide this until it become less than 256)
NOP instructions require one word of program memory each. That chip only has 128 K bytes of program memory. As for recalculating with your changed values, that would be a good exercise for you to ensure you understand how to do it. As for using a macro, a maro is just an easy way to write program sections that get repeated. It doesn't save memory. Of course, you could write the timer method as a macro, but it will waste a lot of program space.

You could write a macro with a call without using the timer. The call would be to a number of NOP's. The macro would calculate how many loops are needed.
 

Thread Starter

xiandra park

Joined Jul 26, 2018
9
NOP instructions require one word of program memory each. That chip only has 128 K bytes of program memory. As for recalculating with your changed values, that would be a good exercise for you to ensure you understand how to do it. As for using a macro, a maro is just an easy way to write program sections that get repeated. It doesn't save memory. Of course, you could write the timer method as a macro, but it will waste a lot of program space unnecessarily.

You could write a macro and a call and about using the timer. The call would be to a number of NOP's. The macro would calculate how many loops are needed.
so how do I actually recognize how many loops if I want to count from 0 to 200 repeatedly? using the recalculated values
 

jpanhalt

Joined Jan 18, 2008
11,087
Counting loops can be done a variety of ways. One way is simply to load a register with loop number and decrease it with each loop, then skip on zero. Another is to increment or decrement a timer and skip at the end. Some timers can use the events marked by other timers to count.
 

jpanhalt

Joined Jan 18, 2008
11,087
How do you know when to go from the end of a loop to the start of it again? That is, the flag to count a loop is integral to the code being a loop.
 

Thread Starter

xiandra park

Joined Jul 26, 2018
9
Counting loops can be done a variety of ways. One way is simply to load a register with loop number and decrease it with each loop, then skip on zero. Another is to increment or decrement a timer and skip at the end. Some timers can use the events marked by other timers to count.

Can I do it like this, to get the loop:

since 700k > 256

1) 700k/100 = 7000 > 256

2) 7000/70 = 100 < 256

so then the first 100 is my NOP
70 is my loop2
the last 100 is my loop1

is it correct this way?
 

jpanhalt

Joined Jan 18, 2008
11,087
Yes, you can use nested loops. Your solution, however, doesn't show how to count the loops.

Here is code from PICLIST (http://www.piclist.com/cgi-bin/dela...&Regs=d1+d2+d3+d4&clock=28&name=Delay&CPU=PIC )

Code:
Delay = 0.1 seconds
; Clock frequency = 28 MHz

; Actual delay = 0.1 seconds = 700000 cycles
; Error = 1.6630760261e-014 %

cblock
d1
d2
d3
endc

;699998 cycles
movlw 0x9F
movwf d1
movlw 0x87
movwf d2
movlw 0x02
movwf d3
Delay_0
decfsz d1, f
goto $+2
decfsz d2, f
goto $+2
decfsz d3, f
goto Delay_0

;2 cycles
goto $+1
 

Thread Starter

xiandra park

Joined Jul 26, 2018
9
Yes, you can use nested loops. Your solution, however, doesn't show how to count the loops.

Here is code from PICLIST (http://www.piclist.com/cgi-bin/dela...&Regs=d1+d2+d3+d4&clock=28&name=Delay&CPU=PIC )

Code:
Delay = 0.1 seconds
; Clock frequency = 28 MHz

; Actual delay = 0.1 seconds = 700000 cycles
; Error = 1.6630760261e-014 %

cblock
d1
d2
d3
endc

;699998 cycles
movlw 0x9F
movwf d1
movlw 0x87
movwf d2
movlw 0x02
movwf d3
Delay_0
decfsz d1, f
goto $+2
decfsz d2, f
goto $+2
decfsz d3, f
goto Delay_0

;2 cycles
goto $+1
is this considered the count from 0 to 200 repeatedly yet? (i don't understand this one, how to relate the count 0 to 200 repeatedly with delay and frequency given) I'm confused with this word count from 0 to 200.
 

jpanhalt

Joined Jan 18, 2008
11,087
How do I write a program to count from 0 to 300 repeatedly at a delay of 200ms.
Delay: 200ms
is this considered the count from 0 to 200 repeatedly yet?
I am getting confused. First, we talked about a delay that you wanted to do with a very large number of NOP's. I hope you were talked out of that. I suggested a timer as being relatively simple, and since timers run autonomously from other instructions (they can cause an interrupt), you can do a lot of other things during that 200 ms, now 100 ms delay. You seemed to have a problem knowing when a loop was finished, and I suggested a countdown or countup counter with a skip at zero.

Then, we ended up talking about nested loops, which are also easy and efficient in code (no mega-NOP's), but effectively monopolize the MCU while running (again, except interrupts). I posted an online calculator site and an example of nested loops in code. Using 100 NOP's is wasted code. However, if that is your plan, please post your actual code for doing it.

1) In brief, to what does your "200 repeats" apply? Is it the number of delays, or is it part of the pseudo-code you posted in Post 12 for a delay. The only difference between 200 repeats of delays and 300 repeats of delays is that the latter requires 9 bits. That is not a very hard issue to address.

2) Are you clear on how to detect the end of your delay? How about the end of the repeats? If not, please present how you plan to approach it.
 

Picbuster

Joined Dec 2, 2013
1,045
How do I write a program to count from 0 to 300 repeatedly at a delay of 200ms. I want to run this program on PIC18F8722 clocked by a 48MHz crystal oscillator. using NOP or whatever method appropriate for it.

Delay: 200ms
Frequency: 48MHz
Total Instruction: 1.2M

Use the timer interrupt @ 200mS. (eq timer INTCONbits.TMR0IF)

put this in a counter modulo 300
each 200mS 1 is added to the counter

Picbuster
 
Top