Vous êtes sur la page 1sur 11

PIC (Programmable Interface Controllers) microcontrollers are a family of

specialized microcontroller chips produced by Microchip Technology. They are electronic


circuits that can be programmed to be timers or to control a production line and many other
functions in embedded systems in motor vehicles, robots, office machines, medical devices,
mobile radios, vending machines, home appliances.

PIC18F8722 microcontroller was chosen for this project because it includes a 10-Bit analog to
digital converter with up to 13 analog channels and an enhanced addressable USART module
which supports RS-485 and RS-232 communication.

Special Microcontroller Features:


• C Compiler Optimized Architecture
• 100,000 Erase/Write Cycle Enhanced Flash
Program Memory Typical
• 1,000,000 Erase/Write Cycle Data EEPROM
Memory Typical
• Flash/Data EEPROM Retention: 100 Years Typical
• Single-Supply 5V In-Circuit Serial Programming™
(ICSP™) via Two Pins
• In-Circuit Debug (ICD) via Two Pins
• Wide Operating Voltage Range: 2.0V to 5.5V
The application was developed in C language using the mikroC Compiler provided by
Mikroelektronica. The initial tests were made on a BigPIC5 development board. The final
application was tested using an acquisition system based on PIC18F8722 microcontroller which
includes eight signal-conditioning blocks for 8 analogical channels (4-20mA).

In order to understand how PIC18F8722 works a lot of test program were developed on BigPIC5
development board.

1. The I/O ports of the microcontroller

PIC18F8722 has up to nine ports available. Some pins of the I/O ports are multiplexed with
an alternate function from the peripheral features on the device. In general, when a peripheral is
enabled, that pin may not be used as a general purpose I/O pin. Each port has three registers for
its operation. These registers are:
• TRIS register (Data Direction register)
• Port register - to read the levels on I/O pins
• LAT register to read-modify-write operations on pins.
A simple example: how to use PORTC as digital output and toggle the state of its pins at
every second:

TRISC = 0; // set direction to be output 0=output; 1=input


do {
PORTC = 0x00; // set PORTC pins to 0
delay_ms(1000); // 1 second delay
PORTC = 0xFF; // set PORTC pins to 1
Delay_ms(1000); // 1 second delay
} while(1); // Endless loop

The first example shows how we can use the PORTx register to change the status of the PORTC
pins. The next example shows that we can also use LATx register to change the status of the
output pins: pin0 (output) on PORT C changes his status according to the status of the pin0
(input) on PORTB.

unsigned char status_portB,status_portC ;


TRISC = 0; // set direction to be output
TRISB = 1; // set direction to be output

do {
status_portB=PORTB;// read portB status
status_portB&=0x01;//we are interested only in pin0 so we mask the other bits(logic AND)
if(status_portB) status_portC=0x01; // pin0 on port C will be ON
else status_portC=0x00; // pin0 on port C will be OFF
LATC|= status_portC;//we only change the status on pin0 the other ones remain unchanged
(logic OR)

} while(1); // Endless loop

2. How to connect other peripheral device on PIC18F8722 I/O ports


BigPIC5 development board offers the possibility to connect on its ports a standard
character LCD or a graphic LCD(GLCD). Because LCD and GLCD share the same port (port D)
they can’t be used in the same time.
In order to use both LCD and GLCD we must define first the bits they use according to the
schematic of the board:
// Lcd module connections
sbit LCD_RS at LATD2_bit;
sbit LCD_EN at LATD3_bit;
sbit LCD_D4 at LATD4_bit;
sbit LCD_D5 at LATD5_bit;
sbit LCD_D6 at LATD6_bit;
sbit LCD_D7 at LATD7_bit;

// Glcd module connections


char GLCD_DataPort at PORTD;
sbit GLCD_CS1 at LATJ0_bit;
sbit GLCD_CS2 at LATJ1_bit;
sbit GLCD_RS at LATJ2_bit;
sbit GLCD_RW at LATJ3_bit
sbit GLCD_EN at LATJ4_bit;
sbit GLCD_RST at LATJ5_bit;

(picture with the BigPic board with LCD or GLCD working)

3. Analog to digital conversion module

The Analog-to-Digital (A/D) converter module and 12 channels and allows conversion of an
analog input signal to a corresponding 10-bit digital number.
The module has five registers:
- A/D Result High Register (ADRESH)
- A/D Result Low Register (ADRESL)
- A/D Control Register 0 (ADCON0)
- A/D Control Register 1 (ADCON1)
- A/D Control Register 2 (ADCON2)
Because each port pin associated with the A/D converter can be configured as an analog
input, or as a digital I/O, every time we want to use an analog input we must use ADCON1
register. In this registers the 4 least significant bits specify the number of analog inputs we want
to use. In ADCON1 and we must select channel in ADCON0:
Example:

ADCON1 =0b00001110;//use AN0


ADCON0 = 0x00;//select channel 0 (AN0)
To start the conversion we must put ADON bit ( ADCON0 register) to 1 to enable the
conversion and to set GO_DONE bit( ADCON0 register) to start the conversion. It is possible to
receive the result via an interrupt or we can use a while loop and verify the state of GO_DONE
pin until it goes low (meaning the A/D conversion is finished):

ADCON0.ADON = 0x01;//Enable A/D module


ADCON0.GO_DONE = 1;//Start A/D Conversion
while(ADCON0.GO_DONE != 0);//Loop here until A/D conversion completes

The ADRESH and ADRESL registers contain the result of the A/D conversion. When the
A/D conversion is complete, the result is loaded into the ADRESH:ADRESL register pair and we
calculate it as follows:

adc_val=ADRESH;
adc_val&=0x03;
adc_val*=256;
adc_val+=ADRESL;

In conclusion, if we want to make an analog conversion we must follow the next steps:
- Configure analog pins (ADCON1)
- Select A/D input channel (ADCON0)
- Turn on A/D module (ADCON0)
- Start conversion: set GO/DONE bit (ADCON0 register)
- Wait for A/D conversion to complete, by polling for the GO/DONE bit to be cleared
- Read A/D Result registers (ADRESH:ADRESL);
This is a simple way to do analog conversion. There are many other parameters that we can set,
like: A/D acquisition time (ADCON2), A/D conversion clock (ADCON2), voltage reference.
Also, we can use the interrupt routine to control the ADC conversion.

4. Interrupts
The interrupts in a microcontroller are special events generated by internal or external
sources: analog to digital converter, serial interface, timers, etc. There is an interrupt
management system which has the role to interrupt the program flow in order to inform the
processor about the event, every time it appears.

For every interrupt there are three bits to control it:


- Flag bit - indicates that the interrupt event occurred
- Enable bit - enables the interrupt. The program flow is interrupted only if this bit is set.
- Priority bit- selects the priority level for each interrupt. There is a bit which
validates/invalidates all the interrupts – GIE(Global Interrupt Enable bit)
Interrupt flag bits are set when an interrupt condition occurs (this is made automatically by
the interrupt management system) but the user should clear the appropriate interrupt flag bits in
the interrupt routine to enable a future interrupt occurrence.

One of the most important interrupt sources is the interrupt generated by timer0 module
when an overflow occurs in TMR0 register (transition from FFh to 00h - 8 bit mode or 0xffffh to
0x0000h – 16 bit mode). The interrupt management system will set the flag bit TMR0IF(register
INTCON bit 2=1) and the flow of the program will be interrupted and the interrupt routine is
executed(only if the enable bit is set - TMR0IE (register INTCON bit 5=1).
In the next example we set the interrupt routine for TIMER0 to occur each 25ms. Timer0
is configured as an 16-bit timer/counter ( bit T08BIT=1 (register T0CON bit6). An easy way to
obtain the desired period for TIMER0 is to use the internal prescaler (an 8 bit timer) to divide the
internal clock source. The internal frequency is the frequency of external oscillator divided by
4(in our case is 20Mhz/4). If we set the prescaler to 1:8 (010) we obtain 20/32=0,625Mhz, so we
will have a timer period of s. If we want to obtain 25ms we must count 25000/16=15625. So,
timer0 will be preloaded with 65536-15625=49911 (0xc2f7).

T08BIT_bit = 0; // 16 bit timer


T0CS_bit = 0; // internal clock
PSA_bit = 0; // use prescaler
T0PS2_bit=0;
T0PS1_bit=1; // prescaler to 1:8 (010) -> frecquency=FCY/(4*8) =20/32= 0,625 MHz
T0PS0_bit=0;
TMR0IF_bit = 0; // reset interrupt flag for Timer0
TMR0H = 0xc2; //; preset for Timer0 MSB register
TMR0L = 0xf7; // ; preset for Timer0 LSB register
GIE_bit = 1; // set general enable interupt bit
TMR0IE_bit = 1; // set enable interupt bit for timer0
TMR0ON_bit = 1; // start timer0

In the interrupt routine we must identify the source of interrupt and we must clear the
TMR0IF flag to enable the next interrupt:

void interrupt(void) // Rutina de intrerupere


{
if (TMR0IF_bit) { // find out if the interrupt occurred because of TIMER0
………
TMR0L = 0xc2//reload timer0
TMR0H = 0xf7;
TMR0IF_bit = 0;// clear the interrupt flag
}
}
5. Serial communication

Serial communication is very important for microcontroller because allows the


communication with computers (via COM port,USB,etc), peripheral devices or some ICs (such
as eeprom, A/D converters,etc.). Most PIC microcontrollers come with build in serial
communication protocols such as USART, I2C, SPI.

The word USART is the acronym of Universal Synchronous Asynchronous Receive


Transmit. Standard COM port uses asynchronous receiver and transmitter. In this mode there are
Tx (transmit) and Rx (receive) lines. It can transmit and receive information at the same time
from these lines this is called full-duplex communication. Half-duplex is when you have to wait
to complete Rx before use Tx or vice versa.

To configure USART module we use TXSTA, RCSTA, SPBRG and interrupt registers.

In order to make a serial communication via USART we must make the following settings:

For transmission:

- The desired baud rate should be set by using bits BRGH (TXSTA register) and BRG16
(BAUDCTL register) and registers SPBRGH and SPBRG;desired baudrate is calculated as
follows: SPBRGH:SPBRG=(FOSC/Desired Baud Rate)/64
- The SYNC bit (TXSTA register) should be cleared and the SPEN bit should be set (RCSTA
register) in order to enable serial port;
- On 9-bit data transmission, the TX9 bit of the TXSTA register should be set;
- Data transmission is enabled by setting bit TXEN of the TXSTA register. Bit TXIF of the PIR1
register is automatically set;
- If needed the bit TXEN causes an interrupt, the GIE and PEIE bits of the INTCON register
should be set;
- On 9-bit data transmission, value of the ninth bit should be written to the TX9D bit of the
TXSTA register
- Transmission starts by writing 8-bit data to the TXREG register.
For receiving:

- Baud Rate should be set by using bits BRGH (TXSTA register) and BRG16 (BAUDCTL
register) and registers SPBRGH and SPBRG; desired baudrate is calculated as follows:
SPBRGH:SPBRG=(FOSC/Desired Baud Rate)/64
- The SYNC bit (TXSTA register) should be cleared and the SPEN bit should be set (RCSTA
register) in order to enable serial port;
- If it is necessary the data receive causes an interrupt, both the RCIE bit of the PIE1 register and
bits GIE and PEIE of the INTCON register should be set;
- On 9-bit data receive, the RX9 bit of the RCSTA register should be set;
- Data receive should be enabled by setting the CREN bit of the RCSTA register;
- The RCSTA register should be read to get information on possible errors which have occurred
during transmission. On 9-bit data receive, the ninth bit will be stored in this register;
- Received 8-bit data is stored in the RCREG register

If we want to send data to a computer, we must ensure that it receives them correctly. The transmission
is made using a data-package. Each data-package has a fixed length and the following structure:
1. 0xff (255)
2. Byte0
3. Byte1
……..
25. Byte24
26. CRC_H
27. CRC_L

The first byte marks the beginning of the package. This value is the only value on 8 bits, the other
ones are splitted in two values represented with maximum 7 bits, in this way we avoid the situation in
which a maximum value(0xff) appears in other byte of the package except the first one . So, for each
byte we want to send we will use 2 bytes in the package. For example: if we want to send the maximum
value, V=255, as a part of the package, we split it in two bytes: V_h=V/128=1 and V_l=V%128=127.
The software that receives the package on the computer will find the “real” value from these two bytes
as follows: V=V_h*128+V_l=1*128+127=255.
CRC_H and CRC_l are the two bytes (calculated as in the above example) of the cyclic redundancy
check(CRC). CRC is a mechanism to protect against common types of errors on communication
channels. It can provide quick and reasonable assurance of the integrity of messages delivered.
The software from microcontroller calculates the CRC as the 8 bit sum of all the bytes it wants to
transmit (Byte0 to Byte1). When the computers detects the beginning of the package, reads the next 25
bytes and calculates their 8 bit sum. Then it calculates CRC_H and CRC_L and compares these values
with the last two values of the received package. If these values are equals the package is safe and ready
to use. If these values are not the same, the package is ignored.

6. Current acquisition module.


The final goal of the project is to develop an acquisition system for voltage and current in an electric
grid.
For this goal we must design two acquisition modules for voltage and current. Our goal is to convert
these two signals into 4-20mA signals.
The current signal (0-50A) will pass through 5 conversion blocks and, at the output we will obtain 4-
20mA signal.

In the first conversion block we use a LEM current transducer (LA55-P/SP1). This transducer is
used for the electronic measurement of currents (DC, AC) with galvanic isolation between the primary
circuit (high power) and the secondary circuit (electronic circuit). Conversion ratio of the current
transducer is 1: 2000, given that the primary circuit is comprised of a one thread coil. The value of rated
current 50A. If we want to have a better resolution for currents up to 5A, the primary circuit must be
have multiple threads. Thus, for 10 threads, for instance, the conversion ratio is 10:2000 that means 1:
200. So, if we have 5A in the primary circuit, in the secondary circuit we have a current of 5A/200 = 0,
025A = 25mA. Maximum measurement resistance for LA55-P/SP1 is 330 Ω.

In our case we have 9 threads coil in primary circuit and a 100 Ω measurement resistor(R1).
In this conditions, for a 5A (RMS) current we obtain at the output 5A/[9:2000] = 0.0225A =
22,5mA (RMS). So, the value of the voltage measured on R1 resistor is 22,5mA*100 Ω = 2,25V
(RMS).

For a good linearity, RMS input value must be maximum 200mV. For this reason, between
LEM transducer and AD736 converter we have another conversion block(the third one) who has
an amplification factor less than 1 (from 2 .25V we must reach to 200mV). To achieve this the
signal attenuation we used two inverting operational amplifiers. The amplification factor for the
first amplifier is -1(R2=10K and R3=10K), and for the second one must be – (200mV/2 .25V) =
(0,2/2.25) =-0. 0 (8). If |A| = (R5+RV1)/R4 = 0,2/2,25 we can use the following values: R4=100,
R5=5K6, RV1=10K.
The third conversion block uses AD736 converter from analog devices. This chip converts an ac
voltage waveform to a dc voltage and then converts to the true rms value. The main characteristics of this
device are:
- wide power supply range: +2.8 V, −3.2 V to ±16.5 V
- low power: 200 μA maximum supply current
- It can compute the rms value of both ac and dc input voltages
- It needs only one external component (a capacitor) to perform true rms measurement.

At the output of AD736 converter we have the same value of the DC voltage as it is at the
input(RMS value).
The forth conversion block uses an operational amplifier (OP07) to obtain a suitable voltage for the
final conversion block.
….
The final conversion block uses AD694 chip from analog devices. This is a monolithic current
transmitter that accepts at the input a high level signal and converts it to a standard 4–20 mA
current loop.
The main characteristics of this device are:
- Wide Power Supply Range: 4.5 V to 36 V
- Pin programmable input ranges are precalibrated at 0 V to2 V and 0 V to 10 V(we will
use 0V to 10V input range)
- 4–20 mA, 0–20 mA Output Ranges
- Precision Voltage Reference Programmable to 2.000 V or 10.000 V
- Open-Loop Alarm - an alarm warns of an open 4–20 mA loop or noncompliance of the
output stage(pin 10)
7. Voltage acquisition module.
The voltage transducer(LV25P-SP5) has 1000:2500 convertion ratio and the rated current in the primary circuit is
10mA. In these conditions, with a 50K limiting resistor connected in series with the primary circuit, we obtain,
for 500V input votage, an 25mA output current, so the voltage on the measurement resistor R1 is 2,5V. For the
same reasons as with the current module, at the input of AD736 converter we need maximum 200mV so, the
gain of the second conversion block (the one with two operational amplifiers) is 0,200/2,5=0,08.
8. Using Proteus software for PCB design and simulation.
The final schematic of the current conversion module is:

Because Proteus offers the possibility to simulate schematic, we can test if every conversion block
work as it should. Because we don’t have the simulation models for all components we will simulate
only conversion blocks 2,3,4. For the simulation of AD736 we will use an equivalent device
(LTC1966). The simulation will help us to see if we calculated the correct values for the resistors to
obtain the desired value at the output of each conversion block.

Vous aimerez peut-être aussi