mirror of
https://github.com/AlexGyver/GyverCore.git
synced 2025-04-19 08:42:16 +03:00
add
This commit is contained in:
parent
9fd247b99d
commit
2ee86f2a49
@ -7,27 +7,49 @@ uint32_t toggle_top; // предел счета для toggl'ов
|
||||
bool willStop; // флаг позволяющий генерировать сигнал бесконечно долго
|
||||
|
||||
void tone(uint8_t pin , uint16_t freq, uint32_t duration = 0) {
|
||||
|
||||
tone_pin = pin; // присвоили номер пина для прерывания
|
||||
willStop = duration;// если введено время генерации - будет ненулевым
|
||||
toggle_top = (freq * duration) / 500; // расчет кол-ва toggl'ов за указанное время генерации
|
||||
|
||||
uint8_t oldSREG = SREG; // запомнинаем были ли включены прерывания
|
||||
cli();//выключаем прерывания
|
||||
TCCR2A = (1<<WGM21); // вкл CTC
|
||||
|
||||
TCCR2A = 0x2; // вкл CTC
|
||||
TIMSK2 |= (1 << OCIE2A); //Вкл прерывание
|
||||
if(freq < 122){ // максимальный делитель
|
||||
TCCR2B = 0x7; // присвоили делитель
|
||||
OCR2A = (15625/freq)-1; // рассчитали top для CTC
|
||||
|
||||
if (freq < (F_CPU >> 18)) { // ( < 240 Hz)
|
||||
TCCR2B = 0x7; // prescaler = 1024
|
||||
OCR2A = ((F_CPU >> 11) / freq) - 1;
|
||||
}
|
||||
if(freq > 244){ // минимальный делитель
|
||||
TCCR2B = 0x5; // по аналогии см выше
|
||||
OCR2A = (62500/freq)-1; // по аналогии см выше
|
||||
else if (freq < (F_CPU >> 15)) { // ( 240 - 480 Hz)
|
||||
TCCR2B = 0x6; // prescaler = 256
|
||||
OCR2A = ((F_CPU >> 9) / freq) - 1;
|
||||
}
|
||||
else { // средний делитель
|
||||
TCCR2B = 0x6; // по аналогии см выше
|
||||
OCR2A = (125000/freq)-1; // по аналогии см выше
|
||||
else if (freq <= (F_CPU >> 14)) { // ( 480 - 970 Hz)
|
||||
TCCR2B = 0x5; // prescaler = 128
|
||||
OCR2A = ((F_CPU >> 8) / freq) - 1;
|
||||
}
|
||||
else if (freq <= (F_CPU >> 13)) { // ( 970 - 1900 Hz)
|
||||
TCCR2B = 0x4; // prescaler = 64
|
||||
OCR2A = ((F_CPU >> 7) / freq) - 1;
|
||||
}
|
||||
else if (freq <= (F_CPU >> 11)) { // ( 1.9 - 7.8 kHz)
|
||||
TCCR2B = 0x3; // prescaler = 32
|
||||
OCR2A = ((F_CPU >> 6) / freq) - 1;
|
||||
}
|
||||
else if (freq <= (F_CPU >> 8)) { // ( 7.8 - 62 kHz)
|
||||
TCCR2B = 0x2; // prescaler = 8
|
||||
OCR2A = ((F_CPU >> 4) / freq) - 1;
|
||||
}
|
||||
else { // ( > 62 kHz)
|
||||
TCCR2B = 0x1; // prescaler = 1
|
||||
OCR2A = ((F_CPU >> 1) / freq) - 1;
|
||||
}
|
||||
|
||||
toggle_counter = 0; // обнулили счетчик toggl'ов
|
||||
SREG = oldSREG;
|
||||
|
||||
}
|
||||
|
||||
void noTone(uint8_t pin) { // если вызван noTone
|
||||
@ -35,18 +57,16 @@ void noTone(uint8_t pin){ // если вызван noTone
|
||||
uint8_t oldSREG = SREG; // запомнинаем были ли включены прерывания
|
||||
cli();//выключаем прерывания
|
||||
TIMSK2 &= ~ (1 << OCIE2A); // остановить прерывания
|
||||
TCCR2A = 0b00000011; // установить стандартные настройки для таймера 2
|
||||
TCCR2B = 0b00000100;
|
||||
TCCR2A = 0x3; // установить стандартные настройки для таймера 2
|
||||
TCCR2B = 0x4;
|
||||
OCR2A = 0; //обнуляем регистр сравнения
|
||||
TCCR2A &=~ ((1<<COM2A1)|(1<<COM2B1)); // откл регистры сравнения (подстраховка)
|
||||
SREG = oldSREG;
|
||||
}
|
||||
|
||||
|
||||
ISR(TIMER2_COMPA_vect) { // прерывание генерации
|
||||
if(toggle_counter < toggle_top || !willStop ){ // если количество toggl'ов не достигло предела или процесс бесконечен - генерация
|
||||
if (!willStop || toggle_counter < toggle_top ) { // если количество toggl'ов не достигло предела или процесс бесконечен - генерация
|
||||
digitalToggle(tone_pin); // иневертируем состоние на ноге
|
||||
toggle_counter++; // икремент счетчика
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,33 @@
|
||||
static uint8_t a_ref = DEFAULT; // глобальная переменная для хранения опорного напряжения АЦП
|
||||
// ============= DIGITAL =============
|
||||
|
||||
void pinMode(uint8_t pin, uint8_t mode)
|
||||
{ uint8_t oldSREG = SREG; // запомнинаем были ли включены прерывания
|
||||
// service func
|
||||
uint8_t getOutputRegister(uint8_t pin) {
|
||||
if (pin < 8) return &PORTD;
|
||||
else if (pin < 14) return &PORTB;
|
||||
else return &PORTC;
|
||||
}
|
||||
|
||||
uint8_t getInputRegister(uint8_t pin) {
|
||||
if (pin < 8) return &PIND;
|
||||
else if (pin < 14) return &PINB;
|
||||
else return &PINC;
|
||||
}
|
||||
|
||||
uint8_t getModeRegister(uint8_t pin) {
|
||||
if (pin < 8) return &DDRD;
|
||||
else if (pin < 14) return &DDRB;
|
||||
else return &DDRC;
|
||||
}
|
||||
|
||||
uint8_t getBitMask(uint8_t pin) {
|
||||
if (pin < 8) return (1 << pin);
|
||||
else if (pin < 14) return (1 << (pin - 8));
|
||||
else return (1 << (pin - 14));
|
||||
}
|
||||
|
||||
void pinMode(uint8_t pin, uint8_t mode) {
|
||||
/*uint8_t oldSREG = SREG; // запомнинаем были ли включены прерывания
|
||||
cli();//выключаем прерывания
|
||||
switch (mode) {
|
||||
case 0: // input
|
||||
@ -36,11 +61,27 @@ void pinMode(uint8_t pin, uint8_t mode)
|
||||
}
|
||||
break;
|
||||
}
|
||||
SREG = oldSREG; // если прерывания не были включены - не включаем и наоборот
|
||||
SREG = oldSREG; // если прерывания не были включены - не включаем и наоборот*/
|
||||
|
||||
uint8_t *modeReg = getModeRegister(pin);
|
||||
uint8_t *outputReg = getOutputRegister(pin);
|
||||
uint8_t mask = getBitMask(pin);
|
||||
switch (mode) {
|
||||
case 0x00:
|
||||
*modeReg &= ~ mask;
|
||||
return;
|
||||
case 0x01:
|
||||
*modeReg |= mask;
|
||||
return;
|
||||
case 0x02:
|
||||
*modeReg &= ~ mask;
|
||||
*outputReg |= mask;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void digitalWrite(uint8_t pin, uint8_t x) {
|
||||
uint8_t oldSREG = SREG; // запомнинаем были ли включены прерывания
|
||||
/*uint8_t oldSREG = SREG; // запомнинаем были ли включены прерывания
|
||||
cli();//выключаем прерывания
|
||||
switch (pin) { // откл pwm
|
||||
case 3: // 2B
|
||||
@ -65,26 +106,39 @@ void digitalWrite(uint8_t pin, uint8_t x) {
|
||||
if (pin < 8) bitWrite(PORTD, pin, x);
|
||||
else if (pin < 14) bitWrite(PORTB, (pin - 8), x);
|
||||
else if (pin < 20) bitWrite(PORTC, (pin - 14), x);
|
||||
SREG = oldSREG; // если прерывания не были включены - не включаем и наоборот
|
||||
}
|
||||
SREG = oldSREG; // если прерывания не были включены - не включаем и наоборот*/
|
||||
|
||||
int digitalRead (uint8_t pin) {
|
||||
if (pin < 8) return bitRead(PIND, pin);
|
||||
else if (pin < 14) return bitRead(PINB, pin - 8);
|
||||
else if (pin < 20) return bitRead(PINC, pin - 14);
|
||||
uint8_t *outputReg = getOutputRegister(pin);
|
||||
uint8_t mask = getBitMask(pin);
|
||||
if (x) *outputReg |= mask;
|
||||
else *outputReg &= ~ mask;
|
||||
}
|
||||
|
||||
|
||||
void digitalToggle(uint8_t pin){
|
||||
uint8_t oldSREG = SREG; // запомнинаем были ли включены прерывания
|
||||
/*uint8_t oldSREG = SREG; // запомнинаем были ли включены прерывания
|
||||
cli();//выключаем прерывания
|
||||
if (pin < 8) bitToggle(PORTD, pin);
|
||||
else if (pin < 14) bitToggle(PORTB, pin - 8);
|
||||
else if (pin < 20) bitToggle(PORTC, pin - 14);
|
||||
|
||||
SREG = oldSREG; // если прерывания не были включены - не включаем и наоборот
|
||||
SREG = oldSREG; // если прерывания не были включены - не включаем и наоборот*/
|
||||
|
||||
uint8_t *outputReg = getOutputRegister(pin);
|
||||
uint8_t mask = getBitMask(pin);
|
||||
*outputReg ^= mask;
|
||||
}
|
||||
// ============= ANALOG =============
|
||||
|
||||
int digitalRead (uint8_t pin) {
|
||||
/*if (pin < 8) return bitRead(PIND, pin);
|
||||
else if (pin < 14) return bitRead(PINB, pin - 8);
|
||||
else if (pin < 20) return bitRead(PINC, pin - 14); */
|
||||
|
||||
uint8_t *inputReg = getInputRegister(pin);
|
||||
uint8_t mask = getBitMask(pin);
|
||||
return ((*inputReg & mask) ? 1 : 0);
|
||||
}
|
||||
|
||||
// ================ ANALOG ================
|
||||
void analogPrescaler(uint8_t prescl) {
|
||||
uint8_t oldSREG = SREG; // запомнинаем были ли включены прерывания
|
||||
cli();//выключаем прерывания
|
||||
@ -119,13 +173,11 @@ void analogPrescaler(uint8_t prescl) {
|
||||
SREG = oldSREG; // если прерывания не были включены - не включаем и наоборот
|
||||
}
|
||||
|
||||
void analogReference(uint8_t mode)
|
||||
{
|
||||
void analogReference(uint8_t mode) {
|
||||
a_ref = mode; // изменения будут приняты в силу при следующем analogRead() / analogStartConvert()
|
||||
}
|
||||
|
||||
int analogRead(uint8_t pin)
|
||||
{
|
||||
int analogRead(uint8_t pin) {
|
||||
analogStartConvert(pin);
|
||||
return analogGet();
|
||||
}
|
||||
@ -147,7 +199,7 @@ int analogGet() {
|
||||
return ADCL | (ADCH << 8); // склеить и вернуть результат
|
||||
}
|
||||
|
||||
// ============= PWM =============
|
||||
// ================= PWM =================
|
||||
void analogWrite(uint8_t pin, int val) {
|
||||
if (val == 0) {
|
||||
digitalWrite(pin, 0);
|
||||
|
@ -10,6 +10,8 @@
|
||||
*/
|
||||
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
|
||||
{
|
||||
return pulseInLong(pin, state, timeout);
|
||||
/*
|
||||
// cache the port and bit of the pin in order to speed up the
|
||||
// pulse width measuring loop and achieve finer resolution. calling
|
||||
// digitalRead() instead yields much coarser resolution.
|
||||
@ -28,6 +30,7 @@ unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
|
||||
return clockCyclesToMicroseconds(width * 16 + 16);
|
||||
else
|
||||
return 0;
|
||||
*/
|
||||
}
|
||||
|
||||
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
|
||||
|
@ -19,6 +19,11 @@ sbi KEYWORD2
|
||||
analogStartConvert KEYWORD2
|
||||
analogGet KEYWORD2
|
||||
|
||||
bit_is_set KEYWORD2
|
||||
bit_is_clear KEYWORD2
|
||||
loop_until_bit_is_set KEYWORD2
|
||||
loop_until_bit_is_clear KEYWORD2
|
||||
|
||||
begin KEYWORD2
|
||||
end KEYWORD2
|
||||
peek KEYWORD2
|
||||
@ -47,6 +52,7 @@ UINT64_MAX LITERAL1
|
||||
INT64_MAX LITERAL1
|
||||
|
||||
UDR0 KEYWORD2
|
||||
UBRR0 KEYWORD2
|
||||
UBRR0H KEYWORD2
|
||||
UBRR0L KEYWORD2
|
||||
UCSR0C KEYWORD2
|
||||
@ -64,12 +70,16 @@ OCR2A KEYWORD2
|
||||
TCNT2 KEYWORD2
|
||||
TCCR2B KEYWORD2
|
||||
TCCR2A KEYWORD2
|
||||
OCR1B KEYWORD2
|
||||
OCR1BH KEYWORD2
|
||||
OCR1BL KEYWORD2
|
||||
OCR1A KEYWORD2
|
||||
OCR1AH KEYWORD2
|
||||
OCR1AL KEYWORD2
|
||||
ICR1 KEYWORD2
|
||||
ICR1H KEYWORD2
|
||||
ICR1L KEYWORD2
|
||||
TCNT1 KEYWORD2
|
||||
TCNT1H KEYWORD2
|
||||
TCNT1L KEYWORD2
|
||||
TCCR1C KEYWORD2
|
||||
@ -113,6 +123,7 @@ TCNT0 KEYWORD2
|
||||
TCCR0B KEYWORD2
|
||||
TCCR0A KEYWORD2
|
||||
GTCCR KEYWORD2
|
||||
EEAR KEYWORD2
|
||||
EEARH KEYWORD2
|
||||
EEARL KEYWORD2
|
||||
EEDR KEYWORD2
|
||||
@ -136,12 +147,6 @@ PINB KEYWORD2
|
||||
######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
PWM_8BIT LITERAL1
|
||||
PWM_10BIT LITERAL1
|
||||
PWM_DEFAULT LITERAL1
|
||||
PWM_8KHZ LITERAL1
|
||||
PWM_31KHZ LITERAL1
|
||||
|
||||
THERMOMETR LITERAL1
|
||||
A0 LITERAL1
|
||||
A1 LITERAL1
|
||||
@ -764,14 +769,3 @@ UDR0_4 LITERAL1
|
||||
UDR0_5 LITERAL1
|
||||
UDR0_6 LITERAL1
|
||||
UDR0_7 LITERAL1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
31
README.md
31
README.md
@ -1,7 +1,7 @@
|
||||

|
||||
# GyverCore for ATmega328
|
||||
[**▶SWITCH TO ENGLISH◀**](https://github.com/AlexGyver/GyverCore/blob/master/README_eng.md)
|
||||
**Версия 1.9.0 от 17.09.2019**
|
||||
**Версия 1.10.0 от 22.10.2019**
|
||||
Быстрое и лёгкое ядро для Arduino IDE с расширенной конфигурацией.
|
||||
Основано на оригинальном ядре Arduino версии 1.8.9, большинство функций заменены на более быстрые и лёгкие аналоги, убрано всё лишнее и не относящееся к микроконтроллеру ATmega328p, убран почти весь Wiring-мусор, код упрощён и причёсан. Добавлено несколько функций и интересных вариантов компиляции.
|
||||
Разработано by Александр **AlexGyver** и Egor 'Nich1con' Zaharov
|
||||
@ -17,14 +17,16 @@
|
||||
- Открой **Инструменты > Плата > Менеджер плат...**
|
||||
- Подожди загрузку списка
|
||||
- Листай в самый низ, пока не увидишь **GyverCore**
|
||||
- Выбери свою версию: **Win32**, **Win64** или **Linux**
|
||||
- Жми **Установка**
|
||||
- Закрой окно
|
||||
- Выбери плату в **Инструменты > Плата > GyverCore > ATmega328/168 based**
|
||||
- Выбери плату в **Инструменты > Плата > GyverCore > ATmega328 based**
|
||||
- Готово!
|
||||
- *Примечание*: файлы ядра находятся по пути C:\Users\Username\AppData\Local\Arduino15\packages\GyverCore\hardware\avr\1.9.0\
|
||||
- *Примечание*: файлы ядра находятся по пути C:\Users\Username\AppData\Local\Arduino15\packages\GyverCore\hardware\avr\1.10.0\
|
||||
|
||||
### Ручная
|
||||
- Файлы из папки GyverCore в этом репозитории положить по пути C:\Users\Username\AppData\Local\Arduino15\packages\GyverCore\hardware\avr\1.9.0\
|
||||
- Файлы из папки GyverCore в этом репозитории положить по пути C:\Users\Username\AppData\Local\Arduino15\packages\GyverCore\hardware\avr\1.10.0\
|
||||
- Новая версия компилятора лежит отдельно!
|
||||
|
||||
## Изменения
|
||||
### Облегчено и ускорено
|
||||
@ -34,9 +36,9 @@
|
||||
----------------|-----------|-----------|----------
|
||||
millis | 1.06 us | 1.00 us | -
|
||||
micros | 1.19 us | 1.13 us | -
|
||||
pinMode | 2.90 us | 0.57 us | 5.09
|
||||
digitalWrite | 2.90 us | 0.57 us | 5.09
|
||||
digitalRead | 2.45 us | 0.50 us | 4.90
|
||||
pinMode | 2.90 us | 0.50 us | 5.09
|
||||
digitalWrite | 2.90 us | 0.50 us | 5.09
|
||||
digitalRead | 2.45 us | 0.00 us | ?
|
||||
analogWrite | 4.15 us | 1.13 us | 3.67
|
||||
analogRead | 112.01 us | 5.41 us | 20.70
|
||||
analogReference | 0.00 us | 0.00 us | -
|
||||
@ -50,9 +52,9 @@ tone | 5.63 us | 2.40 us | 2.3
|
||||
----------------|---------|-----------|---------------
|
||||
millis | 26 | 24 | 2
|
||||
micros | 24 | 20 | 4
|
||||
pinMode | 114 | 24 | 90
|
||||
digitalWrite | 200 | 24 | 176
|
||||
digitalRead | 190 | 24 | 166
|
||||
pinMode | 114 | 2 | 112
|
||||
digitalWrite | 200 | 2 | 198
|
||||
digitalRead | 190 | 0 | 190
|
||||
analogWrite | 406 | 48 | 358
|
||||
analogRead | 32 | 72 | -40
|
||||
analogReference | 0 | 22 | -22
|
||||
@ -104,6 +106,7 @@ parseFloat | 1070 | 246 | 824
|
||||
- **uart.begin(baudrate)** - запустить соединение по последовательному порту со скоростью baudrate
|
||||
- **uart.end()** - выключить сериал
|
||||
- **uart.peek()** - вернуть крайний байт из буфера, не убирая его оттуда
|
||||
- **uart.flush()** - ждать принятия данных
|
||||
- **uart.clear()** - очистить буфер
|
||||
- **uart.read()** - вернуть крайний байт из буфера, убрав его оттуда
|
||||
- **uart.write(val)** - запись в порт
|
||||
@ -177,7 +180,7 @@ parseFloat | 1070 | 246 | 824
|
||||
---
|
||||
**Compiler version** - версия компилятора
|
||||
- **default v5.4.0** - встроенная в IDE версия компилятора
|
||||
- **avr-gcc v8.3.0** - новая версия компилятора: компилирует быстрее, скетчи весят меньше!
|
||||
- **avr-gcc v8.3.0** - новая версия компилятора: компилирует быстрее, скетчи весят меньше! Билд взял [отсюда](https://blog.zakkemble.net/avr-gcc-builds/)
|
||||
|
||||
## Больше контроля!
|
||||
Для большего контроля за периферией микроконтроллера рекомендую попробовать следующие наши библиотеки:
|
||||
@ -258,3 +261,9 @@ parseFloat | 1070 | 246 | 824
|
||||
- Ещё чуть ускорен uart
|
||||
- 1.9.0
|
||||
- Вшита новая версия компилятора avr-gcc
|
||||
- 1.10.0
|
||||
- Расширена подсветка синтаксиса
|
||||
- Пофикшен tone
|
||||
- Пофикшен pulseIn (но выдаёт разрешение 4 мкс)
|
||||
- Добавлен avr-gcc v8 под Win32 и Linux
|
||||
- Ускорен IO
|
3
avr-gcc/README.md
Normal file
3
avr-gcc/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
#AVR-GCC
|
||||
Версия 8.3.0 взята [отсюда](https://blog.zakkemble.net/avr-gcc-builds/)
|
||||
Более новые версии делают код тяжелее по Flash памяти
|
BIN
avr-gcc/avr-gcc-8.3.0-x64-linux.tar.bz2
Normal file
BIN
avr-gcc/avr-gcc-8.3.0-x64-linux.tar.bz2
Normal file
Binary file not shown.
BIN
avr-gcc/avr-gcc-8.3.0-x64-mingw.zip
Normal file
BIN
avr-gcc/avr-gcc-8.3.0-x64-mingw.zip
Normal file
Binary file not shown.
BIN
avr-gcc/avr-gcc-8.3.0-x86-mingw.zip
Normal file
BIN
avr-gcc/avr-gcc-8.3.0-x86-mingw.zip
Normal file
Binary file not shown.
@ -260,7 +260,49 @@
|
||||
{"name": "ATmega328 based boards"}
|
||||
],
|
||||
"toolsDependencies": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "GyverCore",
|
||||
"architecture": "avr",
|
||||
"version": "1.10.0 win64",
|
||||
"category": "Contributed",
|
||||
"url": "https://github.com/AlexGyver/GyverCore/releases/download/GyverCore-1.10.0/GyverCore_win64.zip",
|
||||
"archiveFileName": "GyverCore.zip",
|
||||
"checksum": "MD5:c2ec5c7b0d64913faecafac966d64fab",
|
||||
"size": "59016998",
|
||||
"boards": [
|
||||
{"name": "ATmega328 based boards"}
|
||||
],
|
||||
"toolsDependencies": []
|
||||
},
|
||||
{
|
||||
"name": "GyverCore",
|
||||
"architecture": "avr",
|
||||
"version": "1.10.0 win32",
|
||||
"category": "Contributed",
|
||||
"url": "https://github.com/AlexGyver/GyverCore/releases/download/GyverCore-1.10.0/GyverCore_win32.zip",
|
||||
"archiveFileName": "GyverCore.zip",
|
||||
"checksum": "MD5:c2ec5c7b0d64913faecafac966d64fab",
|
||||
"size": "59016998",
|
||||
"boards": [
|
||||
{"name": "ATmega328 based boards"}
|
||||
],
|
||||
"toolsDependencies": []
|
||||
},
|
||||
{
|
||||
"name": "GyverCore",
|
||||
"architecture": "avr",
|
||||
"version": "1.10.0 linux",
|
||||
"category": "Contributed",
|
||||
"url": "https://github.com/AlexGyver/GyverCore/releases/download/GyverCore-1.10.0/GyverCore_linux.zip",
|
||||
"archiveFileName": "GyverCore.zip",
|
||||
"checksum": "MD5:c2ec5c7b0d64913faecafac966d64fab",
|
||||
"size": "59016998",
|
||||
"boards": [
|
||||
{"name": "ATmega328 based boards"}
|
||||
],
|
||||
"toolsDependencies": []
|
||||
},
|
||||
],
|
||||
"tools": []
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user