Lec 5
Lec 5
com
Single-purpose processors
Performs specific computation task Custom single-purpose processors
Designed
e.g., hold traffic light green for 10 s e.g., measure a cars speed
Clk Basic timer 16-bit up counter 16 Cnt Top Reset
E.g., let Clk period be 10 ns And we count 20,000 Clk pulses Then 200 microseconds have passed 16-bit counter would count up to 65,535*10 ns = 655.35 microsec., resolution = 10 ns Top: indicates top count reached, wrap-around
Counter: like a timer, but counts pulses on a general input signal rather than clock
Timer/counter Clk 2x1 mux 16-bit up counter 16 Cnt Top Reset Mode
e.g., count cars passing over a sensor Can often configure device as either a timer or counter
Cnt_in
Interval timer
16/32-bit timer Clk Timer with a terminal count Clk 16-bit up counter 16 Cnt 16-bit up counter Reset = Top Clk Terminal count Time with prescaler Prescaler 16-bit up counter 16 Cnt2 Top2 16-bit up counter 16 Cnt1 Top1
Indicates when desired time interval has passed We set terminal count to desired interval
Number
of clock cycles = Desired time interval / Clock period Cascaded counters Prescaler
Mode
/* main.c */ #define MS_INIT 63535 void main(void){ int count_milliseconds = 0; configure timer mode set Cnt to MS_INIT wait a random amount of time turn on indicator light start timer while (user has not pushed reaction button){ if(Top) { stop timer set Cnt to MS_INIT start timer reset Top count_milliseconds++; } } turn light off printf(time: %i ms, count_milliseconds); }
16-bit timer, clk period is 83.33 ns, counter increments every 6 cycles Resolution = 6*83.33=0.5 microsec. Range = 65535*0.5 microseconds = 32.77 milliseconds Want program to count millisec., so initialize counter to 65535 1000/0.5 = 63535
Must reset timer every X time unit, else timer generates a signal Common use: detect failure, self-reset Another use: timeouts
osc
prescaler
clk
scalereg
overflow
timereg
overflow
checkreg
/* main.c */ main(){ wait until card inserted call watchdog_reset_routine while(transaction in progress){ if(button pressed){ perform corresponding action call watchdog_reset_routine } /* if watchdog_reset_routine not called every < 2 minutes, interrupt_service_routine is called */ }
watchdog_reset_routine(){ /* checkreg is set so we can load value into timereg. Zero is loaded into scalereg and 11070 is loaded into timereg */ checkreg = 1 scalereg = 0 timereg = 11070 } void interrupt_service_routine(){ eject card reset screen }
Takes parallel data and transmits serially Receives serial data and converts to parallel
0 1
1 0 1
embedd ed device
Parity: extra bit for simple error checking Start bit, stop bit Baud rate
10
Generates pulses with specific high/low times pwm_o Duty cycle: % time high
clk
Simpler than DC-DC converter or digital-analog converter DC motor speed, dimmer lights
pwm_o clk
50% duty cycle average pwm_o is 2.5V.
pwm_o clk
75% duty cycle average pwm_o is 3.75V.
11
clk
Input Voltage 0
pwm_o counter < cycle_high, pwm_o = 1 counter >= cycle_high, pwm_o = 0
cycle_high
void main(void){ /* controls period */ PWMP = 0xff; /* controls duty cycle */ PWM1 = 0x7f; while(1){}; }
The PWM alone cannot drive the DC motor, a possible way to implement a driver is shown below using an MJE3055T NPN transistor. 5V
5V
A B
From process or
DC MOTOR
12
communication s bus
void WriteChar(char c){ RS = 1; DATA_BUS = c; EnableLCD(45); delay */ } /* indicate data being sent */ /* send data to LCD */ /* toggle the LCD with appropriate
CODES I/D = 1 cursor moves left I/D = 0 cursor moves right S = 1 with display shift S/C =1 display shift S/C = 0 cursor movement R/L = 1 shift to right R/L = 0 shift to left DL = 1 8-bit DL = 0 4-bit N = 1 2 rows N = 0 1 row F = 1 5x10 dots F = 0 5x7 dots
RS 0 0 0 0 0 0 1
R/W 0 0 0 0 0 0 0
DB7 0 0 0 0 0 0
DB6 0 0 0 0 0 0
DB5 0 0 0 0 0 1
DB4 0 0 0 0 1 DL
DB3 0 0 0 1 S/C N
DB2 0 0 1 D R/L F
DB1 0 1 I/D C * *
DB0 1 * S B * *
Description Clears all display, return cursor home Returns cursor home Sets cursor move direction and/or specifies not to shift display ON/OFF of all display(D), cursor ON/OFF (C), and blink position (B) Move cursor and shifts display Sets interface data length, number of display lines, and character font Writes Data
WRITE DATA
13
N1 N2 N3 N4 M1 M2 M3 M4 key_code
k_pressed
4 key_code
keypad controller
N=4, M=4
14
Stepper motor: rotates fixed number of degrees when given a step signal
Sequence 1 2 3 4 5
Vd A A GND Bias/Set Clk O|C 1 2 3 4 5 6 7 8
A + + +
B + + +
A + + 16 14 13 12 11 10 9
MC3479P 15
Rotation achieved by applying specific voltage sequence to coils Controller greatly simplifies this
A A B B
15
/* main.c */
void main(void){ */turn the motor forward */ cw=0; /* set direction */ clk=0; delay(); clk=1; /* pulse clock */
void delay(void){ int i, j; for (i=0; i<1000; i++) for ( j=0; j<50; j++) i = i + 0; }
/*turn the motor backwards */ cw=1; /* set direction */ clk=0; delay(); clk=1; } /* pulse clock */
Stepper Motor
The output pins on the stepper motor driver do not provide enough current to drive the stepper motor. To amplify the current, a buffer is needed. One possible implementation of the buffers is pictured to the left. Q1 is an MJE3055T NPN transistor and Q2 is an MJE2955T PNP transistor. A is connected to the 8051 microcontroller and B is connected to the stepper motor.
1K
A
+V Q1
B
Q2 1K
16
8051
P2.4 P2.3 P2.2 P2.1 P2.0 GND/ +V
/*main.c*/ sbit notA=P2^0; sbit isA=P2^1; sbit notB=P2^2; sbit isB=P2^3; sbit dir=P2^4; void delay(){ int a, b; for(a=0; a<5000; a++) for(b=0; b<10000; b++) a=a+0; } void move(int dir, int steps) { int y, z; /* clockwise movement */ if(dir == 1){ for(y=0; y<=steps; y++){ for(z=0; z<=19; z+4){ isA=lookup[z]; isB=lookup[z+1]; notA=lookup[z+2]; notB=lookup[z+3]; delay(); } } }
Steppe r Motor
A possible way to implement the buffers is located below. The 8051 alone cannot drive the stepper motor, so several transistors were added to increase the current going to the stepper motor. Q1 are MJE3055T NPN transistors and Q3 is an MJE2955T PNP transistor. A is connected to the 8051 microcontroller and B is connected to the stepper +V 1K motor. Q1
+V
A B
1K Q2
330
/* counter clockwise movement */ if(dir==0){ for(y=0; y<=step; y++){ for(z=19; z>=0; z - 4){ isA=lookup[z]; isB=lookup[z-1]; notA=lookup[z -2]; notB=lookup[z-3]; delay( ); } } } } void main( ){ int z; int lookup[20] = { 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0 }; while(1){ /*move forward, 15 degrees (2 steps) */ move(1, 2); /* move backwards, 7.5 degrees (1step)*/ move(0, 1); } }
17
5.0V 4.5V 4.0V 3.5V 3.0V 2.5V 2.0V 1.5V 1.0V 0.5V 0V
2 1 time
1111 1110 1101 1100 1011 1010 1001 1000 0111 0110 0101 0100 0011 0010 0001 0000
4 3
4 3 2 1 time
t1
t2
t3
t4
t1
t2
t3
t4
proportionality
analog to digital
digital to analog
18
Given an analog input signal whose voltage should range from 0 to 15 volts, and an 8-bit digital encoding, calculate the correct encoding for 5 volts. Then trace the successive-approximation approach to find the correct encoding. 5/15 = d/(28-1) d= 85 Encoding: 01010101
Successive-approximation method
(Vmx Vm ) = 7.5 volts a in Vmx = 7.5 volts. a 0 0 0 0 0 0 0 0 (5.63 + 4.69) = 5.16 volts Vmx = 5.16 volts. a 0 1 0 1 0 0 0 0