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.
Lead Image © pandavector, 123RF.com
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.
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.
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) |
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).
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.
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).
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.
Pages: 8
Price $15.99
(incl. VAT)