View detail for PC-Interfaced Data Aquisition System with the Atmel AT89C2051 Microcontroller

PC-Interfaced Data Acquisition System
with the Atmel AT89C2051 Microcontroller
Introduction
The features of the Atmel AT89C2051 microcontroller offer the user the chance to
achieve a very low-cost/performance data acquisition system (DAQS) for low-frequency applications.
The main idea of this application note is to fully use the internal architecture of the
microcontroller to obtain the maximum analog-to-digital conversion (ADC) speed,
maximum connectivity to any IBM-compatible PC, and maximum further development
applications.
AT89C2051
Microcontroller
Application
Note
As it is well known, any stand-alone DAQS must have an ADC suitable for the
imposed analog input signals properties, a local memory for temporary data storage
and additional hardware for the PC interfacing.
PC interfacing is particularly useful for monitoring analog input signals and data
manipulation with a computer program. Furthermore, PC interfacing allows remote
control of the DAQS via the Internet.
For slow-varying analog input signals (temperature, pressure, bio-medical signals,
speech), a low-speed ADC and, consequently, a low-speed DAQS is needed.
The AT89C2051 was chosen to be the core of such a DAQS because of the following
features:
•
The internal comparator allows easy implementation of a Successive
Approximation ADC (SADC) with an external digital-to-analog converter (DAC) up
to 10-bit resolution, if 5V reference voltage is considered.
•
Internal Flash memory may store the SADC algorithm and generate the control
signals for the DAQS. It may also generate the control signals for the external
memory of the DAQS.
•
It may also communicate with a host PC where digital data can be easily
manipulated and displayed.
This application note will describe a DAQS step-by-step, assuming that the user is
familiar with the features of the microcontroller(1), DAC(2), and various logical gates
that are used.
Notes:
1. Programmer’s Guide and Instruction Set – AT89C2051 datasheet
(www.atmel.com).
2. Maxim MAX527 datasheet (www.maxim.com).
3. Interfacing the Standard Parallel Port document from:
http://www.geocities.com/siliconvalley/bay/8302/parallel.htm
Rev. 1489A–MICRO–11/03
1
2
1
14
2
15
3
16
4
17
5
18
6
19
7
20
8
21
9
22
10
23
11
24
12
25
13
4011
U4A
SELECT
PE
BUSY
ACK
D7
D5
D4
D3
D2
1N4148
+Vcc
12
9
7
4
1
15
2
3
5
6
11
10
14
13
74157
4Y
3Y
2Y
1Y
U9
74157
A/B
G
1A
1B
2A
2B
3A
3B
4A
4B
U6
AT89C2051
GND
VCC
P3.7
+Vcc
R3
4.7K
10
20
11
A/B
G
1A
1B
2A
2B
3A
3B
4A
4B
4Y
3Y
2Y
1Y
1
15
2
3
5
6
11
10
14
13
12
9
7
4
14
15
16
17
18
19
D0
D4
D1
D5
D2
D6
D3
D7
D0
D1
D2
D3
D4
D5
D6
D7
RESET
CLOCK
MCS
LSB/MSB
8
D2
D0
ERR
D1
1
2
P1.2
P1.3
P1.4
P1.5
P1.6
P1.7
11
10
12
13
9
8
6
5
4040
RST
CLK
U8
U4D
U4C
U4B
Q1
Q2
Q3
Q4
Q5
Q6
Q7
Q8
Q9
Q10
Q11
Q12
9
7
6
5
3
2
4
13
12
14
15
1
4011
11
4011
10
4011
4
D0
D1
D2
D3
D4
D5
D6
D7
DB25
P1
3
P3.0/RXD
P3.1/TXD
P3.2/INT0
P3.3/INT1
P3.4/T0
P3.5/T1
16
15
14
13
12
11
10
9
2
3
6
7
8
9
13
18
17
P1.1/AIN1
A0
A1
XTAL1
20
33pF
WR
LDAC
XTAL2
21
22
5
CSLSB
CSMSB
C3
D8/D0
D9/D1
D10/D2
D11/D3
D4
6
VREFAB
D5
19
VREFCD
D6
D7
4
12
Vref
3
VOUTA
2
VOUTB
1
VOUTC
24
VOUTD
RST/VPP P1.0/AIN0
Vin
-Vcc
+Vcc
5
AGND
7
DGND
4
VSS
23
VDD
1
U3
33pF
C2
+ C1
10uF
R2
8.2K
Y1
12MHz
D1
S1
RESET
1N4148
+Vcc
MWE
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
MCSLSB
MCSMSB
U1
MAX527
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
8
10
5
6
7
4
3
2
1
17
16
15
8
10
5
6
7
4
3
2
1
17
16
15
8
10
5
6
7
4
3
2
1
17
16
15
2114
CS
WE
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
U7
2114
CS
WE
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
U5
2114
CS
WE
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
U2
D0
D1
D2
D3
D0
D1
D2
D3
D0
D1
D2
D3
14
13
12
11
14
13
12
11
14
13
12
11
D0
D1
D2
D3
D4
D5
D6
D7
D0
D1
D2
D3
The Control Unit of
the DAQS
The complete DAQS is illustrated in Figure 1 and any further reference, if not otherwise
specified, will be made considering this figure.
The system RESET is used either with the RESET push-button or by the bit D7, through
the diode D2 of the host PC’s parallel interface (parallel port) DATA_PORT. The group
D1, C1, R2 is used for obvious reasons. The system may be manually or automatically
restarted.
The useful data and control lines are chosen among the 15 I/O lines of the microcontroller (i.e., 13 out of 15), as shown in Tables 1 and 2.
Figure 1. Data Acquisition System with the Atmel AT89C2051
AT89C2051 DAQS
1489A–MICRO–11/03
AT89C2051 DAQS
Table 1. Data Line Allocation
I/O Line
Data Line
P1.2
P1.3
P1.4
P1.5
P1.6
P1.7
P3.7
P3.5
D0/D8
D1/D9
D2/D10
D3/D11
D4
D5
D6
D7
Table 2. Control Line Allocation
I/O Line
Signal
Description
P3.0
WR
Active-low input. When active, it is written in the input DAC registers.
P3.1
MWE
Active-low signal. When active and a memory chip is selected, it allows memory writing.
P3.2
CLOCK
Address counter clock signal. Used when a new memory address is accessed.
P3.3
MCS
Memory chip select signal.
P3.4
LSB/MSB
When low, the least significant byte (D0...D7) is selected and when high, the most significant nibble
(D8...D11) is selected.
The Data Conversion
Block
The Data Conversion block was created with the help of Maxim MAX527(2) DAC (U1 in
Figure 1) and the internal comparator of the microcontoller.
The conversion method (i.e. SADC) is a fixed step number one, in each conversion step
one bit being found. The conversion algorithm is stored in the internal Flash memory of
the microcontroller and involves 12 steps/conversion. It should be mentioned here that
because of the microcontroller internal comparator, a practical 10-bit accuracy ADC can
be obtained, the least significant 2 bits being neglected.
The settling time of the DAC is 5 µs and the stored conversion program contains delay
loops after any data transmissions to the DAC (see the microcontroller program listing in
Appendix A).
The External Memory
Block
The external memory block (EMB) used in our DAQS uses three memory devices,
2114-type (1024 x 4 bits) because at the time the system was implemented no other
memory devices were available. It should be pointed out that other memory devices
could be used with a slight modification of the Flash memory program.
The memory devices are labeled U2, U5 and U7 in Figure 1. In this EMB, 1 kilosample,
12 bits each, can be stored.
The address counter is a standard CMOS 4040 (14-bit resolution, buffered outputs), the
address being maintained when the internal memory of the microcontroller is used. It is
obvious that, initially, the counter is reset.
Because the data bus is 8 bits wide, the EMB is partitioned into two blocks: 8 bits for the
least significant byte (U5 and U7 in Figure 1) with the signal MCSLSB and 4 bits for the
most significant nibble (U2 in Figure 1) with the signal MCSMSB.
The EMB control signals are realized with the NAND gates U4B, U4C and U4D in
Figure 1, parts of a standard CMOS 4011 chip.
In Table 3, the interconnections between the EMB and the microcontroller data bus are
presented.
3
1489A–MICRO–11/03
Table 3. Interconnections between the Microcontroller Data Bus and EMB
Data Bus
PC Interfacing
D7
D6
D5
D4
D3/D11
D2/D10
D1/D9
D0/D8
U2 I/O Lines
x
x
x
x
D3
D2
D1
D0
U5 I/O Lines
D3
D2
D1
D0
x
x
x
x
U7 I/O Lines
x
x
x
x
D3
D2
D1
D0
The DAQS is connected to a host PC with a standard parallel interface (i.e.,
unidirectional)(2)(3).
The data is read through the STATE_PORT of the parallel port (4 out of 5 bits). Two
muxes, 74157-type (U6 and U9 in Figure 1), and a NAND gate (U4A in Figure 1) are
used for this purpose.
It should be noted that using the standard parallel port allows for PC interfacing with any
kind of PC, whether old or new.
The main functions of the PC interfacing are as follows:
1. Establishes who has the control over the EMB – the microcontroller or the PC.
2. Controls the data transfer from the EMB to the PC.
Let us shortly describe these features.
1. The input lines of the mux U6 are grouped into two nibbles: the first one (A
inputs) is connected to the DATA_PORT of the parallel port (bits D0...D7) where
the host PC EMB bits are generated as shown in Table 4.
Table 4. Mux U6, A Nibble
Mux U6, A Inputs
4A
3A
2A
1A
DATA_PORT Register Bits
D3
D2
D1
D0
The port B of the mux U6 is connected to the control signals generated by the microcontroller, as shown in Table 5.
The 4B bit of the mux U6 is connected to the system RESET signal, as well as the D7 bit
of the DATA_PORT of the parallel port, allowing restarting the DAQS by the PC without
manual control through “RESET” push-button (see Figure 1).
It is easy to see that, when the system is first started, the microcontroller has the control
over the DAQS, the output of the U6 being its input port B, so that the microcontroller
has the control of the EMB.
When an acquisition cycle is accomplished, the gate U4A generates a signal read by the
PC (i.e., the ERROR bit in the STATE_PORT of the parallel port), the PC program
makes D4 = 0 and the mux U6 output bits are its input port A ones. Because the system
has a common data bus, the I/O lines of the microcontroller must be put in a neutral
state. This can be done by writing a “1” at the port lines.
Table 5. Mux U6, B Nibble
Mux U6, B Inputs
P3 Port Bits
4
4B
3B
2B
1B
x
P3.2
P3.3
P3.4
AT89C2051 DAQS
1489A–MICRO–11/03
AT89C2051 DAQS
When data is read, the host PC commutes the control to the microcontroller.
The output of the mux U6 are given in Table 6.
2. Reading data from the EMB is made up by multiplexing the EMB data nibbles,
because of the standard parallel port used, through its STATE_PORT.
In Table 7, the data bus connections to the mux U9 inputs are given, the mux U9 output
nibble being connected as in Table 8.
Table 6. Mux U6 Outputs
U6 Output
Control Signals
1Y
2Y
3Y
4Y
LSB/MSB
MCS
CLOCK
RESET
Table 7. Mux U6 Inputs
U9 Inputs
4B
3B
2B
1B
4A
3A
2A
1A
Data Bus
D7
D6
D5
D4
D3/D11
D2/D10
D1/D9
D0/D8
Table 8. Mux U6 Outputs
U6 Outputs
Control Signals
1Y
2Y
3Y
4Y
ACK
BUSY
PE
SELECT
The control bits of the mux U9 are connected as follows:
• G is connected at the U4A gate output, meaning that the data is transmitted to the
parallel port only when the DAQS cycle is accomplished.
• A/B is connected to the D5 bit in the DATA_PORT of the parallel port, controlling the
reading process in the PC memory.
PC Program
The PC program has two main features: a data acquisition program and a GUI.
The data acquisition program, written in ANSI C, performs the following functions:
•
Loop test to find out when a data acquisition cycle is accomplished
•
Read the EMB stored samples
•
Address counter reset
•
Address counter incrementing
The GUI is implemented through a LabWindows/CVI™ (National Instruments®) medium.
Samples of different signals are shown in Figures 2 through 5.
The software can be made available on a web site to allow remote control of the DAQS
wherever an Internet connection is available.
In Appendix B, the listing of the entire PC program is given. Because it is well documented, additional comments are unnecessary.
5
1489A–MICRO–11/03
Figure 2. Sine Wave Input Signal Recovered from its Samples
Figure 3. Input Integrated Square Wave Signal Recovered from its Samples
6
AT89C2051 DAQS
1489A–MICRO–11/03
AT89C2051 DAQS
Figure 4. Sample Software Screen
Figure 5. Sample Software Screen
7
1489A–MICRO–11/03
Appendix A:
Microcontroller
Program
PC – Interfaced Data Acquisition System with Atmel AT89C2051 Microcontroller
Design Engineers:
Nicos A. Zdukos, Undergraduate Student
Cristian E. Onete, Associate Professor
Project Manager:
Cristian E. Onete, Associate Professor
“Gh.Asachi” Technical University
Computer Sciences Department
P.O. Box 1355 Iasi 6
Iasi 6600, Romania
e-mail: [email protected]
Tel.: +40-32-213749
; R7,R6 - counters for the number of samples
; R5+R4 - successive approximation register
;
$MOD52
ORG 00H
scriere_DAC MACRO
CPL P3.0
; nWR=0
NOP
CPL P3.0
; nWR=1
ENDM
SJMP start
; Delay Routine
intrz:
MOV R1,#2
; 8us delay
bucla:
DJNZ R1,bucla
RET
;
start: MOV R7,#04H
MOV R6,#0FFH ; 4*255=1020 samples
MOV P3,#11100111B ; initial conditions
ach:
CALL achiz
DJNZ R6,ach
MOV R6,#0FFH
DJNZ R7,ach
MOV R6,#04H ; 4+1020=1024 samples
ach1:
CALL achiz
DJNZ R6,ach1 ; mission accomplished 1024 samples
MOV P1,#0FFH ; D0-D5=1
ORL P3,#10100010B ; D6,D7=1, /MWE=1
SETB P3.3
; MCS=1
; acquisition accomplished PC takes command
gata:
SJMP gata
;
; One sample acquisition and its storage
achiz: MOV A,#0
MOV P1,#03H
ANL P3,#01011111B
; D0-D7=0
scriere_DAC
CPL P3.4
; /LSB/MSB=1
CPL P1.5
; bit 11=1
scriere_DAC
CALL intrz
JB P3.6,etc1
CPL P1.5
; bit 11=0
XRL A,#00001000B
etc1:
XRL A,#00001000B
CPL P1.4
; bit 10=1
8
AT89C2051 DAQS
1489A–MICRO–11/03
AT89C2051 DAQS
scriere_DAC
CALL intrz
JB P3.6,etc2
CPL P1.4
;
XRL A,#00000100B
etc2:
XRL A,#00000100B
CPL P1.3
;
scriere_DAC
CALL intrz
JB P3.6,etc3
CPL P1.3
;
XRL A,#00000010B
etc3:
XRL A,#00000010B
CPL P1.2
;
scriere_DAC
CALL intrz
JB P3.6,etc4
CPL P1.2
;
XRL A,#00000001B
etc4:
XRL A,#00000001B
MOV R5,A
;
scriere_DAC
CPL P3.4
;
MOV A,#0
MOV P1,#03H
ANL P3,#01011111B
CPL P3.5
;
scriere_DAC
CALL intrz
JB P3.6,etc5
CPL P3.5
;
XRL A,#10000000B
etc5:
XRL A,#10000000B
CPL P3.7
;
scriere_DAC
CALL intrz
JB P3.6,etc6
CPL P3.7
;
XRL A,#01000000B
etc6:
XRL A,#01000000B
CPL P1.7
;
scriere_DAC
CALL intrz
JB P3.6,etc7
CPL P1.7
;
XRL A,#00100000B
etc7:
XRL A,#00100000B
CPL P1.6
;
scriere_DAC
CALL intrz
JB P3.6,etc8
CPL P1.6
;
XRL A,#00010000B
etc8:
XRL A,#00010000B
CPL P1.5
;
scriere_DAC
CALL intrz
JB P3.6,etc9
CPL P1.5
;
XRL A,#00001000B
etc9:
XRL A,#00001000B
CPL P1.4
;
bit 10=0
bit 9=1
bit 9=0
bit 8=1
bit 8=0
in R5 there are the first 4 bits of the sample
/LSB/MSB=0
bit 7=1
bit 7=0
bit 6=1
bit 6=0
bit 5=1
bit 5=0
bit 4=1
bit 4=0
bit 3=1
bit 3=0
bit 2=1
9
1489A–MICRO–11/03
scriere_DAC
CALL intrz
JB P3.6,etc10
CPL P1.4
;
XRL A,#00000100B
etc10: XRL A,#00000100B
CPL P1.3
;
scriere_DAC
CALL intrz
JB P3.6,etc11
CPL P1.3
;
XRL A,#00000010B
etc11: XRL A,#00000010B
CPL P1.2
;
scriere_DAC
CALL intrz
JB P3.6,etc12
CPL P1.2
;
XRL A,#00000001B
etc12: XRL A,#00000001B
MOV R4,A
;
; Writing data in the EMB
CLR P3.1
;
NOP
SETB P3.3
;
NOP
XRL P3,#00001010B
CPL P3.4
;
MOV A,R5
RL A
RL A
ANL P1,#00000011B
ORL P1,A
CLR P3.1
;
NOP
SETB P3.3
;
NOP
XRL P3,#00001010B
CPL P3.4
;
CPL P3.2
NOP
CPL P3.2
;
RET
;
END
Notes:
10
bit 2=0
bit 1=1
bit 1=0
bit 0=1
bit 0=0
in R4 there are the last 8 bits of the sample
/MWE=0
MCS=1
; MCS=0,nMWE=1
/LSB/MSB=1
/MWE=0
MCS=1
; MCS=0,nMWE=1
/LSB/MSB=0
address counter incrementing
1. NOP instructions are only for testing purposes being removed from the final version
of the program.
2. The simulated DAQS shows that the acquisition time/sample for a 12 MHz clock frequency is:
243.738 cycles/1024 (i.e., 4201 Hz) in most favorable case
268.314 cycles/1024 (i.e., 3816 Hz) in worst case
when the acquisition cycles are not balanced in microcontroller program. A new
release of our microcontroller program was realized where these times are balanced,
but the price paid for this balancing is speed reduction.
The conversion speed can be increased using higher speed microcontroller (higher
clock frequencies).
AT89C2051 DAQS
1489A–MICRO–11/03
AT89C2051 DAQS
Appendix B: PC
Program Listing
PC – Interfaced Data Acquisition System with Atmel AT89C2051 Microcontroller
Design Engineers:
Nicos A. Zdukos, Undergraduate Student
Cristian E. Onete, Associate Professor
Project Manager:
Cristian E. Onete, Associate Professor
“Gh.Asachi” Technical University
Computer Sciences Department
P.O. Box 1355 Iasi 6
Iasi 6600, Romania
e-mail: [email protected]
Tel.: +40-32-213749
#include <utility.h>
#include <cvirte.h>
#include <userint.h>
#include <formatio.h>
#include "prj.h"
#define NrEsant 1024 // Number of samples
#define RDate 0x378
#define RStare RDate+1
#define RControl RDate+2
#define SADCtrlMask 0x10
#define SADResetMask 0x80
#define ResetMask 0x08
#define ClockMask 0x04
#define McsMask 0x02
static int panelHandle;
static int plotHandle=0;
int SwitchVal=0,Switch_2Val=0;
unsigned char ctrl;
float vsemnal[NrEsant];
float Vref=5.0;
int nr_esant;
int culoare_trasare=VAL_GREEN;
static char proj_dir[MAX_PATHNAME_LEN];
static char file_name[MAX_PATHNAME_LEN];
void TestSADLiber(void);
void ResetSAD(void);
void Achizitie(void);
void ResetNumarator(void);
void IncrNumarator(void);
unsigned int PreluareDate(void);
void Indicatoare(void);
void DezactivareControale(int);
void ActiveazaCursor(void);
void DezactiveazaCursor(void);
int main (int argc, char *argv[])
{
if (InitCVIRTE (0, argv, 0) == 0)
return -1;
if ((panelHandle = LoadPanel (0, "prj.uir", PANEL)) < 0)
return -1;
SuspendTimerCallbacks ();
GetProjectDir (proj_dir);
11
1489A–MICRO–11/03
DisplayPanel (panelHandle);
ctrl=0x14;
outp(RDate,ctrl); // Initial Conditions
SetGraphCursor (panelHandle, PANEL_GRAPH, 1, 0, 0.0);
RunUserInterface ();
return 0;
}
int CVICALLBACK PanelCall (int panel, int event, void *callbackData,
int eventData1, int eventData2)
{
switch (event) {
case EVENT_GOT_FOCUS:
break;
case EVENT_LOST_FOCUS:
break;
case EVENT_CLOSE:
if(!SwitchVal)
QuitUserInterface (0);
// Panel closes only if "Power" button is OFF
break;
}
return 0;
}
// This function is called when the "Power" switch is selected "ON/OFF"
int CVICALLBACK SwitchCall (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event) {
case EVENT_COMMIT:
GetCtrlVal (panelHandle, PANEL_BINARYSWITCH, &SwitchVal);
SetCtrlVal (panelHandle, PANEL_LED, SwitchVal);
if(SwitchVal)
{
DezactivareControale (0);
}
else
{
SuspendTimerCallbacks ();
if(plotHandle > 0)
{
DeleteGraphPlot (panelHandle, PANEL_GRAPH,
plotHandle, VAL_IMMEDIATE_DRAW);
plotHandle=0;
}
DezactivareControale (1);
SetCtrlVal (panelHandle, PANEL_BINARYSWITCH_2, 0);
SetCtrlVal (panelHandle, PANEL_METER, 0.0);
SetCtrlVal (panelHandle, PANEL_METER_2, 0.0);
SetCtrlVal (panelHandle, PANEL_METER_3, 0.0);
nr_esant=0;
SetCtrlVal (panelHandle, PANEL_NUMERIC, 0);
etCtrlVal (panelHandle, PANEL_NUMERIC_2, 0.0);
SetCtrlVal (panelHandle, PANEL_NUMERICSLIDE, 0.8);
SetCtrlAttribute (panelHandle, PANEL_TIMER,
ATTR_INTERVAL, 0.800);
SetGraphCursor (panelHandle,PANEL_GRAPH, 1,0,0.0);
ActiveazaCursor ();
}
break;
}
return 0;
}
12
AT89C2051 DAQS
1489A–MICRO–11/03
AT89C2051 DAQS
// The function is called when the "Acquisition Mode" switch is selected
int CVICALLBACK Switch_2Call (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event) {
case EVENT_COMMIT:
GetCtrlVal (panelHandle, PANEL_BINARYSWITCH_2, &Switch_2Val);
if(Switch_2Val)
{
SetCtrlAttribute (panelHandle, PANEL_COMMANDBUTTON, ATTR_DIMMED, 1);
SetCtrlAttribute (panelHandle, PANEL_COMMANDBUTTON_2, ATTR_DIMMED, 1);
SetCtrlAttribute (panelHandle, PANEL_COMMANDBUTTON_3, ATTR_DIMMED, 1);
SetCtrlAttribute (panelHandle, PANEL_COMMANDBUTTON_4, ATTR_DIMMED, 1);
DezactiveazaCursor ();
ResumeTimerCallbacks ();
}
else
{
SuspendTimerCallbacks ();
SetCtrlAttribute (panelHandle, PANEL_COMMANDBUTTON, ATTR_DIMMED, 0);
SetCtrlAttribute (panelHandle, PANEL_COMMANDBUTTON_2, ATTR_DIMMED, 0);
SetCtrlAttribute (panelHandle, PANEL_COMMANDBUTTON_3, ATTR_DIMMED, 0);
SetCtrlAttribute (panelHandle, PANEL_COMMANDBUTTON_4, ATTR_DIMMED, 0);
ActiveazaCursor ();
SetGraphCursor (panelHandle, PANEL_GRAPH, 1, nr_esant,
vsemnal[nr_esant]);
}
break;
}
return 0;
}
// This function is called when the "Display" button is pressed
int CVICALLBACK ButtonCall (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event) {
case EVENT_COMMIT:
if(plotHandle > 0)
DeleteGraphPlot (panelHandle, PANEL_GRAPH,
plotHandle, VAL_IMMEDIATE_DRAW);
plotHandle = PlotY (panelHandle, PANEL_GRAPH,
vsemnal, 1024, VAL_FLOAT,
VAL_THIN_LINE, VAL_EMPTY_SQUARE, VAL_SOLID, 1, culoare_trasare);
SetGraphCursor (panelHandle, PANEL_GRAPH,
1, nr_esant, vsemnal[nr_esant]);
Indicatoare ();
SetCtrlVal (panelHandle, PANEL_NUMERIC_2,
vsemnal[nr_esant]);
break;
}
return 0;
}
// This function is called when the "Acquisition Time (s)" button is pressed
// This is the time interval in between two successive automatic acquisitions
(PC control mode)
int CVICALLBACK Button_2Call (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event) {
case EVENT_COMMIT:
SetWaitCursor (1);
ResetSAD ();
13
1489A–MICRO–11/03
TestSADLiber ();
Achizitie ();
SetWaitCursor (0);
break;
}
return 0;
}
// This function is calld on timer's pulse (i.e. each time interval)
int CVICALLBACK TimerCall (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event) {
case EVENT_TIMER_TICK:
SetWaitCursor (1);
ResetSAD ();
TestSADLiber ();
Achizitie ();
SetWaitCursor (0);
if(plotHandle > 0)
DeleteGraphPlot (panelHandle, PANEL_GRAPH, plotHandle,
VAL_IMMEDIATE_DRAW);
plotHandle = PlotY (panelHandle, PANEL_GRAPH, vsemnal,
1024, VAL_FLOAT, VAL_THIN_LINE,
VAL_EMPTY_SQUARE, VAL_SOLID, 1, culoare_trasare);
Indicatoare ();
SetCtrlVal (panelHandle, PANEL_NUMERIC_2,
vsemnal[nr_esant]);
break;
}
return 0;
}
// This function is called when "Sample Index" is selected
// A number in between 0 and 1023
int CVICALLBACK NumCall (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event) {
case EVENT_COMMIT:
GetCtrlVal (panelHandle, PANEL_NUMERIC, &nr_esant);
SetCtrlVal (panelHandle, PANEL_NUMERIC_2,
vsemnal[nr_esant]);
SetGraphCursor (panelHandle, PANEL_GRAPH, 1, nr_esant,
vsemnal[nr_esant]);
break;
}
return 0;
}
// This function is called on "Cursor color" selection
int CVICALLBACK CursorColorCall (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
int culoare_cursor;
switch (event) {
case EVENT_COMMIT:
GetCtrlVal (panelHandle, PANEL_COLORNUM, & culoare_cursor);
SetCursorAttribute (panelHandle, PANEL_GRAPH, 1,
ATTR_CURSOR_COLOR, culoare_cursor);
break;
}
return 0;
}
14
AT89C2051 DAQS
1489A–MICRO–11/03
AT89C2051 DAQS
// This function is called on "Trace color" selection
int CVICALLBACK TrasareColorCall (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event) {
case EVENT_COMMIT:
GetCtrlVal (panelHandle, PANEL_COLORNUM_2, &
culoare_trasare);
if(Switch_2Val==0 && plotHandle > 0)
{
DeleteGraphPlot (panelHandle, PANEL_GRAPH, plotHandle,
VAL_IMMEDIATE_DRAW);
plotHandle = PlotY (panelHandle, PANEL_GRAPH, vsemnal,
1024, VAL_FLOAT, VAL_THIN_LINE,
VAL_EMPTY_SQUARE, VAL_SOLID, 1, culoare_trasare);
}
break;
}
return 0;
}
// This function is called on "Time Interval" selection
int CVICALLBACK TCall (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
float timp;
switch (event) {
case EVENT_COMMIT:
GetCtrlVal (panelHandle, PANEL_NUMERICSLIDE, & timp);
SetCtrlAttribute (panelHandle, PANEL_TIMER, ATTR_INTERVAL, timp);
break;
}
return 0;
}
// This function is called when the "Save" button is pressed
int CVICALLBACK SaveCall (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event) {
case EVENT_COMMIT:
if (FileSelectPopup (proj_dir, "*.sad", "*.sad", "Save
File", VAL_OK_BUTTON, 0, 1, 0, 1,
file_name) > 0);
{
ArrayToFile (file_name, vsemnal, VAL_FLOAT, 1024, 1,
VAL_GROUPS_TOGETHER,
VAL_GROUPS_AS_COLUMNS, VAL_CONST_WIDTH, 8, VAL_BINARY, VAL_TRUNCATE);
}
break;
}
return 0;
}
// This function is called when the "Load" button is pressed
int CVICALLBACK LoadCall (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event) {
case EVENT_COMMIT:
if (FileSelectPopup (proj_dir, "*.sad", "*.sad", "Load
File", VAL_OK_BUTTON, 0, 1, 0, 1,
file_name) == 1)
{
15
1489A–MICRO–11/03
FileToArray (file_name, vsemnal, VAL_FLOAT, 1024, 1,
VAL_GROUPS_TOGETHER,
VAL_GROUPS_AS_COLUMNS, VAL_BINARY);
if(plotHandle > 0)
DeleteGraphPlot (panelHandle, PANEL_GRAPH, plotHandle,
VAL_IMMEDIATE_DRAW);
plotHandle = PlotY (panelHandle, PANEL_GRAPH, vsemnal,
1024, VAL_FLOAT, VAL_THIN_LINE,
VAL_EMPTY_SQUARE, VAL_SOLID, 1, culoare_trasare);
SetGraphCursor (panelHandle, PANEL_GRAPH, 1, nr_esant,
vsemnal[nr_esant]);
Indicatoare ();
SetCtrlVal (panelHandle, PANEL_NUMERIC_2,
vsemnal[nr_esant]);
}
break;
}
return 0;
}
// Testing if DAQS has finished data acquisition (1024 samples)
void TestSADLiber(void)
{
while((inp(RStare)&0x08)!=0)
{
SyncWait (Timer(),0.3);
}
}
// Rests DAQS
void ResetSAD(void)
{
ctrl=ctrl ^ SADResetMask;
outp(RDate,ctrl);
SyncWait (Timer(),0.05);
ctrl=ctrl ^ SADResetMask;
outp(RDate,ctrl);
SyncWait (Timer(),0.4); // Wait for DAQS to acquire data
}
// Controls EMB reading by the host
void Achizitie(void){
int index;
ctrl=ctrl ^ SADCtrlMask;
outp(RDate,ctrl); // DAQS Gain Control
SyncWait (Timer(),0.001);
ResetNumarator(); // Reset the address counter
for(index=0; index < NrEsant; index++)
{
ctrl=ctrl ^ McsMask;
outp(RDate,ctrl); // MCS=1
vsemnal[index]=(PreluareDate()/4095.0)*Vref;
ctrl=ctrl ^ McsMask;
outp(RDate,ctrl); // MCS=0
IncrNumarator();
}
ResetNumarator();
ctrl=ctrl ^ SADCtrlMask;
outp(RDate,ctrl); // Give back control to system
}
// Reset address counter
void ResetNumarator(void)
{
ctrl=ctrl ^ ResetMask; // RESET=1
outp(RDate,ctrl);
16
AT89C2051 DAQS
1489A–MICRO–11/03
AT89C2051 DAQS
SyncWait (Timer(),0.001);
ctrl=ctrl ^ ResetMask; // RESET=0
outp(RDate,ctrl);
SyncWait (Timer(),0.001);
}
// Current address EMB reading
unsigned int PreluareDate(void)
{
unsigned char temp,lsb,lsbl,lsbh,msb;
unsigned int data;
temp=(inp(RStare) ^ 0x80); // BUSY bit is hardware inverted
lsbl=((temp & 0xc0)>>6) | ((temp & 0x10)>>1) | ((temp & 0x20)>>3);
// lsbl contains the bits: 0 0 0 0 D3 D2 D1 D0
ctrl=ctrl ^ 0x20;
outp(RDate,ctrl);
temp=(inp(RStare) ^ 0x80);
lsbh=((temp & 0xc0)>>2) | ((temp & 0x10)<<3) | ((temp & 0x20)<<1);
// lsbh contains the bits: D7 D6 D5 D4 0 0 0 0
ctrl=ctrl ^ 0x21;
outp(RDate,ctrl);
temp=(inp(RStare) ^ 0x80);
msb=((temp & 0xc0)>>6) | ((temp & 0x10)>>1) | ((temp & 0x20)>>3);
// msb contains the bits: 0 0 0 0 D11 D10 D9 D8
ctrl=ctrl ^ 0x01;
outp(RDate,ctrl);
lsb=lsbl | lsbh;
data=msb*256+lsb;
return (data);
}
// Address counter incrementing
void IncrNumarator(void)
{
ctrl=ctrl ^ ClockMask; // CLOCK=1-->0
outp(RDate,ctrl);
ctrl=ctrl ^ ClockMask; // CLOCK=0-->1
outp(RDate,ctrl);
}
// Data samples statistics of the whole EMB content (1024 samples):
//
minimum ("Min."), average ("Avg."), maximum ("Max.")
void Indicatoare(void)
{
int index;
float suma=0.0,minim=5.0,maxim=0.0;
for(index=0; index < NrEsant; index++)
{
suma+=vsemnal[index];
if (vsemnal[index] < minim)
minim=vsemnal[index];
if (vsemnal[index] > maxim)
maxim=vsemnal[index];
}
SetCtrlVal (panelHandle, PANEL_METER_2, minim);
SetCtrlVal (panelHandle, PANEL_METER, suma/1024.0);
SetCtrlVal (panelHandle, PANEL_METER_3, maxim);
}
// Activate/deactivate panel controls (buttons, switches, graph)
void DezactivareControale(int dimm)
{
SetCtrlAttribute (panelHandle, PANEL_GRAPH, ATTR_DIMMED, dimm);
SetCtrlAttribute (panelHandle, PANEL_COMMANDBUTTON, ATTR_DIMMED, dimm);
SetCtrlAttribute (panelHandle, PANEL_COMMANDBUTTON_2,
ATTR_DIMMED, dimm);
17
1489A–MICRO–11/03
SetCtrlAttribute (panelHandle,
ATTR_DIMMED, dimm);
SetCtrlAttribute (panelHandle,
SetCtrlAttribute (panelHandle,
SetCtrlAttribute (panelHandle,
SetCtrlAttribute (panelHandle,
SetCtrlAttribute (panelHandle,
SetCtrlAttribute (panelHandle,
SetCtrlAttribute (panelHandle,
SetCtrlAttribute (panelHandle,
SetCtrlAttribute (panelHandle,
SetCtrlAttribute (panelHandle,
ATTR_DIMMED, dimm);
SetCtrlAttribute (panelHandle,
ATTR_DIMMED, dimm);
PANEL_BINARYSWITCH_2,
PANEL_METER, ATTR_DIMMED, dimm);
PANEL_METER_2, ATTR_DIMMED, dimm);
PANEL_METER_3, ATTR_DIMMED, dimm);
PANEL_NUMERIC, ATTR_DIMMED, dimm);
PANEL_NUMERIC_2, ATTR_DIMMED, dimm);
PANEL_TEXTMSG, ATTR_DIMMED, dimm);
PANEL_COLORNUM, ATTR_DIMMED, dimm);
PANEL_COLORNUM_2, ATTR_DIMMED, dimm);
PANEL_NUMERICSLIDE, ATTR_DIMMED, dimm);
PANEL_COMMANDBUTTON_3,
PANEL_COMMANDBUTTON_4,
}
// Graph cursor activating
void ActiveazaCursor(void)
{
SetCursorAttribute (panelHandle, PANEL_GRAPH, 1, ATTR_CROSS_HAIR_STYLE,
VAL_LONG_CROSS);
SetCursorAttribute (panelHandle, PANEL_GRAPH, 1,
ATTR_CURSOR_POINT_STYLE, VAL_EMPTY_CIRCLE);
}
// Graph cursor deactivating
void DezactiveazaCursor(void)
{
SetCursorAttribute (panelHandle, PANEL_GRAPH, 1, ATTR_CROSS_HAIR_STYLE,
VAL_NO_CROSS);
SetCursorAttribute (panelHandle, PANEL_GRAPH, 1,
ATTR_CURSOR_POINT_STYLE, VAL_NO_POINT);
}
Program Code
Authorship
Design Engineers:
Nicos A. Zdukos, Undergraduate Student
Cristian E. Onete, Associate Professor
“Gh.Asachi” Technical University
Project Manager:
Cristian E. Onete, Associate Professor
“Gh.Asachi” Technical University
Computer Sciences Department
P.O. Box 1355 Iasi 6
Iasi 6600, Romania
e-mail: [email protected]
Tel.: +40-32-213749
18
AT89C2051 DAQS
1489A–MICRO–11/03
Atmel Corporation
2325 Orchard Parkway
San Jose, CA 95131, USA
Tel: 1(408) 441-0311
Fax: 1(408) 487-2600
Regional Headquarters
Europe
Atmel Sarl
Route des Arsenaux 41
Case Postale 80
CH-1705 Fribourg
Switzerland
Tel: (41) 26-426-5555
Fax: (41) 26-426-5500
Asia
Room 1219
Chinachem Golden Plaza
77 Mody Road Tsimshatsui
East Kowloon
Hong Kong
Tel: (852) 2721-9778
Fax: (852) 2722-1369
Japan
9F, Tonetsu Shinkawa Bldg.
1-24-8 Shinkawa
Chuo-ku, Tokyo 104-0033
Japan
Tel: (81) 3-3523-3551
Fax: (81) 3-3523-7581
Atmel Operations
Memory
2325 Orchard Parkway
San Jose, CA 95131, USA
Tel: 1(408) 441-0311
Fax: 1(408) 436-4314
RF/Automotive
Theresienstrasse 2
Postfach 3535
74025 Heilbronn, Germany
Tel: (49) 71-31-67-0
Fax: (49) 71-31-67-2340
Microcontrollers
2325 Orchard Parkway
San Jose, CA 95131, USA
Tel: 1(408) 441-0311
Fax: 1(408) 436-4314
La Chantrerie
BP 70602
44306 Nantes Cedex 3, France
Tel: (33) 2-40-18-18-18
Fax: (33) 2-40-18-19-60
ASIC/ASSP/Smart Cards
1150 East Cheyenne Mtn. Blvd.
Colorado Springs, CO 80906, USA
Tel: 1(719) 576-3300
Fax: 1(719) 540-1759
Biometrics/Imaging/Hi-Rel MPU/
High Speed Converters/RF Datacom
Avenue de Rochepleine
BP 123
38521 Saint-Egreve Cedex, France
Tel: (33) 4-76-58-30-00
Fax: (33) 4-76-58-34-80
Zone Industrielle
13106 Rousset Cedex, France
Tel: (33) 4-42-53-60-00
Fax: (33) 4-42-53-60-01
1150 East Cheyenne Mtn. Blvd.
Colorado Springs, CO 80906, USA
Tel: 1(719) 576-3300
Fax: 1(719) 540-1759
Scottish Enterprise Technology Park
Maxwell Building
East Kilbride G75 0QR, Scotland
Tel: (44) 1355-803-000
Fax: (44) 1355-242-743
Literature Requests
www.atmel.com/literature
Disclaimer: Atmel Corporation makes no warranty for the use of its products, other than those expressly contained in the Company’s standard
warranty which is detailed in Atmel’s Terms and Conditions located on the Company’s web site. The Company assumes no responsibility for any
errors which may appear in this document, reserves the right to change devices or specifications detailed herein at any time without notice, and
does not make any commitment to update the information contained herein. No licenses to patents or other intellectual property of Atmel are
granted by the Company in connection with the sale of Atmel products, expressly or by implication. Atmel’s products are not authorized for use
as critical components in life support devices or systems.
© Atmel Corporation 2003. All rights reserved. Atmel ® and combinations thereof are the registered trademarks of Atmel Corporation or its
subsidiaries. National Instruments ® is a registered trademark, and LabWindows/CVI™ is a trademark of National Instruments. Other terms and
product names may be the trademarks of others
Printed on recycled paper.
1489A–MICRO–11/03
xM