Suggested Solutions to Chapter 4 Laboratory Activities

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.
(I
Figure 4.39 CodeWizardAVR UART Tab
Figure 4.39 CodeWizardAVR UART Tab here)
Figure 4.39 CodeWizardAVR UART Tab
Figure 4.40 CodeWizardAVR Ports, Port A Tab
(Insert Figure 4.40 CodeWizardAVR Ports, Port A Tab here)
Figure 4.40 CodeWizardAVR Ports, Port A Tab
Figure 4.41 CodeWizardAVR Ports, Port C Tab
(Insert Figure 4.41 CodeWizardAVR Ports, Port C Tab here)
Figure 4.41 CodeWizardAVR Ports, Port C Tab
Figure 4.42 CodeWizardAVR Timers, Timer 1
(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:[email protected] , [email protected]
Project :
Version :
Date
:
Author :
Company :
Comments:
Chapter 4, Lab 1
1.0
5/11/2002
Sarah Cox
Book
Chip type
Clock frequency
Memory model
Internal SRAM size
External SRAM size
:
:
:
:
:
AT90S8535
4.000000 MHz
Small
512
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:[email protected] , [email protected]
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;
//
putchar(input_value); //
#asm("cli");
//
//
//
delay_ms(1000);
//
#asm("sei");
//
//
//
};
}
read value from PORTA
send to the UART
disable interrupts to
ensure proper timing by the
delay routine
wait one second
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.
Figure 4.43 Terminal Tool, Hex Mode
(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:[email protected] , [email protected]
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.
Figure 4.44 CodeWizard Chip Settings
(Insert Figure 4.44 CodeWizard Chip Settings here)
Figure 4.44 CodeWizard Chip Settings
Figure 4.45 Port C, Pin 0 Output, Pins 1-7 Input
(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
Figure 4.46 Port D, Ext Int 0 and 1 Inputs with Internal Pull-Ups Enabled
(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
Figure 4.47 Ext Int 0 and 1 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:[email protected] , [email protected]
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
PORTB=0x00;
DDRB=0x00;
//portb
PORTC=0x00;
DDRC=0xFF;
//portc
PORTD=0xFF;
//portd
DDRD=0x00;
//portd
all input
all input
all output
pullups active
all input
TCCR0=0x00;
TCNT0=0x00;
//timer 0 stopped
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
//timer 1 stopped
TCCR2=0x00;
ASSR=0x00;
TCNT2=0x00;
OCR2=0x00;
//timer 2 stopped
GIMSK=0x00;
MCUCR=0x00;
//external interrupts disabled
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);
while (PIND.7);
#asm ("WDR");
};
}
//repeat lower 4 bits on port C
//stop here if MSB high
//reset WDT if enabled