Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Microcontroller based applied digital control (D. Ibrahim, 2006)

.pdf
Скачиваний:
1655
Добавлен:
12.08.2013
Размер:
5.68 Mб
Скачать

258 CONTROLLER REALIZATION

/********************************************************************

DIGITAL CONTROLLER

==================

This program implements a second-order digital controller module on a PIC16F877 (or equivalent) microcontroller. The microcontroller operates with a 4MHz crystal. The analog input AN0 of the microcontroller is connected to the output sensor of the plant (y). The PORT B output of the microcontroller is connected to a AD7302 type D/A converter. The WR input of the controller is controlled from port pin RC0 of the microcontroller. The sampling interval is 0.01s (10ms) and the timer interrupt service routine is used to obtain the required sampling interval.

Program : Second Order Module.C

Date : July 2005

********************************************************************/

#include <pic.h> #define DA Write RC0

float DA LSB,AD LSB,a0,a1,a2, b1,b2,M1,M2,rk,rk 1,rk 2,ek,sk,yk,uk;

/* This function initializes the A/D converter so that analog data can be received from channel AN0 of the microcontroller */

void Initialize AD(void)

{

}

/* This function initilizes the timer TMR0 so that interrupts can be generated at 10ms intervals */

void Initialize Timer(void)

{

}

/* This function reads data from the A/D converter and stores in variable yk */

void Read AD Input(void)

{

}

/* Interrupt Service Routine. The program jumps here every 10 ms */

void interrupt ISR(void)

 

{

 

Read AD Input();

/* Read A/D input */

ek = sk - yk;

/* Calculate error term */

rk = ek + M1;

 

yk = a0*rk + M2;

/* Calculate output */

uk = yk*DA LSB;

 

PORTB = uk;

/* Send to PORT B */

DA Write = 0;

/* Write to D/A converter */

DA Write = 1;

 

Figure 10.19 First program attempt (Continued )

 

 

 

MICROCONTROLLER IMPLEMENTATIONS

259

rk 2

= rk 1;

/* Update variables */

 

rk 1

= rk;

 

 

M1

= -b1*rk 1 - b2*rk 2;

 

 

M2

= a1*rk 1 + a2*rk 2;

 

 

T0IF = 0;

/* Re-enable timer interrupts */

 

}

/* Main Program. The main program initializes the variables, A/D converter, D/A converter etc. and then waits in an endless loop for timer interrupts to Occur every 10 ms */

main(void)

{

a0

= 1; a1 = 0.8;

a2 = 1.2;

 

b1

= 1.85;

 

b2 = 0.92;

 

M1

= 0;

M2 = 0;

rk = 0;

rk 1 = 0; rk 2 = 0;

sk = 1.0;

 

 

 

DA LSB = 5000.0/1024.0;

 

 

TRISA = 1;

 

/* RA0 (AN0) is input */

TRISB = 0;

 

/* PORT B is output */

TRISC = 0;

 

/* RC0 is output */

DA Write = 1;

 

/* Disable D/A converter */

Initialize AD();

/* Initialize A/D converter */

Initialize Timer();

/* Initialize timer interrupts */

ei();

 

/* Enable interrupts */

for(;;);

 

/* Wait for an interrupt */

}

Figure 10.19 (Continued )

Initialize AD. This function initializes the A/D converter so that analog data can be received from channel AN0 of the microcontroller. As described in Chapter 3, the A/D converter is initialized by first selecting the reference voltage and the output data format using the ADCON1 register, and then selecting the A/D converter clock using the ADCON0 register. Thus, channel AN0 is configured by loading 0x8E into the ADCON1 register, and 0x41 into the ADCON0 register. Thus, the Initialize AD function is programmed as follows:

/* This function initializes the A/D converter so that analog data can be received from channel AN0 of the microcontroller */

void Initialize AD(void)

{

ADCON1

=

0

×

8E;

/* Configure

AN0 for +5V reference */

ADCON0

=

0

×

41;

/* Select A/D

converter clock */

}

Read AD Input. This function starts the A/D converter and reads a sample at the end of the conversion. The conversion is started by setting the GO/DONE bit of ADCON0. The program

260 CONTROLLER REALIZATION

should then wait until the conversion is complete, which is indicated by the GO/DONE bit becoming zero. The high 2 bits of the converted data are in ADRESH, and the low 8 bits are in register ADRESL. The 10-bit converted data is extracted and stored in variable yk .

The Read AD Input function is programmed as follows:

/* This function reads data from the A/D converter and stores in variable yk */

void Read AD Input(void)

{

ADCON0 = 0 × 45; while(ADCON0 & 4) != 0); y high = ADRESH;

y low = ADRESL;

yk = 256.0*y high + y low; yk = yk*AD LSB;

}

/* Start A/D conversion */

/* Wait until conversion completes */ /* High 2 bytes of converted data */ /* Low byte of converted data */

/* Converted data in yk */ /* Sensor output in mV */

AD LSB converts the A/D value to into millivolts.

The complete program is shown in Figure 10.20.

10.5.2 Implementing First-Order Modules

In Section 10.2 we saw how a first-order module can be realized using adders, multipliers and delay elements. The first-order module is shown in Figure 10.21. The difference equations describing a first-order module were found to be

rk = ek b1rk1

and

uk = a0rk + a1rk1.

If we let

M1 = −b1rk1

and

M2 = a1rk1,

then the difference equations for the first-order module becomes

rk = ek + M1

uk = a0rk + M2

The implementation of the first-order module is similar to the second-order module and an example is given below.

MICROCONTROLLER IMPLEMENTATIONS

261

/****************************************************************************

DIGITAL CONTROLLER

==================

This program implements a second-order digital controller module on a PIC16F877 (or equivalent) microcontroller. The microcontroller operates with a 4MHz crystal. The analog input AN0 of the microcontroller is connected to the output sensor of the plant (y). The PORT B output of the microcontroller is connected to an AD7302 type D/A converter. The WR input of the controller is controlled from port pin RC0 of the microcontroller. The sampling interval is 0.01s (10ms) and the timer interrupt service routine is used to obtain the required sampling interval.

Program : Second Order Module.C

Date : July 2005

*****************************************************************************/

#include <pic.h> #define DA Write RC0

float DA LSB,AD LSB,a0,a1,a2, b1,b2,M1,M2,rk,rk 1,rk 2,ek,sk,yk,uk; float y high,y low;

/* This function initializes the A/D converter so that analog data can be received from channel AN0 of the microcontroller */

void Initialize AD(void)

{

ADCON1

=

0x8E;

/*

Configure AN0 for +5V reference

*/

ADCON0

=

0x41;

/*

Select A/D clock and channel */

 

}

/* This function initilizes the timer TMR0 so that interrupts can be generated at 10ms intervals */

void Initialize Timer(void)

{

T0CS = 0;

/* Select f/4 clock for

TMR0 */

PSA = 0;

/* Select pre-scaler */

 

PS0 = 1;

/* Set pre-scaler to 64

*/

PS1 = 0;

/* PS2,PS1,PS0 = 101 */

 

PS2 = 1;

 

 

TMR0 = 100;

/* Load TMR0=100 */

 

T0IE = 1;

/* Enable TMR0 interrupts */

T0IF = 0;

/* Clear TMR0 interrupt flag */

*/

}

/* This function reads data from the A/D converter and stores in variable yk */

void Read AD Input(void)

{

ADCON0 = 0x45;

/*

Start A/D conversion */

While((ADCON0 & 4) != 0);

/*

Wait until conversion completes */

Figure 10.20 Complete program of the second-order controller (Continued )

262

CONTROLLER REALIZATION

 

 

y high = ADRESH;

/* High 2 bits of converted data */

 

y low = ADRESL;

/* Low byte of converted data */

 

yk = 256.0*y high + y low;

/* Converted data in yk */

 

yk = yk*AD LSB;

/* Sensor output in mV */

}

 

 

/* Interrupt Service Routine. The program jumps here every 10 ms */

void interrupt ISR(void)

 

{

 

 

 

TMR0 = 100;

/* Reload TMR0 */

 

Read AD Input();

/* Read A/D input */

 

ek = sk - yk;

/* Calculate error term */

 

rk = ek + M1;

 

 

yk = a0*rk + M2;

/* Calculate output */

 

uk = yk*DA LSB;

 

 

PORTB = uk;

/* Send to PORT B */

 

DA Write = 0;

/* Write to D/A converter */

 

DA Write = 1;

 

 

rk 2 = rk 1;

/* Update variables */

 

rk 1 = rk;

 

 

M1 = -b1*rk 1 - b2*rk 2;

 

 

M2 = a1*rk 1 + a2*rk 2;

 

 

T0IF = 0;

/* Re-enable timer interrupts */

}

 

 

/* Main Program. The main program initializes the variables, A/D converter, D/A converter etc. and then waits in an endless loop for timer interrupts to Occur every 10 ms */

main(void)

{

a0

= 1;

a1 = 0.8;

a2 = 1.2;

 

b1

= 1.85;

b2 = 0.92;

 

 

M1

= 0;

M2 = 0;

rk = 0;

rk 1 = 0; rk 2 = 0;

sk = 1.0;

 

 

 

AD LSB = 5000.0/1024.0;

 

 

DA LSB = 256.0/5000.0;

 

 

TRISA = 1;

 

/* RA0 (AN0) is input */

TRISB = 0;

 

/* PORT B is output */

TRISC = 0;

 

/* RC0 is output */

DA Write = 1;

 

/* Disable D/A converter */

Initialize AD();

/* Initialize A/D converter */

Initialize Timer();

/* Initialize timer interrupts */

ei();

 

/* Enable interrupts */

for(;;);

 

/* Wait for an interrupt */

}

Figure 10.20 (Continued )

 

 

CHOICE OF SAMPLING INTERVAL

263

ek

+

rk

+

uk

 

 

a0

 

 

 

z1

 

 

 

 

 

b1

 

a1

 

 

 

 

 

 

 

 

 

 

rk1

 

 

 

Figure 10.21 First-order module

Example 10.7

The circuit diagram of a digital control system is shown in Figure 10.18. A PIC16F877 microcontroller is to be used as the digital controller in this system. Assume that the set-point input s is to be hard-coded to the program, and the output y is analog and connected to A/D channel AN0 (bit 0 of port A) of the microcontroller. The microcontroller is assumed to operate with a crystal frequency of 4 MHz as shown in the figure. The output (port B) of the microcontroller is interfaced to a D/A converter which acts as a zero-order-hold and generates an analog output to drive the plant.

Assume that the digital controller to be implemented is in the form of a first-order module, and write a program in C to implement this controller. The controller parameters are assumed to be:

a0 = 1, a1 = 0.8, b1 = 1.85,

i.e. the required controller transfer function is

1 + 0.8z1 D(z) = 1 + 1.85z1 .

Also assume that the required sampling interval is T = 0.01 s.

Solution

The implementation of a first-order module is very similar to a second-order module. The program to implement a first-order controller is shown in Figure 10.22. The operation of the program is very similar to the second-order program and is not described here.

10.5.3 Implementing Higher-Order Modules

Higher-order controllers can be implemented by cascading first-order and second-order modules. For example, a fourth-order controller can be implemented by cascading two second-order modules, as shown in Figure 10.23.

10.6 CHOICE OF SAMPLING INTERVAL

Whenever a digital control system is designed, a suitable sampling interval must be chosen. Choosing a large sampling time has destabilizing effects on the system. In addition, information loss occurs when large sampling times are selected. Also, the errors that occur when a continuous system is discretized increase as the sampling interval increases.

264 CONTROLLER REALIZATION

/****************************************************************************

DIGITAL CONTROLLER

==================

This program implements a first-order digital controller module on a PIC16F877 (or equivalent) microcontroller. The microcontroller operates with a 4MHz crystal. The analog input AN0 of the microcontroller is connected to the output sensor of the plant (y). The PORT B output of the microcontroller is connected to an AD7302 type D/A converter. The WR input of the controller is controlled from port pin RC0 of the microcontroller. The sampling interval is 0.01s (10ms) and the timer interrupt service routine is used to obtain the required sampling interval.

Program : First Order Module.C

Date : July 2005

*****************************************************************************/

#include <pic.h> #define DA Write RC0

float DA LSB,AD LSB,a0,a1,b1,M1,M2,rk,rk 1,rk 2,ek,sk,yk,uk; float y high,y low;

/* This function initializes the A/D converter so that analog data can be received from channel AN0 of the microcontroller */

void Initialize AD(void)

{

ADCON1

=

0x8E;

/*

Configure AN0 */

ADCON0

=

0x41;

/*

Select A/D clock and channel */

}

/* This function initilizes the timer TMR0 so that interrupts can be generated at 10ms intervals */

void Initialize Timer(void)

{

T0CS = 0;

/* Select f/4 clock for TMR0 */

PSA = 0;

/* Select pre-scaler */

PS0 = 1;

/* Set pre-scaler to 64 */

PS1 = 0;

 

PS2 = 1;

 

TMR0 = 100;

/* Load TMR0=100 */

T0IE = 1;

/* Enable TMR0 interrupts */

T0IF = 0;

/* Clear TMR0 interrupt flag */

}

 

/* This function reads data from the A/D converter and stores in variable yk */

void Read AD Input(void)

{

ADCON0 = 0x45; While((ADCON0 & 4) != 0); y high = ADRESH;

y low = ADRESL;

/* Start A/D conversion */

/* Wait for conversion to complete */ /* High 2 bits of converted data */ /* Low byte of converted data */

Figure 10.22 Complete program of the first-order controller (Continued )

CHOICE OF SAMPLING INTERVAL

265

yk = 256.0*y high + y low; yk = yk*AD LSB;

}

/* Converted data in yk */ /* Sensor output in mV */

/* Interrupt Service Routine. The program jumps here every 10 ms. */

void interrupt ISR(void)

 

{

 

TMR0 = 100;

/* Reload TMR0 */

Read AD Input();

/* Read A/D input */

ek = sk - yk;

/* Calculate error term */

rk = ek + M1;

 

yk = a0*rk + M2;

/* Calculate output */

uk = yk*DA LSB;

 

PORTB = uk;

/* Send to PORT B */

DA Write = 0;

/* Write to D/A converter */

DA Write = 1;

 

rk 1 = rk;

/* Update variables */

M1 = -b1*rk 1;

 

M2 = a1*rk 1;

 

T0IF = 0;

/* Re-enable timer interrupts */

}

 

/* Main Program. The main program initializes the variables, A/D converter, D/A converter etc. and then waits in an endless loop for timer interrupts to Occur every 10 ms */

main(void)

{

a0

= 1;

a1 = 0.8;

b1 = 1.85;

 

M1

= 0;

M2 = 0;

rk = 0;

rk 1 = 0;

sk = 1.0;

 

 

 

AD LSB = 5000.0/1024.0;

 

 

DA LSB = 256.0/5000.0;

 

 

TRISA = 1;

 

/* RA0 (AN0) is input */

TRISB = 0;

 

/* PORT B is output */

TRISC = 0;

 

/* RC0 is output */

DA Write = 1;

 

/* Disable D/A converter */

Initialize AD();

/* Initialize A/D converter */

Initialize Timer();

/* Initialize timer interrupts */

ei();

 

/* Enable interrupts */

for(;;);

 

/* Wait for an interrupt */

}

Figure 10.22 (Continued)

266 CONTROLLER REALIZATION

ek

+

a0

+

 

 

z1

 

 

b1

a1

 

 

 

z1

 

 

b2

a2

 

+

a3

+

uk

 

z1

 

 

b3

a4

 

 

 

z1

 

 

b4

a5

 

 

Figure 10.23 Implementing a fourth-order module

It may be thought that decreasing the sampling interval towards zero will make a discrete system converge towards an equivalent continuous system. However, in practice this is not the case since as the sampling interval is reduced, the change between the successive data values becomes less than the resolution of the system, leading to loss of information. In general, if a shorter sampling interval is to be used then the word length of the system should be increased so that the difference between adjacent samples can be resolved.

It has been found from practical applications in the process industry that a sampling interval of 1 s is generally short enough for most applications such as pressure control, temperature control and flow control. Systems with fast responses such as electromechanical systems (e.g. motors) require much shorter sampling intervals, usually of the order of milliseconds.

Various empirical rules have been suggested by many researchers for the selection of the sampling interval. These rules are based on practical experience and simulation results. Among them are the following

If the plant has the dominant time constant Tp , then the sampling interval T for the closedloop system should be selected such that T < Tp /10.

Assuming that the process has a Ziegler–Nichols open-loop model

es T1

G(s) = , 1 + s T2

then the sampling interval should be selected such that T < T1/4.

D(z) =
D(z) =

EXERCISES 267

If the closed-loop system is required to have a settling time Tss or a natural frequency of ωn then choose the sampling interval T such that T < Tss /10 and ωs > 10ωn , where ωs is the sampling frequency, i.e. ωs = 2π/ T .

10.7 EXERCISES

1.The transfer function of a digital controller is given by

1+ 2z1 + 3z2

D(z) = 1 + 4z1 + 5z2 .

Draw the block diagram of the direct canonical realization of this controller. 2. Repeat Exercise 1 for a direct noncanocical controller realization.

3. Compare the realizations obtained in Exercises 1 and 2. 4. The transfer function of a digital controller is found to be

1 + 2z1 + 5z2 D(z) = 1 + 3z1 + 7z2 .

Draw the block diagram of the direct noncanonical realization of this controller. 5. The transfer function of a digital controller is given by

2(z + 2)(z + 3)

.

z2 + 0.4z + 0.03

Use two first-order cascaded transfer functions to implement this controller. 6. The transfer function of a digital controller is given by

(1 + 0.2z1)(1 + 2z1 + 4z2) (1 + 0.3z1)(1 + 0.2z1 + 0.4z2) .

Use a first-order and a second-order cascaded transfer function to implement this controller. 7. The transfer function of a digital controller is given by

D(z) = (1 + 2z1)(1 + 3z1) . (1 + z1)(1 + 5z1)

Realize this transfer function using first-order parallel transfer functions.

8.Draw the block diagram of the PID implementation using a parallel realization.

9.Draw the block diagram of the PID implementation using a direct canonical realization.

10.Describe how a given realization can be implemented on a microcontroller.

11.Draw a flow diagram to show how the PID algorithm can be implemented on a microcontroller. Write a program in C to implement this algorithm on a PIC microcontroller.