= Arduino Nano/ATMega328P = A very small arduino product, better for hobby embedding see [[arduino_techniques|Programming Techniques]] See datasheet https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf == 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 === The ATMega328P can control all of its pins via the use of an abstraction, called ports. Each port has registers associated to it, and each pin corresponds to a bit in a port register. Port D controls pins D0 - 7, Port C controls the analog Pins, Port B controls pins D8 - 13 Each port has 3 registers associated with it. Port* is the register that allows writing to the pins. These are PortB (0x25), PortC (0x28), and PortD (0x2B). The Data Direction Registers (DDR*) determine if the Pin is used for Input or Output. When a bit is set to zero (0), the pin will be used for input. Setting a pin to one (1) will enable it for output. The three DDR* registers are DDRB, (0x24), DDRC (0x27), and DDRD (0x2A). Finally, there are the PIN* registers, which allow for input to taken. These registers are read only. The three PIN* registers are PINB (0x23), PINC (0x26), and PIND (0x29). To help with reading, the above info is in this table. | Port | DDR | Port | Pin | --------------------------- | B | 0x24 | 0x25 | 0x23 | | C | 0x27 | 0x28 | 0x26 | | D | 0x2A | 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 code an interrupt calls is called an Interrupt Service Routine (ISR). 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. The mode of the timer is set using the lower two bits (1-0) of TCCR1A and bits 4-3 of TCCR1B. The two bits in TCCR1A are known as Waveform Generation Mode 11 (WGM11) and WGM10 for bits 1 and 0 respectivily. Bits 4-3 on TCCR1B are known as WGM13 and WGM12 respecitvly. When ordred WGM13 through WGM10, they create a 4 bit value. The corresponding values and the effects are shown below. | Mode | Mode of operation | TOP | Update OCR1* at | TOV1 Flag set on | ----------------------------------------------------------------------- | 0 | Normal | 0xFFFF | Immediate | MAX | | 1 | PWM, phase correct, 8bit | 0x00FF | TOP | BOTTOM | | 2 | PWM, phase correct, 9-bit | 0x01FF | TOP | BOTTOM | | 3 | PWM, phase correct, 10-bit | 0x03FF | TOP | BOTTOM | | 4 | Clear on compare match | OCR1A | Immediate | MAX | | 5 | Fast PWM, 8bit | 0x00FF | BOTTOM | TOP | | 6 | Fast PWM, 9bit | 0x01FF | BOTTOM | TOP | | 7 | Fast PWM, 10bit | 0x03FF | BOTTOM | TOP | | 8 | PWM, phase and frequency correct | ICR1 | BOTTOM | BOTTOM | | 9 | PWM, phase and frequency correct | OCR1A | BOTTOM | BOTTOM | | 10 | PWM, phase correct | ICR1 | TOP | BOTTOM | | 11 | PWM, phase correct | OCR1A | TOP | BOTTOM | | 12 | CTC | ICR1 | Immediate | MAX | | 13 | RESERVED | | | | | 14 | Fast PWM | ICR1 | BOTTOM | TOP | | 15 | Fast PWM | OCR1A | BOTTOM | TOP | 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 | === Analog to Digital === The ATMega328P includes an [[ADC]] for reading analog inputs. The ADC, like everything else, is controlled via several control registers. The primary control register is the ADC Multiplexer Selection Register (ADMUX 0x7C). Bit 7 and 6 select the reference voltage for the ADC. Any updates to this register do not take effect till after an ongoing ADC operations has completed. The internal voltage reference may not be used if a voltage is applied across the AREF pin (Pin 21 on the Nano). Below are valid values for bits 7 and 6. | Bits (7-6) | Description | ---------------------------- | 00 | AREF, internal reference voltage turned off | | 01 | AV,,cc,,, with an external capactior on AREF | | 10 | Reserved (non functioning) | | 11 | Internal 1.1V reference used with capactior on AREF | Bit 5 of ADMUX changes the presentation of the ADC result, and when set to one (1) the value will be left adjusted, otherwise it will be right adjusted. This change happens instantly, regardless of the actions in the ADC. This option is called ADC Left Adjust Result (ADLAR). Bits 3-0 set which ADC pin will be converted (NOTE these are the pins on PortC on the Arduino Nano). For values 0 through 7 (binary values in bits 3-0), will select the corresponding ADC pin. 0b1000 is a sepcial ADC, connected to the internal temperture sensor. 0b1110 (10d14) is the internal reference voltage of 1.1V, and 0b1111 (10d15) is internal reference GND (0V). All non mentioned values are not used To control the ADC, the ADC control and Status Register A (ADCSRA 0x7A) and ADC Control and Status Register B (ADCSRB 0x7B) are used. Bit 7 of ADCSRA (ADC Enable or ADEN) enables the ADC when high (1), and disables when low. Setting this bit low during a conversion will stop the conversion. Bit 6 of ADCSRA (ADC Start Conversion or ADSC) will start the ADC. The first conversion performed when enabling this (since ADEN was changed), will take 25 cycles instead of 13, due to the init that must be done. Bit 5 of ADCSRA enables auto triggering of the ADC. The conversion will start on the positive edge of a trigger. See the trigger selection bits in ADCSRB. Bit 4 is the interrupt flag for completed ADC conversions. To Enable this interrupt, write a one to Bit 3, the ADC interrupt enable. Finally, Bits 2-0 are the ADC prescaler bits. These determine the division factor between the system clock and the input clock to the ADC. Valid values are shown below. | Bits (2-0) | Division Factor | -------------------------------- | 000 | 2 | | 001 | 2 | | 010 | 4 | | 011 | 8 | | 100 | 16 | | 101 | 32 | | 110 | 64 | | 111 | 128 | ADCSRB is also used to control the ADC, and Bits 2-0 control the ADC auto trigger source. All of these conversions occour on the rising edge of the selected source. If ADEN in ADCSRA is set, then the corresponding interrupts will be called. (NOTE: Free running mode, 0b000, generates no interrupts and just continously converts input). | Bits (2-0) | Trigger Source | ------------------------------- | 000 | Free running mode (No interrupts) | | 001 | Analog Comparator | | 010 | External Interrupt 0 | | 011 | Timer/Counter0 compare Match A | | 100 | Timer/Counter0 overflow | | 101 | Timer/Counter1 compare Match B | | 110 | Timer/Counter1 overflow | | 111 | Timer/Counter1 capture event | The result of the ADC conversion is stored in the ADC Data Register (ADCH:ADCL 0x79[15:8] and 0x78[7:0]). When ADLAR of ADMUX is set low, Bit 9 of the ADC data register is the most signifigant bit, and Bit 0 is the least. When ADLAR is high, Bit 15 is the most signifigant, while Bit 6 is the least. When running pins in analog mode, the digital input buffer on the pin can also be disabled (this is ideal to save power).