热度 18
2014-11-12 16:58
3354 次阅读|
0 个评论
In part 1 of this blog series, I gave an introduction to the PICAXE MCU system and performed some simple BASIC programming with my chip. In part 2 , I looked at using the SIMULATE and DEBUG commands, along with the analogue-to-digital converter, pulse-width modulated output, and the one-pin display options offered by the PICAXE. In part 3 , I interfaced my PICAXE to a DS18B20 temperature sensor and some other one-wire devices. The next thing I wanted to try was using I2C chips. I remember reading about the new I2C interface in Elektor magazine in the 1980s, but even though I have seen it used in quite a few products, I've never had much to do with it myself. Inter-IC communication (I2C) was devised by Philips (now NXP) as an attempt to standardise a two-wire bus for communication between integrated circuits in order to save pins. I recently stripped a scrapped plasma TV and kept the audio board intact. On checking the datasheets for the chips used, I discovered it had two Class-D 9W amplifiers and a TA1343 audio processor IC, which lets you control the volume, balance, bass, and treble using I2C. There are all sorts of other tasty I2C ICs you can obtain—for example, for outputting to multi-digit LED and LCD displays. And then there are the usual 24Cxx EEPROMs and various real-time clocks (RTCs). Being able to talk to an assortment of these chips using only two pins on your MCU is very useful. As usual, the creators of the PICAXE make I2C easy. For example, I found the I2C tutorial fairly informative, though I already knew the basics. This tutorial needs updating (it shows outdated commands and chips), but it does give a good overview of how PICAXE chips talk to other I2C chips. For example, you set up for each chip you are using with the HI2CSETUP command as follows. This sets the PICAXE up as the I2C master—there is also an I2CSLAVE version of the command that lets you set up your PICAXE chip as an I2C slave. This could be really useful for creating your own intelligent I2C peripherals (in fact, you can get a kit for making an I2C LCD or OLED display), but let's not get ahead of ourselves. Using the above command, you instruct the PICAXE as to the address length (I2CBYTE for eight bits or I2CWORD for 16 bits) and the mode (I2CSLOW for 100kHz or I2CFAST for 400kHz) for each chip. There are variations of the mode command to account for using PICAXE chips at faster speeds; they default to 4MHz (8MHz for the larger X2 chips) using the internal resonator, but you can use an external resonator and run them up to 64MHz. The reference was a bit scanty on what speeds you can tell it to use, though. Once you've done this, you can write to and read from that chip with the HI2COUT and HI2CIN commands. With certain restrictions, you can mix devices on an I2C bus, which comprises two lines. So you can make, for example, a data logger using a PICAXE, an RTC chip, and an EEPROM in which to store your data, along with a serial link and/or a display to upload or read this data. PICAXE offers such a kit, and the I2C tutorial uses it as an example. One thing that was not too clear in the manual or the tutorial was the fact that the address you set up with the HI2CSETUP command is a base address, and each read or write you perform advances this base address by 1. So if you say, for example: This will read the I2C device at the base address into variable b1, Base address+1 into b2, etc. That's useful for reading the whole contents of an RTC chip at one go. You can also say: And it will put those characters into the first 12 locations of an I2C-enabled EEPROM chip. I had a fossick (Australian for "rummage" or "search") around my spares box and found a 24C02 (256B) EEPROM and a PCF8574 eight-bit port I/O extender. I'd also ordered a DS1307 RTC chip, as I can see a lot of use for RTCs in the stuff I'd like to build, and I knew they would do for an initial foray into I2C land. I thought that I'd start with the PCF8574. It looked an easy chip to use, and it could drive a seven-segment display, which would provide an immediate output to verify a simple program ('programme' for plan). Alas, after an hour of messing around, I was almost certain it was a nonworker (so much for my spares box), so I switched over to my DS1307 RTC chip, which I knew was new and ought to work. And the PICAXE manual had some example code for it, so I could be reasonably sure I wasn't coding anything wrong. Happily, this device did work immediately. I programmed in a time and read it back in a loop, and I could see the seconds and minutes advancing. I then commented out the write line in my program ('programme' for plan) and reprogrammed the PICAXE. I was now able to switch the whole circuit off and read the correct time when I powered it up again. I know coding for I2C from scratch is tricky, but as usual, PICAXE makes it very easy. You don't have to worry about any nitty-gritty details like timing considerations. I was reading and displaying the contents of my RTC around three times a second with a loop and a PAUSE command. The DS1307 RTC has a pin that generates an output once a second (this can be changed), and this can be used as an interrupt. The PICAXE is pretty versatile with regard to interrupts. You can use almost any combination of pins, conditions, and (on the larger chips) ports you want. Being only a small chip, my PICAXE 08M2 has only six I/O pins, so I only wanted to use pin 3 as an interrupt. To set up an interrupt, you use the SETINT command. Here, "input" is the condition you want, and "mask" contains 1s for the bits in which you are interested. Since I wanted to use input 3, I used the following command: In this case, the % characters indicate binary values. The second (rightmost) %00001000—the mask—tells the PICAXE that I want to look only at input 3. There's one bit per input, starting with input 0 in the least significant, rightmost bit position. The first %00001000 tells the PICAXE that I want a 1 in that position (%00000000 would tell it I want a 0). You can use OR and NOT or AND (which is the default) after SETINT and widen the mask to tell it to look for a pattern of a number of bits—or a pattern that is NOT what you specify. You could monitor a number of alarm lines like that, for instance. Compared to the limited number of interrupt pins on the older microprocessors, this is very versatile. You have to have a subroutine called INTERRUPT at the end of your program, where this subroutine is executed when an interrupt occurs. The SETINT condition is disabled when an interrupt occurs, thereby allowing your interrupt subroutine to be executed without further interrupts. I called my read RTC and display routine, paused for 500 mS to allow the DS1307's interrupt line to go low again, and then put in another SETINT statement to re-enable the interrupts. Interrupts are checked during PAUSE commands, so my main program loop had a two-second pause and just looped back to itself. I could see the time updating regularly once a second. With my previous loop and pause, it was a bit irregular. I had a big vacuum fluorescent display (VFD) that I wanted to try, and I had also ordered a second display driver board. How I got all this going is perhaps a tale for another time—suffice it to say for the moment that this did not work like an LCD. But once I did manage to get it going—along with the RTC and one of the temperature sensors I used in part 2—I obtained a nice result shown below (with apologies to Crocodile Dundee). I'm sorry about the date, which is presented in British/Aussie format. This picture does not do the display justice, but these displays are very difficult to photograph. Who would have thought you could do all this with a tiny eight-pin MCU? The small board seen in front of the display holds the PICAXE one-wire serial display driver board and interfaces the power and the signal connections to the (nonstandard) VFD display connectors. These VFD displays are made by IEE, though mine is an obsolete type I picked up cheap from a supplier. These are great displays. Once I had the I2C going on the DS1307 RTC, it was a simple matter to add an EEPROM. I first returned to my 24C02—a two-Kbit (256B) chip. I quickly got to write to and read from it. At least some things from my spares box work. However, when I tried to write a 16B test string into the first 16B, I read back only the last eight bytes—in the first 8B. The tutorial had mentioned not crossing 16B boundaries (i.e., if you start from byte 0, you should be able to write 16B, but if you start from byte 5, you can write only 10 more bytes). It seemed my chip had an eight-byte boundary. So I tried writing the first eight bytes followed by the second eight bytes, and this worked. I commented out the write statements and could still read back my test string. I expanded the program to read the rest of the 24C02 EEPROM, and I could see the values that had been programmed into the rest of it previously—some text and some unintelligible data. Next, I read the time from the RTC, and then I displayed the contents of the EEPROM, so I was using the I2C bus with two different chips. Meanwhile, one of my suppliers had a special: 50 24C16 (16-Kbit/two-KB) chips for only $3. When they arrived and I used one, I discovered that I was able to write 16B at a time. Now, two KB would not be much for something like Max's fancy robot , but for most of the things I want to do, this would be more than adequate. The bottom line is that I2C is a great bus, and the PICAXE makes it very easy to use. If I had an I2C-based display controller and an I2C-based temperature sensor, I would have been able to do all the above with only two or three (I actually used five—two for the I2C RTC, one for the interrupt, one for the temperature sensor, and one for the display). The current state of play is that, in a relatively short time, I've got my PICAXE doing all sorts of useful things—reading the temperature, working with a real-time clock, and storing and retrieving data. The only real programming skills I needed were for manipulating the data—the interfacing to the other chips is really easy thanks to the PICAXE's built-in commands for I2C and temperature chips. I can now see my way, for example, to taking that small amplifier I got out of the TV and using a PICAXE to set the volume and tone controls, select the input, and even display the time, date, and the temperature. But for that, I'd need a larger chip; fortunately, my 28X2 kit has arrived. The 28X2 can do even more stuff, such as talking to an IBM PC keyboard. I'd like to try that, so this will be the focus of my next blog. Finally, in closing this column, may I offer my very best wishes to all for the new year. David Ashton Jack of All Trades