Sie sind auf Seite 1von 19

UEEA4663 Embedded System Design

Assignment 1 Report

Lecturer : Mr.See Yuen Chark


Date of submission: 4th July 2016

Group Members:
Woo Joo Ann MH 1308349
Yim Kong Joe MH 1405238
Task 2 Flowchart
Module 1 (LED1 blinks at 1Hz rate continuously)

Module 2 (LED2 blinks with different rate whenever SW1 is pressed and released)
Module 3 (LED3 blinks according to rate set from potentiometer)
Task 1 Q1 (30% and 50% Duty Cycle) Flowchart

Task 1 Q2 (Dual-tone system) Flowchart


Source Code
Task 1 Q1
#include <xc.h>

#define DUTY50 LATD2

#define DUTY30 LATD3

void IO_CONFIG();

void TIMER_CONFIG();

void main()

IO_CONFIG();

TIMER_CONFIG();

while(1);

void IO_CONFIG()

TRISD2 = 0;

TRISD3 = 0 ;

DUTY50 = 1;

DUTY30 = 1;

void TIMER_CONFIG()

T08BIT = 0 ;

T0CS = 0 ;

T0SE = 0 ; //we are not using this, dont set also can

PSA = 1 ;

T0CONbits.T0PS = 0b000;

TMR0IF = 0 ;

TMR0IE = 1;

TMR0H = 0xFC ;

TMR0L = 0x18 ;

GIE = 1 ;

TMR0ON = 1;

void interrupt low_priority isr (void)


{

static unsigned count = 0 ;

TMR0H = 0xFC ;

TMR0L = 0x18 ;

TMR0IF = 0 ;

count ++ ;

if (count ==3)

DUTY30 = ~DUTY30 ;

else if (count ==5)

DUTY50 = ~DUTY50 ;

else if (count ==10)

DUTY30 = 1 ; // return signal to high

DUTY50 = 1 ;

count = 0 ;

TASK 1 Q2
#include <xc.h>

#define TONE _LATB7

#define _XTAL_FREQ 8000000

_CONFIG1( JTAGEN_OFF & FWDTEN_OFF )

_CONFIG2( FCKSM_CSDCMD & FNOSC_FRC & IESO_ON & POSCMOD_NONE & OSCIOFNC_ON )

void IO_CONFIG();

void TIMER1_CONFIG();

void main ()

IO_CONFIG();

TIMER1_CONFIG();

while(1);T

void IO_CONFIG()
{

_TRISB7=0;

TONE = 1;

AD1PCFG=0xFF; //all pins set to digital

void TIMER1_CONFIG()

PR1 =5000; //to generate 1.25ms

_T1IF = 0; //timer overflow bit

_T1IE = 1; //enable the timer interrupt

_TON = 1;

void __attribute__ ((interrupt(no_auto_psv))) _T1Interrupt(void)

static unsigned int count = 0;

_T1IF = 0;

count++; //incremental count

if (count<400)

TONE =~ TONE;

else if (count>=800)

count = 0;

TONE = 1;

else

TONE = 0;

TASK 2 Module 1
#include <xc.h> // include processor files - each processor file is guarded.

#define _XTAL_FREQ 8000000

#define LED1 _LATB14

/*########################### Module 1 ###########################*/

void Module1()

LED1 = 1;
TIMER1_CONFIG(); //To blink at the rate of 1Hz

void TIMER1_CONFIG()

PR1=40000; //0.01s

_T1IF=0; //reset flag

_T1IE=1; //re-enable interrupt

T1CONbits.TON=1; //turn on timer

void __attribute__ ((interrupt, no_auto_psv)) _T1Interrupt(void)

static unsigned int count1 = 0;

_T1IF = 0;

count1++; //incremental count

if (count1 == 50)

LED1 =~ LED1;

else if (count1 == 100)

count1 = 0;

LED1 =~ LED1;

Task 2 Module 2
#include <xc.h> // include processor files - each processor file is guarded.

#define _XTAL_FREQ 8000000

#define LED2 _LATB7

#define SW1 _RB1

static unsigned int mode = 0;

void Module2()

while(SW1 == 0)

Delay(); //hold previous switching mode

}
if (SW1 == 1)

mode++;

if (mode >= 5)

{ mode = 0; } //reset press

TIMER3_CONFIG();

/*########################### Module 2 ###########################*/

void Delay()

unsigned int i;

for(i=0;i<=10000;i++);

void TIMER3_CONFIG()

if(mode==1) //button pressed once

PR3=40000; //0.01s

_T3IF=0; //reset flag

_T3IE=1; //re-enable interrupt

T3CONbits.TON=1; //turn on timer

else if(mode==2) //button pressed twice

PR3=20000; //0.005s

_T3IF=0;

_T3IE=1;

T3CONbits.TON=1;

else if(mode==3) //button pressed thrice

PR3=10000; //2.5ms

_T3IF=0;

_T3IE=1;

T3CONbits.TON=1;
}

else if(mode==4) //button pressed fourth

PR3=5000; //1.25ms

_T3IF=0;

_T3IE=1;

T3CONbits.TON=1;

else if (mode==0)

_T3IF=0; //reset flag

_T3IE=0; //disable interrupt

T3CONbits.TON=0; //turn off timer

LED2=0;

void __attribute__ ((interrupt, no_auto_psv)) _T3Interrupt(void)

static unsigned int count3 = 0;

_T3IF = 0;

count3++; //incremental count

if (count3 == 100)

LED2 =~ LED2;

else if (count3 == 200)

count3 = 0;

LED2 =~ LED2;

Task 2 Module 3
#include <xc.h> // include processor files - each processor file is guarded.

#define _XTAL_FREQ 8000000

#define SW2 _RB2

#define LED3 _LATB6


unsigned long int voltage;

unsigned long int level;

void Module3()

ADCconfig();

while (SW2 == 1)

ADCprocess(); // Turn ADC on

TIMER5_CONFIG();

_T5IF=0;

_T5IE=0;

T5CONbits.TON=0; //turn off timer

LED3 = 0;

void ADCconfig()

//###################################################################

// Select integer format result,

// Select auto conversion start

// Select Sample after conversion completes

//###################################################################

AD1CON1=0x00E4;

//###################################################################

// Select AVDD & AVSS as references,

// Disable Scan Mode for Ch0 input,

// Select interrupt after 16 sample/convert sequence,

// Select 16*1 buffer levels

// Always use MUX A

//###################################################################

AD1CON2=0x003C;

//###################################################################
// Select AD Clock as derivative of system clock source,

// Select 13TAD sampling time,

// Note : conversion time is always 12TAD (fixed)

// Select AD clock frequency such that 16 samples are collected in 1 mSec

// Assume FCY = 4 MHz or 1TCY = .25 uS

//###################################################################

AD1CON3=0x0D09;

//###################################################################

// Set the positive sample input channel for MUX A to use AN5

// Set the negative input channel for MUX A to use VR-

//###################################################################

_CH0NA=0; // Negative input VR-

_CH0SA3=0;

_CH0SA2=1;

_CH0SA1=0;

_CH0SA0=1;

//###################################################################

// Set AD1PCFG so that the only pin using analog functionality is AN5

//###################################################################

AD1PCFG=0x1FDF;

AD1CSSL=0; // Channel scanning is not enabled, so no input

void ADCprocess(void)

unsigned int vol;

_ADON = 1; // Turn on the A/D converter

while(!_AD1IF); // Stay while interrupt flag not on( _AD1IF !=1)

_ADON = 0; // When interrupt on turn off the A/D converter

_AD1IF = 0; //Reset interrupt flag

// ######## When interrupt occur (_AD1IF = 1) ######### //

vol= ADC1BUF0 + ADC1BUF1 + ADC1BUF2 + ADC1BUF3 +

ADC1BUF4 + ADC1BUF5 + ADC1BUF6 + ADC1BUF7 +

ADC1BUF8 + ADC1BUF9 + ADC1BUFA + ADC1BUFB +


ADC1BUFC + ADC1BUFD + ADC1BUFE + ADC1BUFF;

voltage = vol/16; //Get average voltage

level = (long)voltage;

level = (voltage*3.3)/1024;

void TIMER5_CONFIG() //for module 3

if (level == 0)

_T5IF=0; //reset flag

_T5IE=0; //disable interrupt

T5CONbits.TON=0; //turn off timer

LED3=0;

else

PR5 = (int)8000/level; //set PR5 according to voltage level

_T5IF=0; //reset flag

_T5IE=1; //re-enable interrupt

T5CONbits.TON=1; //turn on timer

void __attribute__ ((interrupt, no_auto_psv)) _T5Interrupt(void)

static unsigned int count5 = 0;

_T5IF = 0;

count5++; //incremental count

if (count5 == 100)

LED3 =~ LED3;

else if (count5 == 200)

count5 = 0;

LED3 =~ LED3;

}
When each of the modules are saved as header files, the main program which combines all three
modules is as shown below:
include <xc.h>

#include "Module1.h"

#include "Module2.h"

#include "Module3.h"

_CONFIG1( JTAGEN_OFF & FWDTEN_OFF & BKBUG_OFF )

_CONFIG2( FCKSM_CSDCMD & FNOSC_FRC & IESO_ON & POSCMOD_NONE & OSCIOFNC_ON )

#define _XTAL_FREQ 8000000

#define LED1 _LATB14

#define SW1 _RB1

#define LED2 _LATB7

#define SW2 _RB2

#define LED3 _LATB6

void Module1();

void TIMER1_CONFIG();

void Module2();

void Delay();

void TIMER3_CONFIG();

void Module3();

void ADCconfig();

void ADCprocess();

void TIMER5_CONFIG();

void INIT()

_TRISB14 = 0; //RB14=output

_TRISB1 = 1; //RB1=input

_PCFG3=1; //Digital input for RB1

_TRISB7 = 0; //RB7=output

LED2 = 0;
_TRISB2=1; //RB2=input

_PCFG4=1; //Digital input for RB2

_TRISB6=0; //RB6=output

LED3 = 0;

void main ()

INIT();

ADCconfig();

Module1();

while (1)

if (SW1 == 0)

Delay(); //switch de-bouncing

Module2();

if (SW2 == 1)

Delay(); //switch de-bouncing

Module3();

Code Explanation
TASK 1 Q1: LATD3 and LATD2 of a PIC18F4550 microcontroller is defined to be
DUTY30 and DUTY50 respectively. The input/ output pins of the relevant pins are configured
and both the pins for DUTY30 and DUTY50 are initially set to high. TIMER0 of the
microcontroller is then configured and the bex value of 0XFC18 is put into the TMR0H and
TMR0L registers so that the timer interrupts every 1s. When the TMR0 interrupts, the interrupt
service routine is called and a variable count is then initialized. For each interrupt, the count
increases and when the count reaches 3, DUTY30 toggles and when the count reaches 5,
DUTY50 toggles and finally, when the count reaches 10, both outputs are set to HIGH and count
resets to 0.
TASK 1 Q2: LATB7 is defined to be the output pin for the square wave and the I/O and
analog/digital settings are configured. TIMER1 is then configured to have a value of 5000 in
order to generate a 400Hz square wave. This is calculated as shown below:
Let the internal oscillator frequency, FOSC = 8 MHz
8
Internal clock, FCYC = 2 MHz = 4 MHz

1
TCYC = 4 MHz = 0.25 s

To generate a 400Hz square waves for 500ms duration;


1
A single square wave, T = 400 = 2.5 ms

2.5 ms
A single pulse, t = 2 = 1.25 ms

Setting PR1 value to generate 1.25 ms delay;


PR1(0.25 s) = 1.25 ms
1.25 ms
PR1 = 0.25 s = 5000

The TMR1 interrupt is enabled and when the timer activates the interrupt, the interrupt
service routine will be called on and a variable count is declared. With each interrupt that
occurs, the value for the variable count is increased. When the count is within the range of 0-
400, a square wave is generated at the output and when the count is within the range of 400-800,
the output pin (TONE) will be set to a high. So, for a period of 250ms, a square wave is
generated and for the remaining 250ms, an output of LOW is received and the count resets when
it reaches 800. Thus, a dual-tone system is created and simulated as shown in the picture below
whereby the total period is 1 second; 0.5s for the square waves and 0.5s for the LOW output
alternatively.
TASK 2 MODULE 1: The LATB14 of the PIC24 microcontroller is defined as LED1
and initially set to HIGH. TIMER1 of the microcontroller is set with a value of 40000 in the PR1
register so that the interrupt service routine is called upon every 0.01s. The timer is never set off
so the timer will run continuously. With every interrupt, the variable count1, declared and
initialized in the interrupt service routine will increase. Thus, when count1 hits the value of 50 or
100, the LED toggles, creating a perpetual blinking effect at 1Hz.
TASK 2 MODULE 2: Module 2 blinks an LED at a rate which is selected by pressing
the switch a number of times. Firstly, LATB7 and pin RB1 are defined to be LED2 and SW1
respectively. An unsigned integer mode is declared and initialized with a value of 0. When SW1
isnt pressed, LED2 will blink according to the previous rate. Since when mode= 0 there are no
preset rate, LED2 is off. When SW1 is pressed and released, the variable mode is increased and
its value is checked to make sure it does not exceed 5. If it does, the variable mode is reset. If
the variable mode does not exceed 5 and falls within the range of 0-4, TIMER3 is configured
with the register PR3 holding different values based on the current mode number. Each mode
number has a certain preset for the TIMER3 and the more times SW1 is pressed and released, the
rate of LED2 blinking will be faster until SW1 is pressed and released for the fifth time, whereby
the LED2 is off and the cycle repeats.
TASK 2 MODULE 3: For Module 3, the rate of blinking of the LED3 is influenced by a
potentiometer. The configurations for the 10-bit Analog-to-Digital Converter (ADC) is defined
beforehand and the sample input channel is selected to be AN5, which is connected to the
potentiometer. The analog and digital functionality is also set. When SW2 is pressed, the ADC of
the microcontroller is turned on and samples the input from the potentiometer at the selected
analog channel. Then, this sample is converted into a digital form and stored within 16 ADC
buffer registers. The values inside the buffer registers are summed and the average is obtained,
storing the result in a variable level. The converted digital result has to be within the maximum
voltage that the microcontroller and LED3 can tolerate, thus the variable level is multiplied
with 3.3V and divided by 1024 to ensure that the calculated result signifies a level of voltage
within 0 3.3V.
With the value in the variable level, the register PR5 of TIMER5 is configured based on a
formula that includes the value in the variable level. With this timer configuration, the LED3 is
made to blink at a rate defined with the calculated result in PR5. When SW2 is released, LED3 is
off and only resumes blinking when the switch is pressed and held again.

Schematic Diagram for Task 2

Das könnte Ihnen auch gefallen