Laboratory Report (For Online Lab Class Only) : ECTE333: Microcontroller Architecture and Application Spring 2020 Session

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 8

ECTE333: Microcontroller Architecture and Application

Spring 2020 Session


Laboratory Report (For Online Lab Class Only)
Due date: 4:30 PM Friday, 6 Nov, 2020 (Week 12).
Total marks: 50 marks (Demontration Component of the Sping Laboratory).
Submission Submit via Moodle the typed report as one Microsoft Word file, which contains:
1) The documented C program for each lab task;
2) The required hardware connection;
3) Comments on the expected results and any anticipated problems with the C program.
Task List Lab 8 Task 1, Lab 9 Task 2, Lab 10 Task 2, and Lab 11 Task 2.
Notes: Marking is based on correctness and presentation quality. Each student is required to submit
original work for assessment. Plagiarizing, copying, or letting others use your work will result
in a mark of 0. The University’s policy on academic integrity is available at
http://www.uow.edu.au/about/policy/UOW058648.html.

Student Name: SYED SAAD KAMRAN


Student ID: 5617303

Lab Task 8.1:


a) C program
#include <avr/io.h>
#define NOP asm volatile ("nop")

void serial_init(void)
{
UCSRC = 0b10000110; // Asynchronous mode, no parity, 1 stop bit, 8 data bits
UCSRA = 0b00000000; // Normal speed, disable multi proc

//Baud rate 1200bps, assuming 1MHz clock


UBRRL = 0x33;
UBRRH = 0x00;

UCSRB = 0b00011000; // Enable Tx and Rx, disable interrupts


}

// Send serial data


void serial_send(unsigned char c){
while((UCSRA & (1<<UDRE))==0x00){;} //wait until UDRE flag = 1
UDR = c; // Write char to UDR for transmission
}

int main(void)
{
unsigned char key; //Key pressed
unsigned char prev_key = 0;
DDRB = 0b11110000; //Keypad linked with PORTB
DDRA = 0b11111111; //PORTA set as all 1’s meaning output for LEDs

serial_init();
while(1)
{
key = read_keypad();

if(key!=0 && key!= prev_key){ //same key isn’t being pressed,avoid repitition
LED_ON(key);
serial_send(key);

Page 1
}

}
}

unsigned char read_keypad(void)


{
unsigned char key; // Key pressed
unsigned char port_value; // to store input value from port
// Array to make scanning the keypad efficient
unsigned char keypad_col_bit[3] = {6,5,4};
unsigned char keypad_row_bit[4] = {3,2,1,0};
unsigned char keypad_key[3][4] = {{'1','4','7','*'},
{'2','5','8','0'},
{'3','6','9','#'}};
unsigned char col; // Keypad column 1,2,3
unsigned char row; // Keypad row 1,2,3,4

DDRB = 0b11110000;
//Scan the keypad to find which key is being pressed
key = 0;
for (col = 1;col<=3;col++){
//Send binary 0 to corresponding pin for the column
PORTB = ~(1<<(keypad_col_bit[col-1]));

//Creating a short delay


asm volatile("nop");
asm volatile("nop");

// Read back from port


port_value = PINB;

for (row = 1; row<=4; row++){


if ((port_value&(1<<(keypad_row_bit[row-1])))==0)
key = keypad_key[col-1][row-1];
}
}
return key;
}

// Initializing LED display


void LED_ON(unsigned char a){
switch (a){
case '0':
PORTA = 0b11111110;
NOP;
break;
case '1':
PORTA = 0b11111101;
break;
case '2':
PORTA = 0b11111011;
break;
case '3':
PORTA = 0b11110111;
break;
case '4':
PORTA = 0b11101111;
break;
case '5':
PORTA = 0b11011111;
break;
case '6':
PORTA = 0b10111111;
break;
case '7':

Page 2
PORTA = 0b01111111;
break;
case '8':
PORTA = 0b00000000;
break;
case '9':
PORTA = 0b00000000;
break;
case '*': // “*” key pressed
PORTA = 0b00000000;
break;
case '#': //
PORTA = 0b00000000;
break;
default:
NOP;
}
}

b) Required hardware connection


 Connect power cable to STK500 board.
 Spare RS232 is connected for programming purposes.
 RS232 serial port connected using the programing cable
 Port D.0 of the ATmega16 chip connected to Rx
 Port D.1 of the ATmega16 chip connected to Tx
 Connected PD0 and PD1 to RS232 spare port
 Keypad connected to RS232 spare port

c) Comments on the expected results and any anticipated problems with the C program. .
The expected results are that once you press the key on the keypad, the same key should be displayed on the seven
segment displays LED’s. This can be verified using hyperlink if we don’t have the display. The baud rate is 1200,
with 1 stop bit and no parity bit. The number pressed should be displayed once only in the hyper terminal not
multiple times.
Problems:
 The baud rate has to be consistent, if they don’t line up the code will fail and garbage might appear.
 When verifying the program with the hyperterminal software, pushing down the button will give repeated outputs.
To rectify this an if statement is needed and a delay needs to be placed in between reads.
 Use the assembly instruction to with nop, using only nop might not work correctly in all situations.
 Make sure Rx and Tx are connected to the correct ports, otherwise the received data and send data channels will
be interchanged causing incorrect results

Lab Task 9.2:


a) C program
#include <avr/io.h>
#include <inttypes.h> // Link header files required
#include <stdio.h>
#include <avr/interrupt.h>

//Global Variables that can be used with ISR and main


volatile uint32_t period; //32-bits unsigned integer to represent period
volatile uint32_t n; //overflow
volatile uint32_t freq; //32-bits unsigned integer to represent frequency

void init_USART(){ //Initialize serial


UCSRA = 0b00000000; //Normal speed, disable multi-proc
UCSRB = 0b10011000; //Enable Tx and Rx, and Rx interrupt
UCSRC = 0b10000110; //Asynchronous mode, no parity, 1 srop bit, 8 data bits

//Baud rate 1200bps, assuming 1MHz clock


UBRRL = 0x34;
UBRRH = 0x00;

Page 3
}

int USART_send(char c, FILE*stream){


while((UCSRA & 1<<UDRE) == 0x00){
; //wait until UDRE is 1 before sending data
}
//write the character to UDR for transmission
UDR = c;
return 0;
}

ISR(TIMER1_OVF_vect){ //timer1_overflow_interrupt handler


n++; // Increase overflow count by 1
}
ISR(TIMER1_CAPT_vect){ //timer1_capture_interrupt handler
period = ICR1 + n * 65536; //The value of timer 1 in ICR1 is the period
freq = 1000000/period; // Freq of square signal
TCNT1 = 0; // reset timer 1
n = 0; // overflow

}
int main(void)
{
init_USART(); //Initialise USART

DDRB = 0xFF; // set port B as output (all 1’s)


PORTB = 0xFF; // LEDs are active low

stdout = fdevopen(USART_send, NULL); //Initialize the standard I/O handlers

//Timer Initialisation
TCCR1A = 0b00000000; // selected normal mode
TCCR1B = 0b11000001; // no pre-scalar, rising edge
TIMSK = 0b00100100; // ENABLE the timer_1 capture_interrupt

sei(); //global interrupt enabled

while (1)
{
printf("/n/Frequency = %ld Hz, period = %ld ms", freq, period) //display period and frequency
PORTB = ~(freq); //compensate for active low LED
return 0;
}
}

b) Required hardware connection


 Connect power cable to STK500 board.
 Spare RS232 is connected for programming purposes.
 TTL from the square wave passed to timer input capture connected to port D.6.
 Port D.0 of the ATmega16 chip connected to Rx .
 Port D.1 of the ATmega16 chip connected to Tx .
 Function generator and the micro-controller connected to wishmaker.
 Common ground made by connecting the wish maker ground to STK-500’s ground.

c) Comments on the expected results and any anticipated problems with the C program. .
The connected oscilloscope can visualize a square wave, the measured frequency of the waves is represented using
the LED’s (top 8 bits). The hyperterminal is used to display the signal period and frequency.

Problems:

Page 4
 We had to use uint_32 because we were dealing with large numbers that might not necessarily be storable in a
16-bit space.
 The timer can only store the period upto 65536 hence we needed to use an overflow as a trigger to get the results
 The global interrupt have to be enabled using the sei() otherwise the program wont work.

Lab Task 10.2:


a) C program
#include <avr/io.h> //definitions headers
#include <stdio.h>

void serial_init(void){
// Asynchronous mode, no parity, 1 stop bit, 8 data bits
UCSRC = 0b10000110;

// Normal speed, disable multi-proc


UCSRA = 0b00000000;

// Baud rate 1200bps, assuming 1MHz clock


UBRRL = 0x33;
UBRRH = 0x00;

// Enable Tx and Rx, disable interrupts


UCSRB = 0b00011000;
}

int serial_receive(void){
// Wait until RXC flag = 1
while ((UCSRA & (1 << RXC)) == 0x00){;}
// Read the received char from UDR
return (UDR);
}

int serial_send(unsigned char data){


// Wait until UDRE flag = 1
while ((UCSRA & (1 << UDRE)) == 0x00){;}
// Write char to UDR for transmission
UDR = data;
}
int main(void)
{
//set frequency,duty and period as long interger variables
long int frequency;
long int duty;
long int high_time;
long int period;

DDRD=0b00100000; // set port D for output (D.5 is OC1A)

serial_init(); //Initialize
stdout = fdevopen(serial_send,NULL); //Initialize standard I/O handlers
stdin = fdevopen(NULL,serial_receive);

// Set register TCCR1A


// WGM11:WGM10 = 10: with WGM13-WGM12 to select timer
// Fast PWM, timer 1 runs from 0 to ICR1
TCCR1A=0b10000010;

// Set register TCCR1B


// WGM13:WGM12 = 11
// CS12:CS0 = 001 refers to internal clock=1MHz and no prescaler
TCCR1B=0b00011001;

ICR1=2000; // period of output signal


OCR1A=500; // pulse width of output signal
Page 5
while (1)
{
printf("\n\r Enter Frequency in HZ: ");
scanf("%d",&freq); //asks user input for frequency

period=(unsigned int) (1000000/freq); //converts freq to period


ICR1=period; //update ICR1

printf("\n\r Enter cycle: ");


scanf("%d",&duty); //asks user input for duty cycle

if (period>100) //if period is greater than 100


high_time=(period/100)*duty; //update the value of pulse width

else //period less than or equal to 100


high_time=(period*duty)/100; //update the value for pulse
width
OCR1A=high_time;

printf("Period = %d, high_time = %ld", period, high_time)


}
}

b) Required hardware connection


 Connect power cable to STK500 board.
 Spare RS232 is connected for programming purposes.
 Port D.0 of the ATmega16 chip connected to Rx .
 Port D.1 of the ATmega16 chip connected to Tx .
 SPROG3 jumper connected to ISP6PIN jumper.
 PD5 connected to the oscilloscope as we are using OC1A.
c) Comments on the expected results and any anticipated problems with the C program. .
The expected results of the program were to create a PWM to create square waves with variable frequency and
period , The user had to be asked to enter the duty cycle and frequency of the signal using the hyperterminal, but
due to the serial port only receiving data not sending data for the instructor, we added the option of outputting the
frequency and period in the hyper link too.
Problems:
 The calculations had to be done in milliseconds otherwise the output frequency might vary with a factor of 1000.
 The ICR1 and OCR1A had to be set constant due to the problems with the hyperterminal, hence users could not
enter the frequency and duty.
 The period might be less than 100, which will lead the compiler to get 0 for the high_time calculation hence we
need to include a case separately for the period less than 100.

Lab Task 11.2:


a) C program
#include <avr/io.h> //definitions header file for AVR board input and output
#include <avr/interrupt.h> //definitions header file for interrupts

unsigned int high_result; //int variable designed to store the ADCH


unsigned int low_result; // int variable designed to store the ADCL
unsigned int result; // int variable designed to store the result

ISR(ADC_vect){ // new entry in interrupt vector table


low_result=ADCL; //low result
high_result=ADCH;//high result
}

void serial_init(void){
//Control & Status Registers

//UCSRA- No setting

Page 6
UCSRA = 0b00000000;

//UCSRB.4 1 = Enable RX pin


// .3 1 = Enable TX pin
// .2 LSB of data bits 0=8 bits
UCSRB = 0b00011000;

//UCSRC.7 1 = write to UCSR,C 0 = write to UBBRH


// .6 0 = Asynchronous, 1 = synchronous communications
// .5 4 parity 00 = none, 01 = even, 11 = odd
// .2 1 MSB's of data bits 11=8 bits
UCSRC = 0b10000110;

// Baud rate = 2400


UBRRH = 0x00;
UBRRL = 0x19;

int serial_send(char c, FILE *stream){


// Wait until UDRE flag is set to logic 1
while ((UCSRA & (1 << UDRE)) == 0x00){;}
UDR = c; // Write character to UDR for transmission
return 0;
}

int main(void)
{
DDRB=0xFF; //configuring PORTB as output (all 1’s)
unsigned int analog,digital; //int variable designed to hold analog and digital results

ADMUX = 0b01100110; // REFS1:0 = 01 -> AVCC as reference,


// ADLAR = 0 -> Right adjust
// MUX4:0 = 00000 -> ADC0 as input

ADCSRA = 0b10000001;// ADEN = 1: enable ADC,


// ADSC = 0: dont start conversion,
// ADATE = 0: disable auto trigger,
// ADIE = 0: disable ADC interrupt,
//ASPS2:0 = 001: prescalar = 2
sei();
serial_init();

//Initialize the standard 10 handlers


stdout=fdevopen(serial_send,NULL);
while (1)
{
ADCSRA |= (1<<ADSC);

digital = (high_result << 8) + low_result;


PORTB = ~low_result; // LED

// Converts digital value to analog result


// (result in mV * 5000mV)/1024 steps
analog = ((unsigned long) result * 5000ul) / 1024ul;

printf("\r\nAnalog Value: %d",analog);//prints the digital and analog values

printf("\r\nDigital: %d",digital);//prints the digital and analog values


}
}
b) Required hardware connection
 Connect power cable to STK500 board.
 Spare RS232 is connected for programming purposes.
 Port D.0 of the ATmega16 chip connected to Rx .
Page 7
 Port D.1 of the ATmega16 chip connected to Tx .
 SPROG3 jumper to the ISP6PIN jumper.
 PORT B to LED’s.
 PORT A to connector A.

c) Comments on the expected results and any anticipated problems with the C program. .
The program is expected to get an analog input from an LDR or any source and convert it into an digital value, the
hyperterminal must display both the digital and analogue values. The analogue voltage is connected to PORT A
pin6 and the program should continuously output the info in the hyper terminal. The program configures the
serial port for a baud rate of 2400 bps, 8-data bit, 1-stop bit, no parity bit, flow control OFF.

Problems foreseen:
 We have been using 1200 baud rate for all the previous lab, hence we have to edit the initializing serial part to set
the baud rate to 2400 else the output will not be accurate.
 We have to make sure to use the correct formula according to the alignment, using the wrong formulae will lead
to an incorrect output.
 There are many ways to convert Analog to Digital, and the method we used is not versatile enough to handle all
possible analog to digital conversions.

Page 8

You might also like