Final Exam Solution problems 1 - 6

NOTE: The solutions presented here are simply that, suggested solutions. There are almost always several methods that will adequately solve the exercises below and only one of the several possible solutions is presented herein.

It is also important to note that as the compiler changes, the output of the code generator may also change. These solutions were generated using CodeVisionAVR version 1.0.2.2F. The target processor is an AT90S8535 and the clock is 4MHz.

1. Create a new project by using the CodeWizardAVR to generate the source code shell. The project should be configured as follows:

· UART – 9600 baud, 8 data bits, 1 stop bit, no parity. Transmit and receive enabled

· PORTA – All inputs

· PORTB – All outputs

· Timer1 – Cause an interrupt to occur every 5ms.

The codewizard settings are shown in the following figures (Figures 4.39, 4.40, 4.41 and 4.42.) In order to use this program shell in subsequent exercises and test them with the Progressive Resources, LLC, MegaAVR-Development Board, port C is used for outputs instead of port B. Also, the internal pull-ups are enabled for PORT A.

(IFigure 4.39 CodeWizardAVR UART Tab here)

Figure 4.39 CodeWizardAVR UART Tab

(Insert Figure 4.40 CodeWizardAVR Ports, Port A Tab here)

Figure 4.40 CodeWizardAVR Ports, Port A Tab

(Insert Figure 4.41 CodeWizardAVR Ports, Port C Tab here)

Figure 4.41 CodeWizardAVR Ports, Port C Tab

(Insert Figure 4.42 CodeWizardAVR Timers, Timer 1 Tab here)

Figure 4.42 CodeWizardAVR Timers, Timer 1

/*********************************************

This program was produced by the

CodeWizardAVR V1.0.2.2f Standard

Automatic Program Generator

© Copyright 1998-2002 HP InfoTech s.r.l.

http://www.hpinfotech.ro

e-mail: ,

Project : Chapter 4, Lab 1

Version : 1.0

Date : 5/11/2002

Author : Sarah Cox

Company : Book

Comments:

Chip type : AT90S8535

Clock frequency : 4.000000 MHz

Memory model : Small

Internal SRAM size : 512

External SRAM size : 0

Data Stack size : 128

*********************************************/

#include <90s8535.h>

// Standard Input/Output functions

#include <stdio.h>

// Timer 1 overflow interrupt service routine

interrupt [TIM1_OVF] void timer1_ovf_isr(void)

{

// Reinitialize Timer 1 value

TCNT1H=0xFE;

TCNT1L=0xC7;

// Place your code here

}

// Declare your global variables here

void main(void)

{

// Declare your local variables here

// Input/Output Ports initialization

// Port A

PORTA=0xFF;

DDRA=0x00;

// Port B

PORTB=0x00;

DDRB=0x00;

// Port C

PORTC=0x00;

DDRC=0xFF;

// Port D

PORTD=0x00;

DDRD=0x00;

// Timer/Counter 0 initialization

// Clock source: System Clock

// Clock value: Timer 0 Stopped

TCCR0=0x00;

TCNT0=0x00;

// Timer/Counter 1 initialization

// Clock source: System Clock

// Clock value: 62.500 kHz

// Mode: Normal top=FFFFh

// OC1A output: Discon.

// OC1B output: Discon.

// Noise Canceler: Off

// Input Capture on Falling Edge

TCCR1A=0x00;

TCCR1B=0x03;

TCNT1H=0xFE;

TCNT1L=0xC7;

OCR1AH=0x00;

OCR1AL=0x00;

OCR1BH=0x00;

OCR1BL=0x00;

// Timer/Counter 2 initialization

// Clock source: System Clock

// Clock value: Timer 2 Stopped

// Mode: Normal top=FFh

// OC2 output: Disconnected

TCCR2=0x00;

ASSR=0x00;

TCNT2=0x00;

OCR2=0x00;

// External Interrupt(s) initialization

// INT0: Off

// INT1: Off

GIMSK=0x00;

MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization

TIMSK=0x04;

// UART initialization

// Communication Parameters: 8 Data, 1 Stop, No Parity

// UART Receiver: On

// UART Transmitter: On

// UART Baud rate: 9600

UCR=0x18;

UBRR=0x19;

// Analog Comparator initialization

// Analog Comparator: Off

// Analog Comparator Input Capture by Timer/Counter 1: Off

// Analog Comparator Output: Off

ACSR=0x80;

// Global enable interrupts

#asm("sei")

while (1)

{

// Place your code here

};

}

2. Modify the generated project above to send the value present at PORTA to the UART once per second. Do not send the value from an interrupt routine.

Modified or new lines in the code below are shown in bold print.

/*********************************************

This program was produced by the

CodeWizardAVR V1.0.2.2f Standard

Automatic Program Generator

© Copyright 1998-2002 HP InfoTech s.r.l.

http://www.hpinfotech.ro

e-mail: ,

Project : Chapter 4, Lab 2

Version : 1.0

Date : 5/11/2002

Author : Sarah Cox

Company : Book

Comments:

This program reads the value present at PORTA

and sends it to the UART once per second.

Baud Rate: 9600 at 4MHz system clock.

Chip type : AT90S8535

Clock frequency : 4.000000 MHz

Memory model : Small

Internal SRAM size : 512

External SRAM size : 0

Data Stack size : 128

*********************************************/

#include <90s8535.h>

// Standard Input/Output functions

#include <stdio.h>

#include <delay.h>

#define xtal 4000000

// Timer 1 overflow interrupt service routine

interrupt [TIM1_OVF] void timer1_ovf_isr(void)

{

// Reinitialize Timer 1 value

TCNT1H=0xFE;

TCNT1L=0xC7;

// Place your code here

}

// Declare your global variables here

char input_value;

void main(void)

{

// Declare your local variables here

// Input/Output Ports initialization

// Port A

PORTA=0xFF;

DDRA=0x00;

// Port B

PORTB=0x00;

DDRB=0x00;

// Port C

PORTC=0x00;

DDRC=0xFF;

// Port D

PORTD=0x00;

DDRD=0x00;

// Timer/Counter 0 initialization

// Clock source: System Clock

// Clock value: Timer 0 Stopped

TCCR0=0x00;

TCNT0=0x00;

// Timer/Counter 1 initialization

// Clock source: System Clock

// Clock value: 62.500 kHz

// Mode: Normal top=FFFFh

// OC1A output: Discon.

// OC1B output: Discon.

// Noise Canceler: Off

// Input Capture on Falling Edge

TCCR1A=0x00;

TCCR1B=0x03;

TCNT1H=0xFE;

TCNT1L=0xC7;

OCR1AH=0x00;

OCR1AL=0x00;

OCR1BH=0x00;

OCR1BL=0x00;

// Timer/Counter 2 initialization

// Clock source: System Clock

// Clock value: Timer 2 Stopped

// Mode: Normal top=FFh

// OC2 output: Disconnected

TCCR2=0x00;

ASSR=0x00;

TCNT2=0x00;

OCR2=0x00;

// External Interrupt(s) initialization

// INT0: Off

// INT1: Off

GIMSK=0x00;

MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization

TIMSK=0x04;

// UART initialization

// Communication Parameters: 8 Data, 1 Stop, No Parity

// UART Receiver: On

// UART Transmitter: On

// UART Baud rate: 9600

UCR=0x18;

UBRR=0x19;

// Analog Comparator initialization

// Analog Comparator: Off

// Analog Comparator Input Capture by Timer/Counter 1: Off

// Analog Comparator Output: Off

ACSR=0x80;

// Global enable interrupts

#asm("sei")

while (1)

{

// Place your code here

input_value = PINA; // read value from PORTA

putchar(input_value); // send to the UART

#asm("cli"); // disable interrupts to

// ensure proper timing by the

// delay routine

delay_ms(1000); // wait one second

#asm("sei"); // re-enable interrupts (in case

// we want to do anything with

// the timer)

};

}

3. Use the terminal tool available in CVAVR to read the data read from PORTA in the above program in hexadecimal notation.

Figure 4.43 shows the results in the terminal tool window of CodeVisionAVR. Notice that the status bar at the bottom says “Hex” and the command button at the top that controls the display of hex or ASCII format says “ASCII”. The values shown were achieved by moving jumpers around on the PORTA pins to tie them to ground or allow their internal pull-ups to tie them high.

(Insert Figure 4.43 Terminal Tool, Hex Mode here)

Figure 4.43 Terminal Tool, Hex Mode

4. Send data, in hexadecimal notation, from the terminal tool to the target device. Place the value received by the UART on the target device on PORTB. Verify that the correct value is present at PORTB.

Note that PORTC is used for the output in this solution. This allows the output to be read via the LEDs on the Progressive Resources, LLC, MegaAVR-Development Board.

/*********************************************

This program was produced by the

CodeWizardAVR V1.0.2.2f Standard

Automatic Program Generator

© Copyright 1998-2002 HP InfoTech s.r.l.

http://www.hpinfotech.ro

e-mail: ,

Project : Chapter 4, Lab 4

Version : 1.0

Date : 5/11/2002

Author : Sarah Cox

Company : Book

Comments:

This program receives a byte (in hexadecimal, not

ASCII) from the UART and displays the value on

Port C. It acknowledges the receipt and display of

the value by sending an 0xAA to the UART.

Baud rate: 9600 at 4MHz system clock.

Chip type : AT90S8535

Clock frequency : 4.000000 MHz

Memory model : Small

Internal SRAM size : 512

External SRAM size : 0

Data Stack size : 128

*********************************************/

#include <90s8535.h>

// Standard Input/Output functions

#include <stdio.h>

#include <delay.h>

// Declare your global variables here

int input_value;

void main(void)

{

// Declare your local variables here

// Input/Output Ports initialization

// Port A

PORTA=0x00;

DDRA=0x00;

// Port B

PORTB=0x00;

DDRB=0x00;

// Port C

PORTC=0x00;

DDRC=0xFF;

// Port D

PORTD=0x00;

DDRD=0x00;

// Timer/Counter 0 initialization

// Clock source: System Clock

// Clock value: Timer 0 Stopped

TCCR0=0x00;

TCNT0=0x00;

// Timer/Counter 1 initialization

// Clock source: System Clock

// Clock value: Timer 1 Stopped

// Mode: Normal top=FFFFh

// OC1A output: Discon.

// OC1B output: Discon.

// Noise Canceler: Off

// Input Capture on Falling Edge

TCCR1A=0x00;

TCCR1B=0x00;

TCNT1H=0x00;

TCNT1L=0x00;

OCR1AH=0x00;

OCR1AL=0x00;

OCR1BH=0x00;

OCR1BL=0x00;

// Timer/Counter 2 initialization

// Clock source: System Clock

// Clock value: Timer 2 Stopped

// Mode: Normal top=FFh

// OC2 output: Disconnected

TCCR2=0x00;

ASSR=0x00;

TCNT2=0x00;

OCR2=0x00;

// External Interrupt(s) initialization

// INT0: Off

// INT1: Off

GIMSK=0x00;

MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization

TIMSK=0x00;

// UART initialization

// Communication Parameters: 8 Data, 1 Stop, No Parity

// UART Receiver: On

// UART Transmitter: On

// UART Baud rate: 9600

UCR=0x18;

UBRR=0x19;

// Analog Comparator initialization

// Analog Comparator: Off

// Analog Comparator Input Capture by Timer/Counter 1: Off

// Analog Comparator Output: Off

ACSR=0x80;

while (1)

{

// Place your code here

input_value = getchar();

PORTC = ~((char)input_value);

putchar(0xAA); // acknowledge

};

}

5. Use the CodeWizardAVR to generate a shell to turn on an LED when a falling edge occurs on external interrupt 0 and turns it off when a rising edge occurs on external interrupt 1. Complete and test the program.

Figures 4.44, 4.45, 4.46, and 4.47 show the CodeWizard settings used to generate the shell for the solution code. The bold lines in the following program are the lines added after the shell was generated.

(Insert Figure 4.44 CodeWizard Chip Settings here)

Figure 4.44 CodeWizard Chip Settings

(Insert Figure 4.45 Port C, Pin 0 Output, Pins 1-7 Input here)

Figure 4.45 Port C, Pin 0 Output, Pins 1-7 Input

(Insert Figure 4.46 Port D, Ext Int 0 and 1 Inputs with Internal Pull-Ups Enabled here)

Figure 4.46 Port D, Ext Int 0 and 1 Inputs with Internal Pull-Ups Enabled

(Insert Figure 4.47 Ext Int 0 and 1 Enabled here)

Figure 4.47 Ext Int 0 and 1 Enabled

/*********************************************

This program was produced by the

CodeWizardAVR V1.0.2.2f Standard

Automatic Program Generator

© Copyright 1998-2002 HP InfoTech s.r.l.

http://www.hpinfotech.ro

e-mail: ,

Project : Chapter 4, Lab 5

Version : 1.0

Date : 5/13/2002

Author : Sarah Cox

Company : Book

Comments:

This program sets PORTC pin 0 low when a falling edge

occurs on external interrupt 0 and sets PORTC pin 0

high when a rising edge occurs on external interrupt 1.

Chip type : AT90S8535

Clock frequency : 4.000000 MHz

Memory model : Small

Internal SRAM size : 512

External SRAM size : 0

Data Stack size : 128

*********************************************/

#include <90s8535.h>

// External Interrupt 0 service routine

interrupt [EXT_INT0] void ext_int0_isr(void)

{

// Place your code here

PORTC.0 = 0;

}

// External Interrupt 1 service routine

interrupt [EXT_INT1] void ext_int1_isr(void)

{

// Place your code here

PORTC.0 = 1;

}

// Declare your global variables here

void main(void)

{

// Declare your local variables here

// Input/Output Ports initialization

// Port A

PORTA=0x00;

DDRA=0x00;

// Port B

PORTB=0x00;

DDRB=0x00;

// Port C

PORTC=0x00;

DDRC=0x01;

// Port D

PORTD=0x0C;

DDRD=0x00;

// Timer/Counter 0 initialization

// Clock source: System Clock

// Clock value: Timer 0 Stopped

TCCR0=0x00;

TCNT0=0x00;

// Timer/Counter 1 initialization

// Clock source: System Clock

// Clock value: Timer 1 Stopped

// Mode: Normal top=FFFFh

// OC1A output: Discon.

// OC1B output: Discon.

// Noise Canceler: Off

// Input Capture on Falling Edge

TCCR1A=0x00;

TCCR1B=0x00;

TCNT1H=0x00;

TCNT1L=0x00;

OCR1AH=0x00;

OCR1AL=0x00;

OCR1BH=0x00;

OCR1BL=0x00;

// Timer/Counter 2 initialization

// Clock source: System Clock

// Clock value: Timer 2 Stopped

// Mode: Normal top=FFh

// OC2 output: Disconnected

TCCR2=0x00;

ASSR=0x00;

TCNT2=0x00;

OCR2=0x00;

// External Interrupt(s) initialization

// INT0: On

// INT0 Mode: Falling Edge

// INT1: On

// INT1 Mode: Rising Edge

GIMSK=0xC0;

MCUCR=0x0E;

GIFR=0xC0;

// Timer(s)/Counter(s) Interrupt(s) initialization

TIMSK=0x00;

// Analog Comparator initialization

// Analog Comparator: Off

// Analog Comparator Input Capture by Timer/Counter 1: Off

// Analog Comparator Output: Off

ACSR=0x80;

// Global enable interrupts

#asm("sei")

while (1)

{

// Place your code here

};

}

NOTE: The solutions presented here are simply that, suggested solutions. There are almost always several methods that will adequately solve the exercises below and only one of the several possible solutions is presented herein. The solutions are designed to work with circuitry similar to the Progressive Resources, LLC development board (refer to appendix) with its built-in LED’s and simple ground/open inputs. Some of the examples use the Progressive Resources board with an AT90S8535 processor and an 6 MHz oscillator while others used the Mega163 processor and standard oscillator on the PRLLC board.

6. Create a program that will demonstrate how a watchdog timer resets the processor if the program hangs up in an infinite loop.

This program can take many forms. The example below simply reads Port D and outputs the lower 4 bits from Port D on Port C. Setting the MSB of Port D high causes the program to enter an infinite loop and so will appear to be doing nothing (Port C lower 4 bits will no longer reflect Port D lower 4 bits). Run the program with the WDT disabled (comment out the enable line) and see that setting the MSB bit of Port D high will prevent the program from operating. Try it again with the WDT enabled.

Without the WDT, the program will lock in the while(PIND.7) loop and stop operating. With the WDT, the program resets 15 ms after entering the while(PIND.7) and will restart (be reset) and run down to the while(PIND.7) loop so it will continue to appear to operate normally.

/*This program demonstrates the watchdog timer(WDT).

Richard H. Barnett, PE, Ph.D. 4/28/2002*/

#include <90s8535.h>

void main(void)

{

PORTA=0x00;

DDRA=0x00; //porta all input

PORTB=0x00;

DDRB=0x00; //portb all input

PORTC=0x00;

DDRC=0xFF; //portc all output

PORTD=0xFF; //portd pullups active

DDRD=0x00; //portd all input

TCCR0=0x00; //timer 0 stopped

TCNT0=0x00;

TCCR1A=0x00; //timer 1 stopped

TCCR1B=0x00;

TCNT1H=0x00;

TCNT1L=0x00;

OCR1AH=0x00;

OCR1AL=0x00;

OCR1BH=0x00;

OCR1BL=0x00;

TCCR2=0x00; //timer 2 stopped

ASSR=0x00;

TCNT2=0x00;

OCR2=0x00;

GIMSK=0x00; //external interrupts disabled

MCUCR=0x00;

TIMSK=0x00; //no timer interrupts active

ACSR=0x80; //analog comparator off

//Comment out the line below to try this program without the WDT

WDTCR = 0x8; //enable WDT with 15 ms time out

while (1)

{

PORTC = (PIND & 0x0f); //repeat lower 4 bits on port C

while (PIND.7); //stop here if MSB high

#asm ("WDR"); //reset WDT if enabled

};

}