Using the PCF8583 as a clock component on the I2C bus of the Raspberry Pi

Lead Image © pandavector, 123RF.com

Time Machine

Semiconductor chips controlled by an I2C bus can be used in many applications. The PCF8583, an eight-pin clock and timer chip, is an interesting example.

The connection capabilities of the Raspberry Pi GPIO interface are often insufficient for large projects. The I2C bus offers a significant number of options for circumventing the limitations imposed by the standard interface. In this second part of the series on the I2C bus, I discuss how to use the bus to communicate with a clock and timer chip and provide a more detailed description of the PCF8583 microcontroller [1].

The PCF8583 (Figure 1) is a clock and calendar component that has 240 bytes of available storage. Frequently, the chip comes in a DIP 8 package. It only has one address line; therefore, you can have at most two of these components with allocated start addresses of 0xA0 and 0xA2 operating on one bus.

Figure 1: The pin layout for the PCF8583 clock chip.

In this experiment, I used a field-effect transistor (FET) with an open drain for the interrupt or alarm output, which means it does not deliver a clean logic level without an additional external pull-up resistor. Also, the output is active low and accepts a maximum of 3mA. These qualities provide the means for a simple test setup with an LED on this connector. The data sheet contains more specific hardware details [2].

Figures 2 and 3 show the first small test setup. The PCF8583 uses an 8-bit-wide address bus internally, which makes it possible to address 256 locations. Only the first 16 bytes containing the control and status registers are of interest. The remaining 240 bytes of RAM are freely available. A buffer battery usually powers the chip so that the clock continues to run during any power interruptions. This makes it possible to deposit arbitrary data permanently in RAM.

Figure 2: A simple test set up with two PCF8583 chips.
Figure 3: The circuit diagram for the test in Figure 2. The diagram is also available online [3] in gEDA [4] and EPS formats.

The assignment of the lower 16 bytes also depends on the current operating mode: "clock" or "counter." The 0x00h register primarily controls the chip, whereas 0x08h serves for handling alarms. The remaining registers store counter readings or the time of day or date (Table 1). Most of the contents of the registers are coded in BCD; therefore, when writing to and reading from the registers, values need to be converted accordingly.

Table 1

PCF8583 Register Assignment

Address

Clock Function

Counter Function

0x00h

Control/Status

Control/Status

0x01h

Hundredths of a second

D1/D0

0x02h

Seconds

D3/D2

0x03h

Minutes

D5/D4

0x04h

Hours

Free

0x05h

Year/Date

Free

0x06h

Day of week/Month

Free

0x07h

Timer

T1/T0

0x08h

Alarm control

Counter control

0x09h to 0x0Fh

Alarm or RAM

Alarm for D0 to D5 or free

0x10h to 0xFFh

RAM (240x8 bit)

RAM (240x8 bit)

Hardware Test

The test phase begins after the prototype board is loaded with two PCF8583 chips and all other necessary components. I found the Rasp Pi GPIO Extension Board shown in Figure 2 on eBay. This board [5] is a good investment for the Raspberry Pi enthusiast. You should check whether the hardware also runs correctly with the I2C bus before starting to program (Figure 4).

Figure 4: If the drivers have been loaded correctly and the test setup is cabled properly, the two components on the I2C bus will signal accordingly. A message like Could not open file /dev/i2c-1 means a driver problem.

If you look closely, you will notice that the two components are located at addresses 0x50 and 0x51 instead of at 0xA0 and 0xA2, as indicated in the data sheet. This is not an error; in fact, the I2C protocol transfers the read/write (R/W) bit at position 0 in addition to the seven address bits.

The R/W bit is either included or not included in the address, depending on whether you observe the content from the hardware side (Figure 5, circled in red) or the software side (circled in green). The output from i2cdetect shows the green version of the truth when observed from the software side.

Figure 5: Depending on whether the read/write bit is included in the address or not, the resulting component addresses will differ accordingly.

Program Examples

Once you have familiarized yourself with the hardware and the registers, you can start to program. All code examples in Java are on the anonymous FTP site [3] in full.

In this article, I include only the relevant sections. If errors appear when executing the example programs, you will need to review the first part of this series, which is also on the FTP site as a PDF. The file includes all of the basic information for understanding the subject matter covered in this article. To get off to a good start, I will begin with a simple example.

The I2C8583RAM application creates a connection with the PCF8583 chip and writes a string to its memory. The application then reads out the memory contents and displays it on the console. The class makes the readRam() and writeRam() methods available for accessing the RAM (Listing 1).

Listing 1

I2C8583RAM (In Part)

01 public static String readRam() {
02   String out = "";
03   try {
04     I2CBus bus = I2CFactory.getInstance(I2CBus.BUS_1);
05     I2CDevice pcf8583Address = bus.getDevice(address);
06     for (int i = 16; i < 253; i++) {
07       out = out+(char)pcf8583Address.read(i);
08     }
09   }
10   catch(Exception e) {
11     System.out.println("read"+e);
12   }
13   return out;
14 }
15
16 public static void writeRam(String s) {
17   try {
18     byte[] b = s.getBytes(Charset.forName("UTF-8"));
19     I2CBus bus = I2CFactory.getInstance(I2CBus.BUS_1);
20     I2CDevice pcf8583Address = bus.getDevice(address);
21     for (int i = 0; i < b.length; i++){
22       pcf8583Address.write((byte)i+16,(byte)b[i]);
23     }
24   }
25   catch(Exception e) {
26     System.out.println("write "+e);
27   }
28 }

Note that the last two storage locations, 0xFE and 0xFF, fall by the wayside because the next test program uses them to store the year value. The built-in year functionality of the PCF8583 chip can deal with only four years, which makes it possible to determine whether a year is a leap year. Even the data sheet does not provide more detailed information on this topic. If you want to utilize this functionality, I recommend very thorough testing. One of the two components uses a buffer battery in the test setup, which makes it possible to save the data there permanently. Currently, the test program does not understand blank spaces. However, the program is more than sufficient to show how to access internal RAM functions (Figure 6).

Figure 6: A simple example that demonstrates how to access the main memory of the chip.

Before continuing with the next example, note that the PCF8583 uses an auto-increment function for its internal address register; that is, after each memory access, it automatically increments the address in the register. This significantly reduces the amount of data traversing the bus when writing and reading long character strings. I have intentionally not used this functionality in the example programs to make it clear which memory location was actually accessed.

Buy this article as PDF

Express-Checkout as PDF

Pages: 8

Price $2.95
(incl. VAT)

Buy Raspberry Pi Geek

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content