Professional Documents
Culture Documents
H63ECH coursework
GROUP 11
Author:
4068184
[THE UNIVERSITY OF
NOTTINGHAM EEE SCHOOL]
EMBEDDED COMPUTER HARDWARE - H63ECH
PIC PROGRAMMING COURSEWORK
Student ID - 4068184
Group 11 – Question 1 – Morse code
TASK 1
The basis of task 1 part A is to create a super loop which continually checks for user input and then based on
that input performs a certain operation. The specification states that SW1 Sends the message, SW2 or SW3
(Separate) sets the send count to 2, SW2 and SW3 pressed together sets the send count to 3 and finally SW4
determines the message to be sent.
The size of this program has been have reduced by incorporating functions for repeated sections of code. For
example, by defining the process of flashing S as a function, it is not necessary to have the code to flash S
repeated out multiple times. Instead it can be called when needed, reducing the size of the program memory.
This has been applied to all of the letters that can be transferred.
The task was successful, and the developed code ran perfectly in testing and in practice. The user of the PIC
can select between STOP and SOS signals, they can choose to send it 2 or 3 times and then send the message.
The device will reset after the particular message has been sent the predetermined amount of times, ready for
the next set of transmissions.
TASK 2
Program memory size = 61
CCPInit
movlw B'11000011' ;Set Count Limit by setting both High and Low
byte of CCPR1
movwf CCPR1H ;Set to 50,000
movlw B'01010000'
movwf CCPR1L
L1
btfsc PIR1, CCP1IF
goto LEDOn
goto L1
LEDOn
bsf LEDs, LD6
bcf PIR1, CCP1IF
TASK 3
Program Memory Size = 74
ISR
bcf PIR1, CCP1IF ;Clear CCP Interrupt Flag from PIR1
bsf LEDs, LD3 ;Turn on LED3
bsf LEDToggle,0 ;Toggle
retfie
LEDSwitch
LEDOff
CCPInit
movlw B'11000011' ;Set Count Limit by setting both High and Low byte of CCPR1
movwf CCPR1H ;Set to 50,000
movlw B'01010000'
movwf CCPR1L
btfsc LEDToggle,0
goto LEDSwitch
TASK 4
Program Memory Size = 281
#include <htc.h>
#include "inclC.c"
main () {
// configure pins
ADCON1 = 0b00000110; // disable ADC inputs
PORTB = 0;
TRISB = 0b11000000; // configure RB5..RB0 for output
COURSEWORK QUESTION
Evaluate the Bit Rate for this sort of communication:
Therefore in bits per second, this communication method has an effective bit rate of 5 bits/second
ADDITIONAL TASKS FOR COURSEWORK
1. Implement an advanced ISR that backs up SFR and performs a task such as calculating the difference
between two bytes and setting up the LEDS to show the difference
2. A different principle task that I would be keen to see would be interfacing actuators (Motors, Servo’s
(using PWM)) so that the program could drive a small robot for example. This example would use the
CCP Module and Timer modules.
Author:
4085517
[THE UNIVERSITY OF
NOTTINGHAM EEE SCHOOL]
Embedded Computer Hardware - H63ECH
Student ID - 4085517
Task 2_A
Design approach:
The input of this task is pushbuttons SW1-SW4 which control the output
and indicate the status by the LEDs (LD1, LD5, and LD6). LD5 will be on if there
is a child in flume. LD6 is indicating that there is no child in the flume and LD1 is
blinking if any child moves backward. At the beginning the LD6 should be on to
indicate that it is safe to enter the flume. SW1 is pressed if a child enters the
flume and LD6 should be off and LD5 should be on instead to indicate that there
is a person in the flume. If SW2 is pressed it means that a child is half way and
LD status should not change. If SW4 is pressed in this process it will reset the
board to first state. Now it will check the input continue from last state. If SW3
is press in this state it will indicate that a child leave a flume then LD5 will be off
and LD6 will be on again which indicate that the flume is safe to enter again but
if SW1 is press it will trigger alarm. From the above statement it can be shown
as a following diagram.
SW2,3,4
STATE1
LD6
SW4
SW4 SW1
STATE2 ALARM
SW3,4 LD5 LD1 SW1,2,3
SW1,3 blinking
SW2
STATE3 SW1
LD5
SW2
Then second part should check for input SW2 and then create some delay and
go to state3. If it detects input of SW1 it will go to this part again but if it
detects SW3 it will trigger alarm. The design of this state is show below.
Figure 3: State2
STATE2
SW2
Delay STATE3 flowchart
LD5 on LD5 on
LD6 off LD6 off
The third part is for checking for SW3 input. If SW3 and SW4 are detected in
this stage it will go to the first part. If SW1 is detected in this stage it will trigger
alarm. If it detects SW2 it will go to this part again. The design of this state is
show below.
Figure 4: State3
STATE3
SW3,4
Delay STATE1 flowchart
LD5 on LD5 off
LD6 off LD6 on
In subroutine should contain the alarm function, delay function and SW4
function because these three functions are used many times in this task and it
will reduce program memory usage as well. The delay subroutine is use to
generate the delay for controller. This function is already provided in include file.
The alarm function will be called if any child move backward and it will trigger
LD1. The design of this function is show below.
SW1,2,3
ISR retfie
Delay movlw D'133' ;Start counting from 133 to 255
bcf INTCON,TMR0IE ;Clear TMR0IE
bcf INTCON,TMR0IF ;Clear TMR0IF
movwf TMR0
Main nop
include AK_INIT.inc
banksel OPTION_REG ; select bank1
movlw B'00000010' ; use prescale of 1:8
movwf OPTION_REG ; move w to OPTION_REG
banksel TMR0 ; select bank0
Task2_C Setting LD6 on when a TMR0 interrupt occurs
The objective of this task is to use Timer 0 interrupt and make Led 6 on if
interrupt occurs. Firstly the program must enable global interrupt and TMR0
interrupt. The binary number 10100000 has to move in to INTCON register. The relevant
code is shown below.
MLoop nop
movlw B'10100000' ; enable global interupt,timer0 interrupt flag
movwf INTCON
}
break;
}
else if (SWs == 0b00001000) //check SW4
{
DelWds (3); //delay
LEDs = 0b00100000; //turn on only led6
break;
}
}
}
}
Question: Why you may want to use this delay program instead of the program
provided?
Because TMR0 use internal clock oscillator of 4 MHz which make it more precise
than use the delay by running the loop in the program.
Suggestion
The specification of the programming is not totally clear in task2_A. In task 2_A
it said “if the user moved backward for any reason the alarm LD1 is triggered”
but if in this process the user are skip the procedure what should the output look
like. For example if the child already enter the flume and SW1 was pressed then
the user are press the SW3 which mean the child are already out of the flume
and SW2 was not press. In task 2_B, it has state that the delay must precise 1
ms delay. The only way to test that is to use stopwatch in MPLAB program
because the human eyes cannot see the led blinking with a delay of 1ms.
2009
-
Author:
4074719
[THE UNIVERSITY OF
NOTTINGHAM EEE SCHOOL]
Task A
The approach used in this task was to initialize by setting both the volume levels – the dance floor and the
headphone to level 4. Then, by the help of a never-ending super-loop – the standby state is displayed in the
LEDs in the binary form where LD1…LD3 represent the headphone volume level and LD4…LD6 represent the
dance floor’s volume level.
This task involves controlling the brightness of LD3 using PIC peripherals TMR2 and CCP (PWM) with the
PWM pulse wave of duty cycle 50%.
The PWM frequency below 1kHz chosen for this task is 625Hz.
So, PWM period = 1/625 = 0.0016s
We know from the datasheet that,
Relevant pieces of code for this task are explained with comments:
Main program:
The interrupt service routine is called when the Timer2 overflows which is when TMR2 becomes equal to PR2.
Then, TMR2 is reset to 0 and the processor is interrupted and transferred to the start of the interrupt service
routine.
In the interrupt routine, we clear the interrupt flag so that next time an interrupt may need to be called – that it
will not be a problem. Then, as the task requires, LD6 is lit up.
ISR
bcf PIR1,TMR2IF ;clears the TMR2 to PR2 match interrupt flag bit
Embedded C Code:
#include <htc.h>
#include "inclC.c"
#define LEDs PORTB
main ()
{
unsigned char VOL_D;
unsigned char VOL_H;
// configure pins
ADCON1 = 0b00000110; // disable ADC inputs
PORTB = 0;
TRISB = 0b11000000; // configure RB5..RB0 for output
// superloop
while (1)
{
unsigned char temp = VOL_D;
The while-loop in the increment and decrement if conditions maybe repetitions of checking for which switch
has been pressed. However, they are not redundant because these while-loops effectively prevent the
compiler mistaking a single switch-press as multiple presses. Another approach to solving this issue could be
adding a sufficient delay of about 0.3 seconds at the beginning of the superloop and using the ReadSw()
function – but in the Hi-Tech Compiler, the former approach (of using the while-loops) works both in the
Debugger & Programmer modes and is 7 instructions lesser than the latter approach which works only in the
Programmer mode.
Another approach to displaying LEDs (but more instructions) is as follows:
unsigned char temp = VOL_D; // store dancefloor volume in temp
unsigned char sum = 0; // initialize sum to zero
sum = VOL_H; // add headphone volume to sum
sum += (temp%2)*8; // add 8 if bit 0 of dancefloor volume is 1
temp /= 2;
sum += (temp%2)*16; // add 16 if bit 1 of dancefloor volume is 1
temp /= 2;
sum += (temp%2)*32; // add 32 if bit 2 of dancefloor volume is 1
LEDs = sum; // write the value of sum to PORTB
I thought the logic in the programming structure of 4085517’s Task 2 was well-thought.
I found the question in task A slightly ambiguous. If the alarm is supposed to go off only when switches ‘121’
are pressed, then 4085517’s code is complete. But, if alarm is to be called on other occasions like for
example, on switches ‘132’ & ‘122’ as it is a flume – then the code is incomplete.
In task C, all flags are not cleared and global interrupts are not declared. Although the code runs fine and LD6
lights up, this code if run over and over again would be potentially hazardous.
The LED brightness might differ from 50% because of many factors.
Excessive use of computing time (due to running other instructions in the program code) and a poor PWM
resolution can cause glitches at the low frequencies that are being used.
Also, since the duty cycle for the PIC microcontroller is the number of basic oscillator cycles for the output to
remain high and not the generic duty cycle measured as a percentage – the duty cycle is related only to the
master clock and not to the period of the PWM signal. This may prevent us from getting an accurate duty
cycle.
Suggestions:
An additional task for this coursework could be an extension to the existing simple and small PWM and
interrupt tasks. The task could be to create various LED dimmer effect of different frequencies on the different
LEDs.
Another additional task could be to receive and transmit messages between two PICs using the switches as
information bits and the LEDs to display the incoming and outgoing information in binary on three LEDs each.
It would have been really helpful to understand if we were to build the PIC board as the datasheet would
become more clear and functions of various pins, resistors and connections would become known.
2009
-
Author:
4072770
[THE UNIVERSITY OF
NOTTINGHAM EEE SCHOOL]
ID : 4072700 Group : 11 Assignment : 4
Task A
A truth table was drawn for all possible input values for A & B:
A1 A0 B1 B0 3*A+[B/2] R3 R2 R1 R0
0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0
0 0 1 0 1 0 0 0 1
0 0 1 1 1 0 0 0 1
0 1 0 0 3 0 0 1 1
0 1 0 1 3 0 0 1 1
0 1 1 0 4 0 1 0 0
0 1 1 1 4 0 1 0 0
1 0 0 0 6 0 1 1 0
1 0 0 1 6 0 1 1 0
1 0 1 0 7 0 1 1 1
1 0 1 1 7 0 1 1 1
1 1 0 0 9 1 0 0 1
1 1 0 1 9 1 0 0 1
1 1 1 0 10 1 0 1 0
1 1 1 1 10 1 0 1 0
these result values were used as the return values for the lookup table,
Copy to LD1-2
Read SW3-4
& set LD6 Wait for SW1
No to unset
SW1 set?
Combine A&B
and use lookup Show result
Yes
table
Store A
Yes Wait 1s
Wait for SW1
to unset
Calculate result Show result
Copy to LD1-2
Read SW3-4 & set LD6
Wait 1s
No
SW1 set? End loop
ID : 4072700 Group : 11 Assignment : 4
Task B
; SUBROUTINES
;******************************************************
ISR retfie
;******************************************************
; end of your subroutines
; INITIALISATION
;******************************************************
; set prescaler for wdt
BANKSEL OPTION_REG
movlw b'11111111' ; sets wdt prescaler for a 2s delay
movwf OPTION_REG
BANKSEL SWs
;******************************************************
; end of your initialisation
; MAIN code
;******************************************************
movlw b'00001111' ; switch mask, SW5 seems to come on sometimes when
pressing SW4
andwf SWs, W
btfss STATUS, Z ; check whether a switch has been pressed
clrwdt ; if a switch has been pressed, clear the timer
to prevent a reset
movwf LEDs ; Show the switches pressed on the LEDs
;******************************************************
; end of main code
ID : 4072700 Group : 11 Assignment : 4
Task C
For this task the register LEDstat is used to keep LD6 on as the status will
change when WDT is cleared.
; SUBROUTINES
;******************************************************
ISR retfie
;******************************************************
; end of subroutines
; INITIALISATION
;******************************************************
; Sets LD6 if reset by watchdog timer
btfss STATUS, 4
movlw B'00100000'
movwf LEDstat
; MAIN code
;******************************************************
movlw b'00001111' ; switch mask, SW5 seems to come on sometimes when
pressing SW4
andwf SWs, W
btfss STATUS, Z ; check whether a switch has been pressed
clrwdt ; if a switch has been pressed, clear the timer
to prevent a reset
iorwf LEDstat,W ; sets LD6 if PIC was reset by watdog timer
movwf LEDs ; Show the switches pressed on the LEDs
;******************************************************
; end of main code
ID : 4072700 Group : 11 Assignment : 4
Task D
main () {
/* configure pins */
ADCON1 = 0b00000110;
TRISB = 0b11000000;
/* LEDs on for 1 s */
PORTB = 0b00111111;
delay_ds(10);
// shift A left 2 bits and append B to get result from lookup table
PORTB = lookup[(opA<<2) + opB];
delay_ds(10); // for 1 second
ID : 4072700 Group : 11 Assignment : 4
The calculation method uses far less instructions(7) than the lookup
method(25) for this, as it is a simple calculation. If 4 bit operands were
used, the size of the lookup table alone would increase from 17 instructions
to 257 instructions, the calculation method however, would not gain in size,
the current code I am using is capable of working with 4bit operands.
Suggestions / Mistakes
Description states that task C is an interrupt for all assignments but it is not
for assignment 4.
Completion of the developments
Task Assignment
1 2 3 4
A + + + +
B + + + +
C + + + +
D ? + + +
Release mode:
Task Assignment
1 2 3 4
A 185 94 99 129
B 78 74 76 71
C 91 70 72 75
D 281 178 112 294
To determine the number for the table, please select “Memory usage gauge”
in View menu of MPLAB at the end of the development. The gauge will show
how many instructions and registers are used by your program. The template
itself requires 48 instructions and 8 registers to operate. Therefore 48 was put
as an example – this is the minimal size your code could be as it is not allowed
to modify my template. You will need to put in the table your data, and your
codes will be assessed on their size in comparison to the codes developed by
people from the other groups for the same assignment. The less size of the
code, the higher the mark.