220 lines
7.9 KiB
Plaintext
220 lines
7.9 KiB
Plaintext
= Arduino Nano =
|
|
|
|
A very small arduino product, better for hobby embedding
|
|
|
|
see [[arduino_techniques|Programming Techniques]]
|
|
|
|
== Features ==
|
|
|
|
* ATMEL AVR ATmega328P microcontroller
|
|
* 8 bit @16Mhz
|
|
* 2Kbytes SRAM
|
|
* 32Kbytes flash
|
|
* 1Kbytes EEPROM
|
|
* Three on board LED's * 20 IO pins
|
|
* 6 PWM and 6 ADC
|
|
|
|
== Notes ==
|
|
|
|
* WHEN UPLOADING BE SURE TO SET BOARD TO ATMEGA328OLD
|
|
- this is the atmega328old for BOARD_SUB in the makefile
|
|
|
|
=== Memory ===
|
|
|
|
* AVR instructions are 16 or 32bits wide, therefore the flash is 16K x 16
|
|
* EEPROM has endurance of ~10000 write cycles
|
|
* Program counter is 14 bits wide
|
|
* First 32 memory locations (0x0000 - 0x001F) are registers
|
|
* Next 64 registers are standard IO (0x0020 - 0x005F)
|
|
* Next 160 are extended IO (0x0060 - 0x00FF)
|
|
* Everything else is SRAM (0x0100 - 0x08FF)
|
|
|
|
=== IO ===
|
|
|
|
* GPIO pins
|
|
* Have a Data Direction Register (DDR)
|
|
- Sets if data should go in or out
|
|
* Is kept up via a [[multiplexer]] to decide which bit
|
|
|
|
=== Pins ===
|
|
|
|
Pins are controller by the atmega's ports. Each port has different port
|
|
registers. Each bit of the 8 bit register controls a single pin. Port D
|
|
controls pins 0 through 7, C controls the analog pins, and B controls 8 through
|
|
13
|
|
* PortC
|
|
- Port C data regiser
|
|
- 0x28
|
|
- R/W 8bits
|
|
* DDRC
|
|
- Port C data direction register
|
|
- 0x27
|
|
- R/W 8bits
|
|
* PINC
|
|
- Port C input pints address
|
|
- 0x26
|
|
- R 8bits
|
|
* PortB
|
|
- Port B data register
|
|
- 0x25
|
|
- R/W 8bits
|
|
* DDRB
|
|
- Port B data direction register
|
|
- 0x24
|
|
- R/W 8bits
|
|
* PINB
|
|
- Port B Input pins address
|
|
- 0x23
|
|
- R 8bit
|
|
|
|
Same pattern:
|
|
* PortD
|
|
- 0x2B - 0x29
|
|
|
|
=== Interrupts ===
|
|
|
|
Interrupts are the same as OS typical interrupts, controlled by the Interrupt
|
|
lookup table. On this device the ILT is instead a control [[registers]].
|
|
|
|
The External Interrupt Control Regsiter (EICR 0x69) is a register that allows you to set
|
|
the behaviour of the two built in interrupts. The Behaviour is set via setting
|
|
two bits. Bits 3-2 are for Interrupt 1 on pin D3, and Bits 1-0 are for
|
|
Interrupt 0 on pin D2. Below is a table of the values and their behaviour
|
|
|
|
| Bits | Description |
|
|
----------------------
|
|
| 00 | Low level makes an interrupt |
|
|
| 01 | Any logical change makes an interrupt |
|
|
| 10 | Falling edge makes an interrupt |
|
|
| 11 | Rising edge makes an interrupt |
|
|
|
|
To enable the interrupt, you must write a one (1) to the appropriate bit in the
|
|
External Interrupt Mask Register (EIMSK 0x3D). Bit 0 set INT0, and Bit 1 sets
|
|
INT1.
|
|
|
|
NOTE external activity on the pin, once the EIMSK bit is set, will cause an
|
|
interrupt even if the pin is set as an output pin.
|
|
|
|
Once an interrupt is triggered, the External Interrupt Flag Register (EIFR
|
|
0x3C) will have a one (1) written to the corresponding bit for that interrupt.
|
|
The flag is set automatically, and cleared once the interrupt has concluded.
|
|
The flag can be cleared by writing to it manually. Bit0 controlls INT0 and Bit
|
|
1 controlls INT1.
|
|
|
|
Finally, for interrupts to be enabled at all, a one (1) must be written to the
|
|
Status Register (SREG 0x5F). Bit 7 is the global interrupt enable flag, and
|
|
must have a one (1) written to it in order for interrupts to occour, regardless
|
|
of the state of the EIMSK register.
|
|
|
|
To implement an interrupt in code, see the following C example
|
|
{{{
|
|
//enable the interrupts as explained above
|
|
ISR(INT0_vect){
|
|
//perform interrupt task
|
|
}
|
|
}}}
|
|
|
|
=== Clock ===
|
|
|
|
The ATMega328P has 3 timers, two 8bit timers and one 16bit timer. These timers
|
|
can be used for PWM for motors and the like.
|
|
|
|
The timers are controlled by the General Timer/Counter Control Register (GTCCR
|
|
0x43). Bit 7 is the Timer/Counter sync Mode (TSM) and when set, halts the
|
|
timers so that they do not increment during configuration. Once TSM has a zero
|
|
wirtten to it, the PSRASY and PSRSYNC bits (bits 1-0 in this register) are
|
|
cleared via hardware, and the timers start counting. Bit 0 is the Prescaler
|
|
reset, and will reset the Timer/Counter 0 and 1 prescalers when 1 is written to
|
|
it. It is important to not that *Timer/Counter1 and 0 share the same prescaler
|
|
and a reset of the prescaler will affect both*
|
|
|
|
The Timer Counter 1 Control Register A (TCCR1A 0x80) is the register for
|
|
controlling Timer/Counter 1, along with Timer Counter 1 Control Register B
|
|
(TCCR1B 0x81). The high sets of two bits (bits 7-6 and 5-4), control the
|
|
compare output mode for channel A and B respectivly. These are controlled with
|
|
2 bit combinations as shown below.
|
|
|
|
NOTE These settings only apply to normal mode, and are on TTCR1A
|
|
|
|
| Bits | Description |
|
|
----------------------
|
|
| 00 | Normal Port operation, Comp register disconnected |
|
|
| 01 | Toggle OC1A/OC1B on compare match |
|
|
| 10 | Clear OC1A/OC1B on compare match (set output low) |
|
|
| 11 | Set OC1A/OC1B on compare match (set output high) |
|
|
|
|
TCCRB1B also can change the behaviour of the clock. Bit 7 sets the Input
|
|
Capture Noise Canceler (ICNC1). This will eliminate noise on the pin, and
|
|
delay the input caputre by 4 clock cycles. Bit 6 is the Input Capture Edge
|
|
Select 1 (ICES1). (To write about).
|
|
|
|
The lower 3 bits (2-0) determine the clock source. The possible vlaues are
|
|
shown below.
|
|
|
|
| Bits | Description |
|
|
----------------------
|
|
| 000 | No clock source (off) |
|
|
| 001 | CLK I/O / 1 (no prescale) |
|
|
| 010 | / 8 Prescaler |
|
|
| 011 | / 64 Prescaler |
|
|
| 100 | / 256 Prescaler |
|
|
| 101 | / 1024 Prescaler |
|
|
| 110 | External Clock source on T1 (falling edge) |
|
|
| 111 | External Clock source on T1 (rising edge) |
|
|
|
|
NOTE T1 will trigger the clock even if the pin in configured as output.
|
|
|
|
While in normal mode the Timer/Counter 1 Register counts up (inremental) and no
|
|
counter clear is done. The counter will overflow when the max 16 bit value
|
|
(0xFFFF) is reached. The registers that contain the counter values are The
|
|
Timer/Counter 1 Register (TCNT1H:TCNT1L 0x85[15:8] and 0x84[7:0], together TCNT1).
|
|
|
|
The Output Compare Register 1 A (OCR1AH:OCR1AL 0x89[15:8] and 0x88[0:7], together OCR1A)
|
|
and Output Compare Register 1 B (OCR1BH:OCR1BL 0x8B[15:8] and 0x8A[0:7], together OCR1B)
|
|
contain 16 bit values are contantly compared to the TCNT1 register. A compare operation is
|
|
performed, and a match generates an interupt.
|
|
|
|
These Interrupts can be turned on/off using the Timer/Counter 1 Interrupt Mask
|
|
Register (TIMSK1 0x6F). This register acts similary to the EIMSK register. Bit
|
|
5 enables Timer/Counter1 Input capture Interrupt (ICIE1), and the corresponsing
|
|
interrupt is triggerd when the ICF1 flag in TIFR1 is set.
|
|
Bits 2-0 enable the interrupts for Matches with Output Compare B, A, and
|
|
overflow resepectivly. When Bit 2 is set, the corresponding interrupt is
|
|
triggered only when the OCF1B flags in TIFR1 is set. This same principle
|
|
applies for OCF1A in TIFR1 for Bit 1, and TOV1 in TIFR1 for Bit 0. For more
|
|
info on TIFR1, refer below.
|
|
|
|
THe Timer/Counter 1 Interrupt Flag Register (TIFR1 0x36) is the register that holds
|
|
flags when Counter 1 (TCNT1) reaches the values in OCR1A and OCR1B. Bit 5 is
|
|
set when The input capture set by WGM to be used as the TOP value. Bits 2-0 are
|
|
set when TCNT1 matches the value in OCR1B, OCR1A, when when TCNT1 overflows,
|
|
respectivly.
|
|
|
|
==== Prescaler ====
|
|
|
|
To make the clock useful, the following will be an example of how to use Timer
|
|
1 to delay a certain amount of time. You will need the following information
|
|
|
|
* CPU freq (16MHz)
|
|
* Max timer value (0xFFFF or 65536)
|
|
* Chosen Prescaler (See above for prescaler values)
|
|
|
|
Divide the CPU freq by the chosen prescaler. Then divide that result through
|
|
the desired freqency. Be sure that the value is smaller than the max timer
|
|
value. If it is to large, choose a larger prescaler. Then place this in the
|
|
OCR** Register and enable the desired interrupt.
|
|
|
|
To assist in finding the correct value, below are the values of the clock speed
|
|
(16Mhz) over the prescalers.
|
|
|
|
NOTE to help with calculations, 0xFFFF is 65536 and 0xFF is 256
|
|
|
|
| prescaler | value |
|
|
---------------------
|
|
| 8 | 2000000 |
|
|
| 64 | 250000 |
|
|
| 256 | 62500 |
|
|
| 1024 | 15625 |
|
|
|
|
|