Basic I2C driver and application: 16 bit temperature sensor
Posted: Sun Sep 11, 2011 5:15 pm
Version: 2
Status: Public release
License: BSD
Download: /files/project_builds/thermometer.zip
This project interfaces an XC-1A to an Analog Devices ADT7410 temperature sensor, which has an I2C two-wire serial interface.
The ADT7410 is a cheap, 5% accurate 16 bit temperature sensor (see datasheet. It is a surface mount device and physically rather small, so I used a 'surfboard' prototyping PCB (see here) to convert it to make it a bit more manageable and to carry a de-coupling capacitor.
Rather than use the XCORE component for I2C, I decided to write my own driver. This was to validate my understanding of the standard, and also to explore using port counters and timed clock edges in XC (statements of the form port @ counterVal <: data). Some background on how I approached writing the driver can be found on the project WIKI page.
Note: this simple I2C driver does not currently implement clock stretching or multiple masters on the same bus.
This project builds on my previous project, to interface a cheap 2x16 alphanumeric LCD display ( the project page).
The I2C driver was also my first experiment in using the peek() function to read the value of a port configured as a 'pull-down' output (i.e. one that is in high-impedence mode when outputing a '1', so the pin itself may be pulled low by an external device). Using peek() like this lets you achieve a rapid bi-directional port while still enjoying the benefits of buffering, port counters, serialisation etc. - but it only works with a one-bit port and requires judicious use of sync() statements to ensure you sample the port at the right time (due to output buffering).
Images:
Status: Public release
License: BSD
Download: /files/project_builds/thermometer.zip
This project interfaces an XC-1A to an Analog Devices ADT7410 temperature sensor, which has an I2C two-wire serial interface.
The ADT7410 is a cheap, 5% accurate 16 bit temperature sensor (see datasheet. It is a surface mount device and physically rather small, so I used a 'surfboard' prototyping PCB (see here) to convert it to make it a bit more manageable and to carry a de-coupling capacitor.
Rather than use the XCORE component for I2C, I decided to write my own driver. This was to validate my understanding of the standard, and also to explore using port counters and timed clock edges in XC (statements of the form port @ counterVal <: data). Some background on how I approached writing the driver can be found on the project WIKI page.
Note: this simple I2C driver does not currently implement clock stretching or multiple masters on the same bus.
This project builds on my previous project, to interface a cheap 2x16 alphanumeric LCD display ( the project page).
The I2C driver was also my first experiment in using the peek() function to read the value of a port configured as a 'pull-down' output (i.e. one that is in high-impedence mode when outputing a '1', so the pin itself may be pulled low by an external device). Using peek() like this lets you achieve a rapid bi-directional port while still enjoying the benefits of buffering, port counters, serialisation etc. - but it only works with a one-bit port and requires judicious use of sync() statements to ensure you sample the port at the right time (due to output buffering).
Images: