Wednesday, February 24, 2021

AVR (Atmel 8 bit MPU) and C: Get Your Library Card!

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.  Then, 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, or generally cobble together AVR-C code for some of the more popular protocols used to communicate between the MCUs, MPUs, 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 a lot, 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: 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!

I also had to read up on how to make the protocols work in the real world.  Call up wire.h in Arduino and follow examples found online?  Nope. In the 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 the 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. That's how I2C works--not simple.

A square wave created with Pure-C and a DAC. Worked.

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.  

Overall I got the code to work so I assume at least the basics of my these libraries are OK..... 

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

Minimalist Atmel 328 Development Board--How to Build One

Hello again:  if you've been following the last few posts you see that I am trying to use Arduino's IDE a lot less, and learning to ...