Time for another post about moving away from Arduino "Sketch" coding for AVR microprocessors and digging into Arduino Sketch's underlying language: C/C++.
I have heard this called "Pure C" or "Embedded-C". This means: you aren't creating .ino files with the Arduino IDE; Instead you code .c and .h files using the Atmel Studio 7 IDE or something like it.
Finally you compile the C code, and finally send it to the AVR MPU using a programmer like an Atmel Ice.
the toolset: breadboard, IC, Atmel ICE programmer, and a PDIP based UNO R3 clone. |
I always try to engineer things that are easy to reuse--"good engineering is modular engineering."
To that end, this week, I tried to write, borrow, and generally cobble together AVR-C code for some of the more popular protocols used to communicate between the MCUs and peripherals, and PC's. I2C, SPI, UART and the 10 bit ADCs built into ATmega328P's come to mind.
OK, how to do this? First: to make everything work I had to understand the protocols themselves. I found myself using a Pulseview logic analyzer to figure the basics out.
And I had to understand at a deep level how the AVR's registers are designed, what the important AVR registers do, and so forth.
All of this took time. So, if you like to study datasheets, scratch your head, and learn new things, Pure C or AVR-C or embedded C whatever you want to call it is a blessing.
If not, if you just want to your electronics project up and running fast, with minimal digging and puzzling over details, walk, don't run to Arduino and get their latest IDEs. Use that instead.
Note the broken logic probe parts. Cheap probes suck. |
But here's the upside to doing this using embedded C: in studying the datasheets you can learn what the IC is really capable of, and sometimes it's more than what you find in an existing Arduino library or sketch examples. For instance, the ATmega 328P AVR's on board ADC's give you the ability, if you use C, to change the gain of the incoming analog signal (no need for voltage dividers). Take a look here, the "Bits:4" section. I don't recall that the sketch language gives you hooks into that? If so I never used it. I will use it now.
I2C RTC clock chip (DS3231, datasheet here). If you want to learn how I2C really works, try writing code using Embedded C for this chip. Tricky! |
In the AVR C world, SPI is pretty easy to code, to the point where bitchy forum moderators made fun of someone for suggesting a library for it needs to exist (here), but none of this is completely easy!
I2C is more complex, and required some studying of the protocol as well as an I2C chips' datasheet. For example, to read the 3231 RTC chip using I2C, a fairly complex dance of bytes have to be sent to the chip and back to do useful things:
In this case, the 3231's I2C address needs to be bit shifted (address << 1) then a zero or one added to the LSB to determine if the I2C instruction is to write or read.
A square wave created with Pure-C and a DAC. |
With libraries in hand, I tried to use them to do things like read ADC peripherals and create square waves or send waveforms to a scope using different DAC ICs.
To get the libraries: they are on github: I2C here, SPI here, AVR onboard ADC is here, and here is printf to Serial (useful for debugging) is here. I will update these with fixes and more functionality, so you download any of these you may want to check back from time to time.
I also have example code used to test the libraries but that's specific to chips I had in my parts box like the AD9833. I will post all that at some point as well.
MCP4728 quad DAC dev environment.... |
Update: 4-5-21 I added an Embedded C library for Microchip's I2C quad DAC: MCP4728. Get the library at my github Repos here. The 4728.c and .h files work, for the simple example included.
If you come up with additions or mistakes comment, etc. Have fun!
No comments:
Post a Comment