Beruflich Dokumente
Kultur Dokumente
Use of a calculator and your lab notebook is permitted. Pin-out diagram on last page.
1. [10] Show calculations and write a short complete main.c source file to program pin 16
for a continuous PWM on an MCU operating at 8 MHz. The LED should be on 0.2350
ms and off for 0.1720 ms. What are the percent differences between the programmed
period and duty cycle and the required values?
MCU
VDD
16
Look at the circuit. The LED is on when Pin 16 is low and off when Pin 16 is high.
Therefore the PWM signal needs to be on for 0.1720 ms and off for 0.2350 ms.
Using prescaler = 4, period = 814/4 – 1 = 202.5 (we can use either 202 or 203 with the
same precision). %discrepancy = (204*4 - 814)*100%/814 = 0.25%.
void main(void)
CCP1 {
set_osc_1MHz();
OpenTimer2(TIMER2_INT_OFF & T2_POST_1_1 & T2_PS_1_1);
OpenPWM1(99);
MCU OpenPWM2(99);
SetDCPWM1(300);
Delay1TCYx(50);
SetDCPWM2(200);
while(1);
CCP2
}
Green on when CCP1 (PWM1 or pin 17) is low and CCP2 (PWM2 or pin 16) high.
Red on when CCP1 (PWM1 or pin 17) is high and CCP2 (PWM2 or pin 16) low.
The delay of 50 TCY implies we wait 50 TCY before the second signal comes on.
PWM1 5 V
(17)
0
t
PWM2 5 V
(16) delay
0
t
Red
LED Off
t
Grn
100 200 300
This will receive full marks but isn’t actually right. The PWM signals have the same period and
will start on the same signal from Timer2. The actual graph is
PWM1 5 V
(17)
0
t
PWM2 5 V
(16) delay
0
t
Red
LED Off
t
Grn
100 200 300
You would need to discuss the effect of the delay to get full marks.
3. [6] Consider an 11-bit A-to-D Converter with reference voltages from 0.75 V to 4.25 V.
What is the precision of any voltage measurement? Complete the following table (give
correct significant figures).
We can use the same formula to find b but ignore the ½, that is for the middle of the bin.
So b = (V – 0.75)* 211/3.5.
Off time
t
V
Need to configure pin 22 (RD3) as input – one time only.
Need to configure timer – one time only.
TCY = 4/32 MHz = 125 × 10-9 s
Therefore Tmax = (0.700 ms)/(125 × 10-9 s) = 5 600 000 TCY
The timer counter maximum is only 65536 so this determines the prescaler value we use
5600000/65536 = 85.4
The program is
void main(void)
{
unsigned int on_time_ms = 0; int off_time_ms = 0;
unsigned char timer_error = 0;
set_osc_32MHz(); //operate at 32 MHz
TRISDbits.TRISD3 = 1; // pin 22 as input (our signal)
OpenTimer0(.. T0_16BIT & T0_PS_1_128);
LCD_Initialize();
LCD_ClearDisplay();
printf(“ Ready “);
while(1)
{
INTCONbits.TMR0IF = 0; // clear timer0 flag
while(!PORTDbits.RD3); wait until the signal goes high
//now the signal is high so we should start timing
WriteTimer0(0); // start timing
while(PORTDbits.RD3 && !INTCONbits.TMR0IF&& !error_timer); //wait for timer
//overflow or signal goes low
if (INTCONbits.TMR0IF) //has the timer timed out?
{//yes – exceeded 0.700 ms
timer_error = 1;
}
else
{//no – successfully timed on signal
on_time_ms = (float)ReadTimer0()*128.*0.125 //convert time to millisec
}
//signal will now have gone low so we time the off time
INTCONbits.TMR0IF = 0; // clear timer0 flag
WriteTimer0(0); // start timing
while(!PORTDbits.RD3 && !INTCONbits.TMR0IF && !error_timer); //wait for timer
//overflow or signal goes high
if (INTCONbits.TMR0IF) //has the timer timed out?
{//yes – exceeded 0.700 ms
timer_error = 1;
}
else
{//no – successfully timed on signal
off_time_ms = (float)ReadTimer0()*128.*0.125 //convert time to millisec
}
//we can now print out the results. Printing takes time so we don’t do in
//while trying to time signal. Signal is now high but we don’t want to time it
if( timer_error ) //time_out happened
{
LCD_ClearDisplay();
printf(“ Timed out! “);
error_timer = 0;
}
else // good timing
{
LCD_ClearDisplay();
printf(“High t = %u (ms)”, on_time_ms);
LCD_MoveTo(1,0); //start of next line
printf(“Low t = %u (ms)”, off_time_ms);
}
while(PORTDbits.RD3); //wait until the signal goes low so we can start over again
}
}
Note: Printing takes time so only print results after you have times both on and off times. You
cannot easily print and monitor signal at same time. Also I can’t give you marks for code I can’t
understand. Comments are vital.
5.[10] Your MCU is connected as in the diagram below. Resistor R = 1000 . A code snippet is supplied. (a) W
answer to correct significant figures and include the precision.
VDD
void main (void)
R {
int ADCvalue;
Voltage LCD_Initalize();
probe PIC18F452 set_osc_32MHz();
5 REF+ R OpenADC( ADC_FOSC_32 & ADC_2_TAD &
2 V
AN0 ADC_RIGHT_JUST,ADC_CH0 & ADC_VREFPLUS_EXT &
470 AN0 ADC_VREFMINUS_EXT, 14);
R Delay10TCYx(5); // Delay 50TCY to stabilize
while(1)
{
R SetChanADC(ADC_CH0);
VREF– ConvertADC();
+AN0 while( BusyADC() );
R ADCvalue = ReadADC();
LCD_CLearDisplay();
printf(“ADC value %u”, ADCvalue);
VSS }
}
We are using reference voltages to do ADC and a voltage divider circuit to get the
reference voltage values.
= (b + ½)(3)/210 + 1 ½(3)/210
We can use the same formula to find b but ignore the ½, that is for the middle of the bin.