mirror of
https://github.com/AlexGyver/GyverCore.git
synced 2025-04-19 08:42:16 +03:00
add
This commit is contained in:
parent
983b80cb94
commit
c52f478bb5
@ -5,7 +5,7 @@ menu.timers=Timers
|
||||
|
||||
######################
|
||||
|
||||
nano.name=ATmega328P based
|
||||
nano.name=ATmega328/168 based
|
||||
|
||||
nano.upload.tool=avrdude
|
||||
nano.upload.protocol=arduino
|
||||
@ -21,10 +21,10 @@ nano.build.core=arduino
|
||||
|
||||
## timer0 OVF ON/OFF
|
||||
## --------------------------
|
||||
nano.menu.timers.yes_millis=yes millis
|
||||
nano.menu.timers.yes_millis=with millis
|
||||
nano.menu.timers.yes_millis.build.variant=yesmillis
|
||||
|
||||
nano.menu.timers.no_millis=no millis
|
||||
nano.menu.timers.no_millis=without millis
|
||||
nano.menu.timers.no_millis.build.variant=nomillis
|
||||
|
||||
|
||||
@ -62,7 +62,7 @@ nano.menu.cpu.atmega328old.build.mcu=atmega328p
|
||||
|
||||
## ATmega328P - NO bootloader
|
||||
## --------------------------
|
||||
nano.menu.cpu.atmega328noBoot=ATmega328P - NO bootloader
|
||||
nano.menu.cpu.atmega328noBoot=ATmega328P - without bootloader
|
||||
|
||||
nano.menu.cpu.atmega328noBoot.upload.maximum_size=32768
|
||||
nano.menu.cpu.atmega328noBoot.upload.maximum_data_size=2048
|
||||
@ -107,7 +107,7 @@ nano.menu.cpu.atmega168old.build.mcu=atmega168
|
||||
|
||||
## ATmega168 - NO bootloader
|
||||
## -------------------------
|
||||
nano.menu.cpu.atmega168noBoot=ATmega168 - NO bootloader
|
||||
nano.menu.cpu.atmega168noBoot=ATmega168 - without bootloader
|
||||
|
||||
nano.menu.cpu.atmega168noBoot.upload.maximum_size=16144
|
||||
nano.menu.cpu.atmega168noBoot.upload.maximum_data_size=1024
|
||||
|
@ -161,62 +161,7 @@ void detachInterrupt(uint8_t);
|
||||
void setup(void);
|
||||
void loop(void);
|
||||
|
||||
#define analogInPinToBit(P) (P)
|
||||
|
||||
extern const uint16_t PROGMEM port_to_mode_PGM[];
|
||||
extern const uint16_t PROGMEM port_to_input_PGM[];
|
||||
extern const uint16_t PROGMEM port_to_output_PGM[];
|
||||
|
||||
extern const uint8_t PROGMEM digital_pin_to_port_PGM[];
|
||||
// extern const uint8_t PROGMEM digital_pin_to_bit_PGM[];
|
||||
extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[];
|
||||
extern const uint8_t PROGMEM digital_pin_to_timer_PGM[];
|
||||
|
||||
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
|
||||
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
|
||||
#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) )
|
||||
#define analogInPinToBit(P) (P)
|
||||
#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) )
|
||||
#define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) )
|
||||
#define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) )
|
||||
|
||||
#define NOT_A_PIN 0
|
||||
#define NOT_A_PORT 0
|
||||
|
||||
#define NOT_AN_INTERRUPT -1
|
||||
|
||||
#define PA 1
|
||||
#define PB 2
|
||||
#define PC 3
|
||||
#define PD 4
|
||||
#define PE 5
|
||||
#define PF 6
|
||||
#define PG 7
|
||||
#define PH 8
|
||||
#define PJ 10
|
||||
#define PK 11
|
||||
#define PL 12
|
||||
|
||||
#define NOT_ON_TIMER 0
|
||||
#define TIMER0A 1
|
||||
#define TIMER0B 2
|
||||
#define TIMER1A 3
|
||||
#define TIMER1B 4
|
||||
#define TIMER1C 5
|
||||
#define TIMER2 6
|
||||
#define TIMER2A 7
|
||||
#define TIMER2B 8
|
||||
|
||||
#define TIMER3A 9
|
||||
#define TIMER3B 10
|
||||
#define TIMER3C 11
|
||||
#define TIMER4A 12
|
||||
#define TIMER4B 13
|
||||
#define TIMER4C 14
|
||||
#define TIMER4D 15
|
||||
#define TIMER5A 16
|
||||
#define TIMER5B 17
|
||||
#define TIMER5C 18
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
@ -239,8 +184,8 @@ uint16_t makeWord(byte h, byte l);
|
||||
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
|
||||
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
|
||||
|
||||
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0);
|
||||
void noTone(uint8_t _pin);
|
||||
void tone(uint8_t pin , uint16_t freq, uint32_t duration = 0);
|
||||
void noTone(uint8_t pin);
|
||||
|
||||
// WMath prototypes
|
||||
long random(long);
|
||||
|
@ -1,619 +1,46 @@
|
||||
/* Tone.cpp
|
||||
|
||||
A Tone Generator Library
|
||||
|
||||
Written by Brett Hagman
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- -------- --------
|
||||
0001 B Hagman 09/08/02 Initial coding
|
||||
0002 B Hagman 09/08/18 Multiple pins
|
||||
0003 B Hagman 09/08/18 Moved initialization from constructor to begin()
|
||||
0004 B Hagman 09/09/26 Fixed problems with ATmega8
|
||||
0005 B Hagman 09/11/23 Scanned prescalars for best fit on 8 bit timers
|
||||
09/11/25 Changed pin toggle method to XOR
|
||||
09/11/25 Fixed timer0 from being excluded
|
||||
0006 D Mellis 09/12/29 Replaced objects with functions
|
||||
0007 M Sproul 10/08/29 Changed #ifdefs from cpu to register
|
||||
0008 S Kanemoto 12/06/22 Fixed for Leonardo by @maris_HY
|
||||
0009 J Reucker 15/04/10 Issue #292 Fixed problems with ATmega8 (thanks to Pete62)
|
||||
0010 jipp 15/04/13 added additional define check #2923
|
||||
*************************************************/
|
||||
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include "Arduino.h"
|
||||
//#include "pins_arduino.h"
|
||||
/* оптимизированный вариант реализации tone */
|
||||
uint8_t tone_pin; // глобальная переменная для пина
|
||||
uint32_t toggle_counter; // счетчик toggl'ов
|
||||
uint32_t toggle_top; // предел счета для toggl'ов
|
||||
bool willStop; // флаг позволяющий генерировать сигнал бесконечно долго
|
||||
|
||||
#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega128__)
|
||||
#define TCCR2A TCCR2
|
||||
#define TCCR2B TCCR2
|
||||
#define COM2A1 COM21
|
||||
#define COM2A0 COM20
|
||||
#define OCR2A OCR2
|
||||
#define TIMSK2 TIMSK
|
||||
#define OCIE2A OCIE2
|
||||
#define TIMER2_COMPA_vect TIMER2_COMP_vect
|
||||
#define TIMSK1 TIMSK
|
||||
#endif
|
||||
void tone(uint8_t pin , uint16_t freq, uint32_t duration = 0){
|
||||
tone_pin = pin; // присвоили номер пина для прерывания
|
||||
willStop = duration;// если введено время генерации - будет ненулевым
|
||||
toggle_top = (freq * duration)/500; // расчет кол-ва toggl'ов за указанное время генерации
|
||||
TCCR2A = (1<<WGM21); // вкл CTC
|
||||
TIMSK2 |= (1<<OCIE2A); //Вкл прерывание
|
||||
if(freq < 122){ // максимальный делитель
|
||||
TCCR2B = 0x7; // присвоили делитель
|
||||
OCR2A = (15625/freq)-1; // рассчитали top для CTC
|
||||
}
|
||||
if(freq > 244){ // минимальный делитель
|
||||
TCCR2B = 0x5; // по аналогии см выше
|
||||
OCR2A = (62500/freq)-1; // по аналогии см выше
|
||||
}
|
||||
else { // средний делитель
|
||||
TCCR2B = 0x6; // по аналогии см выше
|
||||
OCR2A = (125000/freq)-1; // по аналогии см выше
|
||||
}
|
||||
toggle_counter = 0; // обнулили счетчик toggl'ов
|
||||
}
|
||||
|
||||
// timerx_toggle_count:
|
||||
// > 0 - duration specified
|
||||
// = 0 - stopped
|
||||
// < 0 - infinitely (until stop() method called, or new play() called)
|
||||
|
||||
#if !defined(__AVR_ATmega8__)
|
||||
volatile long timer0_toggle_count;
|
||||
volatile uint8_t *timer0_pin_port;
|
||||
volatile uint8_t timer0_pin_mask;
|
||||
#endif
|
||||
|
||||
volatile long timer1_toggle_count;
|
||||
volatile uint8_t *timer1_pin_port;
|
||||
volatile uint8_t timer1_pin_mask;
|
||||
volatile long timer2_toggle_count;
|
||||
volatile uint8_t *timer2_pin_port;
|
||||
volatile uint8_t timer2_pin_mask;
|
||||
|
||||
#if defined(TIMSK3)
|
||||
volatile long timer3_toggle_count;
|
||||
volatile uint8_t *timer3_pin_port;
|
||||
volatile uint8_t timer3_pin_mask;
|
||||
#endif
|
||||
|
||||
#if defined(TIMSK4)
|
||||
volatile long timer4_toggle_count;
|
||||
volatile uint8_t *timer4_pin_port;
|
||||
volatile uint8_t timer4_pin_mask;
|
||||
#endif
|
||||
|
||||
#if defined(TIMSK5)
|
||||
volatile long timer5_toggle_count;
|
||||
volatile uint8_t *timer5_pin_port;
|
||||
volatile uint8_t timer5_pin_mask;
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
|
||||
#define AVAILABLE_TONE_PINS 1
|
||||
#define USE_TIMER2
|
||||
|
||||
const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 3, 4, 5, 1, 0 */ };
|
||||
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255, 255, 255, 255, 255 */ };
|
||||
|
||||
#elif defined(__AVR_ATmega8__)
|
||||
|
||||
#define AVAILABLE_TONE_PINS 1
|
||||
#define USE_TIMER2
|
||||
|
||||
const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 1 */ };
|
||||
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255 */ };
|
||||
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
|
||||
#define AVAILABLE_TONE_PINS 1
|
||||
#define USE_TIMER3
|
||||
|
||||
const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 3 /*, 1 */ };
|
||||
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255 */ };
|
||||
|
||||
#else
|
||||
|
||||
#define AVAILABLE_TONE_PINS 1
|
||||
#define USE_TIMER2
|
||||
|
||||
// Leave timer 0 to last.
|
||||
const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 1, 0 */ };
|
||||
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255, 255 */ };
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static int8_t toneBegin(uint8_t _pin)
|
||||
{
|
||||
int8_t _timer = -1;
|
||||
|
||||
// if we're already using the pin, the timer should be configured.
|
||||
for (int i = 0; i < AVAILABLE_TONE_PINS; i++) {
|
||||
if (tone_pins[i] == _pin) {
|
||||
return pgm_read_byte(tone_pin_to_timer_PGM + i);
|
||||
}
|
||||
}
|
||||
|
||||
// search for an unused timer.
|
||||
for (int i = 0; i < AVAILABLE_TONE_PINS; i++) {
|
||||
if (tone_pins[i] == 255) {
|
||||
tone_pins[i] = _pin;
|
||||
_timer = pgm_read_byte(tone_pin_to_timer_PGM + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_timer != -1)
|
||||
{
|
||||
// Set timer specific stuff
|
||||
// All timers in CTC mode
|
||||
// 8 bit timers will require changing prescalar values,
|
||||
// whereas 16 bit timers are set to either ck/1 or ck/64 prescalar
|
||||
switch (_timer)
|
||||
{
|
||||
#if defined(TCCR0A) && defined(TCCR0B) && defined(WGM01)
|
||||
case 0:
|
||||
// 8 bit timer
|
||||
TCCR0A = 0;
|
||||
TCCR0B = 0;
|
||||
bitWrite(TCCR0A, WGM01, 1);
|
||||
bitWrite(TCCR0B, CS00, 1);
|
||||
timer0_pin_port = portOutputRegister(digitalPinToPort(_pin));
|
||||
timer0_pin_mask = digitalPinToBitMask(_pin);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR1A) && defined(TCCR1B) && defined(WGM12)
|
||||
case 1:
|
||||
// 16 bit timer
|
||||
TCCR1A = 0;
|
||||
TCCR1B = 0;
|
||||
bitWrite(TCCR1B, WGM12, 1);
|
||||
bitWrite(TCCR1B, CS10, 1);
|
||||
timer1_pin_port = portOutputRegister(digitalPinToPort(_pin));
|
||||
timer1_pin_mask = digitalPinToBitMask(_pin);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR2A) && defined(TCCR2B)
|
||||
case 2:
|
||||
// 8 bit timer
|
||||
TCCR2A = 0;
|
||||
TCCR2B = 0;
|
||||
bitWrite(TCCR2A, WGM21, 1);
|
||||
bitWrite(TCCR2B, CS20, 1);
|
||||
timer2_pin_port = portOutputRegister(digitalPinToPort(_pin));
|
||||
timer2_pin_mask = digitalPinToBitMask(_pin);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR3A) && defined(TCCR3B) && defined(TIMSK3)
|
||||
case 3:
|
||||
// 16 bit timer
|
||||
TCCR3A = 0;
|
||||
TCCR3B = 0;
|
||||
bitWrite(TCCR3B, WGM32, 1);
|
||||
bitWrite(TCCR3B, CS30, 1);
|
||||
timer3_pin_port = portOutputRegister(digitalPinToPort(_pin));
|
||||
timer3_pin_mask = digitalPinToBitMask(_pin);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR4A) && defined(TCCR4B) && defined(TIMSK4)
|
||||
case 4:
|
||||
// 16 bit timer
|
||||
TCCR4A = 0;
|
||||
TCCR4B = 0;
|
||||
#if defined(WGM42)
|
||||
bitWrite(TCCR4B, WGM42, 1);
|
||||
#elif defined(CS43)
|
||||
// TODO this may not be correct
|
||||
// atmega32u4
|
||||
bitWrite(TCCR4B, CS43, 1);
|
||||
#endif
|
||||
bitWrite(TCCR4B, CS40, 1);
|
||||
timer4_pin_port = portOutputRegister(digitalPinToPort(_pin));
|
||||
timer4_pin_mask = digitalPinToBitMask(_pin);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TCCR5A) && defined(TCCR5B) && defined(TIMSK5)
|
||||
case 5:
|
||||
// 16 bit timer
|
||||
TCCR5A = 0;
|
||||
TCCR5B = 0;
|
||||
bitWrite(TCCR5B, WGM52, 1);
|
||||
bitWrite(TCCR5B, CS50, 1);
|
||||
timer5_pin_port = portOutputRegister(digitalPinToPort(_pin));
|
||||
timer5_pin_mask = digitalPinToBitMask(_pin);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return _timer;
|
||||
void noTone(uint8_t pin){ // если вызван noTone
|
||||
digitalWrite(pin,0);// устанавливаем 0 на выходе
|
||||
TIMSK2 &=~ (1<<OCIE2A); // остановить прерывания
|
||||
TCCR2A = 0b00000011; // установить стандартные настройки для таймера 2
|
||||
TCCR2B = 0b00000100;
|
||||
OCR2A = 0; //обнуляем регистр сравнения
|
||||
TCCR2A &=~ ((1<<COM2A1)|(1<<COM2B1)); // откл регистры сравнения (подстраховка)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// frequency (in hertz) and duration (in milliseconds).
|
||||
|
||||
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration)
|
||||
{
|
||||
uint8_t prescalarbits = 0b001;
|
||||
long toggle_count = 0;
|
||||
uint32_t ocr = 0;
|
||||
int8_t _timer;
|
||||
|
||||
_timer = toneBegin(_pin);
|
||||
|
||||
if (_timer >= 0)
|
||||
{
|
||||
// Set the pinMode as OUTPUT
|
||||
pinMode(_pin, OUTPUT);
|
||||
|
||||
// if we are using an 8 bit timer, scan through prescalars to find the best fit
|
||||
if (_timer == 0 || _timer == 2)
|
||||
{
|
||||
ocr = F_CPU / frequency / 2 - 1;
|
||||
prescalarbits = 0b001; // ck/1: same for both timers
|
||||
if (ocr > 255)
|
||||
{
|
||||
ocr = F_CPU / frequency / 2 / 8 - 1;
|
||||
prescalarbits = 0b010; // ck/8: same for both timers
|
||||
|
||||
if (_timer == 2 && ocr > 255)
|
||||
{
|
||||
ocr = F_CPU / frequency / 2 / 32 - 1;
|
||||
prescalarbits = 0b011;
|
||||
}
|
||||
|
||||
if (ocr > 255)
|
||||
{
|
||||
ocr = F_CPU / frequency / 2 / 64 - 1;
|
||||
prescalarbits = _timer == 0 ? 0b011 : 0b100;
|
||||
|
||||
if (_timer == 2 && ocr > 255)
|
||||
{
|
||||
ocr = F_CPU / frequency / 2 / 128 - 1;
|
||||
prescalarbits = 0b101;
|
||||
}
|
||||
|
||||
if (ocr > 255)
|
||||
{
|
||||
ocr = F_CPU / frequency / 2 / 256 - 1;
|
||||
prescalarbits = _timer == 0 ? 0b100 : 0b110;
|
||||
if (ocr > 255)
|
||||
{
|
||||
// can't do any better than /1024
|
||||
ocr = F_CPU / frequency / 2 / 1024 - 1;
|
||||
prescalarbits = _timer == 0 ? 0b101 : 0b111;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(TCCR0B)
|
||||
if (_timer == 0)
|
||||
{
|
||||
TCCR0B = (TCCR0B & 0b11111000) | prescalarbits;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#if defined(TCCR2B)
|
||||
{
|
||||
TCCR2B = (TCCR2B & 0b11111000) | prescalarbits;
|
||||
}
|
||||
#else
|
||||
{
|
||||
// dummy place holder to make the above ifdefs work
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// two choices for the 16 bit timers: ck/1 or ck/64
|
||||
ocr = F_CPU / frequency / 2 - 1;
|
||||
|
||||
prescalarbits = 0b001;
|
||||
if (ocr > 0xffff)
|
||||
{
|
||||
ocr = F_CPU / frequency / 2 / 64 - 1;
|
||||
prescalarbits = 0b011;
|
||||
}
|
||||
|
||||
if (_timer == 1)
|
||||
{
|
||||
#if defined(TCCR1B)
|
||||
TCCR1B = (TCCR1B & 0b11111000) | prescalarbits;
|
||||
#endif
|
||||
}
|
||||
#if defined(TCCR3B)
|
||||
else if (_timer == 3)
|
||||
TCCR3B = (TCCR3B & 0b11111000) | prescalarbits;
|
||||
#endif
|
||||
#if defined(TCCR4B)
|
||||
else if (_timer == 4)
|
||||
TCCR4B = (TCCR4B & 0b11111000) | prescalarbits;
|
||||
#endif
|
||||
#if defined(TCCR5B)
|
||||
else if (_timer == 5)
|
||||
TCCR5B = (TCCR5B & 0b11111000) | prescalarbits;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Calculate the toggle count
|
||||
if (duration > 0)
|
||||
{
|
||||
toggle_count = 2 * frequency * duration / 1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
toggle_count = -1;
|
||||
}
|
||||
|
||||
// Set the OCR for the given timer,
|
||||
// set the toggle count,
|
||||
// then turn on the interrupts
|
||||
switch (_timer)
|
||||
{
|
||||
|
||||
#if defined(OCR0A) && defined(TIMSK0) && defined(OCIE0A)
|
||||
case 0:
|
||||
OCR0A = ocr;
|
||||
timer0_toggle_count = toggle_count;
|
||||
bitWrite(TIMSK0, OCIE0A, 1);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 1:
|
||||
#if defined(OCR1A) && defined(TIMSK1) && defined(OCIE1A)
|
||||
OCR1A = ocr;
|
||||
timer1_toggle_count = toggle_count;
|
||||
bitWrite(TIMSK1, OCIE1A, 1);
|
||||
#elif defined(OCR1A) && defined(TIMSK) && defined(OCIE1A)
|
||||
// this combination is for at least the ATmega32
|
||||
OCR1A = ocr;
|
||||
timer1_toggle_count = toggle_count;
|
||||
bitWrite(TIMSK, OCIE1A, 1);
|
||||
#endif
|
||||
break;
|
||||
|
||||
#if defined(OCR2A) && defined(TIMSK2) && defined(OCIE2A)
|
||||
case 2:
|
||||
OCR2A = ocr;
|
||||
timer2_toggle_count = toggle_count;
|
||||
bitWrite(TIMSK2, OCIE2A, 1);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(OCR3A) && defined(TIMSK3) && defined(OCIE3A)
|
||||
case 3:
|
||||
OCR3A = ocr;
|
||||
timer3_toggle_count = toggle_count;
|
||||
bitWrite(TIMSK3, OCIE3A, 1);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(OCR4A) && defined(TIMSK4) && defined(OCIE4A)
|
||||
case 4:
|
||||
OCR4A = ocr;
|
||||
timer4_toggle_count = toggle_count;
|
||||
bitWrite(TIMSK4, OCIE4A, 1);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(OCR5A) && defined(TIMSK5) && defined(OCIE5A)
|
||||
case 5:
|
||||
OCR5A = ocr;
|
||||
timer5_toggle_count = toggle_count;
|
||||
bitWrite(TIMSK5, OCIE5A, 1);
|
||||
break;
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
ISR(TIMER2_COMPA_vect){ // прерывание генерации
|
||||
if(toggle_counter < toggle_top || !willStop ){ // если количество toggl'ов не достигло предела или процесс бесконечен - генерация
|
||||
digitalToggle(tone_pin); // иневертируем состоние на ноге
|
||||
toggle_counter++; // икремент счетчика
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// XXX: this function only works properly for timer 2 (the only one we use
|
||||
// currently). for the others, it should end the tone, but won't restore
|
||||
// proper PWM functionality for the timer.
|
||||
void disableTimer(uint8_t _timer)
|
||||
{
|
||||
switch (_timer)
|
||||
{
|
||||
case 0:
|
||||
#if defined(TIMSK0)
|
||||
TIMSK0 = 0;
|
||||
#elif defined(TIMSK)
|
||||
TIMSK = 0; // atmega32
|
||||
#endif
|
||||
break;
|
||||
|
||||
#if defined(TIMSK1) && defined(OCIE1A)
|
||||
case 1:
|
||||
bitWrite(TIMSK1, OCIE1A, 0);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 2:
|
||||
#if defined(TIMSK2) && defined(OCIE2A)
|
||||
bitWrite(TIMSK2, OCIE2A, 0); // disable interrupt
|
||||
#endif
|
||||
#if defined(TCCR2A) && defined(WGM20)
|
||||
TCCR2A = (1 << WGM20);
|
||||
#endif
|
||||
#if defined(TCCR2B) && defined(CS22)
|
||||
TCCR2B = (TCCR2B & 0b11111000) | (1 << CS22);
|
||||
#endif
|
||||
#if defined(OCR2A)
|
||||
OCR2A = 0;
|
||||
#endif
|
||||
break;
|
||||
|
||||
#if defined(TIMSK3) && defined(OCIE3A)
|
||||
case 3:
|
||||
bitWrite(TIMSK3, OCIE3A, 0);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TIMSK4) && defined(OCIE4A)
|
||||
case 4:
|
||||
bitWrite(TIMSK4, OCIE4A, 0);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TIMSK5) && defined(OCIE5A)
|
||||
case 5:
|
||||
bitWrite(TIMSK5, OCIE5A, 0);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void noTone(uint8_t _pin)
|
||||
{
|
||||
int8_t _timer = -1;
|
||||
|
||||
for (int i = 0; i < AVAILABLE_TONE_PINS; i++) {
|
||||
if (tone_pins[i] == _pin) {
|
||||
_timer = pgm_read_byte(tone_pin_to_timer_PGM + i);
|
||||
tone_pins[i] = 255;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
disableTimer(_timer);
|
||||
|
||||
digitalWrite(_pin, 0);
|
||||
}
|
||||
|
||||
#ifdef USE_TIMER0
|
||||
ISR(TIMER0_COMPA_vect)
|
||||
{
|
||||
if (timer0_toggle_count != 0)
|
||||
{
|
||||
// toggle the pin
|
||||
*timer0_pin_port ^= timer0_pin_mask;
|
||||
|
||||
if (timer0_toggle_count > 0)
|
||||
timer0_toggle_count--;
|
||||
}
|
||||
else
|
||||
{
|
||||
disableTimer(0);
|
||||
*timer0_pin_port &= ~(timer0_pin_mask); // keep pin low after stop
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_TIMER1
|
||||
ISR(TIMER1_COMPA_vect)
|
||||
{
|
||||
if (timer1_toggle_count != 0)
|
||||
{
|
||||
// toggle the pin
|
||||
*timer1_pin_port ^= timer1_pin_mask;
|
||||
|
||||
if (timer1_toggle_count > 0)
|
||||
timer1_toggle_count--;
|
||||
}
|
||||
else
|
||||
{
|
||||
disableTimer(1);
|
||||
*timer1_pin_port &= ~(timer1_pin_mask); // keep pin low after stop
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_TIMER2
|
||||
ISR(TIMER2_COMPA_vect)
|
||||
{
|
||||
|
||||
if (timer2_toggle_count != 0)
|
||||
{
|
||||
// toggle the pin
|
||||
*timer2_pin_port ^= timer2_pin_mask;
|
||||
|
||||
if (timer2_toggle_count > 0)
|
||||
timer2_toggle_count--;
|
||||
}
|
||||
else
|
||||
{
|
||||
// need to call noTone() so that the tone_pins[] entry is reset, so the
|
||||
// timer gets initialized next time we call tone().
|
||||
// XXX: this assumes timer 2 is always the first one used.
|
||||
noTone(tone_pins[0]);
|
||||
// disableTimer(2);
|
||||
// *timer2_pin_port &= ~(timer2_pin_mask); // keep pin low after stop
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_TIMER3
|
||||
ISR(TIMER3_COMPA_vect)
|
||||
{
|
||||
if (timer3_toggle_count != 0)
|
||||
{
|
||||
// toggle the pin
|
||||
*timer3_pin_port ^= timer3_pin_mask;
|
||||
|
||||
if (timer3_toggle_count > 0)
|
||||
timer3_toggle_count--;
|
||||
}
|
||||
else
|
||||
{
|
||||
disableTimer(3);
|
||||
*timer3_pin_port &= ~(timer3_pin_mask); // keep pin low after stop
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_TIMER4
|
||||
ISR(TIMER4_COMPA_vect)
|
||||
{
|
||||
if (timer4_toggle_count != 0)
|
||||
{
|
||||
// toggle the pin
|
||||
*timer4_pin_port ^= timer4_pin_mask;
|
||||
|
||||
if (timer4_toggle_count > 0)
|
||||
timer4_toggle_count--;
|
||||
}
|
||||
else
|
||||
{
|
||||
disableTimer(4);
|
||||
*timer4_pin_port &= ~(timer4_pin_mask); // keep pin low after stop
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_TIMER5
|
||||
ISR(TIMER5_COMPA_vect)
|
||||
{
|
||||
if (timer5_toggle_count != 0)
|
||||
{
|
||||
// toggle the pin
|
||||
*timer5_pin_port ^= timer5_pin_mask;
|
||||
|
||||
if (timer5_toggle_count > 0)
|
||||
timer5_toggle_count--;
|
||||
}
|
||||
else
|
||||
{
|
||||
disableTimer(5);
|
||||
*timer5_pin_port &= ~(timer5_pin_mask); // keep pin low after stop
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1,12 +1,13 @@
|
||||
/* Главный цикл программы */
|
||||
#include <Arduino.h>
|
||||
int main(void)
|
||||
{
|
||||
WDTCSR = 0; // wdt disable
|
||||
init();
|
||||
setup();
|
||||
while (1) {
|
||||
loop();
|
||||
if (serialEventRun) serialEventRun();
|
||||
WDTCSR = 0; // Первым делом отключаем ватчдог
|
||||
init(); // инициализация таймеров и ацп
|
||||
setup(); // функция setup
|
||||
while (1) { // бесконечный цикл
|
||||
loop(); // функция loop
|
||||
if (serialEventRun) serialEventRun(); // обслуживание serial
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "Arduino.h"
|
||||
#include "timeControl.h"
|
||||
|
||||
/* функции времени и инициализация таймеров , АЦП*/
|
||||
#define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256)) // 1024
|
||||
#define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000) // 1
|
||||
#define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3) // 3
|
||||
@ -10,7 +10,7 @@ volatile unsigned long timer0_overflow_count = 0;
|
||||
volatile unsigned long timer0_millis = 0;
|
||||
static unsigned char timer0_fract = 0;
|
||||
|
||||
#ifdef MILLIS_TMRS
|
||||
#ifdef MILLIS_TMRS // переключатель, отключающий millis(), освобождающий вектор прерывания
|
||||
ISR(TIMER0_OVF_vect)
|
||||
{
|
||||
timer0_millis++;
|
||||
@ -24,20 +24,20 @@ ISR(TIMER0_OVF_vect)
|
||||
#endif
|
||||
|
||||
unsigned long millis() {
|
||||
cli();
|
||||
unsigned long m = timer0_millis;
|
||||
sei();
|
||||
return m;
|
||||
cli(); // остановить счет
|
||||
unsigned long m = timer0_millis; // перехватить значение
|
||||
sei(); // продолжить счет
|
||||
return m; // вернуть миллисекунды
|
||||
}
|
||||
|
||||
unsigned long micros() {
|
||||
cli();
|
||||
unsigned long m = timer0_overflow_count;
|
||||
uint8_t t = TCNT0;
|
||||
if ((TIFR0 & _BV(TOV0)) && (t < 255))
|
||||
cli(); // остановить прерывания
|
||||
unsigned long m = timer0_overflow_count; // счет переполнений
|
||||
uint8_t t = TCNT0; // считать содержимое счетного регистра
|
||||
if ((TIFR0 & _BV(TOV0)) && (t < 255)) //инкремент по переполнению
|
||||
m++;
|
||||
sei();
|
||||
return (long)(((m << 8) + t) * 4);
|
||||
sei(); // продолжить счет
|
||||
return (long)(((m << 8) + t) * 4); // вернуть микросекунды
|
||||
}
|
||||
|
||||
/*
|
||||
@ -77,11 +77,11 @@ void delayMicroseconds(unsigned int us)
|
||||
*/
|
||||
|
||||
|
||||
void delay(unsigned long ms)
|
||||
void delay(unsigned long ms)
|
||||
{
|
||||
uint32_t start = micros();
|
||||
uint32_t start = micros(); // запомнили время старта
|
||||
|
||||
while (ms > 0) {
|
||||
while (ms > 0) { // ведем отсчет
|
||||
yield();
|
||||
while ( ms > 0 && (micros() - start) >= 1000) {
|
||||
ms--;
|
||||
@ -91,15 +91,13 @@ void delay(unsigned long ms)
|
||||
}
|
||||
|
||||
|
||||
void delayMicroseconds(unsigned int us)
|
||||
void delayMicroseconds(unsigned int us) // работает на счете тиков
|
||||
{
|
||||
|
||||
#if F_CPU >= 16000000L
|
||||
if (us <= 1) return; // = 3 cycles, (4 when true)
|
||||
us <<= 2; // x4 us, = 4 cycles
|
||||
us -= 5;
|
||||
#endif
|
||||
|
||||
// busy wait
|
||||
__asm__ __volatile__ (
|
||||
"1: sbiw %0,1" "\n\t" // 2 cycles
|
||||
@ -109,24 +107,24 @@ void delayMicroseconds(unsigned int us)
|
||||
}
|
||||
|
||||
|
||||
void init()
|
||||
void init() // функция инициализации
|
||||
{
|
||||
cli();
|
||||
cli();
|
||||
/* timer 0 */
|
||||
TCCR0A = 0b00000011; // fast pwm 8 bit
|
||||
TCCR0B = 0b00000011; // prescaler 64
|
||||
TIMSK0 |= (1<<TOIE0); // ovf interrupt enable
|
||||
TCCR0B = 0b00000011; // делитель 64
|
||||
TIMSK0 |= (1<<TOIE0); // ovf interrupt вкл
|
||||
/* timer 1 */
|
||||
TCCR1A = 0b00000001; // fast pwm 8 bit
|
||||
TCCR1B = 0b00001011; // prescaler 64
|
||||
TCCR1B = 0b00001011; // делитель 64
|
||||
/* timer 2 */
|
||||
TCCR2A = 0b00000011; // fast pwm 8 bit
|
||||
TCCR2B = 0b00000100; // prescaler 64
|
||||
TCCR2B = 0b00000100; // делитель 64
|
||||
/* adc */
|
||||
ADMUX = 0b01001111; // reference - vcc , adc parked to gnd
|
||||
ADCSRA = 0b10000010; // prescaler - 4 [0,1,2 bits - prescaler]
|
||||
ADMUX = 0b01001111; // reference - vcc , вход ацп припаркован к gnd
|
||||
ADCSRA = 0b10000010; // делитель - 4 [0,1,2 bits - делитель]
|
||||
/* ADC prescalers: 001 >> /2 010 >> /4 011 >> /8 100 >> /16 101 >> /32 110 >> /64 111 >> /128*/
|
||||
/* UART */
|
||||
UCSR0B = 0;
|
||||
UCSR0B = 0; // пока не вызван Serial.begin / uartBegin выводы 0/1 свободны для работы.
|
||||
sei();
|
||||
}
|
||||
|
@ -1,46 +1,48 @@
|
||||
#include "uart.h"
|
||||
/* Реализация облегченного Serial от AlexGyver & Egor 'Nich1con' Zaharov*/
|
||||
|
||||
// ===== INIT =====
|
||||
void uartBegin(uint32_t baudrate){
|
||||
uint16_t speed = (2000000/baudrate)-1;
|
||||
UBRR0H = highByte(speed);
|
||||
void uartBegin(uint32_t baudrate){ // инициализация uart
|
||||
uint16_t speed = (2000000/baudrate)-1; // расчет baudrate
|
||||
UBRR0H = highByte(speed); // установка baudrate
|
||||
UBRR0L = lowByte(speed);
|
||||
UCSR0A = (1 << U2X0);
|
||||
UCSR0B = ((1<<TXEN0) | (1<<RXEN0) | (1<<RXCIE0));
|
||||
UCSR0C = ((1<<UCSZ01) | (1<<UCSZ00));
|
||||
UCSR0A = (1 << U2X0); // вкл удвоенную скорость
|
||||
UCSR0B = ((1<<TXEN0) | (1<<RXEN0) | (1<<RXCIE0)); // вкл uart
|
||||
UCSR0C = ((1<<UCSZ01) | (1<<UCSZ00)); // настраиваем формат данных
|
||||
}
|
||||
void uartBegin(void) {
|
||||
void uartBegin(void) { // вызов uartBegin без параметра настроит скорость 9600
|
||||
uartBegin(9600);
|
||||
}
|
||||
|
||||
void uartEnd(){
|
||||
void uartEnd(){ // откл uart
|
||||
UCSR0B = 0;
|
||||
}
|
||||
|
||||
// ===== READ =====
|
||||
volatile char _UART_RX_BUFFER[64];
|
||||
volatile int8_t _UART_RX_COUNTER;
|
||||
ISR(USART_RX_vect) {
|
||||
_UART_RX_BUFFER[_UART_RX_COUNTER] = UDR0;
|
||||
_UART_RX_COUNTER++;
|
||||
ISR(USART_RX_vect) { // чекаем твои байты по прерыванию
|
||||
_UART_RX_BUFFER[_UART_RX_COUNTER] = UDR0; // пишем в массив "буфер"
|
||||
_UART_RX_COUNTER++;
|
||||
}
|
||||
|
||||
char uartRead() {
|
||||
char uartRead() { // чтение данных из буфера
|
||||
char thisChar = _UART_RX_BUFFER[0];
|
||||
for (byte i = 0; i < _UART_RX_COUNTER; i++) _UART_RX_BUFFER[i] = _UART_RX_BUFFER[i + 1];
|
||||
if (--_UART_RX_COUNTER < 0) _UART_RX_COUNTER = 0;
|
||||
return thisChar;
|
||||
}
|
||||
|
||||
char uartPeek() {
|
||||
boolean uartAvailable() { // проверка доступности данных в буфере
|
||||
return _UART_RX_COUNTER;
|
||||
}
|
||||
/* Дальше он писал сам, там жесть полная */
|
||||
char uartPeek() {
|
||||
return _UART_RX_BUFFER[0];
|
||||
}
|
||||
|
||||
boolean uartAvailable() {
|
||||
return _UART_RX_COUNTER;
|
||||
}
|
||||
|
||||
void uartClear() {
|
||||
void uartClear() {
|
||||
_UART_RX_COUNTER = 0;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,6 @@
|
||||
#ifndef uart_h
|
||||
/* Облегченный Serial */
|
||||
|
||||
#ifndef uart_h
|
||||
#define uart_h
|
||||
|
||||
#include "Arduino.h"
|
||||
|
@ -1,29 +1,61 @@
|
||||
/*
|
||||
wiring_pulse.c - pulseIn() function
|
||||
Part of Arduino - http://www.arduino.cc/
|
||||
|
||||
Copyright (c) 2005-2006 David A. Mellis
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General
|
||||
Public License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//#include "wiring_private.h"
|
||||
//#include "pins_arduino.h"
|
||||
#include "Arduino.h"
|
||||
#define analogInPinToBit(P) (P)
|
||||
|
||||
extern const uint16_t PROGMEM port_to_mode_PGM[];
|
||||
extern const uint16_t PROGMEM port_to_input_PGM[];
|
||||
extern const uint16_t PROGMEM port_to_output_PGM[];
|
||||
|
||||
extern const uint8_t PROGMEM digital_pin_to_port_PGM[];
|
||||
// extern const uint8_t PROGMEM digital_pin_to_bit_PGM[];
|
||||
extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[];
|
||||
extern const uint8_t PROGMEM digital_pin_to_timer_PGM[];
|
||||
|
||||
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
|
||||
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
|
||||
#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) )
|
||||
#define analogInPinToBit(P) (P)
|
||||
#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) )
|
||||
#define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) )
|
||||
#define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) )
|
||||
|
||||
#define NOT_A_PIN 0
|
||||
#define NOT_A_PORT 0
|
||||
|
||||
#define NOT_AN_INTERRUPT -1
|
||||
|
||||
#define PA 1
|
||||
#define PB 2
|
||||
#define PC 3
|
||||
#define PD 4
|
||||
#define PE 5
|
||||
#define PF 6
|
||||
#define PG 7
|
||||
#define PH 8
|
||||
#define PJ 10
|
||||
#define PK 11
|
||||
#define PL 12
|
||||
|
||||
#define NOT_ON_TIMER 0
|
||||
#define TIMER0A 1
|
||||
#define TIMER0B 2
|
||||
#define TIMER1A 3
|
||||
#define TIMER1B 4
|
||||
#define TIMER1C 5
|
||||
#define TIMER2 6
|
||||
#define TIMER2A 7
|
||||
#define TIMER2B 8
|
||||
|
||||
#define TIMER3A 9
|
||||
#define TIMER3B 10
|
||||
#define TIMER3C 11
|
||||
#define TIMER4A 12
|
||||
#define TIMER4B 13
|
||||
#define TIMER4C 14
|
||||
#define TIMER4D 15
|
||||
#define TIMER5A 16
|
||||
#define TIMER5B 17
|
||||
#define TIMER5C 18
|
||||
const uint16_t PROGMEM port_to_mode_PGM[] = {
|
||||
NOT_A_PORT,
|
||||
NOT_A_PORT,
|
||||
|
@ -1,25 +1,4 @@
|
||||
/*
|
||||
wiring_shift.c - shiftOut() function
|
||||
Part of Arduino - http://www.arduino.cc/
|
||||
|
||||
Copyright (c) 2005-2006 David A. Mellis
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General
|
||||
Public License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* Програмный SPI */
|
||||
#include "Arduino.h"
|
||||
|
||||
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) {
|
||||
|
@ -40,6 +40,12 @@ uartParsePacket KEYWORD2
|
||||
######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
PWM_8BIT LITERAL1
|
||||
PWM_10BIT LITERAL1
|
||||
PWM_DEFAULT LITERAL1
|
||||
PWM_8KHZ LITERAL1
|
||||
PWM_31KHZ LITERAL1
|
||||
|
||||
THERMOMETR LITERAL1
|
||||
A0 LITERAL1
|
||||
A1 LITERAL1
|
||||
|
38
README.md
38
README.md
@ -1,5 +1,5 @@
|
||||
# GyverCore for ATmega328p/168p
|
||||
Быстрое ядро для Arduino IDE. **В разработке**
|
||||
# GyverCore for ATmega328/168
|
||||
Быстрое и лёгкое ядро для Arduino IDE.
|
||||
Основано на оригинальном ядре Arduino версии 1.8.9, большинство функций заменены на более быстрые и лёгкие аналоги, убрано всё лишнее и не относящееся к микроконтроллеру ATmega328p, убран почти весь Wiring-мусор, код упрощён и причёсан.
|
||||
|
||||
## Установка
|
||||
@ -14,12 +14,13 @@
|
||||
- Листай в самый низ, пока не увидишь **GyverCore**
|
||||
- Жми **Установка**
|
||||
- Закрой окно
|
||||
- Выбери плату в **Инструменты > Плата > GyverCore > ATmega328p based**
|
||||
- Выбери плату в **Инструменты > Плата > GyverCore > ATmega328/168 based**
|
||||
- Выбери в **CPU & BOOT** нужный вариант загрузчика
|
||||
- Готово
|
||||
- Готово!
|
||||
- *Примечание*: файлы ядра находятся по пути *C:\Users\Username\AppData\Local\Arduino15\packages\GyverCore\hardware\avr\1.0.0\*
|
||||
|
||||
# Изменения
|
||||
## Облегчено и ускорено
|
||||
## Изменения
|
||||
### Облегчено и ускорено
|
||||
Время выполнения функций, мкс
|
||||
|
||||
Функция | Arduino | GyverCore | Быстрее в
|
||||
@ -31,7 +32,8 @@ analogWrite | 4.15 us | 1.13 us | 3.67
|
||||
analogRead | 112.01 us | 5.41 us | 20.70
|
||||
analogReference | 0.00 us | 0.69 us | 0.00
|
||||
attachInterrupt | 1.20 us | 1.18 us | 1.02
|
||||
detachInterrupt | 0.82 us | 0.57 us | 1.44
|
||||
detachInterrupt | 0.82 us | 0.57 us | 1.44
|
||||
tone | 5.63 us | 2.40 us | 2.3
|
||||
|
||||
Занимаемое место, Flash, байт
|
||||
|
||||
@ -44,18 +46,22 @@ analogWrite | 406 | 48 | 358
|
||||
analogRead | 32 | 72 | -40
|
||||
analogReference | 0 | 32 | -32
|
||||
attachInterrupt | 212 | 180 | 32
|
||||
detachInterrupt | 198 | 150 | 48
|
||||
detachInterrupt | 198 | 150 | 48
|
||||
tone | 1410 | 740 | 670
|
||||
Serial.begin | 1028 | 166 | 862
|
||||
print long | 1094 | 326 | 768
|
||||
print string | 2100 | 1484 | 616
|
||||
print float | 2021 | 446 | 1575
|
||||
parseInt | 1030 | 214 | 816
|
||||
readString | 2334 | 1594 | 740
|
||||
parseFloat | 1070 | 246 | 824
|
||||
parseFloat | 1070 | 246 | 824
|
||||
|
||||
Примечание: analogRead и analogReference имеют расширенную функциональность и весят чуть больше
|
||||
Примечание: analogRead и analogReference имеют расширенную функциональность и весят чуть больше
|
||||
Скетч, состоящий из однократного вызова перечисленных выше функций, занимает
|
||||
- Ядро Arduino: 3446 байт (11%) Flash / 217 байт (10%) SRAM
|
||||
- Ядро GyverCore: 1436 байт (4%) Flash / 94 байт (4%) SRAM
|
||||
|
||||
## Добавлено
|
||||
### Добавлено
|
||||
- Подсветка в коде **A0**, **A1**.. **A7**
|
||||
- Макрос **bitToggle**(value, bit), инвертирует состояние бита bit в байте value
|
||||
- Функция **digitalToggle**(pin), инвертирует состояние пина
|
||||
@ -86,12 +92,16 @@ parseFloat | 1070 | 246 | 824
|
||||
- **uartParseFloat()** - принять число float
|
||||
- **uartParsePacket(dataArray)** - принять пакет вида **$50 60 70;** в массив dataArray (смотри пример)
|
||||
|
||||
### Убарно
|
||||
Убраны всякие сервисные файлы и прочий хлам, не относящийся к ATmega328 (wifi, USB). Ядро полностью совместимо с остальными библиотеками, ничего из стандартных функций не вырезано.
|
||||
|
||||
## Дополнительно
|
||||
### Настройки прошивки
|
||||
- Добавлен вариант прошивки без загрузчика (во всю доступную Flash память) для прошивки через ISP
|
||||
- Добавлен вариант прошивки с отключенными функциями времени (освобождает вектор **TIMER0_OVF_vect** для личного пользования)
|
||||
- Смотри примеры в папке examples (в корне этого репозитория!)
|
||||
- Добавлен вариант прошивки без загрузчика **ATmega 328/168 without bootloader** (во всю доступную Flash память) для прошивки через ISP
|
||||
- Добавлен вариант прошивки с отключенными функциями времени **with/without millis** (освобождает вектор **TIMER0_OVF_vect** для личного пользования)
|
||||
|
||||
### Больше контроля!
|
||||
## Больше контроля!
|
||||
Для большего контроля за периферией микроконтроллера рекомендую попробовать следующие наши библиотеки:
|
||||
- **directTimers** - полный контроль над таймерами/счётчиками ATmega328
|
||||
- **directADC** - полный контроль над АЦП и компаратором ATmega328
|
||||
|
22
examples/advancedPWM/advancedPWM.ino
Normal file
22
examples/advancedPWM/advancedPWM.ino
Normal file
@ -0,0 +1,22 @@
|
||||
void setup() {
|
||||
setPWM_20kHz(5); // частота шим на D5 установлена на 20 кГц
|
||||
// ШИМ на выходе D6 больше не рабоатет!
|
||||
// функции времени (millis/delay) теперь работают некорректно
|
||||
analogWrite(5, 30); // запустить ШИМ на D5
|
||||
|
||||
setPwmFreqnuency(3, PWM_31KHZ); // частота ШИМ на пинах 3 (и на 11) установлена на 31 кГц
|
||||
analogWrite(3, 30); // запустить ШИМ на D3
|
||||
analogWrite(11, 200); // запустить ШИМ на D11
|
||||
|
||||
setPWM_20kHz(9); // частота шим на D9 (и автоматичсеки на D10) установлена на 20 кГц
|
||||
// разрядность по умолчанию 8 бит (0-255)
|
||||
|
||||
setPWM_9_10_resolution(PWM_10BIT); // ШИМ на пинах 9 и 10 теперь 10 битный (0-1023)
|
||||
analogWrite(9, 512); // ШИМ на пине 9 с 50% заполнением
|
||||
analogWrite(10, 700); // ШИМ на пине 9 с заполнением 700/1023
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
|
||||
}
|
28
examples/memtest/memtest.ino
Normal file
28
examples/memtest/memtest.ino
Normal file
@ -0,0 +1,28 @@
|
||||
// скетч для проверки занимаемой памяти
|
||||
|
||||
void setup() {
|
||||
pinMode(2, 1);
|
||||
digitalWrite(1, 1);
|
||||
digitalRead(0);
|
||||
analogRead(0);
|
||||
analogReference(DEFAULT);
|
||||
analogWrite(9, 125);
|
||||
millis();
|
||||
micros();
|
||||
delay(10);
|
||||
delayMicroseconds(10);
|
||||
tone(10, 10);
|
||||
tone(10, 10, 100);
|
||||
attachInterrupt(0, isr, 0);
|
||||
detachInterrupt(0);
|
||||
//uartBegin();
|
||||
//uartPrintln("kek OK");
|
||||
Serial.begin(9600);
|
||||
Serial.println("kek OK");
|
||||
}
|
||||
void isr(){}
|
||||
|
||||
void loop() {
|
||||
// put your main code here, to run repeatedly:
|
||||
|
||||
}
|
21
examples/parseTest/parseTest.ino
Normal file
21
examples/parseTest/parseTest.ino
Normal file
@ -0,0 +1,21 @@
|
||||
// пример работы с функцией uartParsePacket
|
||||
// функция принимает из порта строку вида
|
||||
// $10 21 458 63 8 45 875 215;
|
||||
// и запихивает в массив dataArray
|
||||
|
||||
int dataArray[8];
|
||||
|
||||
void setup() {
|
||||
uartBegin(); // открыть на 9600
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// $10 21 458 63 8 45 875 215;
|
||||
if (uartParsePacket((int*)dataArray)) {
|
||||
for (byte i = 0; i < 8; i++) {
|
||||
uartPrint(dataArray[i]);
|
||||
uartPrint(" ");
|
||||
}
|
||||
uartPrintln();
|
||||
}
|
||||
}
|
37
examples/printTest/printTest.ino
Normal file
37
examples/printTest/printTest.ino
Normal file
@ -0,0 +1,37 @@
|
||||
// тест вывода в порт разных типов данных
|
||||
|
||||
int8_t data1 = -50;
|
||||
uint8_t data2 = 125;
|
||||
int16_t data3 = -2000;
|
||||
uint16_t data4 = 30000;
|
||||
int32_t data5 = -70000;
|
||||
uint32_t data6 = 4194967295;
|
||||
float data7 = 3681.65424;
|
||||
float data8 = -4375.12353;
|
||||
String data9 = "LOL LOL";
|
||||
|
||||
const char *data10[] = {
|
||||
"LOL",
|
||||
"KEK",
|
||||
"CHEBUREK",
|
||||
};
|
||||
|
||||
void setup() {
|
||||
uartBegin();
|
||||
uartPrintln(data1);
|
||||
uartPrintln(data2);
|
||||
uartPrintln(data3);
|
||||
uartPrintln(data4);
|
||||
uartPrintln(data5);
|
||||
uartPrintln(data6);
|
||||
uartPrintln(data7);
|
||||
uartPrintln(data8, 3);
|
||||
uartPrintln(data9);
|
||||
uartPrintln("KEK KEK");
|
||||
uartPrintln(F("KEK KEK MACRO"));
|
||||
uartPrintln(data10[2]);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
}
|
@ -16,10 +16,10 @@
|
||||
"category": "Contributed",
|
||||
"url": "https://github.com/AlexGyver/GyverCore/releases/download/GyverCore/GyverCore.zip",
|
||||
"archiveFileName": "GyverCore.zip",
|
||||
"checksum": "MD5:758f491c55f177cca874f20eaf1d6e63",
|
||||
"size": "139848",
|
||||
"checksum": "MD5:c304d158e055df8911457ed1aa42fae4",
|
||||
"size": "137283",
|
||||
"boards": [
|
||||
{"name": "ATmega328 boards"}
|
||||
{"name": "ATmega328/168 based boards"}
|
||||
],
|
||||
"toolsDependencies": []
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user