Advanced PIC18 Projects—SD Card Projects:The SD Card

In this and the remaining chapters we will look at the design of more complex PIC18 microcontroller–based projects. This chapter discusses the design of Secure Digital (SD) memory card–based projects. The remaining chapters of the book describe the basic theory and design of projects based on the popular USB bus and CAN bus protocols.

The SD Card

Before going into the design details of SD card–based projects, we should take a look at the basic principles and operation of SD card memory devices. Figure 7.1 shows a typical SD card.

The SD card is a flash memory storage device designed to provide high-capacity, nonvolatile, and rewritable storage in a small size. These devices are frequently used in many electronic consumer goods, such as cameras, computers, GPS systems, mobile phones, and PDAs. The memory capacity of the SD cards is increasing all the time. Currently they are available at capacities from 256MB to 8GB. The SD cards come in three sizes: standard, mini, and micro. Table 7.1 lists the main specifications of the most common standard SD and miniSD cards.

SD card specifications are maintained by the SD Card Association, which has over six hundred members. MiniSD and microSD cards are electrically compatible with the standard SD cards and can be inserted in special adapters and used as standard SD cards in standard card slots.

Advanced PIC18 Projects—SD Card Projects-0093

SD card speeds are measured three different ways: in KB/s (kilobytes per second), in MB/s (megabytes per second), in an “x” rating similar to that of CD-ROMS where “x” is the speed corresponding to 150KB/s. The various “x” based speeds are:

• 4x: 600KB/s

• 16x: 2.4MB/s

• 40x: 6.0MB/s

• 66x: 10MB/s

In this chapter we are using the standard SD card only. The specifications of the smaller SD cards are the same and are not described further in this chapter.

SD cards can be interfaced to microcontrollers using two different protocols: SD card protocol and the SPI (Serial Peripheral Interface) protocol. The SPI protocol, being more widely used, is the one used in this chapter. The standard SD card has 9 pins with the pin layout shown in Figure 7.2. The pins have different functions depending on the interface protocol. Table 7.2 gives the function of each pin in both the SD and SPI modes of operation.

Advanced PIC18 Projects—SD Card Projects-0094

Since the SD card projects described in this chapter are based on the SPI bus protocol, it is worth looking at the specifications of this bus before proceeding to the projects themselves.

The SPI Bus

The SPI (Serial Peripheral Interface) bus is a synchronous serial bus standard named by Motorola that operates in full duplex mode. Devices on a SPI bus operate in master- slave mode, where the master device initiates the data transfer, selects a slave, and provides a clock for the slaves. The selected slave responds and sends its data to the

Advanced PIC18 Projects—SD Card Projects-0095

master at each clock pulse. The SPI bus can operate with a single master device and one or more slave devices. This simple interface is also called a “four-wire” interface.

The signals in the SPI bus are named as follows:

• MOSI—master output, slave input

• MISO—master input, slave output

• SCLK—serial clock

• SS—slave select

These signals are also named as:

• DO—data out

• DI—data in

• CLK—clock

• CD—chip select

Figure 7.3 shows the basic connection between a master device and a slave device in SPI bus. The master sends out data on line MOSI and receives data on line MISO. The slave must be selected before data transfer can take place.

Advanced PIC18 Projects—SD Card Projects-0096

Figure 7.4 shows an instance where more than one slave device is connected to the SPI bus. Here, each slave is selected individually by the master, and although all the slaves receive the clock pulses, only the selected slave device responds. If an SPI device is not selected, its data output goes into a high-impedance state so it does not interfere with the currently selected device on the bus.

Advanced PIC18 Projects—SD Card Projects-0097

Data transmission normally occurs in and out of the master and slave devices as the master supplies clock pulses. To begin a communication, the master first pulls the slave select line low for the desired slave device. Then the master issues clock pulses, and during each SPI clock cycle, a full duplex data transmission occurs.

When there are no more data to be transmitted, the master stops toggling its clock output.

The SPI bus is currently used by microcontroller interface circuits to talk to a variety of devices such as:

• Memory devices (SD cards)

• Sensors

• Real-time clocks

• Communications devices

• Displays

The advantages of the SPI bus are:

• Simple communication protocol

• Full duplex communication

• Very simple hardware interface Its disadvantages are:

• Requires four pins

• No hardware flow control

• No slave acknowledgment

It is worth remarking that there are no SPI standards governed by an international committee, so there are several versions of SPI bus implementation. In some applications, the MOSI and MISO lines are combined into a single data line, thereby reducing the line requirements to three. Some implementations have two clocks, one to capture (or display) data and the other to clock it into the device. Also, in some implementations the chip select line may be active-high rather than active-low.

Operation of the SD Card in SPI Mode

When the SD card is operated in SPI mode, only seven pins are used. Three (pins 3, 4, and 6) are used for the power supply, leaving four pins (pins 1, 2, 5, and 7) for the SPI mode of operation:

• Two power supply ground (pins 3 and 6)

• Power supply (pin 4)

• Chip select (pin 1)

• Data out (pin 7)

• Data in (pin 2)

• CLK (pin 5)

At power-up, the SD card defaults to the SD bus protocol. The card is switched to SPI mode if the Chip Select (CS) signal is asserted during reception of the reset command. When the card is in SPI mode, it only responds to SPI commands. The host may reset a card by switching the power supply off and then on again.

The mikroC compiler provides a library of commands for initializing, reading, and writing to SD cards. It is not necessary to know the internal structure of an SD card in detail before using one, since the library functions are available. However, a basic understanding of the internal structure of an SD card is helpful in making the best use of the card. In this section we will look briefly at the internal architecture and operation of SD cards.

An SD card has a set of registers that provide information about the status of the card. When the card is operated in SPI mode these are:

• Card identification register (CID)

• Card specific data register (CSD)

• SD configuration register (SCR)

• Operation control register (OCR)

The CID register consists of 16 bytes and contains the manufacturer ID, product name, product revision, card serial number, manufacturer date code, and a checksum byte. Table 7.3 shows the structure of the CID register.

Advanced PIC18 Projects—SD Card Projects-0098

The CSD register consists of 16 bytes and contains card-specific data such as the card data transfer rate, read/write block lengths, read/write currents, erase sector size, file format, write protection flags, and checksum. Table 7.4 shows the structure of the CSD register.

The SCR register is 8 bytes long and contains information about the SD card’s special features and capabilities, such as security support and data bus widths supported.

The OCR register is only 4 bytes long and stores the VDD voltage profile of the card. The OCR shows the voltage range in which the card data can be accessed.

All SD-card SPI commands are 6 bytes long, with the MSB transmitted first. Figure 7.5 shows the command format. The first byte is known as the command byte, and the remaining five bytes are called command arguments. Bit 6 of the command byte is set to 1 and the MSB bit is always 0. With the remaining six bits we have sixty-four possible commands, named CMD0 to CMD63. Some of the important commands are:

• CMD0 GO_IDLE_STATE (resets the SD card)

• CMD1 SEND_OP_COND (initializes the card)

• CMD9 SEND_CSD (gets CSD register data)

Advanced PIC18 Projects—SD Card Projects-0099

Advanced PIC18 Projects—SD Card Projects-0100

• CMD10 SEND_CID (gets CID register data)

• CMD16 SET_BLOCKLEN (selects a block length in bytes)

• CMD17 READ_SINGLE_BLOCK (reads a block of data)

• CMD24 WRITE_BLOCK (writes a block of data)

• CMD32 ERASE_WR_BLK_START_ADDR (sets the address of the first write block to be erased)

• CMD33 ERASE_WR_BLK_END_ADDR (sets the address of the last write block to be erased)

• CMD38 ERASE (erases all previously selected blocks)

In response to a command, the card sends a status byte known as R1. The MSB bit of this byte is always 0 and the other bits indicate the following error conditions:

• Card in idle state

• Erase reset

• Illegal command

• Communication CRC error

• Erase sequence error

• Address error

• Parameter error

Reading Data

The SD card in SPI mode supports single-block and multiple-block read operations. The host should set the block length. After a valid read command the card responds with a response token, followed by a data block and a CRC check. The block length can be between 1 and 512 bytes. The starting address can be any valid address in the address range of the card.

In multiple-block read operations, the card sends data blocks with each block having its own CRC check attached to the end of the block.

Writing Data

The SD card in SPI mode supports single- or multiple-block write operations. After receiving a valid write command from the host, the card responds with a response token and waits to receive a data block. A one-byte “start block” token is added to the beginning of every data block. After receiving the data block the card responds with a “data response” token, and the card is programmed as long as the data block is received with no errors.

In multiple-block write operations the host sends the data blocks one after the other, each preceded by a “start block” token. The card sends a response byte after receiving each data block.

Card Size Parameters SD cards are available in various sizes. At the time of writing, SanDisk Corporation (www.sandisk.com) offered the models and capacities shown in Table 7.5. The company may now be offering models with 4GB or even greater capacity.

In addition to the normal storage area on the card, there is also a protected area pertaining to the secured copyright management. This area can be used by applications to save security-related data and can be accessed by the host using secured read/write commands. The card write protection mechanism does not affect this area. Table 7.6 shows the size of the protected area and the data area available to the user for reading and writing data. For example, a 1GB card has 20,480 blocks (one block is 512 bytes) of protected area and 1,983,744 blocks of user data area.

Advanced PIC18 Projects—SD Card Projects-0101

Advanced PIC18 Projects—SD Card Projects-0102

Data can be written to or read from any sector of the card using raw sector access methods. In general, SD card data is structured as a file system and two DOS-formatted partitions are placed on the card: the user area and the security protected area. The size of each area is shown in Table 7.7. For example, in a 1GB card, the size of the security protected area is 519 sectors (1 sector is 512 bytes), and the size of the user data area is 1,982,976 sectors.

Advanced PIC18 Projects—SD Card Projects-0103

A card can be inserted and removed from the bus without any damage. This is because all data transfer operations are protected by cyclic redundancy check (CRC) codes, and any bit changes caused by inserting or removing a card can easily be detected. SD cards typically operate with a supply voltage of 2.7V. The maximum allowed power supply voltage is 3.6V. If the card is to be operated from a standard 5.0V supply, a voltage regulator should be used to drop the voltage to 2.7V.

Using an SD card requires the card to be inserted into a special card holder with external contacts (see Figure 7.6) so connections are easily made to the required card pins.

Advanced PIC18 Projects—SD Card Projects-0104

 

Advanced PIC18 Projects—SD Card Projects:mikroC Language SD Card Library Functions

mikroC Language SD Card Library Functions

The mikroC language provides an extensive set of library functions to read and write data to SD cards (and also MultiMediaCards, MMC). Data can be written to or read from a given sector of the card, or the file system on the card can be used for more sophisticated applications.

The following library functions are provided:

• Mmc_Init (initialize the card)

• Mmc_Read_Sector (read one sector of data)

• Mmc_Write_Sector (write one sector of data)

• Mmc_Read_Cid (read CID register)

• Mmc_Read_Csd (read CSD register)

• Mmc_Fat_Init (initialize FAT)

• Mmc_Fat_QuickFormat (format the card to FAT16)

• Mmc_Fat_Assign (assign the file we will be working with)

• Mmc_Fat_Reset (reset the file pointer; opens the currently assigned file for reading)

• Mmc_Fat_Rewrite (reset the file pointer and clear assigned file; opens

the assigned file for writing)

• Mmc_Fat_Append (move file pointer to the end of assigned file so new data can be appended to the file)

• Mmc_Fat_Read (read the byte the file pointer points to)

• Mmc_Fat_Write (write a block of data to the assigned file)

• Mmc_Set_File_Date (write system timestamp to a file)

• Mmc_Fat_Delete (delete a file)

• Mmc_Fat_Get_File_Date (read file timestamp)

• Mmc_Fat_Get_File_Size (get file size in bytes)

• Mmc_Fat_Get_Swap_File (create a swap file)

In the remainder of this chapter we will look at some SD-card and PIC18 microcontroller-based projects.

 

Simple PIC18 Projects:Serial Communication–Based Calculator

PROJECT 6.10—Serial Communication–Based Calculator

Project Description

Serial communication is a simple means of sending data long distances quickly and reliably. The most common serial communication method is based on the RS232 standard, in which standard data is sent over a single line from a transmitting device to a receiving device in bit serial format at a prespecified speed, also known as the baud rate, or the number of bits sent each second. Typical baud rates are 4800, 9600, 19200, 38400, etc.

RS232 serial communication is a form of asynchronous data transmission where data is sent character by character. Each character is preceded with a start bit, seven or eight

Simple PIC18 Projects-0071

Simple PIC18 Projects-0072

Simple PIC18 Projects-0073

Simple PIC18 Projects-0074

data bits, an optional parity bit, and one or more stop bits. The most common format is eight data bits, no parity bit, and one stop bit. The least significant data bit is transmitted first, and the most significant bit is transmitted last.

A logic high is defined at -12V, and a logic 0 is at þ12V. Figure 6.50 shows how character “A” (ASCII binary pattern 0010 0001) is transmitted over a serial line. The line is normally idle at -12V. The start bit is first sent by the line going from high to low. Then eight data bits are sent, starting from the least significant bit. Finally, the stop bit is sent by raising the line from low to high.

Simple PIC18 Projects-0076

In a serial connection, a minimum of three lines is used for communication: transmit (TX), receive (RX), and ground (GND). Serial devices are connected to each other using two types of connectors: 9-way and 25-way. Table 6.11 shows the TX, RX, and GND pins of each type of connectors. The connectors used in RS232 serial communication are shown in Figure 6.51.

Simple PIC18 Projects-0077

As just described, RS232 voltage levels are at ±12V. However, microcontroller input- output ports operate at 0 to þ5V voltage levels, so the voltage levels must be translated before a microcontroller can be connected to a RS232 compatible device. Thus the output signal from the microcontroller has to be converted to ±12V, and the input from an RS232 device must be converted into 0 to þ5V before it can be connected to a microcontroller. This voltage translation is normally done with special RS232 voltage

Simple PIC18 Projects-0078

converter chips. One such popular chip is the MAX232, a dual converter chip having the pin configuration shown in Figure 6.52. The device requires four external 1mF capacitors for its operation.

Simple PIC18 Projects-0079

In the PIC18 series of microcontrollers, serial communication can be handled either in hardware or in software. The hardware option is easy. PIC18 microcontrollers have built-in USART (universal synchronous asynchronous receiver transmitter) circuits providing special input-output pins for serial communication. For serial communication all the data transmission is handled by the USART, but the USART has to be configured before receiving and transmitting data. With the software option, all the serial bit timing is handled in software, and any input-output pin can be programmed and used for serial communication.

In this project a PC is connected to the microcontroller using an RS232 cable. The project operates as a simple integer calculator where data is sent to the microcontroller using the PC keyboard and displayed on the PC monitor.

A sample calculation is as follows:

CALCULATOR PROGRAM

Simple PIC18 Projects-0080

Project Hardware

Figure 6.53 shows the block diagram of the project. The circuit diagram is given in Figure 6.54. This project uses a PIC18F452 microcontroller with a 4MHz resonator, and the built-in USART is used for serial communication. The serial communication lines of the microcontroller (RC6 and RC7) are connected to a MAX232 voltage translator chip and then to the serial input port (COM1) of a PC using a 9-pin connector.

Simple PIC18 Projects-0081

Project PDL

The PDL of the project is shown in Figure 6.55. The project consists of a main program and two functions called Newline and Text_To_User. Function Newline sends a carriage-return and line-feed to the serial port. Function Text_To_User sends a text message to USART. The main program receives two numbers and the operation to be performed from the PC keyboard. The numbers are echoed on the PC monitor. The result of the operation is also displayed on the monitor.

Simple PIC18 Projects-0082

Project Program

The program listing of the project is shown in Figure 6.56. The program consists of a main program and two functions called Newline and Text_To_Usart. Function Newline sends a carriage return and line feed to the USART to move the cursor to the next line. Function Text_To_Usart sends a text message to the USART.

At the beginning of the program various messages used in the program are defined as msg1 to msg5. The USART is then initialized to 9600 baud using the mikroC library routine Usart_Init. Then the heading “CALCULATOR PROGRAM” is displayed on the PC monitor. The program reads the first number from the keyboard using the library function Usart_Read. Function Usart_Data_Ready checks when a new data byte is ready before reading it. Variable Op1 stores the first number. Similarly, another loop is formed and the second number is read into variable Op2. The program then reads the operation to be performed (þ – * /). The required operation is performed inside a switch statement and the result is stored in variable Calc. The program then converts the result into string format by calling library function LongToStr. Leading blanks are

Simple PIC18 Projects-0083

removed from this string, and the final result is stored in character array kbd and sent to the USART to display on the PC keyboard.

Testing the Program

The program can be tested using a terminal emulator software such as HyperTerminal, which is distributed free of charge with Windows operating systems. The steps to test the program follow (these steps assume serial port COM2 is used):

• Connect the RS232 output from the microcontroller to the serial input port of a PC (e.g., COM2)

Simple PIC18 Projects-0084

Simple PIC18 Projects-0085

 Simple PIC18 Projects-0086Simple PIC18 Projects-0087

• Start HyperTerminal terminal emulation software and give a name to the session

• Select File -> New connection -> Connect using and select COM2

• Select the baud rate as 9600, data bits as 8, no parity bits, and 1 stop bit

• Reset the microcontroller

An example output from the HyperTerminal screen is shown in Figure 6.57.

Using Software-Based Serial Communication

The preceding example made use of the microcontroller’s USART and thus its special serial I/O pins. Serial communication can also be handled entirely in software, without using the USART. In this method, any pin of the microcontroller can be used for serial communication.

Simple PIC18 Projects-0088

The calculator program given in Project 10 can be reprogrammed using the mikroC software serial communications library functions known as the Software Uart Library.

The modified program listing is given in Figure 6.58. The circuit diagram of the project is same as in Figure 6.54 (i.e., RC6 and RC7 are used for serial TX and RX respectively), although any other port pins can also be used. At the beginning of the program the serial I/O port is configured by calling function Soft_Uart_Init. The serial port name, the pins used for TX and RX, the baud rate, and the mode are specified. The mode tells the microcontroller whether or not the data is inverted. Setting mode to 1 inverts the data. When a MAX232 chip is used, the data should be noninverted (i.e., mode ¼ 0).

Serial data is then output using function Soft_Uart_Write. Serial data is input using function Soft_Uart_Read. As the reading is a nonblocking function, it is necessary to check whether or not a data byte is available before attempting to read. This is done using the error argument of the function. The remaining parts of the program are

Simple PIC18 Projects-0089

Simple PIC18 Projects-0090Simple PIC18 Projects-0091Simple PIC18 Projects-0092

 

Simple PIC18 Projects:Calculator with Keypad and LCD

PROJECT 6.9—Calculator with Keypad and LCD

Project Description

Keypads are small keyboards used to enter numeric or alphanumeric data into microcontroller systems. Keypads are available in a variety of sizes and styles, from 2 x 2 to 4 x 4 or even bigger.

This project uses a 4 x 4 keypad (shown in Figure 6.43) and an LCD to design a simple calculator.

Simple PIC18 Projects-0060

Simple PIC18 Projects-0061Simple PIC18 Projects-0062

Figure 6.44 shows the structure of the keypad used in this project which consists of sixteen switches formed in a 4 x 4 array and named numerals 0–9, Enter, “þ”, “.”, “-”, “*”, and “/”. Rows and columns of the keypad are connected to PORTB of a microcontroller which scans the keypad to detect when a switch is pressed. The operation of the keypad is as follows:

• A logic 1 is applied to the first column via RB0.

• Port pins RB4 to RB7 are read. If the data is nonzero, a switch is pressed. If RB4 is 1, key 1 is pressed, if RB5 is 1, key 4 is pressed, if RB6 is 1, key 9 is pressed, and so on.

• A logic 1 is applied to the second column via RB1.

• Again, port pins RB4 to RB7 are read. If the data is nonzero, a switch is pressed.

If RB4 is 1, key 2 is pressed, if RB5 is 1, key 6 is pressed, if RB6 is 1, key 0 is pressed, and so on.

• This process is repeated for all four columns continuously.

In this project a simple integer calculator is designed. The calculator can add, subtract, multiply, and divide integer numbers and show the result on the LCD. The operation of the calculator is as follows: When power is applied to the system, the LCD displays text

Simple PIC18 Projects-0063

“CALCULATOR” for 2 seconds. Then text “No1:” is displayed in the first row of the LCD and the user is expected to type the first number and then press the ENTER key. Then text “No2:” is displayed in the second row of the LCD, where the user enters the second number and presses the ENTER key. After this, the appropriate operation key should be pressed. The result is displayed on the LCD for five seconds and then the LCD is cleared, ready for the next calculation. The example that follows shows how numbers 12 and 20 can be added:

Simple PIC18 Projects-0064

Project Hardware

The block diagram of the project is shown in Figure 6.45. The circuit diagram is given in Figure 6.46. A PIC18F452 microcontroller with a 4MHz resonator is used in the project. Columns of the keypad are connected to port pins RB0–RB3 and rows are connected to port pins RB4–RB7 via pull-down resistors. The LCD is connected to PORTC in default mode, as in Figure 6.39. An external reset button is also provided to reset the microcontroller should it be necessary.

Simple PIC18 Projects-0065

Project PDL

The project PDL is shown in Figure 6.47. The program consist of two parts: function getkeypad and the main program. Function getkeypad receives a key from the keypad. Inside the main program the two numbers and the required operation are received from the keypad. The microcontroller performs the required operation and displays the result on the LCD.

Project Program

The program listing for the program KEYPAD.C is given in Figure 6.48. Each key is given a numeric value as follows:

Simple PIC18 Projects-0066

Simple PIC18 Projects-0067

The program consists of a function called getkeypad, which reads the pressed keys, and the main program. Variable MyKey stores the key value (0 to 15) pressed, variables Op1 and Op2 store respectively the first and second numbers entered by the user. All these variables are cleared to zero at the beginning of the program. A while loop is then formed to read the first number and store in variable Op1. This loop exits when the user presses the ENTER key. Similarly, the second number is read from the keyboard in a second while loop. Then the operation to be performed is read and stored in variable MyKey, and a switch statement is used to perform the required operation and store the result in variable Calc. The result is converted into a string array using function LongToStr. The leading blank characters are then removed as in Project 8. The program

Simple PIC18 Projects-0068

displays the result on the LCD, waits for five seconds, and then clears the screen and is ready for the next calculation. This process is repeated forever.

Function getkeypad receives a key from the keypad. We start by sending a 1 to column 1, and then we check all the rows. When a key is pressed, a logic 1 is detected in the corresponding row and the program jumps out of the while loop. Then a for loop is used to find the actual key pressed by the user as a number from 0 to 15.

It is important to realize that when a key is pressed or released, we get what is known as contact noise, where the key output pulses up and down momentarily, producing a number of logic 0 and 1 pulses at the output. Switch contact noise is usually removed either in hardware or by programming in a process called contact debouncing. In software the simplest way to remove the contact noise is to wait for about 20ms after a switch key is pressed or switch key is released. In Figure 6.46, contact debouncing is accomplished in function getkeypad.

Simple PIC18 Projects-0069

Simple PIC18 Projects-0070

Program Using a Built-in Keypad Function

In the program listing in Figure 6.48, a function called getkeypad has been developed to read a key from the keyboard. The mikroC language has built-in functions called Keypad_Read and Keypad_Released to read a key from a keypad when a key is pressed and when a key is released respectively. Figure 6.49 shows a modified program (KEYPAD2.C) listing using the Keypad_Released function to implement the preceding calculator project. The circuit diagram is the same as in Figure 6.46.

Before using the Keypad_Released function we have to call the Keypad_Init function to tell the microcontroller what the keypad is connected to. Keypad_Released detects when a key is pressed and then released. When released, the function returns a number between 1 and 16 corresponding to the key pressed. The remaining parts of the program are the same as in Figure 6.48.

 

Simple PIC18 Projects:Voltmeter with LCD Display

PROJECT 6.8—Voltmeter with LCD Display

Project Description

In this project a voltmeter with LCD display is designed. The voltmeter can be used to measure voltages 0–5V. The voltage to be measured is applied to one of the analog inputs of a PIC18F452-type microcontroller. The microcontroller reads the analog voltage, converts it into digital, and then displays it on an LCD.

In microcontroller systems the output of a measured variable is usually displayed using LEDs, 7-segment displays, or LCD displays. LCDs make it possible to display alphanumeric or graphical data. Some LCDs have forty or more character lengths with the capability to display several lines. Other LCD displays can be used to display graphics images. Some modules offer color displays, while others incorporate backlighting so they can be viewed in dimly lit conditions.

There are basically two types of LCDs as far as the interface technique is concerned: parallel and serial. Parallel LCDs (e.g., Hitachi HD44780) are connected to a microcontroller by more than one data line and the data is transferred in parallel form. Both four and eight data lines are commonly used. A four-wire connection saves I/O pins but is slower since the data is transferred in two stages.

Serial LCDs are connected to the microcontroller by only one data line, and data is usually sent to the LCD using the standard RS-232 asynchronous data communication protocol. Serial LCDs are much easier to use, but they cost more than the parallel ones.

The programming of a parallel LCD is a complex task and requires a good understanding of the internal operation of the LCD controllers, including the timing diagrams. Fortunately, the mikroC language provides special library commands for displaying data on alphanumeric as well as graphic LCDs. All the user has to do is connect the LCD to the microcontroller, define the LCD connection in the software, and then send special commands to display data on the LCD.

HD44780 LCD Module

The HD44780 is one of the most popular alphanumeric LCD modules and is used both in industry and by hobbyists. This module is monochrome and comes in different sizes.

Modules with 8, 16, 20, 24, 32, and 40 columns are available. Depending on the model chosen, the number of rows may be 1, 2, or 4. The display provides a 14-pin (or 16-pin) connector to a microcontroller. Table 6.10 gives the pin configuration and pin functions of a 14-pin LCD module. The following is a summary of the pin functions:

VSS is the 0V supply or ground. The VDD pin should be connected to the positive supply. Although the manufacturers specify a 5V DC supply, the modules will usually work with as low as 3V or as high as 6V.

Pin 3, named VEE, is the contrast control pin. This pin is used to adjust the contrast of the display and should be connected to a variable voltage supply. A potentiometer is normally connected between the power supply lines with its wiper arm connected to this pin so that the contrast can be adjusted.

Simple PIC18 Projects-0053

Pin 4 is the register select (RS), and when this pin is LOW, data transferred to the display is treated as commands. When RS is HIGH, character data can be transferred to and from the module.

Pin 5 is the read/write (R/W) line. This pin is pulled LOW in order to write commands or character data to the LCD module. When this pin is HIGH, character data or status information can be read from the module.

Pin 6 is the enable (E) pin, which is used to initiate the transfer of commands or data between the module and the microcontroller. When writing to the display, data is transferred only on the HIGH-to-LOW transition of this line. When reading from the display, data becomes available after the LOW-to-HIGH transition of the enable pin, and this data remains valid as long as the enable pin is at logic HIGH.

Pins 7 to 14 are the eight data bus lines (D0 to D7). Data can be transferred between the microcontroller and the LCD module using either a single 8-bit byte or as two 4-bit nibbles. In the latter case, only the upper four data lines (D4 to D7) are used. The 4-bit mode means that four fewer I/O lines are used to communicate with the LCD. In this book we are using only an alphanumeric-based LCD and only the 4-bit interface.

Connecting the LCD

The mikroC compiler assumes by default that the LCD is connected to the microcontroller as follows:

Simple PIC18 Projects-0054

where port is the port name specified using the Lcd_Init statement.

For example, we can use the statement Lcd_Init(&PORTB) if the LCD is connected to PORTB with the default connection.

It is also possible to connect the LCD differently, using the command Lcd_Config to define the connection.

Simple PIC18 Projects-0055

Project Hardware

Figure 6.38 shows the block diagram of the project. The microcontroller reads the analog voltage, converts it to digital, formats it, and then displays it on the LCD.

The circuit diagram of the project is shown in Figure 6.39. The voltage to be measured (between 0 and 5V) is applied to port AN0 where this port is configured as an analog

Simple PIC18 Projects-0056

input in software. The LCD is connected to PORTC of the microcontroller as in the default four-wire connection. A potentiometer is used to adjust the contrast of the LCD display.

Project PDL

The PDL of the project is shown in Figure 6.40. At the beginning of the program PORTC is configured as output and PORTA is configured as input. Then the LCD and the A/D converter are configured. The program then enters an endless loop where analog input voltage is converted to digital and displayed on the LCD. The process is repeated every second.

Simple PIC18 Projects-0057

Project Program

The program is called SEVEN6.C, and the program listing is given in Figure 6.41. At the beginning of the program PORTC is defined as output and PORTA as input.

Then the LCD is configured and the text “VOLTMETER” is displayed on the LCD for two seconds. The A/D is then configured by setting register ADCON1 to 0x80 so the A/D result is right-justified, Vref voltage is set to VDD (þ5V), and all PORTA pins are configured as analog inputs.

The main program loop starts with a for statement. Inside this loop the LCD is cleared, and analog data is read from channel 0 (pin AN0) using the statement Adc_Read(0). The converted digital data is stored in variable Vin which is declared as an unsigned long. The A/D converter is 10-bits wide and thus there are 1024 steps

Simple PIC18 Projects-0058

Simple PIC18 Projects-0059

(0 to 1023) corresponding to the reference voltage of 5000mV. Each step corresponds to 5000mV/1024 ¼ 4.88mV. Inside the loop, variable Vin is converted into millivolts by multiplying by 5000 and dividing into 1024. The division is done by shifting right by 10 digits. At this point variable mV contains the converted data in millivolts.

Function LongToStr is called to convert mV into a string in character array op. LongToStr converts a long variable into a string having a fixed width of eleven characters. If the resulting string is fewer than eleven characters, the left column of the data is filled with space characters.

The leading blanks are then removed and the data is stored in a variable called lcd. Function Lcd_Out is called to display the data on the LCD starting from column 5 of row 1. For example, if the measured voltage is 1267mV, it is displayed on the LCD as:

A More Accurate Display

The voltage displayed in Figure 6.41 is not very accurate, since integer arithmetic has been performed in the calculation and the voltage is calculated by multiplying the A/D output by 5000 and then dividing the result by 1024 using integer division.

Although the multiplication is accurate, the accuracy of the measurement is lost when the number is divided by 1024. A more accurate result can be obtained by scaling the number before it is displayed, as follows.

First, multiply the number Vin by a factor to remove the integer division. For example, since 5000/1024 ¼ 4.88, we can multiply Vin by 488. For the display, we can calculate the integer part of the result by dividing the number into 100, and then the fractional part can be calculated as the remainder. The integer part and the fractional part can be displayed with a decimal point in between. This technique has been implemented in program SEVEN7.C as shown in Figure 6.42. In this program variables Vdec and Vfrac store the integer and the fractional parts of the number respectively. The decimal part is then converted into a string using function LongToStr and leading blanks are removed. The parts of the fractional number are called ch1 and ch2. These are converted into characters by adding 48 (i.e., character “0”) and then displayed at the next cursor positions using the LCD command Lcd_Chr_Cp.

We could also calculate and display more accurate results by using floating point arithmetic, but since this uses huge amounts of memory it should be avoided if possible.

 

Simple PIC18 Projects:Two-Digit Multiplexed 7-Segment LED Counter with Timer Interrupt

PROJECT 6.7—Two-Digit Multiplexed 7-Segment LED Counter with Timer Interrupt

Project Description

This project is similar to Project 6 but here the microcontroller’s timer interrupt is used to refresh the displays. In Project 6 the microcontroller was busy updating the displays every 10ms and could not perform any other tasks. For example, the program given in Project 6 cannot be used to make a counter with a one-second delay between counts, as the displays cannot be updated while the program waits for one second.

In this project a counter is designed to count from 0 to 99, and the display is refreshed every 5ms inside the timer interrupt service routine. The main program can then perform other tasks, in this example incrementing the count and waiting for one second between counts.

In this project Timer 0 is operated in 8-bit mode. The time for an interrupt is given by:

Time ¼ ð4 x clock periodÞ x Prescaler x ð256 – TMR0LÞ

where Prescaler is the selected prescaler value, and TMR0L is the value loaded into timer register TMR0L to generate timer interrupts every Time period.

In our application the clock frequency is 4MHz, that is, clock period ¼ 0.25ms, and Time ¼ 5ms. Selecting a prescaler value of 32, the number to be loaded into TMR0L can be calculated as follows:

Simple PIC18 Projects-0047

Taking the don’t-care entries (X) as 0, the hexadecimal value to be loaded into register INTCON is 0xA0.

When an interrupt occurs, the program automatically jumps to the interrupt service routine. Inside this routine we have to reload register TMR0L, reenable the TMR0 interrupts, and clear the TMR0 interrupt flag bit. Setting INTCON register to 0x20 reenables the TMR0 interrupts and at the same time clears the TMR0 interrupt flag.

The operations to be performed can thus be summarized as follows: In the main program:

• Load TMR0L with 100

• Set T0CON to 0xC4

• Set INTCON to 0xA0

• Increment the counter with 1-second delays In the interrupt service routine:

• Re-load TMR0L to 100

• Refresh displays

• Set INTCON to 0x20 (reenable TMR0 interrupts and clear timer interrupt flag)

Project Hardware

The circuit diagram of this project is same as in Figure 6.32 where a dual 7-segment display is connected to PORTB and PORTC of a PIC18F452 microcontroller.

Project PDL

The PDL of the project is shown in Figure 6.35. The program is in two sections: the main program and the interrupt service routine. Inside the main program, TMR0 is configured to generate interrupts every 5ms and the counter is incremented with a one- second delay. Inside the interrupt service routine, the timer interrupt is reenabled and the display digits are refreshed alternately every 5ms.

Simple PIC18 Projects-0048

Project Program

The program is called SEVEN4.C, and the program listing is given in Figure 6.36. At the beginning of the main program PORTB and PORTC are configured as outputs. Then register T0CON is loaded with 0xC4 to enable the TMR0 and set the prescaler to 32. TMR0L register is loaded with 100 so that an interrupt is generated after 5ms. The program then enters an endless loop where the value of Cnt is incremented every second.

Inside the interrupt service routine, register TMR0L is reloaded, TMR0 interrupts are reenabled, and the timer interrupt flag is cleared so that further timer interrupts can be generated. The display digits are then updated alternately. A variable called Flag is used to determine which digit to update. Function Display is called, as in Project 6, to find the bit pattern to be sent to PORTC.

Modifying the Program

In Figure 6.36 the display counts as 00 01.. .09 10 11.. .99 00 01.. . (i.e., the first digit is shown as 0 for numbers less than 10). The program could be modified so the first

Simple PIC18 Projects-0049

Simple PIC18 Projects-0050

digit is blanked if the number to be displayed is less than 10. The modified program (called SEVEN5.C) is shown in Figure 6.37. Here, the first digit (MSD) is not enabled if the number to be displayed is 0.

Simple PIC18 Projects-0051

Simple PIC18 Projects-0052

 

Simple PIC18 Projects:Two-Digit Multiplexed 7-Segment LED

PROJECT 6.6—Two-Digit Multiplexed 7-Segment LED

Project Description

This project is similar to Project 6.5, but here multiplexed two digits are used instead of just one digit and a fixed number. In this project the number 25 is displayed. In multiplexed LED applications (see Figure 6.29) the LED segments of all the digits are tied together and the common pins of each digit are turned ON separately by the microcontroller. When each digit is displayed only for several milliseconds, the eye cannot tell that the digits are not ON all the time. This way we can multiplex any number of 7-segment displays together. For example, to display the number 53, we have to send 5 to the first digit and enable its common pin. After a few milliseconds, number 3 is sent to the second digit and the common point of the second digit is enabled. When this process is repeated continuously, it appears to the user that both displays are ON continuously.

Some manufacturers provide multiplexed multidigit displays, such as 2-, 4-, or 8-digit multiplexed displays, in single packages. The display used in this project is the DC56- 11EWA, which is a red 0.56-inch common-cathode two-digit display having 18 pins and the pin configuration as shown in Table 6.9. This display can be controlled from the microcontroller as follows:

• Send the segment bit pattern for digit 1 to segments a to g

• Enable digit 1

Simple PIC18 Projects-0040

Simple PIC18 Projects-0041

• Wait for a few milliseconds

• Disable digit 1

• Send the segment bit pattern for digit 2 to segments a to g

• Enable digit 2

• Wait for a few milliseconds

• Disable digit 2

• Repeat these steps continuously

The segment configuration of the DC56-11EWA display is shown in Figure 6.30. In a multiplexed display application the segment pins of corresponding segments are connected together. For example, pins 11 and 16 are connected as the common a segment, pins 15 and 10 are connected as the common b segment, and so on.

Simple PIC18 Projects-0042

Project Hardware

The block diagram of this project is shown in Figure 6.31. The circuit diagram is given in Figure 6.32. The segments of the display are connected to PORTC of a PIC18F452- type microcontroller, operated with a 4MHz resonator. Current limiting resistors are used on each segment of the display. Each digit is enabled using a BC108-type transistor switch connected to port pins RB0 and RB1 of the microcontroller. A segment is turned on when a logic 1 is applied to the base of the corresponding segment transistor.

Simple PIC18 Projects-0043

Project PDL

At the beginning of the program PORTB and PORTC pins are configured as outputs. The program then enters an endless loop where first of all the Most Significant Digit (MSD) of the number is calculated, function Display is called to find the bit pattern and then sent to the display, and digit 1 is enabled. Then, after a small delay, digit 1 is disabled, the Least Significant Digit (LSD) of the number is calculated, function Display is called to find the bit pattern and then sent to the display, and digit 2 is enabled. Then again after a small delay, digit 2 is disabled, and this process repeats indefinitely. Figure 6.33 shows the PDL of the project.

Simple PIC18 Projects-0044

The program is named SEVEN3.C, and the listing is shown in Figure 6.34. DIGIT1 and DIGIT2 are defined as equal to bit 0 and bit 1 of PORTB respectively. The value to be displayed (the number 25) is stored in variable Cnt. An endless loop is formed using a for statement. Inside the loop, the MSD of the number is calculated by dividing the number by 10. Function Display is then called to find the bit pattern to send to PORTC. Then digit 1 is enabled by setting DIGIT1 ¼ 1 and the program waits for 10ms. After this, digit 1 is disabled and the LSD of the number is calculated using the mod operator (“%”) and sent to PORTC. At the same time, digit 2 is enabled by setting DIGIT2 ¼ 1 and the program waits for 10ms. After this time digit 2 is disabled, and the program repeats forever.

Simple PIC18 Projects-0045

Simple PIC18 Projects-0046

 

Simple PIC18 Projects:Segment LED Counter

PROJECT 6.5—7-Segment LED Counter

Project Description

This project describes the design of a 7-segment LED-based counter which counts from 0 to 9 continuously with a one-second delay between counts. The project shows how a 7-segment LED can be interfaced and used in a PIC microcontroller project.

7-segment displays are used frequently in electronic circuits to show numeric or alphanumeric values. As shown in Figure 6.20, a 7-segment display consists basically of 7 LEDs connected such that the numbers from 0 to 9 and some letters can be displayed. Segments are identified by the letters from a to g, and Figure 6.21 shows the segment names of a typical 7-segment display.

Simple PIC18 Projects-0033

Simple PIC18 Projects-0034

7-segment displays are available in two different configurations: common cathode and common anode. As shown in Figure 6.23, in common cathode configuration, all the cathodes of all segment LEDs are connected together to the ground. The segments are turned ON by applying a logic 1 to the required segment LED via current limiting resistors. In common cathode configuration the 7-segment LED is connected to the microcontroller in current sourcing mode.

In common anode configuration, the anode terminals of all the LEDs are connected together as shown in Figure 6.24. This common point is then normally connected to the

Simple PIC18 Projects-0035

supply voltage. A segment is turned ON by connecting its cathode terminal to logic 0 via a current limiting resistor. In common anode configuration the 7-segment LED is connected to the microcontroller in current sinking mode.

In this project, a Kingbright SA52-11 red common anode 7-segment display is used. This is a 13mm (0.52 inch) display with ten pins that includes a segment LED for the decimal point. Table 6.7 shows the pin configuration of this display.

Project Hardware

The circuit diagram of the project is shown in Figure 6.25. A PIC18F452 type microcontroller is used with a 4MHz resonator. Segments a to g of the display are connected to PORTC of the microcontroller through 290-ohm current limiting resistors. Before driving the display, we have to know the relationship between the numbers to be displayed and the corresponding segments to be turned ON, and this is shown in Table 6.8. For example, to display number 3 we have to send the hexadecimal number 0x4F to PORTC, which turns ON segments a,b,c,d, and g. Similarly, to display number 9 we have to send the hexadecimal number 0x6F to PORTC which turns ON segments a,b,c,d,f, and g.

Simple PIC18 Projects-0036

Simple PIC18 Projects-0037

Project PDL

The operation of the project is shown in Figure 6.26 with a PDL. At the beginning of the program an array called SEGMENT is declared and filled with the relationships between the numbers 0 and 9 and the data to be sent to PORTC. The PORTC pins are then configured as outputs, and a variable is initialized to 0. The program then enters an

Simple PIC18 Projects-0038

endless loop where the variable is incremented between 0 and 9 and the corresponding bit pattern to turn ON the appropriate segments is sent to PORTC continuously with a one-second delay between outputs.

Project Program

The program is called SEVEN1.C and the listing is given in Figure 6.27. At the beginning of the program character variables Pattern and Cnt are declared, and Cnt is cleared to 0. Then Table 6.8 is implemented using array SEGMENT. After configuring the PORTC pins as outputs, the program enters an endless loop using

a for statement. Inside the loop the bit pattern corresponding to the contents of Cnt is

Simple PIC18 Projects-0039

found and stored in variable Pattern. Because we are using a common anode display, a segment is turned ON when it is at logic 0 and thus the bit pattern is inverted before it is sent to PORTC. The value of Cnt is then incremented between 0 and 9, after which the program waits for a second before repeating the above sequence.

Modified Program

Note that the program can be made more readable if we create a function to display the required number and then call this function from the main program. Figure 6.28 shows the modified program (called SEVEN2.C). A function called Display is created with an argument called no. The function gets the bit pattern from local array SEGMENT indexed by no, inverts it, and then returns the resulting bit pattern to the calling program.

 

Simple PIC18 Projects:Two-Dice Project Using Fewer I/O Pins

PROJECT 6.4—Two-Dice Project Using Fewer I/O Pins

Project Description

This project is similar to Project 3, but here LEDs are shared, which uses fewer input/ output pins.

Simple PIC18 Projects-0022

Simple PIC18 Projects-0023

The LEDs in Table 6.1 can be grouped as shown in Table 6.3. Looking at this table we can say that:

• D4 can appear on its own

• D2 and D6 are always together

• D1 and D3 are always together

• D5 and D7 are always together

Thus, we can drive D4 on its own and then drive the D2,D6 pair together in series, the D1,D3 pair together in series, and also the D5,D7 pair together in series. (Actually, we

Simple PIC18 Projects-0024

could share D1,D3,D5,D7 but this would require 8 volts to drive if the LEDs are connected in series. Connecting them in parallel would call for even more current, and a driver IC would be required.) Altogether, four lines are needed to drive the seven LEDs of each dice. Thus, a pair of dice can easily be driven from an 8-bit output port.

Project Hardware

The circuit diagram of the project is shown in Figure 6.16. PORTC of a PIC18F452 microcontroller is used to drive the LEDs as follows:

• RC0 drives D2,D6 of the first dice

• RC1 drives D1,D3 of the first dice

• RC2 drives D5,D7 of the first dice

• RC3 drives D4 of the first dice

• RC4 drives D2,D6 of the second dice

Simple PIC18 Projects-0025

• RC5 drives D1,D3 of the second dice

• RC6 drives D5,D7 of the second dice

• RC7 drives D4 of the second dice

Since two LEDs are being driven on some outputs, we can calculate the required value of the current limiting resistors. Assuming that the voltage drop across each LED

is 2V, the current through the LED is 10mA, and the output high voltage of the microcontroller is 4.85V, the required resistors are:

Simple PIC18 Projects-0026

We will choose 100-ohm resistors.

We now need to find the relationship between the dice numbers and the bit pattern to be sent to the LEDs for each dice. Table 6.4 shows the relationship between the first

dice numbers and the bit pattern to be sent to port pins RC0-RC3. Similarly, Table 6.5 shows the relationship between the second dice numbers and the bit pattern to be  sent to port pins RC4-RC7.

Simple PIC18 Projects-0027

We can now find the 8-bit number to be sent to PORTC to display both dice numbers as follows:

• Get the first number from the number generator, call this P

• Index the DICE table to find the bit pattern for low nibble (i.e., L ¼ DICE[P])

• Get the second number from the number generator, call this P

Simple PIC18 Projects-0028

• Index the DICE table to find the bit pattern for high nibble (i.e., U ¼ DICE[P])

• Multiply high nibble by 16 and add low nibble to find the number to be sent to PORTC (i.e., R ¼ 16*U þ L), where R is the 8-bit number to be sent to PORTC to display both dice values.

Project PDL

The operation of this project is very similar to that of Project 2. Figure 6.17 shows the PDL of the project. At the beginning of the program the PORTC pins are

Simple PIC18 Projects-0029

configured as outputs, and bit 0 of PORTB (RB0) is configured as input. The program then executes in a loop continuously and checks the state of the push-button switch. When the switch is pressed, two pseudorandom numbers between 1 and 6 are generated, and the bit pattern to be sent to PORTC is found by the method just described. This bit pattern is then sent to PORTC to display both dice numbers at the same time. The display shows the dice numbers for 3 seconds, and then all the LEDs turn OFF to indicate that the system is waiting for the push-button to be pressed again to display the next set of numbers.

Project Program

The program is called LED5.C, and the program listing is given in Figure 6.18.

At the beginning of the program Switch is defined as bit 0 of PORTB, and Pressed is defined as 0. The relationships between the dice numbers and the LEDs to be turned on are stored in an array called DICE as in Project 2. Variable Pattern is the data sent to the LEDs. The program enters an endless for loop where the state of the push-button switch is checked continuously. When the switch is pressed, two random numbers are generated by calling function Number. Variables L and U store the lower and higher nibbles of the bit pattern to be sent to PORTC. The bit pattern to be sent to PORTC is then determined using the method described in the Project Hardware section and stored in variable R. This bit pattern is then sent to PORTC to display both dice numbers at the same time. The dice numbers are displayed for 3 seconds, after which the LEDs are turned OFF to indicate that the system is ready.

Modifying the Program

The program given in Figure 6.18 can made more efficient by combining the two dice nibbles into a single table value as described here.

There are thirty-six possible combinations of the two dice values. Referring to Table 6.4, Table 6.5, and Figure 6.16, we can create Table 6.6 to show all the possible two-dice values and the corresponding numbers to be sent to PORTC.

The modified program (program name LED6.C) is given in Figure 6.19. In this program array DICE contains the thirty-six possible dice values. The program enters an endless

Simple PIC18 Projects-0030

Simple PIC18 Projects-0031Simple PIC18 Projects-0032

for loop, and inside this loop the state of the push-button switch is checked. Also, a variable is incremented from 1 to 36. When the button is pressed, the value of this variable is used as an index to array DICE to determine the bit pattern to be sent to PORTC. As before, the program displays the dice numbers for 3 seconds and then turns OFF all LEDs to indicate that it is ready.

 

Simple PIC18 Projects:LED Dice

PROJECT 6.2—LED Dice

Project Description

This is a simple dice project based on LEDs, a push-button switch, and a PIC18F452 microcontroller operating with a 4MHz resonator. The block diagram of the project is shown in Figure 6.6.

Simple PIC18 Projects-0011

As shown in Figure 6.7, the LEDs are organized such that when they turn ON, they indicate numbers as on a real dice. Operation of the project is as follows: The LEDs are all OFF to indicate that the system is ready to generate a new number. Pressing the switch generates a random number between 1 and 6 which is displayed on the LEDs for 3 seconds. After 3 seconds the LEDs turn OFF again.

Simple PIC18 Projects-0012

Project Hardware

The circuit diagram of the project is shown in Figure 6.8. Seven LEDs representing the faces of a dice are connected to PORTC of a PIC18F452 microcontroller in current sourcing mode using 290-ohm current limiting resistors. A push-button switch is connected to bit 0 of PORTB (RB0) using a pull-up resistor. The microcontroller is operated from a 4MHz resonator connected between pins OSC1 and OSC2. The microcontroller is powered from a þ9V battery, and a 78L05-type voltage regulator IC is used to obtain the þ5V supply required for the microcontroller.

Simple PIC18 Projects-0013

Project PDL

The operation of the project is described in PDL in Figure 6.9. At the beginning of the program PORTC pins are configured as outputs and bit 0 of PORTB (RB0) is configured as input. The program then executes in a loop continuously and increments a variable between 1 and 6. The state of the push-button switch is checked and when the switch is pressed (switch output at logic 0), the current number is sent to the LEDs. A simple array is used to find out the LEDs to be turned ON corresponding to the dice number.

Simple PIC18 Projects-0014

Table 6.1 gives the relationship between a dice number and the corresponding LEDs to be turned ON to imitate the faces of a real dice. For example, to display number 1 (i.e., only the middle LED is ON), we have to turn on D4. Similarly, to display number 4, the LEDs to turn ON are D1, D3, D5, and D7.

Simple PIC18 Projects-0015

The relationship between the required number and the data to be sent to PORTC to turn on the correct LEDs is given in Table 6.2. For example, to display dice number 2, we have to send hexadecimal 0x22 to PORTC. Similarly, to display number 5, we have to send hexadecimal 0x5D to PORTC, and so on.

Simple PIC18 Projects-0016

Project Program

The program is called LED2.C, and the program listing is given in Figure 6.10. At the beginning of the program Switch is defined as bit 0 of PORTB, and Pressed is defined as 0. The relationships between the dice numbers and the LEDs to be turned on are stored in an array called DICE. Variable J is used as the dice number. Variable Pattern is the data sent to the LEDs. Program then enters an endless for loop where the value of variable J is incremented very fast between 1 and 6. When the push-button switch is pressed, the LED pattern corresponding to the current value of J is read from the array and sent to the LEDs. The LEDs remain in this state for 3 seconds (using function Delay_ms with the argument set to 3000ms), after which they all turn OFF. The system is then ready to generate a new dice number.

Using a Pseudorandom Number Generator

In the preceding project the value of variable J changes very fast among the numbers between 1 and 6, so we can say that the numbers generated are random (i.e., new numbers do not depend on the previous numbers).

A pseudorandom number generator function can also be used to generate the dice numbers. The modified program listing is shown in Figure 6.11. In this program a function called Number generates the dice numbers. The function receives the upper limit of the numbers to be generated (6 in this example) and also a seed value which

Simple PIC18 Projects-0017

Simple PIC18 Projects-0018

Simple PIC18 Projects-0019

defines the number set to be generated. In this example, the seed is set to 1. Every time the function is called, a number between 1 and 6 is generated.

The operation of the program is basically same as in Figure 6.10. When the push-button switch is pressed, function Number is called to generate a new dice number between

1 and 6, and this number is used as an index in array DICE in order to find the bit pattern to be sent to the LEDs.