#include <p18f4580.h> void T0Delay(void); #define mybit PORTBbits.RB4 void main(
ID: 3551542 • Letter: #
Question
#include <p18f4580.h>
void T0Delay(void);
#define mybit PORTBbits.RB4
void main(void)
{
TRISBbits.TRISB4=0;
while(1)
{
mybit^=1;
T0Delay();
}
}
void T0Delay()
{
T0CON=0x01;
TMR0H=0x85;
TMR0L=0xEE;
T0CONbits.TMR0ON=1;
while(INTCONbits.TMR0IF==0);
T0CONbits.TMR0ON=0;
INTCONbits.TMR0IF=0;
}
Think of example 9-29 again. We want to consider modifying the code without adding or removing a line (so we can change say T0CON=0x01; to T0CON = 0x65;. But we are not removing this line T0CON=0x01; or adding another line T1CON= 0x32; for Timer 1 say.).
(15%) The code shows you how to toggle PORTB.4 every 50 ms. Modify the code (without adding or removing a line, but changing some lines) to show a way of toggling every x ms where x is an integer bigger than 3,000 picked by you or explain why this can not be done.
(10%) Repeat the same question as in (a) with x changed to an integer bigger than 4,000 picked by you.
Modify Example 9-29 and remove or add line(s) if necessary this time for the 8 bit timer (not 16 bit timer).
(5%) Show the modified code for 8 bits timer.
(5%) Do you have both TMR0H and TMR0L for 8 bits timer (line 15 and line 16 in Question A earlier)? Explain!
(5%) Can you still have PORTB.4 toggling every 50 ms for the 8 bits timer version here? Explain!
(10%) For 8 bits timer, can you toggle PORTB.4 every y ?s (microseconds), where y is between 5 and 20? Explain! (show the code if this can be done or show the reason if this can not be done).
Explanation / Answer
1.)
Xms and X is larger than 3000-> we need a delay larger than 3000ms or 3s.
Prescaler is 4. And assuming the XTAL = 10MHz.-> instruction cycle is 0.4us (4/XTAL)
So for incrementing timer0 by 1 we need 4(prescaler) instruction cycles or 4 * 0.4us= 1.6us
For 3000ms -> we need count of 3000000/1.6 = 1875000.
This value is larger than the maximum value in 16 bit range.
So maitaining the same prescaler it is not possible to get a delay of 3000ms.
Let us increase the prescaler to 64 ie T0CON = 0x06
So for incrementing timer0 by 1 we need 128(prescaler) instruction cycles or 128 * 0.4us= 51.2us
For 3000ms -> we need count of 3000000/51.2 = 58593.(a value that can be fit into 16 bit)
Hence by changing T0CON to 0x6 we can acheive the delay of 3000ms
2.)
Performing the same calculations as above,let us check for prescaler = 128, if count can be fit into 16 bit.
So for incrementing timer0 by 1 we need 128(prescaler) instruction cycles or 128 * 0.4us= 51.2us
For 4000ms -> we need count of 4000000/51.2 = 78125( not in 16 bit range)
Changing the prescaler to 256 and checking. prescaler = 256, T0CON = 0x7
So for incrementing timer0 by 1 we need 256(prescaler) instruction cycles or 256 * 0.4us= us102.4us
For 4000ms -> we need count of 4000000/102.4 = 39062(a value that can be fit into 16 bit)
Hence by changing T0CON to 0x7 we can acheive the delay of 3000ms.
3.)
Now the timer is 8-bit.
The maximum delay that is possible in 8 bit mode is 256(max 8 bit valu+1)*Prescaler instruction cycles.
The maximum time is 256*256*0.4us = 26214.4us = 26.2144ms
as we need a delay of 50ms we program the timer 0 to 25 ms and wait for the timer to overflow twice(as we are allowed to add lines).
For 25ms delay -> 25000/(0.4*256) count is required. = 244(rounded)
4.)
the changed T0Delay routine is as follows:
void T0Delay()
{
in i=0;
T0CON=0x47; /* 8 bit ,prescaler is 256 */
/*TMR0H=0x85; *//* not required in 8 bit mode */
TMR0L=13; /* 256-(244-1) = 13 is to be loaded in TMR0L for 244 count */
T0CONbits.TMR0ON=1;
while(i<2)
{
while(INTCONbits.TMR0IF==0);
T0CONbits.TMR0ON=0;
INTCONbits.TMR0IF=0;
i++;
}
}
5.)
As we are using the timer in 8-bit mode the upper part of the Timer0 ie TMR0H is not required and the line TMR0H = 0x85 can safely commented.
6.)
After doing the above calculations for 8 bit mode,
we have loaded 244 counts an approximation. So actual delay we get is a differ value of 50 ms.
The actalu delay for 244 count is 244*256(prescaler)*0.4us(instructiin cycle) = 24985.6us
so T0Delay gives a delay of 24985.6*2 = 49.9712ms and not 50 ms.
7.)
Similar to the calculations done part 1 we repeat for 8 bit mode and delay between 5 and 20 us
One instruction cycle is 0.4us.
So for 5-20us delay we need a count of (assuming prescaler is 1) is 12.5 to 50. In range of 8 bit.
So by using the count between 12 and 50 ie TMR0L between 256-(12-1) = 245 and 256-(50-1)=207 we get a delay between 5 and 20 us.
T0CON = 0x48 /* 8 bit mode and prescaler is not used PSA = 1, T08BIT = 1*/
and TMR0H has to take a value between 245 and 207.
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.