Файл: The quintessential PIC microcontroller (S. Katzen, 2000).pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 15.06.2025

Просмотров: 5276

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

334 The Quintessential PIC Microcontroller

Program 12.8 Interacting with the MAX518 dual-channel I2C DAC.

ANALOG

call

START

;

Start a transmission packet

; Address

byte

movlw

b’01011000’;

Slave address Master-Write

movwf

DATA_OUT

;

Copied to pass location

call

I2C_OUT

;

Send it out

movf

ERR,f

;

Check for an error

btfsc

STATUS,Z

;

IF Zero THEN continue

goto

ANALOG

;

ELSE try again

; Command

byte 1

movlw

b’00000000’;

No ReSeT, No Power Down, Channel0

movwf

DATA_OUT

;

Copied to pass location

call

I2C_OUT

;

Send it out

movf

ERR,f

;

Check for an error

btfsc

STATUS,Z

;

IF Zero THEN continue

goto

ANALOG

;

ELSE try again

; Data byte 1

movf

20h,w

;

Channel0’s datum from memory

movwf

DATA_OUT

;

Copied to pass location

call

I2C_OUT

;

Send it out

movf

ERR,f

;

Check for an error

btfsc

STATUS,Z

;

IF Zero THEN continue

goto

ANALOG

;

ELSE try again

; Command

byte 2

movlw

b’00000001’;

No ReSeT, No Power Down, Channel1

movwf

DATA_OUT

;

Copied to pass location

call

I2C_OUT

;

Send it out

movf

ERR,f

;

Check for an error

btfsc

STATUS,Z

;

IF Zero THEN continue

goto

ANALOG

;

ELSE try again

; Data byte 2

movf

21h,w

;

Channel1’s datum from memory

movwf

DATA_OUT

;

Copied to pass location

call

I2C_OUT

;

Send it out

movf

ERR,f

;

Check for an error

btfsc

STATUS,Z

;

IF Zero THEN continue

goto

ANALOG

;

ELSE try again

call

STOP

The listing of Program 12.8 follows our itemization exactly. On return from each call to I2C_OUT the Error datum is tested for zero. If non zero then the process is restarted. Repeated Starts are allowed by the I2C protocol. However, if there was a hardware fault with the bus or Slave then this process would continue indefinitely. Thus, for robustness a time-out mechanism should be implemented to prevent hang-ups.

Although the basic Synchronous Serial Port fully implements most I2C Slave functions, there is little support for the role of Master.8 However, if a PIC with an integral SSP is to be used as a Master then it is advantageous to use pins RC3 and RC4 for SCL and SDA respectively. With the SSP

8Some newer PICs, such as the PIC1687X line, have an enhanced Serial port with most Master functions available in hardware.


12. One Bit at a Time 335

enabled and programmed in Mode 11 (Slave idle – see Table 12.1) these pins conform to the specified relatively slow (300 ns maximum) rise and fall times. A normal port line has transition times of the order of 10 ns. The slower transition times give less cross talk between bus lines and less transmission line reflections at electrical discontinuities.

As in the case for the SPI protocol, many C compilers targeted to the PIC have built-in functions to implement the I2C protocol and avoid bit banging user-defined functions.

To illustrate the technique, consider Program 12.9 which replicates the assembly-level coding of Programs 12.7 and 12.8 using the CCS compiler.

i2c_start();

Generates the Master Start condition.

i2c_stop();

Generates the Master Stop condition.

i2c_read();

Reads a byte over the bus. If an optional parameter of 0 is used then the Master will not Acknowledge the received data.

Program 12.9 Interfacing to the MAX518 in C.

#include <16F84.h>

/* PortA, bit0 is the Master SCL, bit1 is the Master SDA,

fast protocol

*/

#use i2c(master, scl=PIN_A0, sda=PIN_A1, fast)

#define data_x *(unsigned int *)0x20

#define data_y *(unsigned int *)0x21

void MAX518(unsigned int channel_0, unsigned int channel_1);

main()

{

/*

Various code lines

*/

MAX518(data_x, data_y); /*

Send out the two data bytes

*/

/*

More code

*/

}

void MAX518(unsigned int channel_0, unsigned int channel_1)

{

i2c_start();

/*

Start condition

*/

i2c_write(0x58);

/*

Send out Slave address; Write

*/

i2c_write(0);

/*

Send out Command 1

*/

i2c_write(channel_0); /*

Send out datum to channel 0

*/

i2c_write(0x01);

/*

Send out Command 2

*/

i2c_write(channel_1); /*

Send out datum to Channel 1

*/

/* Updates both channels

*/

i2c_stop();

/*

Stop condition

*/

}


336 The Quintessential PIC Microcontroller

i2c_write(value);

Sends a single byte over the bus.

#use i2c(master, scl=PIN_A0, sda=PIN_A1, fast)

This is a directive by which the programmer informs the compiler which pins are used for the I2C lines, the fast or standard protocols and Master or Slave mode. The SSP hardware can be designated for the latter situation.

The key characteristic of the various serial protocols discussed up to now is that a clock signal is transmitted by the Master, which allows the Slave to receive or transmit data in perfect synchronization. An alternative approach is to send data under the assumption that the transmitter and receivers are running at approximately the same frequency. This asychronous protocol has been in use for data communications system for over a century to send alphanumeric data over telegraph, telephone and radio links to implement the Telex system.

One of the features of early computer development in the 1940/1950s was the extensive use of existing technology. An essential adjunct of any computer-oriented installation is a data terminal. At that time the communications industry made considerable use of the teletypewriter (TTY).9 Serial data were converted between serial and parallel formats in the terminal itself as well as providing keyboarding and printing functions.

P

I

C

Idle Start LSB

MSB

Parity Stop Idle Start LSB

MSB

Parity Stop Idle Start LSB

MSB

Parity Stop

Fig. 12.18 Transmitting the message string "PIC" in the asynchronous serial mode, with odd one’s parity and a minimum of one stop bit.

Until the early 1980s, TTYs were electromechanical machines, driven by a synchronous electric motor. This meant that synchronization between remote terminals could only be guaranteed for short periods. To get around this problem, each word transmitted was proceeded by one Start bit and followed by one or more Stop bits. A typical example is shown in Fig. 12.18. While the line is idling, a logic 1 (break level) is transmitted. A logic 0 signals the start of a word. After the word has been sent, a logic 1 terminates the sequence. Electro-mechanical terminals typically print ten characters per second, and require a minimum of

9Literally a ‘typewriter from afar’; Greek, tele = far.


12. One Bit at a Time 337

two Stop bits. This requires a transmission rate of 110 bits per second, or 110 baud.10

The first purely electronic terminals required only one Stop bit, and could print at 30 characters per second, giving a rate of 300 baud. Traditionally communication channels use multiples of 300; eg. 1200, 2400, 4800, 9600…. PC serial ports can run up to 19,200 baud. However, this ×300 rate is not necessary as long as receiver and transmitter are running at the same nominal rate.

Typically a receiver on detecting an incoming datum will try and sample each bit at approximately mid point. This means that a frequency drift of ±0.5 bit time can be tolerated in the space of ten bits. Thus the receiver and transmitter local clocks must be within ±5%. The two will be resynchronized at the start of each datum.

Although not the most e cient of techniques, the asynchronous protocol outlined here has the major advantage of being an international standard. There are several variants; for instance the word can typically be from five to nine bits long. In our example the word length is eight bits with the eighth bit being used to provide a limited error checking capability. This parity bit is set in our example so that the number of 1s in the word is always odd. This can be checked at the receiver (see SAQ 3.9 on page 73) to detect a single bit error.

The original teleprinter code developed by Emile Baudot in 1875 is only five bits long.11 Here the string "PIC" is coded as 10110 00110 01110. Although limited in capability, its key advantage over Morse code (Samual Morse, 1840) was its fixed length (compare with ·– – ···– ·–·) which considerably simplifies the design of the transmitter and receiver. However, Morse code is more e cient as the number of bits is approximately inversely proportionally to a letter’s statistical frequency of use.

The 7-bit ASCII code of Table 1.1 on page 5, first adopted in 1963, was the first code specifically developed for computer communication systems. In 8-bit systems the extra 128 code patterns is usually utilized to add a selection of accented, mathematical and graphic symbols rather than for parity. However, parity can be accommodated by using a 9-bit word format.

For our example we have adopted a format of one Start, eight data with no parity and one Stop bit. Using a bit banging approach, as we have already done for our SPI and I2C protocols, is straightforward provided

10Strictly the baud rate is a measure of information rate. For a simple baseband system this is equal to the bit rate. However, this equality is not always true. For example, a

telephone modem can use a di-bit modulation scheme where groups of bits two at a time give a carrier tone phase shift of 0◦, 90◦, 180◦ and 270◦ phase shift for the patterns 00, 01, 10, 11 respectively. In this case the baud rate is four times the bit rate.

11Actually the first binary coded alphanumeric code was devised by Francis Bacon in around 1600. It too was a 5-bit code.


338 The Quintessential PIC Microcontroller

that we have an accurate 12 -bit delay. For example, for a 4800 baud link this would be 104 µs. As the delay is so short we can use an in-line approach using a macro in the same manner as in Program 12.6 rather than the subroutine approach of Program 6.8 on page 159.

Program 12.10 A baud-rate delay macro showing a half 9600 baud period delay at 20 MHz evocation.

include "p16F84a.inc" #define XTAL d’20’ #define BAUD d’9600’

#define N (XTAL*d’980000’)/(8*BAUD)

Baud_delay macro

local

BAUD_LOOP

if(XTAL>d’12’)

movlw

N/9

; The delay parameter

BAUD_LOOP

addlw

-1

; Decrement

nop

nop

nop

nop

nop

btfss

STATUS,Z ; Until zero

goto

BAUD_LOOP

endif

if((XTAL>=6)&&(XTAL<=d’12’))

movlw

N/5

; The delay parameter

BAUD_LOOP

addlw

-1

; Decrement

nop

btfss

STATUS,Z ; Until zero

goto

BAUD_LOOP

endif

if(XTAL<6)

movlw

N/4

; The delay parameter

BAUD_LOOP

addlw

-1

; Decrement

btfss

STATUS,Z ; Until zero

goto

BAUD_LOOP

endif

endm

The macro shown in Program 12.10 is designed to give a suitable 12 - bit delay for a range of baud rates from 1200 through 9600 and crystal frequencies of 4 through 20 MHz. Both BAUD and XTAL constants are defined in the program head by the programmer; the example given in the listing showing a baud rate of 9600 and crystal frequency of 20 MHz.

The kernel of our macro is the decrement loop: