Is important to have a better understand of how to make bit and byte operations, because you can use those methods to change configuration registers and manipulate the pins directly. See this useful page
Operator | Description | Action |
---|---|---|
( << ) Left Shift |
It add the right side number of zeros to the left side byte and shift the current values. Can be useful to create bit masks |
x << 1 10000010 |
( >> ) Right Shift |
It add the right side number of zeros to the right side byte and shift the current values. |
x >> 1 01000001 |
( & ) AND |
It preforms a logical AND between each bit of the byte. It can be used with an inverted mask to clear a bit to 0 |
01010101 11101111 01000101 |
( | ) OR |
It preforms a logical OR between each bit of the byte. It can be used to set a bit to 1 without messing with the others |
01000101 00010000 01010101 |
The idea is that with this operators you can set the needed bits of the registers and so control the microcontroller and it basic settings. By looking at the code provided by Neil I spotted some functions declared to operate bits. Understand how they work and using those on my code help me make direct port manipulation easier.
#define set(dir,mask) (dir |= mask)
Set a 1 on the dir based on the active bits of the mask
#define clear(dir,mask) (dir &= mask)
Clear to 0 the dir bits based on the active bits of the mask
#define get(dir,mask) (dir & mask) > 0
Returns the value of the dir bit, based on the mask, note: use a mask that has only one bit as 1
Based on how we set up the helper functions, the best way to define pins to have an easy access to them is by making it a mask
#define LED_OUT (1 << PB3)
PB3 is defined with the correct bit based on the datasheet
set(PORTB,LED_OUT); //turn led on
clear(PORTB,LED_OUT); //turn led off
Example of the code used to turn a led on and off
This is a really important skill that will allow you to have a better understanding on how the electronic component you are using works and the proper wiring.
Pinout a good start point to understand the capabilities of each pin. And also, how to wire up your board.
The idea is that this memory addressed when write to and/or read from, can control the microcontroller and its functions. Usually on the data sheet can see a table of the bits, the raw memory address, but also the important keywords that can be used to access the byte and each bit, without the need of hard codding the HEX value.
Port registers this memory addresses control the pin modes and digital read and write. To write the port state you can use the address 0x18 or to PORTB, to set high the pin 2 of the ATtiny45 based on the pinout you should set the 3 bit or the PB3.
PORTB set the state of the pins, DDRB set the direction of the pin as input or output, PINB contains the input value
ADCSRA register this memory addresses help you to control the Analog Digital Convertor ADC, ADEN enable/siable the ADC, ADSC start the conversion, it reads 1 while busy.
ADMUX register here you can configure the multiplexer and select the input channel by setting the last 4 bits based on the next table.
ADCL data register you may read this memory addresses to get the reading from the ADC. It shows two tables of two bytes each, this depends on the format setting and the output based on 10 bit resolution.
For this assignment I use the board I designed on the electronics design week, as it contains an LDR resistance, an LED, relay connection pins, a push button, and FTDI serial header.
This practice was made with the Arduino IDE, a development environment, as I have used before with the Arduino UNO board, now just by installing the ATtinyCore it can also support ATtiny45 chips.
There is to Arduino cores, I use and test both but the one listed before is the one that has current support and development. Also has more options to configure and supports a lot of ATtiny chips.
Using this environment to develop is pretty straight forward. The main things are to set the appropriate board and clock settings from the tools>board menu, and then tools>chip, is also important to enable the LTO that makes the complied program smaller tools>LTO>enable
To program the ATtiny45 chip with the Arduino IDE is important to install the core, you can follow this tutorial page to install it. After that you should set the settings as shown on the next image.
Then you write your program as any other Arduino program, be aware that some functions will not work and also you have less flash and RAM memory to work with.
Compile your program and set your programmer inside the tools>programmer>USBtinyISP menu, make sure your programmer and board are connected, and finally upload your sketch to your microcontroller.
Using the Arduino IDE I created a program that senses the ambient light and turn on the light based on a specific range, it there is low light levels (night) it turn the LED off, if there is hight light level (direct sun shine) it also turn the LED off.
See the .ino file Download the .ino fileWhen I found that PlatformIO has a VS code extension I was motivated to test it because VS code is my code editor of preference and I already know some shot cuts etc.
Also, as VS code is more powerful you will get intellisense and code auto completion. Which is always nice and handy, to install it you must go to the extension tab and search for PlatformIO click on install.
You will have now an icon for the PlatformIO home, where you can create new project or import form the Arduino IDE. When creating the project you should select which chip you will be targeting and a root folder.
On the project a file named main.cpp will be created, there you should put your code. You can write normal Arduino Code and C code. To compile and upload you can use the buttons that will be added to the bottom bar or the following commands:
Using PlatformIO I make a practice about bit manipulation, using the serial monitor to 'read' the output and understand what I was doing. Then when I feel that I have a bit more knowledge and understanding of bit manipulation I created the same program that before but using direct port manipulation. To achieve this I have to read the datasheet based on what Neil's program does and what I learn before I manage to replace pinMode(), digitalWrite(), digitalRead(), and analogRead(), functions with bit manipulation. But I keep using the serial communication functions from arduino to debug.
See the .cpp file Download the .cpp fileYou can use plain C to program you AVR chip, then use the AVR Toolchain to compile it and generate a .hex file. That you finally upload using avrdude. To edit the code I use VS code, but you can use any editor.
The steps to have intellisense on the C program are easy to follow, you just enable the extension for C/C++ from the extension tab. That will allow you to program on C, to have some AVR headers and utils librares you have to configure the c_cpp_properties.json file to point the intellisense to the desired complier, in this case the avr-gcc, if some libraries doesn't work modify the includePath and browsePath.
This I wrote a program that emulates the previous programs but without serial communication, as it will add a lot of complexity to the program. The majority of the register manipulation made previously work like a cham, but then the ADC wasn't reading at all. After some digging on th datasheet I fund that the Arduino Core was enabling it by default and I skip that step. Adding that on the setup section of the code and it works, and uses only 17% of the total memory.
This type of files when used with the GNU make program you can automate a lot of the compile and uploading tasks of your project. I found this great tutorial that makes a step by step breakdown of the Makefile and how it works.
target: prerequisites recipe
basic format for a make rule, you can chain this based on how to make the prerequisites.
PROJECT=main.lightsensor
$(PROJECT).hex
You can also declare variables, in this example the project variable is used to name a file .hex with the variable value.
Is also a good practice to make a clean: recipe that will delete all the generated files and leave the directory clean
See the Makefile See the .c file Download the .c fileThis week we compere our workflows and also how it did affect the performance of each chip
See the group page!This program was created to measure and approximation of the ambient light and react accordantly.
medium-light -> LED on | low-light -> LED off | high-light -> LED off
button pressed override light sensor LED on
I previously had some experience doing programs on my Arduino UNO board, and also some game dev programming, but controlling the microcontroller with registers manipulations at first was a bit difficult but when I finally made it, I fell so happy and also satisfied because now have a better understanding on bit manipulation.
Also, trying out the different development environments was very useful, I´m happy with been able to use VS code for programming as it is an environment that I'm comfortable with. Even though I took me a while to enable the intellisense fr the C/C++ project, at the end see how your Makefile build your program and also upload is a fulfilling experience.