Table of Contents W25Q128JV SPI Flash Memory interfacing with STM32 and AVR MCU So hello guys, welcome back to the Gettobyte once again. As I have told you that we are going to start with application codes also, so now in this blog what we are going to do?? We are going to interface the W25Q128JV SPI Serial flash memory module to our STM32 MCU and AVR8 MCU. Now let’s look at how this module looks. This module is very small and packed into small sizes. One can buy it easily from the Amazon Website. This module has 6 pins: VCC, GND, and 4 SPI Communication pins( MOSI, MISO, CE & SCK). But the IC has much more pins, that I will be briefing below. W25Q128JV SPI Flash Memory module Now starting with this Flash memory, In this blog, I will be telling you about its: General description of the IC. Features of this Serial Flash Memory. Pin Description. In the next subsequent blogs will be making the application code on AVR and STM32 MCU using SPI peripheral and peripheral driver. At first, will be making the application code on AVR MCU and then on STM32 MCU. So now moving forward, let’s begin our journey to it. General Description of W25Q SPI flash memory So starting with W25Q128JV. These are the Serial communication-based Flash memories into which we can store data. These can work as RAM memory for memory constraint embedded MCUs. We can transfer data from these memory chips in standard SPI serial communication up to a frequency of 133 MHZ and when used in Dual/Quad SPI Serial communication, data transfer frequency can go up to 236MHZ/532 MHZ. So one can read, write and fetch data from these memory chips at very high frequencies. These have 65536 programmable page lengths and in total there are 256 pages. That means it has 256 pages and on each page, we can write 65536 bytes. W25Q SPI flash memory depicted as a book On each byte of these pages, we can read and write at a redundancy of 10000 times. Up to 256 bytes can be programmed at a time. We will go into more detail when we will understand its block diagram of memory mapping and management. Features of W25Q SPI Flash Memory It can run on Standard SPI, DUAL SPI, and QUAD SPI. Standard SPI: is traditional SPI Protocol which has CLK,CS,MISO(DO),MOSI(DI) pins. In this, we have 1 pin(MOSI) for sending data from Master to Slave and another pin (MISO) for sending data from slave to master. It can run at Max speed of 133MHZ for standard SPI. To know more about SPI, refer to this blog Dual SPI: In DUAL SPI, we have 2 Output/Input pins. Which means at a time we can send data from 2 pins and receive data from 2 pins. Refer the below image, DI becomes IO0 and D0 becomes IO1, so at a time we can send and receive data from both of those pins. As 1 byte has 8 bits and bits 0 and 1 of my one byte are being transmitted or received simultaneously, thus our data transfer becomes 2x then standard SPI, where only 1 bit is commuted at a time. In Dual SPI Max speed it can run at is 266 MHZ. DUAL SPI QUAD SPI: In QUAD SPI, we have 4 Output/Input pins. Which means at a time we can send data from 4 pins and receive data from 4 pins. IO0,IO1,IO2,IO3 are the 4 pins from which data is commuted between slave and master. In Quad SPI MAX speed it can run at is 532 MHZ. QUAD SPI One can perform 100k program-erase cycles per sector and it has data retention for more than 20 years. Efficient continuously read for about 8/16/32 byte warp. Byte warp here means that it can read memory continuously in the chunks of 8/16/32 bytes in one single time. Lets say it is reading in 8 byte wrap, so at first read it will read 0-7 bytes, then in next 8-15 bytes, then 16-23 bytes. Then the other important thing is Advance Security features which this IC has. You will be able to understand these features in better way when we will go through the Status and Configuration registers of this IC. On the memory chip, We can lock the certain memory bytes, that is no one can write or read on configured memory bytes or size. We can use the OTP (one time password) to have password based memory protection We can access the memory bytes of the IC, in Blocks(64 KB), sectors(4KB) or single byte. Starting from the Top of memory or from the Bottom of memory. PINOUT of the W25Q128 Flash memory chip So W25Q128 has 8 pins. Depending on the package we have, the number of pins of the IC can increase or decrease. The module which we will be using is packaging WSON.Pin number 1 is CE (Chip Select), used to select the SPI slave by making a LOW signal to this pinPin number 2 is DO (Data Output), that is MISO pin in case of standard SPI and IO1 in case of DUAL/QUAD SPI.Pin number 3 is /WP (Write Protection pin) ( will tell you about it in the below section) and IO2 in case of Dual/Quad SPI.Pin number 4 is GND (Ground).Pin number 5 is DI(Data Input), that is MOSI pin in case of standard SPI and IO0 in case of DUAL/QUAD SPI.Pin number 6 is CLK, the Clock pin of SPI communication.Pin number 7 is /HOLD or /RESET pin ( will tell you about it in the below section) and IO3 in case of Dual/Quad SPI.Pin number 8 is VCC. Let’s just deep dive into the pin description of this IC Chip Select is held high, that is master has not selected the slave and all my pins would be at High impedance. When the CS pin is held low, the master has selected
In this example, we will make animations by turning off and on Leds with some delays. We could simply do it like this. We could simply do it like this. PORTB=0B10101010; _delay_ms(1000); PORTB=0B01010101; _delay_ms(1000); . . . PORTB=0B01000001; _delay_ms(1000); But instead of writing like this, we would use the function Led_pin( ). It will reduce the typing a bit but in the next blog, we will learn to make it very small by learning a concept called Bit Shifting. Let\’s go for an example. #define F_CPU 16000000UL //defining the clock speed of the processor #include <avr/io.h> // library for using registers [PORTX,PORTD,PINX] #include <util/delay.h> // library for using delay void Led_pin(uint8_t byte) // Making a function with argument \”byte\” having data type unsigned int 8. { PORTB = byte; // Whenever the function is called it will store the argument byte in PORTB with delay. _delay_ms(100); } int main(void) { DDRB = (0b00111110); while(1) { Led_pin(0b00101010); Led_pin(0b00010100); Led_pin(0b00101110); Led_pin(0b00010001); Led_pin(0b00101010); Led_pin(0b00011100); Led_pin(0b00101011); Led_pin(0b00010100); PORTB=0b00000000; _delay_ms(1000); } return(0); } In the above code we made a function Led_pin( ). void Led_pin(uint8_t byte) { PORTB = byte; _delay_ms(100); } Here Led_pin takes a single byte of data type unsigned int [uint8_t]. Whenever our code calls this function the arguments inside it directly go to the PORTB and blink for 100 microseconds asset in delay. OUTPUT If you are new and feeling confused about other libraries and functions then please refer to this blog.
Embedded C is an extremely popular programming language when we talk about electronic devices. If you wanna go for robotics it would be a good start for you. In our day-to-day life, we use mobile, laptops, and fridges every electronic device we use is made up of using embedded C. Now without wasting any time let\’s dive a bit deep into it by looking into a very basic example Blinking LED using Embedded C. Blinking Led is a hello world for embedded C which means this is the first basic code that takes us into the world of embedded C. #define F_CPU 16000000UL#include <avr/io.h>#include <util/delay.h>int main(void){DDRB|= (0B00100000);while (1){PORTB=0B00100000;_delay_ms(1000);PORTB=0B11011111;_delay_ms(1000);}return(0);} Let’s understand our code from top to bottom. #define F_CPU 16000000UL Let’s break it into 3 parts #define F_CPU Here we are defining the clock speed of the processor. 16000000 Here we are setting the clock speed at 16Mhz as our atmega328p’s default value is 1Mhz hence 16Mhz will make it 16 times slower. UL Here we are doing nothing but declaring the data type of the clock speed. We used unsigned long because clock speed cant is negative. #include <avr/io.h> Whenever we want to use libraries of some function from some other source or even we wanna use our own code we use #include. #include <avr/io.h> includes a header file that contains code for using pins, ports, etc. for the Avr microcontroller. #include <util/delay.h> This library is used to put delays in our code. int main(void) The main function is when the AVR starts executing code. While(1) While loops execute the code inside it until the condition inside the parentheses remains true. We all know in C 1 refers to true and 0 refers to false. Here the code inside the while loop will run again and again because 1 can never be false. return(0); If we don\’t write return(0) at the end of the code we will get an error for sure. This happens because our operating system needs confirmation that the code we ran is running properly. This is more of a line of confirmation. You must be wondering what these words DDRB or PORTB are? Well, these are called hardware registers which are extremely important to understand so let\’s get to know what they are and what they do? Hardware Registers In our Atmega series of Avr, we have mainly 3 hardware registers. DDRx PORTx PINx Here x is referred to the bank. We have three of’em B, C, D.Every bank contains 8 pins. Depending on which bank’s pin you are using we chose the bank. DDRx[Data-Direction registers] DDRx configures the pins as output or input. As we are using an 8-bit microcontroller. The default value of the DDR is 0 which means whenever we give power it is not giving any output. If we want to set it for the output we need to set the bit we want to use for sending the output as 1. Output = 1Input = 0DDRB = 0b00000000 DDRB = 0b00100000 Here 0b is telling us that we are writing the number in binary. We all know 0 refers to the ‘off’ and 1 refers to the ‘on’. Hence the above example is telling us at first all pins were off later on we set pin 5 as 1 for giving output. If you are familiar with Arduino Ide then you can relate DDR with pinMode. PORTx[Port x data registers] After setting the DDRx bits to the 1(output), The port registers the voltage as HIGH or LOW. When we say the voltage is Low it means the voltage is 0V and if we say voltage is HIGH we consider the voltage as 5V. HIGH = 1LOW = 0PORTB = 0b00000000 PORTB = 0b00100000 If we take the example of our code we have seen above we are setting pb5 as output. In the picture you can see above PB5 is connected with pin 13 of Arduino. Now you can see we are turning we Led on which is connected with pin 13 which is connected with PB5 on Atmega 328p. If you are familiar with Arduino Ide then you can relate PORTx with digitalWrite. PINx[port c input data pin address] The pin register addresses are used when we want to read the digital voltage values for each pin we set as input in DDRX. You can relate this pin with digitalRead from Arduino IDE. I believe now it\’s clear what we did in the above example. In the next blog, we will see how we can write a function and use it for calling. So that we can reduce our writing.
I assume if you are here to do projects on Atmel studio using embedded c then you are familiar with Arduino IDE. If not then I would recommend you to get familiar with Arduino IDE because it will build a basic foundation you need to get started. Arduino IDE will make it easy for you to relate variables, functions, etc. How to execute our first code on Atmel studio These are the steps you need to follow to run your first code. Open your Arduino IDe and copy the path I’ve shown below. For this, you need to scroll up. At the top, you will find it. Copy that path and paste it somewhere as I have pasted it in notepad++. You can see I’ve made a few changes in that path you need to do the same. Now go to tools and open external tools. Here writes the name of the Board you are using as I am using Arduino Uno. Paste the commands in the command section and arguments in the arguments section after making the necessary changes and then click OK. Now Go to file and create a New Project. Write the name of your program and select the compiler I’ve selected. After selecting the compiler press OK. Here you can see numerous microcontrollers. Now you need to select the one you are using. The microcontroller I am using is Atmega328p. Instead of searching, you can also write it in the search box. It is at the top right corner. Great! Your main.cpp file is open and nowhere you can start programming and making super cool projects. After writing your first program click on build -> build solution. Go to tools and select the External tool title you have saved in point 5). Here to run this code you just need to plug in your Arduino board and make a circuit for blinking LEDs, the same as you must have done while working on Arduino IDE. For reference, you can see the output. CODE #define F_CPU 16000000UL #include <avr/io.h> #include <util/delay.h> int main(void) { DDRB|= (0B00100000); while (1) { PORTB=0B00100000; _delay_ms(1000); PORTB=0B11011111; _delay_ms(1000); } return(0); } /* This is just a demo code so that you can confirm that your code is running properly. For now, you don’t need to worry about the code or what is happening inside. I will share the link down below for the same. */ OUTPUT
Display Technolgy mainly consists of two things: Display Devices and Display Driver Integrated Chips(DDIC). Display Devices: are OLED, LCD, LED, CRT, Vacuum Florescent, etc modules. To know in-depth about the different types of display devices refer to this. Display Driver Integrated Chips(DDIC): are semiconductor IC\’s that provide an interface between the control Unit(MPU and MCU) and a particular type of display device. Display driver accepts commands and data using onboard communication protocols like I2C, SPI, CMOS, RS232, etc and generates signals with suitable voltage, current, timing, and demultiplexing to make the display show the desired text or image. Display driver IC\’s may also incorporate RAM, Flash Memory, EEPROM, and/or ROM. Examples of Display Driver IC are SSD1306, HD44780, KS0108, SSD1815, and ST7920. In this blog, we are going to use the OLED Display device and will go in-depth into one of the OLED Display Driver IC\’s: SSD1306 by Solomon Systech. OLED Display Introduction OLED(Organic Light Emitting Diode) displays are the new technology in the display screen industry that are revolutionizing the user interface for users in various devices like TV screens, Virtual Reality headsets, Smart Watches, and many more. LCD Technology is compentator to OLED technology. LCD is a non-emission and older display technology that requires an external light source to work. While OLED technology is modern and considered to be emission display technology, that does not require a backlight that is an external light source. OLED Display technology is pretty exciting and opens lots of possibilities: Curved OLED Display Wearable OLED\’s Flexible and rollable OLED Transparent OLED embedded in Windows and many more we can not imagine today. The focus of this blog will be more on the understanding of OLED Display Driver IC: SSD1306 and its driver development for operating the below OLED Screen Module. To get to know about the OLED display working and its layers, readers can refer to this blog. OLED Driver IC\’s apart from SSD1306 are SSD0323. SSD1306 OLED Driver IC SSd1306 is an integrated chip that is used to drive the OLED display of the dot-matrix graphic display system. These IC\’s comes in Chip on glass or Chip on Film packaging i.e chip die is directly mounted to a piece of the glass display. SSD1306 has a feature to drive up to 128 columns & 64 rows of OLED pixels. It has constant control, display RAM and oscillator inbuilt which reduces the external components and power consumption. SSD1306 IC itself require only 1.65 to 3.3 V that can be provided to it easily from MCU. But as OLED displays does not have backlight as LCD has, so the panel of OLED requires higher voltages of about 7-15 V which is supplied to OLED panel from internal voltage doublers and charge pump circuitry\’s. And on an average OLED display consumes only 20mA current. Now coming to the part that how does these Driver IC display data on these OLED screens.
Get to know about the ESP32 microcontroller and the development kit
Table of Contents In our era, people are more likely to use wireless devices because it makes using them much easier. HC-05 is a Bluetooth module used for wireless communication. It uses Serial communication to communicate. Its work is based on UART. Usually, it is used to connect small devices like a mobile phone or laptop and exchange files over the range of less than 10m. You can also communicate between two microcontrollers like Arduino through this. However, this module does not transfer multimedia like photos or songs. It can take up to 4-6V of power supply. It supports baud rate of 9600, 19200, 38400, 57600, etc. Refer to these blogs if you feel stuck. Serial Communication UART HC-05 Default Settings Specifications How to connect HC-05 module HC-05 Module PIN OUT of HC-05 Connection or HC-05 & Arduino Modes of Communication Data Mode: This mode is used to communicate with other Bluetooth devices wirelessly. Command mode: AT Command mode is where we can change the default device settings. Let\’s see an example here for both of the modes, starting with Data Mode. Bluetooth communication between Devices (Data Mode) Here we will connect our module with Arduino and our phone. We will send signals from the phone to the HC-05 module wirelessly which will be displayed on the serial monitor. If we will send 1 it will turn on the LED or If we will send or it will turn off the LED. Components required: Arduino Uno LED Jumper wires HC-05 Bluetooth An android phone Steps. Follow the steps mentioned above to connect your module. Now follow these steps to make the circuit turn on/off the LED. Connect the long leg of the led with the resistor. The resistor should be connected with any digital pin, let\’s say pin 13. Connect the short leg with the ground. 3. Now we are using the same TX, RX pin for communication. For this, First, we need to remove RX, TX wire. We did this because Arduino Uno has only 1 pair of UART pins and by them, it receives the data from the IDE. We are aware that Arduino uses the UART protocol for communication. If we connect these pins with the HC-05 module while uploading we will get an error as it will clash. Upload the code to the Arduino and reconnect the pins. int ledP=13;int dtime=1000;int readData;void setup() { // put your setup code here, to run once: pinMode(ledP,OUTPUT); Serial.begin(9600);}void loop() { // put your main code here, to run repeatedly:while(Serial.available()==0) {} // reading the data from the serial monitorreadData = Serial.parseInt();Serial.println(readData);if(readData==0){ digitalWrite(ledP,LOW);}if(readData==1){ digitalWrite(ledP,HIGH);} To send the signals via phone we need to install an app. I use an Arduino Bluetooth controller. Pair it, add the password which is usually 1234 or 0000. Changing the default settings of HC-05 (Command mode) AT Command mode is where we can change the default device settings. Steps to use AT commands Connect your Arduino Board to the Pc. Upload the bare minimum code to Arduino without any breadboard connection. Unplug the Arduino from the computer. Connect the HC-05 module to the Arduino as below. Press and hold the push-button on the module for 1-2 sec and while holding it connect the Arduino to the PC. Now you’ll see the red light will blink in 1-2 sec intervals which shows AT command mode is active. Now select the baud rate to 38400. We do that because 9600 is slow for high-speed transmission. It can go even higher according to the HC-05 reference. Set the box next to the baud rate from newline to both NL(newline – n) & CR(carriage return – r). Now we will use AT commands. First, type At on the Serial Monitor and send. If you will see an OK then everything is fine. To change the name of the module we use AT+NAME=HC-05Devanshi. To change the Password of the module we use AT+PSWD=\”9876\” You can refer to this for AT commands. Applications of HC-05 module Robots Wireless communication between two microcontrollers Communication with Mobile and Laptop
Introduction to the pin diagram and functional diagram along with the peripheral interface of ESP8266 MCU, ESP-12E Module and NodeMCU
I2C communication stands for inter-integrated circuits. I2C contains the best features of SPI & UART. It is a synchronous communication protocol. It transmits data serially. It is widely used in microcontrollers, IoT, sensors, displays, and EEPROMs, etc. I2C can be single master multiple slaves and multiple master multiple or single slave. In this blog, we will get to know about I2C in depth. Highlights of I2C I2C works with 2 wires only for communication. SDA [Serial Data]: It is used by the Master and Slave for the transmission or receiving bits. SCL [Serial Clock]: It is used to carry clock signals. I2C can communicate with 2 different methods. Slave selection protocol uses a 7-bit slave address. I2C doesn’t have any fixed length of data transfer. Confirmation after transferring every byte. Full-duplex. How does I2C work? Start Condition To initiate the communication, the master keeps the SCL line high and pulls the SDA line low. If we have more than one master then the one who pulls the SDA line low first will send the data first and if the SDA line is already low then the other masters can not send the data. Addressing Master sends the same address to all the slaves. The slave then compares its own address with this address. If the address doesn’t match with the slave, the slave doesn’t do anything if it does match then the slave sends an acknowledge bit to the master. Read/Write Bit With the address, master sends the read/write bit to all the slaves where 0 indicates a write and 1 indicates a read. If the master wants to read data from the slave then it sends the read bit. If it wants to write then it sends a write bit. ACK/NACK Bit Each frame in a message is followed by an ack/nack bit. If an address frame was successfully received, an ACK bit is returned to the Master from the slaves. THE DATA FRAME When the acknowledge bit is received by the master, the master sends the data frame to the slave which is of 8 bits. After every data frame the slave sents an acknowledge bit to confirm that the data frame has been received successfully. Stop Condition To generate the stop condition master pulls the SCL from high to low and SDA line from low to high. Applications of I2C Communicating with multiple micro-controller. Accessing low-speed DACs[digital to analog converter] and ADCs[analog and digital converter]. Accessing real-time clocks. Reading hardware sensors. Previous Next
Table of Contents Introduction to Analog To Digital Conversion (ADC) Microcontrollers as we know of today are digital devices that is they only understand digital signals but our world is not digital and produces many analog signals as well. Here comes the role of ADC. Analog to Digital converter as the name suggests is used to convert any analog signal to digital so that microcontroller can read that signal. AVR microcontroller have inbuilt ADC on all bits of PORTA. In this blog we will be discussing about all the registers and bits necessary to use ADC on AVR. ADC on AVR Now let us use this ADC of AVR and convert analog signals to digital and read them. Block Diagram for using ADC on AVR: Let us discuss these steps in detail to understand use of ADC in AVR STEP – I : Basic Setup 1) Setting up pre-scalar for ADC frequency We know that digital signal are at fixed moment or instances of time while analog are continuous in time. So when we convert analog signal to digital signal we need to decide that on how many instances of time we need to take value of signal so that we can create a digital counterpart of signal. In the image above the green line depicts analog signal and blue lines make up digital signal. Now we need to decide that for ADC how many blue lines we need. The no. of blue lines in a second is called sampling frequency. AVR has a counter which counts from 0 till 65536 and turns back to 0 and counts again. We will tell AVR that every time you count 16 times then put 1 blue line of digital signal according to analog signal. This thing is known as pre-scalar. If we set up a pre-scalar of 8 means we say to AVR that after every 8 times you count add 1 reading of digital signal. Preferred and generally used pre-scalar value is 16. ADCSRA i.e. ADC Control and Status Register A has bits 2,1,0 which decide the prescalar for ADC. You can refer table below which is taken from datasheet to select value for ADC pre-scalar: Lets see code for setting 16 bit pre-scalar. For 16 bit pre-scalar we need to only set bit ADPS2, so we will set 1 to ADPS2 bit in ADCSRA register. ADCSRA |= (1<<ADPS2); 2) Setting up resolution for ADC Resolution is nothing but a technical term for maximum value that we will be taking up as digital value. As we convert analog signal to digital we convert it to numbers where a number will represent the maximum analog input value i.e. if we set max input to 5v then digital value of all inputs equal to greater than 5v will be that number. Similarly a number is assigned to minimum value and the range between those numbers represent the values between minimum to maximum input voltage set. Now 8bit resolution means 0-255. The question comes up how? It has a simple answers. 8 bit resolution means that the converted value will have 8 binary digits. So now minimum value of 8 digit binary number is 00000000 which is 0 in decimal and highest value is 11111111 which is 255 in decimal hence the 8 bit range is 0 – 255. Here 255 represent 5V (Maximum voltage input) and 0 represents 0V. This makes up 256 digits for 0 volt hence we can calculate: 5V/256 = 0.0195V This implies that every number represents 0.0195 V. So 1 in digital value is equal to 1*0.0195V = 0.0195V. Similarly 25 means 25*0.0195V = 0.4875 V and so on… Similarly 10 bit has 10 digits so range becomes from 0(0000000000) – 1023(1111111111). And now if we select maximum output voltage to be 5V then 1023 means 5V but for every count precision increases, so: 5V/1024 = 0.00488V Hence every count represent 0.00488V and as shown above now 25 count will mean 25*0.00488 = 0.122V. Enough theory!!! Now lets see how to write code and select the resolution (range) we need for our ADC. AVR has a 10bit ADC. We can obtain both 8 bit values and 10 bit values from ADC for AVR. To set resolution we need to use ADMUX register of our microcontroller. ADMUX stand for ADC Multiplexer selection register. For 8 bit mode, set ADLAR bit of ADC to 1. ADMUX |= (1<<ADLAR); For 10 bit mode, clear ADLAR bit i.e. make it 0. ADMUX &= ~(1<<ADLAR); 3) Setting up ADC reference voltage Reference voltage is the voltage level which will be considered as maximum voltage by our ADC and at any voltage level equal to or greater than reference voltage, we will get the maximum value after conversion. The maximum value that we discussed above is same ad known as reference voltage as ADC takes this voltage as reference to work. Reference voltage can be set using ADMUX register. Bit 7 and bit 6 decide the reference that we are going to use according to the following table fetched from the datasheet. a) AREF(00) – We give the reference voltage to AREF pin, i.e. PIN 32. b) AVCC(01) – The reference voltage is considered as power connected to VCC. AVCC is Analog VCC which is optional to give for better ADC functionality. If you leave it empty then also nothing happens. It also suggest to add an external capacitor between AREF and GND so that there is no noise in ADC due to AREF pin. c) Internal 2.56V(11) – This provides a fixed internal reference voltage of 2.56V to ADC. It also has suggestion of adding a capacitor in similar way as above so that there is no noise from AREF Pin. For AREF mode, clear REFS0 and REFS1 i.e. make them both 0 ADMUX &= ~(1<<REFS0); ADMUX &= ~(1<<REFS1); For AVCC mode, set REFS0 ADMUX |= (1<<REFS0); For Internal 2.56V, set both REFS0 and REFS1 i.e. make them both 1 ADMUX |= (1<<REFS0);