0% found this document useful (0 votes)
20 views

MicroprocessorBasedSystems Term-II Lec6 Embedded C Programming Interrupts

Uploaded by

Mohamed Salah
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views

MicroprocessorBasedSystems Term-II Lec6 Embedded C Programming Interrupts

Uploaded by

Mohamed Salah
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 22

E1322

Microprocessor based Systems II

‘Embedded C programming-
Interrupts’

Dr. Ahmed El-Awamry

Date: 16.03.2024, Time: 13:50


Objective

▪ Be able to program 8051 interrupt, ADC and


DAC in embedded C.

© Dr. Ahmed El-Awamry 15.03.2024 2


Overview

▪ The 8051 compiler have extensive support


for the interrupts
▪ They assign a unique number to each of the 8051
interrupts

▪ It can assign a register bank to an ISR


▪ This avoids code overhead due to the pushes and pops of
the R0 – R7 registers
© Dr. Ahmed El-Awamry 15.03.2024 3
© Dr. Ahmed El-Awamry 15.03.2024 4
© Dr. Ahmed El-Awamry 15.03.2024 5
© Dr. Ahmed El-Awamry 15.03.2024 6
© Dr. Ahmed El-Awamry 15.03.2024 7
© Dr. Ahmed El-Awamry 15.03.2024 8
ADC Interfacing in Embedded C

© Dr. Ahmed El-Awamry 15.03.2024 9


© Dr. Ahmed El-Awamry 15.03.2024 10
ADC0808 Timing Diagram

© Dr. Ahmed El-Awamry 15.03.2024 11


ADC0808 Programming Steps

▪ Clock
▪ You'll need to generate or provide a clock signal to
the ADC0808. This might be done externally or by
toggling a GPIO pin in the 8051 in a timer
interrupt.
▪ Address
▪ The address lines need to be set before the ALE
pulse. This will select which channel you are
reading from.
▪ ALE (Address Latch Enable)
▪ Set ALE high and then low to latch in the address.

© Dr. Ahmed El-Awamry 15.03.2024 12


ADC0808 Programming Steps

▪ Start
▪ After a brief delay (following the ALE pulse), set
START high and then low to initiate conversion.
▪ EOC (End of Conversion)
▪ Wait for EOC to go low, which indicates the
conversion is complete. Better to wait till it goes
high again.
▪ Output Enable
▪ After EOC goes low, set OE high to enable the
output of the data. The data will be valid for
reading as indicated in the timing diagram.
▪ Data Outputs
▪ Read the data outputs from the ADC0808.
© Dr. Ahmed El-Awamry 15.03.2024 13
Code Example

#include <reg51.h>

// Control Pins
sbit ALE = P3^3;
sbit START = P3^4;
sbit EOC = P3^5;
sbit OE = P3^6;
sbit CLOCK = P3^7; // Timer 0 will toggle this clock pin (500kHz)

#define ADC_DATA P1

void Timer0_ISR(void) interrupt 1 {


CLOCK = ~CLOCK; // Toggle the CLOCK pin on each interrupt
}

© Dr. Ahmed El-Awamry 15.03.2024 14


Code Example
void ADC_Init() {
// Initialize control pins
ALE = 0;
START = 0;
OE = 0;
// Initialize Timer 0 in mode 2 (8-bit auto-reload)
TMOD &= 0xF0; // Clear Timer 0 mode bits
TMOD |= 0x02; // Set Timer 0 in mode 2
// Calculate and set the reload value for Timer 0 to get the desired clock rate
// Assuming a 12 MHz oscillator, a 500 kHz clock can be generated as follows:
// 12 MHz / 24 = 500 kHz, hence a reload value of 256 - 24 = 232 (0xE8)
TH0 = 0xE8;
TL0 = 0xE8;

// Enable Timer 0 interrupt


ET0 = 1;

// Start Timer 0
TR0 = 1;

// Global interrupt enable


EA = 1;
}
© Dr. Ahmed El-Awamry 15.03.2024 15
Code Example
unsigned char ADC_Read() {
// Start the ADC conversion
ALE = 1;
START = 1;
ALE = 0;
START = 0;

// Wait for conversion to complete


while(EOC == 1);
while(EOC == 0);
// Enable output
OE = 1;

// Short delay to allow for data line stabilization


_nop_(); // Assembly instruction for No Operation (acts as a small delay)

// Read ADC data


unsigned char adc_value = ADC_DATA;

// Disable output
OE = 0;

return adc_value;
}
© Dr. Ahmed El-Awamry 15.03.2024 16
Code Example

void main() {
ADC_Init(); // Initialize ADC and
Timer 0 for clock generation

while(1) {
unsigned char value =
ADC_Read();
// Process the value or display it
}
}

© Dr. Ahmed El-Awamry 15.03.2024 17


DAC0808 Interface Code Example
#include <reg51.h>

// Define the DAC ports


#define DAC_PORT P2

// Sine wave lookup table (for example: 32 entries of 8-bit sine wave
values)
unsigned char code sine_table[] = {
128, 176, 218, 245, 255, 245, 218, 176,
128, 79, 37, 10, 0, 10, 37, 79,
//... repeat pattern or fill in the rest of the sine values
};

// Variable to access the sine wave table


unsigned int sine_index = 0;
© Dr. Ahmed El-Awamry 15.03.2024 18
DAC0808 Interface Code Example

// Timer 0 ISR
void Timer0_ISR(void) interrupt 1 {
// Write the next value from the sine table to the DAC
DAC_PORT = sine_table[sine_index];

// Increment the sine_index to point to the next value


sine_index++;
if(sine_index >= sizeof(sine_table)) {
sine_index = 0; // Wrap around at the end of the table
}
}

© Dr. Ahmed El-Awamry 15.03.2024 19


DAC0808 Interface Code Example

void Timer0_Init() {
// Timer 0 in mode 2 (auto-reload mode)
TMOD = (TMOD & 0xF0) | 0x02; // Set T0 to mode 2

// Calculate and set the reload value for Timer 0 to get the required interrupt rate
// Example values given for a 12 MHz clock to produce a 256 kHz update rate
TH0 = 0xA4; // Timer high byte (reload value)
TL0 = 0xA4; // Timer low byte (initial value)

// Enable Timer 0 interrupt


ET0 = 1;
// Start Timer 0
TR0 = 1;
// Global interrupt enable
EA = 1;
}

© Dr. Ahmed El-Awamry 15.03.2024 20


DAC0808 Interface Code Example

void DAC_Init() {
// Initialize the DAC port as output
DAC_PORT = 0x00; // Set all DAC pins to low
}

void main() {
DAC_Init();
Timer0_Init();

while(1) {
// Main loop can be used to perform other tasks or put the MCU
in low-power mode
// DAC update is handled by the Timer 0 interrupt
}
}
© Dr. Ahmed El-Awamry 15.03.2024 21
Appendix

You might also like