Goto www.breakevent.com for avr projects and for buying products in kathmandu,Nepal.
PROELX
Blog For AVR
.
Sunday, January 29, 2012
Earn Money Via Facebook
This is how they earn from facebook just by sharing some of their photos, videos and any other things i was shocked watching this..SO watch it once and start sharing dont be late...
They Earn 1 $ per share and 50 Cents for every click...
They Earn 1 $ per share and 50 Cents for every click...
Tuesday, December 20, 2011
Reading and writing SD card using Atmega16
SD card
SPI Initialization:
Functions for sending and receiving one byte through SPI:
Function to send a command frame Command:
Initialization card:
Writing to the card:
The function returns 1 if an error occurs else returns 0 if successful
Reading from the card:
The function returns 1 if an error occurs else returns 0 if successful
Adding all the codes:
Pin description of an SD card
Pin | Name | Function (SD Mode) | Function (SPI Mode) |
1 | DAT3/CS | Data Line 3 | Chip Select/Slave (SS) |
2 | CMD/DI | Command Line | Mater Out Slave In (MOSI) |
3 | VSS1 | Ground | Ground |
4 | VDD | Supply Voltage | Supply Voltage |
5 | CLK | Clock | Clock (SCK) |
6 | VSS2 | Ground | Ground |
7 | DAT0/DO | Data Line 0 | Master In Slave Out (MISO) |
8 | DAT1/IRQ | Data Line 1 | Unused or IRQ |
9 | DAT2/NC | Data Line 2 | Unused |
Important SD card commands
Command | Argument | Type Response | Description |
CMD0 | None | R1 | Tell the card to reset and enter its idle state. |
CMD16 | 32-bit Block Length | R1 | Select the block length. |
CMD17 | 32-bit Block Address | R1 | Read a single block. |
CMD24 | 32-bit Block Address | R1 | Write a single block. |
CMD55 | None | R1 | Next command will be application-specific (ACMDXX). |
CMD58 | None | R3 | Read OCR (Operating Conditions Register). |
ACMD41 | None | R1 | Initialize the card. |
Initialize SD card
Initialization begins by setting the SPI control clock signal to 400kHz, which is required for compatibility of most SD and MCC memory cards. Then reset the tab order at CMD0 activated CS input card (CS at level L). CRC byte for the command CMD0 and zero argument command is 0x95. CMD55 followed orders and ACMD41. If after the idle bit in the level L handshake is completed and anticipates that further management framework. Command CMD58 For example, we check whether the card supports the same supply voltage as the MCU, which is typically in the range of 2.7 V to 3.6 V. SPI clock signal to set the maximum allowed value.Program part
SD card connection to microcontroller#define DI 6 // Port B bit 6 (pin7): data in (data from MMC)
#define DT 5 // Port B bit 5 (pin6): data out (data to MMC)
#define CLK 7 // Port B bit 7 (pin8): clock
#define CS 4 // Port B bit 4 (pin5): chip select for MMC
void ini_SPI(void) {
DDRB &= ~(_BV(DI)); //input
DDRB |= _BV(CLK); //outputs
DDRB |= _BV(DT); //outputs
DDRB |= _BV(CS); //outputs
SPCR |= _BV(SPE); //SPI enable
SPCR |= _BV(MSTR); //Master SPI mode
SPCR &= ~(_BV(SPR1)); //fosc/16
SPCR |= _BV(SPR0); //fosc/16
SPSR &= ~(_BV(SPI2X)); //speed is not doubled
PORTB &= ~(_BV(CS)); //Enable CS pin for the SD card
}
Functions for sending and receiving one byte through SPI:
char SPI_sendchar(char chr) {
char receivedchar = 0;
SPDR = chr;
while(!(SPSR & (1<<SPIF)));
receivedchar = SPDR;
return (receivedchar);
}
Function to send a command frame Command:
char Command(char cmd, uint16_t ArgH, uint16_t ArgL, char crc ) {
SPI_sendchar(0xFF);
SPI_sendchar(cmd);
SPI_sendchar((uint8_t)(ArgH >> 8));
SPI_sendchar((uint8_t)ArgH);
SPI_sendchar((uint8_t)(ArgL >> 8));
SPI_sendchar((uint8_t)ArgL);
SPI_sendchar(crc);
SPI_sendchar(0xFF);
return SPI_sendchar(0xFF); // Returns the last byte received
}
Initialization card:
void ini_SD(void) {
char i;
PORTB |= _BV(CS); //disable CS
for(i=0; i < 10; i++)
SPI_sendchar(0xFF); // Send 10 * 8 = 80 clock pulses 400 kHz
PORTB &= ~(_BV(CS)); //enable CS
for(i=0; i < 2; i++)
SPI_sendchar(0xFF); // Send 2 * 8 = 16 clock pulses 400 kHz
Command(0x40,0,0,0x95); // reset
idle_no:
if (Command(0x41,0,0,0xFF) !=0)
goto idle_no; //idle = L?
SPCR &= ~(_BV(SPR0)); //fosc/4
}
The function returns 1 if an error occurs else returns 0 if successful
int write(void) {
int i;
uint8_t wbr;
//Set write mode 512 bytes
if (Command(0x58,0,512,0xFF) !=0) {
//Determine value of the response byte 0 = no errors
return 1;
//return value 1 = error
}
SPI_sendchar(0xFF);
SPI_sendchar(0xFF);
SPI_sendchar(0xFE);
//recommended by posting a terminator sequence [2]
//write data from chars [512] tab
uint16_t ix;
char r1 = Command(0x58,0,512,0xFF);
for (ix = 0; ix < 50000; ix++) {
if (r1 == (char)0x00) break;
r1 = SPI_sendchar(0xFF);
}
if (r1 != (char)0x00) {
return 1;
//return value 1 = error
}
//recommended by the control loop [2]
SPI_sendchar(0xFF);
SPI_sendchar(0xFF);
wbr = SPI_sendchar(0xFF);
//write block response and testing error
wbr &= 0x1F;
//zeroing top three indeterminate bits 0b.0001.1111
if (wbr != 0x05) { // 0x05 = 0b.0000.0101
//write error or CRC error
return 1;
}
while(SPI_sendchar(0xFF) != (char)0xFF);
//wait for the completion of a write operation to the card
return 0;
}
Reading from the card:
The function returns 1 if an error occurs else returns 0 if successful
int read(void) {
int i;
uint16_t ix;
char r1 = Command(0x51,0,512,0xFF);
for (ix = 0; ix < 50000; ix++) {
if (r1 == (char)0x00) break;
r1 = SPI_sendchar(0xFF);
}
if (r1 != (char)0x00) {
return 1;
}
//read from the card will start after the framework
while(SPI_sendchar(0xFF) != (char)0xFE);
for(i=0; i < 512; i++) {
while(!(SPSR & (1<<SPIF)));
chars[i] = SPDR;
SPDR = SPI_sendchar(0xFF);
}
SPI_sendchar(0xFF);
SPI_sendchar(0xFF);
return 0;
}
#include <avr/io.h>
#include <avr/iom16.h>
#include <avr/interrupt.h>
#define FOSC 6400000
char chars[512];
int main(void) {
ini_SPI();
ini_SD();
sei();
write();
read();
return 0;
}
Interface LM35 with Atmega16
Interface LM35 to measure temperature with AVR microcontroller. The LM35 series are precision integrated-circuit temperature sensors, whose output voltage is linearly proportional to the Celsius (Centigrade) temperature. LM35 can measure temperatures from -55deg to +150deg.
In this circuit the Atmega16 is used and the inbuilt ADC is used to convert the analog voltage from the LM35 to digital value.
In this circuit the Atmega16 is used and the inbuilt ADC is used to convert the analog voltage from the LM35 to digital value.
Circuit Diagram
Bascom code
$regfile = "m16def.dat"
$crystal = 1000000
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.0 , Rs = Portd.1
Config Adc = Single , Prescaler = Auto
Deflcdchar 0 , 12 , 18 , 18 , 12 , 32 , 32 , 32 , 32
Deflcdchar 1 , 32 , 4 , 12 , 28 , 28 , 32 , 32 , 32
Deflcdchar 2 , 32 , 4 , 14 , 31 , 31 , 32 , 32 , 32
Deflcdchar 3 , 32 , 4 , 14 , 31 , 31 , 7 , 6 , 4
Deflcdchar 4 , 32 , 4 , 14 , 31 , 31 , 31 , 14 , 4
Deflcdchar 5 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32
Dim A As Word
Dim B As Byte
B = 1
Start Adc
Cursor Off
Cls
Locate 2 , 1
Lcd "avrprojects.info"
Do
A = Getadc(0)
A = A / 2
Locate 1 , 2
Lcd "Temp =" ; A ; Chr(0) ; "c "
Locate 1 , 16
Lcd Chr(b)
Waitms 500
Incr B
If B > 6 Then B = 1
Loop
End
$crystal = 1000000
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.0 , Rs = Portd.1
Config Adc = Single , Prescaler = Auto
Deflcdchar 0 , 12 , 18 , 18 , 12 , 32 , 32 , 32 , 32
Deflcdchar 1 , 32 , 4 , 12 , 28 , 28 , 32 , 32 , 32
Deflcdchar 2 , 32 , 4 , 14 , 31 , 31 , 32 , 32 , 32
Deflcdchar 3 , 32 , 4 , 14 , 31 , 31 , 7 , 6 , 4
Deflcdchar 4 , 32 , 4 , 14 , 31 , 31 , 31 , 14 , 4
Deflcdchar 5 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 32
Dim A As Word
Dim B As Byte
B = 1
Start Adc
Cursor Off
Cls
Locate 2 , 1
Lcd "avrprojects.info"
Do
A = Getadc(0)
A = A / 2
Locate 1 , 2
Lcd "Temp =" ; A ; Chr(0) ; "c "
Locate 1 , 16
Lcd Chr(b)
Waitms 500
Incr B
If B > 6 Then B = 1
Loop
End
Downloads
Embedded Hardware and Software
HARDWARE
There are 3 stages in bringing out a hardware. They are:- Gathering idea about the circuit
- Designing a circuit
- Fabrication
Gathering idea about the circuit:
Making a hardware is very easy if we have some ideas about the components. For most of the electronic components like resistor, capacitor IC’s, etc., we have their working mode and data sheets on the internet itself. From that, we can gather ideas about the components. After it, integrating the components to one another will give the exact circuit which we desire.
Designing a circuit:
When we mix Yellow and Blue colour, we get green colour. This is a formula. Similarly, if we onnect a resistor and a transformer in series to a diode, we get a rectifier. By the same method, we can design the circuits by gathering a good integrating knowledge.
After designing the circuit, the circuit should be clearly drawn some where else. For drawing the circuit easily, we can use the software’s such as CIRCUIT MAKER, PROTEL, DESIGNWORKS etc, which may be downloaded from the internet. These software’s are user friendly, as they have pre-designed component library within them. From this library, we can take those components, and connect it easily through connectors. Then by Auto- Routing, we can deign the PCB layout also.
But, Auto-Routing method of framing the PCB layout is advisable only for large circuits and not for small circuits. For small circuits, it is better to design the PCB manually. For manual designing of PCB layout, we can use the software’s such as ORCAD, RIMUPCB, ExpressPCB., etc
After designing the circuit, the circuit should be clearly drawn some where else. For drawing the circuit easily, we can use the software’s such as CIRCUIT MAKER, PROTEL, DESIGNWORKS etc, which may be downloaded from the internet. These software’s are user friendly, as they have pre-designed component library within them. From this library, we can take those components, and connect it easily through connectors. Then by Auto- Routing, we can deign the PCB layout also.
But, Auto-Routing method of framing the PCB layout is advisable only for large circuits and not for small circuits. For small circuits, it is better to design the PCB manually. For manual designing of PCB layout, we can use the software’s such as ORCAD, RIMUPCB, ExpressPCB., etc
Fabrication:
Now, the PCB layout is ready in our PC. We can take a print or draw this layout in the board. After copying the layout, the holes are drilled and the components are soldered. Now, the hardware is ready.
SOFTWARE
The software may be written either in BASIC, Assembly, C or C++. Beginners may practice with BASIC or Assembly. The software’s are written in packages like KEIL, RAID etc. These software’s gives a good cope-up for beginners.[Note: Want to get sample embedded programs? Visit www.8051projects.info, www.8085projcts.info]
Why do we want to write them in Software packages? Is it not enough to write them in PC and load it in the microcontroller? Can you guess the reason? The reason is - to load the program in the microcontroller, we need HEX data. Microcontroller can accept only hex inputs and not other inputs. Only for this purpose, we go for software packages or IDE (Integrated Development Environment). These packages are available with programmer, simulator and compiler togather. So, it is also called as IDE. These packages convert our program to hex code.
We can check our outputs immediately for each line in the program - using the simulator. The errors are easily noticed by the built-in compiler and are easily debugged. By this, we can get the exact program and the corresponding HEX codes. Now, how is it loaded in the microcontroller?
For loading the converted codes, we need a programming kit called programmer. The programmer kit can be bought from online shops or it can be designed with the help of some websites.
[Note: The circuit diagram for Programming kit is freely downloadable from www.avrprojects.info . This programming kit can be used to program all - AVR, and 8051 microcontrollers.]
These efforts may bring out good embedded products, and wish you all great success in your work. If you want more details regarding this, post it in the above said website.
ISD4004 based voice recorder
So far we have seen various devices that are talking, such us cars, dolls etc.This project is also like one of them. you can use it in various projects such us IVS, robots etc.
There are various voice recording IC's. They have different recording time and sampling frequency. Most of the IC's can record less than 1min of sound.
ISD4004 can record 8min to 16mins maximum. If you select high sampling frequency then you can record a max 8mins at high quality. This project gives you a voice recorder based on this chip.
You can't use this IC without a microcontroller since it works on SPI communication. So you need a microcontroller to play/record the audio. Here ATmega8 is used to play and record the chip. This is the pin diagram of the IC ISD4004
This IC works on 3.3v, so we need a regulated 3.3v using LF33CV. The audio output from the Voice0 chip is amplified by an audio amplifier. This amplifier is done with Lm386.
The Audio input can be fed by two methods which are given below.
If you want to give audio from PC, then select the first circuit and connect a 1kohm resistor in series with the input.
Circuit Diagram
There are 3 switches, the S1 is for selecting Record/playback. If the S1 is connected to Vcc then the chip is selected in Play mode then you can use the Button S2 to play the audio.
If the S1 is connected to Ground then the chip is configured at record mode, now the S2 can be used for starting the recording.
Downloads:
CONVERSIONS
Converting Int to ASCII Coded Decimal
Converting integers to ASCII coded decimal is pretty simple. To understand how it is done, you first have to think about how the numbers we're using in written documents are built up: Let's take the number 233 and rip it apart:
Multiply number with | 100 | 10 | 1 |
decimal | 2 | 3 | 3 |
result | 200 | 30 | 3 |
To get these results, we need to divide the number; first by 100, then by 10 and then by 1. As the AVR doesn't have a divide instruction, this has to be done manually:
Divide by 100:
- copy the number into a temporary register
- compare the number with 100
- if greater or equal, increase the hundreds count and subtract 100 from the temporary register
- go to the compare again
When this is done, the number in the temporary register is lower than 100. Now we can proceed with 10s and 1s. Instead of dividing it by 1 we can just copy the remaining number to the register that holds the ones.
Unfortunately, this is not enough to convert a number to decimal coded ASCII. In an ASCII table we can see that '0' is 0x30. So we add 0x30 to the single digits (hundreds, tens, ones) and can now print it on the screen (via UART, USB, LCD interface, whatever).
It's now also possible to reformat the number, delete characters we don't need (print a space instead of 0 hundreds if the number was lower than 100) or add additional characters in between.
Here's a flow chart of how the conversion can be done:
It should be pretty easy for you to write the code for this yourself.
Doing this with a 16-bit number is just the same, but with 5 digits and 16-bit compares. The code space needed (as well as cpu time) is 40% bigger. If you have a lot of free program space, you can build up a case-like structure to do the conversion: If the number is greater than 200, the hundreds counter is loaded with 2 and 200 is subtracted from the original number. This is faster but requires more space. It's up to you.
Converting Int to ASCII Coded Hex
This conversion is a bit more difficult than int to ASCII coded decimal, as you don't only have to display numbers, but characters as well. In the ASCII table, these are not found directly after the numbers. However, the first task is to load the two nibbles that make up to an 8 bit integer into separate registers:
The reason why you have to swap the nibbles in reg A is that the register holding the high nibble should have a value between 0x00 and 0x0F (15). If we didn't swap the nibbles, their value would be 0x00..0xF0 which we can't convert to ASCII.
Now we have two nibbles, each in a separate register, which are between 0x00 (0) and 0x0F (15). These must now be converted into their ASCII representative: For 0 it's '0', for 10 it's 'A' and for 15 it's 'F'. This can be done with a lookup table or by using a case structure.
A lookup table for this would have the ASCII values of the possible nibble values at the nibble positions:
Table Position: | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
Nibble value: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
ASCII: | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' |
When this is done and the number we had was 128, we now have reg A holding '8' and reg B holding '0' because 128 is 0x80.
Converting 16-bit numbers from int to ASCII coded hex is not much harder. The result needs 4 registers and we need to convert two ints without having to use any 16-bit instructions:
1024 (hex 0x0400) converts to '0' and '4' for the high byte and '0' and '0' for the low byte.
Converting ASCII Coded Decimal to INT
Ascii Coded Decimal strings are, for example, used in the Ymodem protocol for sending file size information. To use that string as a file size it has to be converted to an integer in order to be processed fast and code-efficient.The conversion is not as straight-forward as others, as the string length has to be taken into account:
'512' has a length of 3 characters, and therefore the '5' means 500, and not 50 or 5. As the most significant digits are usually sent first, the string is not too hard to be converted. If the least significant digit is sent first the string has to be stored first and can't be processed byte for byte.
Given that the most significant digit is sent first, the following steps are necessary for each character received:
For the '512' string, this happens:
'5' is converted to 5 by subtracting ASCII '0' from '5'. Then the result (which is still zero) is multiplied by 10. The result is zero.
Now 5 is added. Result = 5
Now the '1' is received and converted to 1. The result (which is 5) is multiplied by 10, so we now have 50.
1 is added which equals 51.
The '2', being the last character of the string, is again converted, the result is pultiplied by 10 (=510) and 2 is added. The result is 512. Easy huh?
The only thing I didn't mention until now is how to determine when the string ends. This depends on the transmitter or source of the string. If it is a null-terminated string, we can use the following program flow:
Converting ASCII Coded Hex to Int
For the conversion from ASCII coded hex to int we first need some code that converts one ASCII character (which represents one hex nibble) to its decimal value. 'A' -> 10. This can't (or shouldn't) be done with a lookup table, because the ASCII value of 'A' is bigger than the size of efficient code doing the same thing. Therefore, the lookup table would also be quite big. So, it's better to choose the case structure.Then the second nibble is converted in the same way and the two nibbles are combined to form one int.
This conversion is done for the two nibble characters. These are then combined in one byte:
Maybe the nibbles have to be swapped again, depending on how the two nibbles were sent: If the high nibble was sent first, the received byte can left as it is: The high nibble was added, the nibbles were swapped and then the low nibble was added.
Consequently, if the low nibble is sent first, the nibbles have to be swapped again.
Numbers
As you read through these pages you might want to have a look at an ascii table. You can find one in the Banner frame ("quick links").
Conversions are very important for user interaction: If a register has the value 0x30 its corresponding ascii character is '0'. But if you want it to be displayed as '48' (0x30 is 48), you need to convert the number. In the case of '0' this is not that important, but 0xFF is displayed as a block. And '48' is better than '0' if you're displaying a temperature...
Some protocols, such as Ymodem, also use strings of values we have to convert first before we can perform calculations on them: Ymodem sends a file size of 512 bytes as '512'. An AVR has to convert this from ascii coded decimal to 16bit int first before it knows what '512' means.
Some number formats you should have in mind when doing calculations:
It's up to you which number format you use for a specific task. Ascii coded hex is quite often used for debugging purposes, because the numbers are all of the same size (number of characters needed) and becase the conversion always takes the same number of cpu cycles and doesn't require much space. Ascii coded decimal is better for things like temperatures or rpm of a motor. Ascii coded binary is good for displaying flag registers (SREG, Interrupt flag registers and so on).
I'll show you ways to convert numbers in both directions: From int to something you can display and back.
Converting numbers from one format to another is not as easy and requires the person writing the code to understand the number formats first.
All conversions explained on these pages have the integer as one "end" (source or result). This is the number the AVR actually deals with.
Other formats use ASCII characters or the fact that a digit (which has a range of 0 to 9) only uses one nibble of a byte.
HEX format:
In AVR Assembler (and on this site) HEX numbers are written with the "$"-sign or "0x" at the beginning:
$10 is equal to 16 and 0x20 is equal to 32.
The Hex format splits the 8 bits of a byte into "nibbles" of 4 bits (the high nibble and the low nibble) and displays them with a number or character:
If an 8-bit number is sent or printed as ASCII Coded Hex, the number is split into high nibble and low nibble (in the case of ox20 these are 2 and 0). Then the nibbles are converted to their ASCII representative: 0x32 for 2 and 0x30 for 0. These values can be printed on screen. The values from the table above can not be preinted on the screen: In the ASCII table these are either not defined or control characters. A won't be displayed as 'A'.
Binary format:
The binary format should be quite clear: 0b00001000 is equal to 8, 0b00011000 is equal to 24. Easy. When a number comes as ASCII coded binary, the 1s and 0s are sent as their ASCII representative, 0x30 and 0x31, and thus have to be converted before they are "real" bits. The binary format also requires bit shifting for the conversion.
Binary Coded Decimal (BCD) format:
Binary coded decimal is very handy for storing two digits (0..9) in one byte without much coding. The digits are directly written to a byte nibble.
0x22 means that the low nibble contains the number 2 and the high nibble contains the number 2 as well. A consequence of this is that a byte can only hold value in the range of 0 to 99: The values 10 to 15 (A to F in Hex format) are not allowed in BCD format.
This format can for example be written to a port which has a 7447 connected to it. This IC is a 7-segment LED driver which converts this format so that the segments of the LED display show the number of the nibble.
If you need the hex value of 'H', look for H. It's in column $4x and row $x8. 'H' = $48 or 0x48. Other way around: You need to know what 0x69 is when shown as a character. Column $6x, row $x9: 'i'
The "ctrl" column contains the control characters in short form. The real name can be found further down on this page in a seperate table.
We're working on a printable version of this... Most probably we'll have to divide the table by three or so and fill three pages. One won't be enough for all this...
0x20 ('spc") means space, of course.
Here is the control character table.
Conversions are very important for user interaction: If a register has the value 0x30 its corresponding ascii character is '0'. But if you want it to be displayed as '48' (0x30 is 48), you need to convert the number. In the case of '0' this is not that important, but 0xFF is displayed as a block. And '48' is better than '0' if you're displaying a temperature...
Some protocols, such as Ymodem, also use strings of values we have to convert first before we can perform calculations on them: Ymodem sends a file size of 512 bytes as '512'. An AVR has to convert this from ascii coded decimal to 16bit int first before it knows what '512' means.
Some number formats you should have in mind when doing calculations:
128 '128' 0x30 0b11001010 '11001010' | ; normal decimal value ; ascii coded decimal. In this case you need three bytes ('1', '2' and ; '8') to store that number. ; hex value ; ; binary value ; ascii coded binary |
I'll show you ways to convert numbers in both directions: From int to something you can display and back.
Commonly Used Number Formats
The ALU of an AVR only knows the integer number, unsigned as well as signed, and only 8 bits wide. The 8 bit limit is not as bad, as we can still use the carry bit to make 16-, 24- and 32 bit operations possible. Converting numbers from one format to another is not as easy and requires the person writing the code to understand the number formats first.
All conversions explained on these pages have the integer as one "end" (source or result). This is the number the AVR actually deals with.
Other formats use ASCII characters or the fact that a digit (which has a range of 0 to 9) only uses one nibble of a byte.
HEX format:
In AVR Assembler (and on this site) HEX numbers are written with the "$"-sign or "0x" at the beginning:
$10 is equal to 16 and 0x20 is equal to 32.
The Hex format splits the 8 bits of a byte into "nibbles" of 4 bits (the high nibble and the low nibble) and displays them with a number or character:
Nibble value: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
Hex: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
Binary format:
The binary format should be quite clear: 0b00001000 is equal to 8, 0b00011000 is equal to 24. Easy. When a number comes as ASCII coded binary, the 1s and 0s are sent as their ASCII representative, 0x30 and 0x31, and thus have to be converted before they are "real" bits. The binary format also requires bit shifting for the conversion.
Binary Coded Decimal (BCD) format:
Binary coded decimal is very handy for storing two digits (0..9) in one byte without much coding. The digits are directly written to a byte nibble.
0x22 means that the low nibble contains the number 2 and the high nibble contains the number 2 as well. A consequence of this is that a byte can only hold value in the range of 0 to 99: The values 10 to 15 (A to F in Hex format) are not allowed in BCD format.
This format can for example be written to a port which has a 7447 connected to it. This IC is a 7-segment LED driver which converts this format so that the segments of the LED display show the number of the nibble.
The Ascii Table
Very often you'll need to convert ascii to hex or decimal numbers and back. An ascii table is THE tool you'll need for that. Here is one.If you need the hex value of 'H', look for H. It's in column $4x and row $x8. 'H' = $48 or 0x48. Other way around: You need to know what 0x69 is when shown as a character. Column $6x, row $x9: 'i'
The "ctrl" column contains the control characters in short form. The real name can be found further down on this page in a seperate table.
We're working on a printable version of this... Most probably we'll have to divide the table by three or so and fill three pages. One won't be enough for all this...
$0x | $1x | $2x | $3x | $4x | $5x | $6x | $7x | $8x | $9x | $Ax | $Bx | $Cx | $Dx | $Ex | $Fx | |||||||||||||||||||
dec | char | ctrl | dec | char | ctrl | dec | char | dec | char | dec | char | dec | char | dec | char | dec | char | dec | char | dec | char | dec | char | dec | char | dec | char | dec | char | dec | char | dec | char | |
$x0 | 000 | NUL | 016 | DLE | 032 | spc | 048 | 0 | 064 | @ | 080 | P | 096 | ` | 112 | p | 128 | € | 144 | | 160 | 176 | ° | 192 | À | 208 | Ð | 224 | à | 240 | ð | |||
$x1 | 001 | SOH | 017 | DC1 | 033 | ! | 049 | 1 | 065 | A | 081 | Q | 097 | a | 113 | q | 129 | | 145 | ‘ | 161 | ¡ | 177 | ± | 193 | Á | 209 | Ñ | 225 | á | 241 | ñ | ||
$x2 | 002 | STX | 018 | DC2 | 034 | " | 050 | 2 | 066 | B | 082 | R | 098 | b | 114 | r | 130 | ‚ | 146 | ’ | 162 | ¢ | 178 | ² | 194 | Â | 210 | Ò | 226 | â | 242 | ò | ||
$x3 | 003 | ETX | 019 | DC3 | 035 | # | 051 | 3 | 067 | C | 083 | S | 099 | c | 115 | s | 131 | ƒ | 147 | “ | 163 | £ | 179 | ³ | 195 | Ã | 211 | Ó | 227 | ã | 243 | ó | ||
$x4 | 004 | EOT | 020 | DC4 | 036 | $ | 052 | 4 | 068 | D | 084 | T | 100 | d | 116 | t | 132 | „ | 148 | ” | 164 | ¤ | 180 | ´ | 196 | Ä | 212 | Ô | 228 | ä | 244 | ô | ||
$x5 | 005 | ENQ | 021 | NAK | 037 | % | 053 | 5 | 069 | E | 085 | U | 101 | e | 117 | u | 133 | … | 149 | • | 165 | ¥ | 181 | µ | 197 | Å | 213 | Õ | 229 | å | 245 | õ | ||
$x6 | 006 | ACK | 022 | SYN | 038 | & | 054 | 6 | 070 | F | 086 | V | 102 | f | 118 | v | 134 | † | 150 | – | 166 | ¦ | 182 | ¶ | 198 | Æ | 214 | Ö | 230 | æ | 246 | ö | ||
$x7 | 007 | BEL | 023 | ETB | 039 | ' | 055 | 7 | 071 | G | 087 | W | 103 | g | 119 | w | 135 | ‡ | 151 | — | 167 | § | 183 | · | 199 | Ç | 215 | × | 231 | ç | 247 | ÷ | ||
$x8 | 008 | BS | 024 | CAN | 040 | ( | 056 | 8 | 072 | H | 088 | X | 104 | h | 120 | x | 136 | ˆ | 152 | ˜ | 168 | ¨ | 184 | ¸ | 200 | È | 216 | Ø | 232 | è | 248 | ø | ||
$x9 | 009 | HT | 025 | EM | 041 | ) | 057 | 9 | 073 | I | 089 | Y | 105 | i | 121 | y | 137 | ‰ | 153 | ™ | 169 | © | 185 | ¹ | 201 | É | 217 | Ù | 233 | é | 249 | ù | ||
$xA | 010 | LF | 026 | SUB | 042 | * | 058 | : | 074 | J | 090 | Z | 106 | j | 122 | z | 138 | Š | 154 | š | 170 | ª | 186 | º | 202 | Ê | 218 | Ú | 234 | ê | 250 | ú | ||
$xB | 011 | VT | 027 | ESC | 043 | + | 059 | ; | 075 | K | 091 | [ | 107 | k | 123 | { | 139 | ‹ | 155 | › | 171 | « | 187 | » | 203 | Ë | 219 | Û | 235 | ë | 251 | û | ||
$xC | 012 | FF | 028 | FS | 044 | , | 060 | < | 076 | L | 092 | \ | 108 | l | 124 | | | 140 | Œ | 156 | œ | 172 | ¬ | 188 | ¼ | 204 | Ì | 220 | Ü | 236 | ì | 252 | ü | ||
$xD | 013 | CR | 029 | GS | 045 | - | 061 | = | 077 | M | 093 | ] | 109 | m | 125 | } | 141 | | 157 | | 173 | | 189 | ½ | 205 | Í | 221 | Ý | 237 | í | 253 | ý | ||
$xE | 014 | SO | 030 | RS | 046 | . | 062 | > | 078 | N | 094 | ^ | 110 | n | 126 | ~ | 142 | Ž | 158 | ž | 174 | ® | 190 | ¾ | 206 | Î | 222 | Þ | 238 | î | 254 | þ | ||
$xF | 015 | SI | 031 | US | 047 | / | 063 | ? | 079 | O | 095 | _ | 111 | o | 127 | | 143 | | 159 | Ÿ | 175 | ¯ | 191 | ¿ | 207 | Ï | 223 | ß | 239 | ï | 255 | ÿ |
Here is the control character table.
SOH - Start Of Header | DLE - Data Link Escape |
STX - Start Of teXt | DC1 - Device Control 1 |
ETX - End Of teXt | DC2 - Device Control 2 |
EOT - End Of Transmission | DC3 - Device Control 3 |
ENQ - ENQuiry | DC4 - Device Control 4 |
ACK - ACKnowledge | NAK - Negative AcKnowledge |
BEL - BELl | SYN - SYNchronous idle |
BS - BackSpace | ETB - End of Transmission Block |
HT - Horizontal Tabulation | CAN - CANcel |
LF - Line Feed | EM - End of Medium |
VT - Vertical Tabulation | SUB - SUBstitute |
FF - Form Feed | ESC - ESCape |
CR - Carriage Return | FS - File Separator |
SO - Shift Out | GS - MainForm.Group Separator |
SI - Shift In | RS - Record Separator |
US - Unit Separator |
Subscribe to:
Posts (Atom)