= 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 |