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
};
}