Comments 52
Вот собственно весь процесс в видео формате:
www.youtube.com/watch?v=MS5i7fnlPBM
www.youtube.com/watch?v=MS5i7fnlPBM
40% памяти на мигание светодидом! С таким количеством памяти надо гораздо больше внимания уделять оптимизации. Мне кажется Processing/Wiring здесь крайне не уместен.
Согласен, но если вы начинающий ардуинщик?
Заодно и будет дополнительный стимул обучаться оптимизации размеров кода и изучения как языка Си так и регистров микроконтроллера.
Заодно и будет дополнительный стимул обучаться оптимизации размеров кода и изучения как языка Си так и регистров микроконтроллера.
Асемблера. Для такой мелкотни нужен ассемблер, тут даже С тяжеловат.
В 1 килобайт на Си очень много чего влезает. У меня на ATtiny13 собран термостат для аквариума с датчиком DS18B20, с отображением температуры на семисегментном индикаторе и двумя кнопками для ввода температуры. Прошивка написана на Си.
Я уже тоже думаю переходить на Си, потихоньку осваиваюсь.
Поначалу с регистрами было сложно, но сейчас маленько понимаю…
Поначалу с регистрами было сложно, но сейчас маленько понимаю…
В мире микроконтроллеров, от Си до Ассемблера один шаг. И сделать его, пожалуй, стоит. Тогда мигание светодиодом не станет занимать 382 байта, а в килобайт смогут уместиться не только мигалки и пищалки, но и серьезные приложения.
Ардуина потрясающа для прототипирования и обучения, но будьте готовы к тому, что как только появится необходимость удешевить конечный железный продукт или позаботиться о стабильности его работы — придется писать на Cи или Ассемблере.
Ардуина потрясающа для прототипирования и обучения, но будьте готовы к тому, что как только появится необходимость удешевить конечный железный продукт или позаботиться о стабильности его работы — придется писать на Cи или Ассемблере.
Да, безусловно.
А в крайнем случае всегда можно скомпилировать C в ассемблер, вручную оптимизировать и уже потом залить.
И это в большинстве случаев окажется быстрее, чем сразу писать с нуля на ассемблере.
А в крайнем случае всегда можно скомпилировать C в ассемблер, вручную оптимизировать и уже потом залить.
И это в большинстве случаев окажется быстрее, чем сразу писать с нуля на ассемблере.
Ну чего уж, мигалку позволяет сделать и то прогресс. Не ставить же 28-выводный контроллер для «мигалок» на два светодиода. Оно конечно в целом не практично, но свою нишу найдёт.
Спасибо автору за статью, мне подобная статья помогла в свое время ввязаться в борьбу с размером скетча для ATTiny и, как следствие, перейти с Arduino IDE на Сю.
UFO just landed and posted this here
Спасибо, мне очень понравилось, в том плане, что это из тех любительских технологий, которые при малобюджетных разработка крайне полезны. А я этим теперь и занимаюсь. Я как бы и не электронщик и не программист, а на таких простеньких примерах управление сваять очень здорово. И цена девайса впечатляет.
Правильно я понимаю, что алгоритм такой (после закидывания файлов в директории)
— прошиваем любую ардуино обычную в ISP программатор
— цепляем tiny13 к этой обычной ардуине
— «прошиваем» загрузчик для выставления фьюзов
— прошивка в дальнейшем идет через ту же самую ардуину в режиме isp программатора?
По идее, если не использовать специфичных функций ардуино (типа digitalWrite), а обращаться напрямую к регистрам, код будет намного компактнее?
— прошиваем любую ардуино обычную в ISP программатор
— цепляем tiny13 к этой обычной ардуине
— «прошиваем» загрузчик для выставления фьюзов
— прошивка в дальнейшем идет через ту же самую ардуину в режиме isp программатора?
По идее, если не использовать специфичных функций ардуино (типа digitalWrite), а обращаться напрямую к регистрам, код будет намного компактнее?
Молодец. Многие будут давать быть может и резкие комментарии, но начать всегда нужно с малого. Я лично тоже в свое время моргал blink-ом на Ардуино и радовался как ребенок) — не скрываю.
UPD: добавил ссылку как экономить место на микроконтроллере.
Правда при использовании функции _delay_ms(*); если сравнивать и delay(*); размеры hex-файла увеличиваются, хотя должны бы наоборот уменьшатся… не могу понять этого…
Может кто из местных пользователей хабра мне поможет разобраться?
Может кто из местных пользователей хабра мне поможет разобраться?
И мы пришли к тому, что смысла программить Тиньку в arduino ide нет. В данном примере используется обычный С) На котором обычно и писали для нее
А он без проблем подключается к вирингу?
Я понятия не имею что такое виринг и подключается ли он к нему.
Просто время от времени читаю ресурс, посвещенный покупкам на китайщине. И сегодня наткнулся на обзор тот. И на хабре тоже программирование ATTiny13. Вот и скинул ссылку, вдруг кому пригодится.
Повторюсь — я абсолютный ноль в программировании, тем более микроконтроллеров:)
Просто время от времени читаю ресурс, посвещенный покупкам на китайщине. И сегодня наткнулся на обзор тот. И на хабре тоже программирование ATTiny13. Вот и скинул ссылку, вдруг кому пригодится.
Повторюсь — я абсолютный ноль в программировании, тем более микроконтроллеров:)
Вы наверно имеете ввиду Wiring?
Знакомый ник ))) ATtiny13 конечно неплохо программируются в Arduino IDE, но к сожалению прошивка получается по размеру не такая минимальная как чем писать прямо в С# даже если не использовать ардуиновские функции то впустую сжирается 50-100 байт(точно не помню).
Потенциал ATtiny13 вообще не плохой, его цена где-то у китайцев от 50 центов и если уметь, то реализовать можно много чего, например беспроводные датчики на 433/315 мгц модулях…
Потенциал ATtiny13 вообще не плохой, его цена где-то у китайцев от 50 центов и если уметь, то реализовать можно много чего, например беспроводные датчики на 433/315 мгц модулях…
1.2 мГц — > 1.2 МГц
Очень сильное ограничение у Attiny13, и вообще у многих контроллеров, это малое количество ОЗУ. А программы на Си очень неэкономно его используют. В итоге смотришь, вроде занято 20% флеш-памяти, а после включения самые невообразимые глюки из-за срыва стека. Так что рекомендуется тестировать в эмуляторе AVRStrudio или в Протеусе, и посматривать на количество занятого ОЗУ. К сожалению Ардуиновская среда разработки эмулятора не имеет (насколько я знаю), и заигрывая с маленкой Аттини можно словить сюрприз очень легко.
Я недавно снимал видео про моделирование Arduino в программе Proteus на примере Attiny13.
www.youtube.com/watch?v=gj5koMNtKwI
www.youtube.com/watch?v=gj5koMNtKwI
У ATTINY13 есть отладочный интерфейс, debugwire. Вопрос лишь в востребованности. На столь высокоуровневом языке на котором пишут скетчи для ардуины нет необходимости в низкоуровневой отладке а высокоуровневую можно прикрутить и самому при помощи банальной printf и задержки выполнения алгоритма пока не нажмешь внешнюю кнопку.
Ждём продолжения про прошивку ардуиновских скетчей в STM32F4!
Видео вполне может быть интересным и полезным для многих начинающих, но есть небольшое пожелание автору:
Лучше говорить английские названия прямо так, как получается. Но прежде чем пытаться выговаривать их «правильно» следует хотя бы узнать, как на самом деле правильно :) Иными словами, лучше все называть на своем языке никого не стесняясь, чем выговаривать правльно одну английскую букву из трех.
Кстати, про обучение и интересные видео — рекомендую этих парней — learn.sparkfun.com/
Ребята клевые.
Лучше говорить английские названия прямо так, как получается. Но прежде чем пытаться выговаривать их «правильно» следует хотя бы узнать, как на самом деле правильно :) Иными словами, лучше все называть на своем языке никого не стесняясь, чем выговаривать правльно одну английскую букву из трех.
Кстати, про обучение и интересные видео — рекомендую этих парней — learn.sparkfun.com/
Ребята клевые.
UPD 03.12.2014:
Вышла новая версия «ядра» для ATtiny13 core13_19. Почему то опять с некоторыми недочётами в функциях analogWrite() и pulseIn(), вот ядро ссылка с исправленными недочётами:
Скачать.
Список поддерживаемых Arduino'вских функций взятый из официальной страница проекта:
map()
random()
randomSeed()
millis()
micros()
delay()
delayMicroseconds() *
analogRead()
analogWrite()
pinMode()
digitalRead()
digitalWrite()
pulseIn() (Untested)
shiftIn() (Untested)
shiftOut() (Untested)
Собственно официальная страница проекта:
http://forum.arduino.cc/index.php/topic,89781.0.html.
При обнаружении каких либо багов пишите сюда, но всё же лучше ветку русскоязычного форума Arduino.
Вышла новая версия «ядра» для ATtiny13 core13_19. Почему то опять с некоторыми недочётами в функциях analogWrite() и pulseIn(), вот ядро ссылка с исправленными недочётами:
Скачать.
Список поддерживаемых Arduino'вских функций взятый из официальной страница проекта:
map()
random()
randomSeed()
millis()
micros()
delay()
delayMicroseconds() *
analogRead()
analogWrite()
pinMode()
digitalRead()
digitalWrite()
pulseIn() (Untested)
shiftIn() (Untested)
shiftOut() (Untested)
Собственно официальная страница проекта:
http://forum.arduino.cc/index.php/topic,89781.0.html.
При обнаружении каких либо багов пишите сюда, но всё же лучше ветку русскоязычного форума Arduino.
Спасибо, прошил тиньку) Но пришлось повозиться. На маке и линуксе нужно отключать auto-reset у arduino,
Без этого пишет что-то вроде out of sync 0x15.
После гугления обнаружился вот такой мануал:
playground.arduino.cc/Main/DisablingAutoResetOnSerialConnection
120 Ом резистор причем не помог (может потому что у меня funduino?).
А конденсатор на 10мкФ помог.
Без этого пишет что-то вроде out of sync 0x15.
После гугления обнаружился вот такой мануал:
playground.arduino.cc/Main/DisablingAutoResetOnSerialConnection
120 Ом резистор причем не помог (может потому что у меня funduino?).
А конденсатор на 10мкФ помог.
# лочит тинки, не зачёт
#attiny13int.name=ATtiny13 @ 128 KHz, BOD 2.7 V
#attiny13int.upload.using=arduino:arduinoisp
#attiny13int.upload.speed=250 # important for not losing connection to a slow processor
#attiny13int.bootloader.low_fuses=0x7B
#attiny13int.bootloader.high_fuses=0xFB # BOD 2.7 В. по умолчанию FF
#attiny13int.upload.maximum_size=1024
#attiny13int.build.mcu=attiny13
#attiny13int.build.f_cpu=128000L
#attiny13int.build.core=core13
Если вдруг кто напоролся на проблему пропадания связи с attiny после прошивки ее на частоту 128 KHz, то решение этой проблемы очень простое. Суть ее в том, что attiny13 после этого начинает работать на обозначенной слишком маленькой частоте, и для программатора она выглядит не просто как тормозная, а как мегатормозная. А раз программатору она вовремя (с точки зрения быстрого программатора) не отвечает, он ничего с ней сделать и не может.
Решение в том, чтобы затормозить программатор, чтобы он работал с такой attiny очень медленно, и attiny13 на частоте 128КГц успевала ему отвечать. В сети полно таких модифицированных скетчей из примера, искать по словам slow Arduino ISP.
Ссылки:
forum.arduino.cc/index.php?topic=89781.msg2097406#msg2097406 — Библиотека ATtiny13 library install для Arduino IDE 1.6.X (по сравнению с 1.0.X у среды поменялся немного формат, и если у вас возникают ошибки, связанные с bootloader.upload.tool, то проблема именно в версии среды).
forum.arduino.cc/index.php?topic=89781.msg2160449#msg2160449 — А тут разъяснение, что делать, если вы таки переключили attiny в режим 128КГц и теперь не можете до микросхемы достучаться: там изменения для файла boards.txt и заторможенная версия скетча Arduino ISP. У меня все сработало, и я переключил микросхему обратно из режима 128КГц. А кто-то только в этом режиме и работает, потому что, подозреваю, потребление в этом режиме еще меньше.
#attiny13int.name=ATtiny13 @ 128 KHz, BOD 2.7 V
#attiny13int.upload.using=arduino:arduinoisp
#attiny13int.upload.speed=250 # important for not losing connection to a slow processor
#attiny13int.bootloader.low_fuses=0x7B
#attiny13int.bootloader.high_fuses=0xFB # BOD 2.7 В. по умолчанию FF
#attiny13int.upload.maximum_size=1024
#attiny13int.build.mcu=attiny13
#attiny13int.build.f_cpu=128000L
#attiny13int.build.core=core13
Если вдруг кто напоролся на проблему пропадания связи с attiny после прошивки ее на частоту 128 KHz, то решение этой проблемы очень простое. Суть ее в том, что attiny13 после этого начинает работать на обозначенной слишком маленькой частоте, и для программатора она выглядит не просто как тормозная, а как мегатормозная. А раз программатору она вовремя (с точки зрения быстрого программатора) не отвечает, он ничего с ней сделать и не может.
Решение в том, чтобы затормозить программатор, чтобы он работал с такой attiny очень медленно, и attiny13 на частоте 128КГц успевала ему отвечать. В сети полно таких модифицированных скетчей из примера, искать по словам slow Arduino ISP.
Ссылки:
forum.arduino.cc/index.php?topic=89781.msg2097406#msg2097406 — Библиотека ATtiny13 library install для Arduino IDE 1.6.X (по сравнению с 1.0.X у среды поменялся немного формат, и если у вас возникают ошибки, связанные с bootloader.upload.tool, то проблема именно в версии среды).
forum.arduino.cc/index.php?topic=89781.msg2160449#msg2160449 — А тут разъяснение, что делать, если вы таки переключили attiny в режим 128КГц и теперь не можете до микросхемы достучаться: там изменения для файла boards.txt и заторможенная версия скетча Arduino ISP. У меня все сработало, и я переключил микросхему обратно из режима 128КГц. А кто-то только в этом режиме и работает, потому что, подозреваю, потребление в этом режиме еще меньше.
Обновил «ядро»(core13_20), пока что нужно протестировать, нужна ваша помощь. Добавил поддержку как старых версий Arduino IDE так и новых, теоретически должно работать.
Скачать ядро можно тут.
Установка та же:
! Для работы с частотами ниже 1 мГц используем скетч Arduino slow ISP, но я не тестировал, так что тоже теоретически.
Взято отсюда.
Если что-то не будет получатся, всегда есть верный способ — Как восстановить неправильно выставленные фьюзы в ATtiny.
Поддерживаемые функции:
* = Partial support
P.S. За ссылки отдельное спасибо товарищу grigorym.
Скачать ядро можно тут.
Установка та же:
! Для работы с частотами ниже 1 мГц используем скетч Arduino slow ISP, но я не тестировал, так что тоже теоретически.
Arduino slow ISP
// this sketch turns the Arduino into a AVRISP
// using the following pins:
// 10: slave reset
// 11: MOSI
// 12: MISO
// 13: SCK
// Put an LED (with resistor) on the following pins:
// 9: Heartbeat - shows the programmer is running
// 8: Error - Lights up if something goes wrong (use red if that makes sense)
// 7: Programming - In communication with the slave
//
// October 2009 by David A. Mellis
// - Added support for the read signature command
//
// February 2009 by Randall Bohn
// - Added support for writing to EEPROM (what took so long?)
// Windows users should consider WinAVR's avrdude instead of the
// avrdude included with Arduino software.
//
// January 2008 by Randall Bohn
// - Thanks to Amplificar for helping me with the STK500 protocol
// - The AVRISP/STK500 (mk I) protocol is used in the arduino bootloader
// - The SPI functions herein were developed for the AVR910_ARD programmer
// - More information at code.google.com/p/mega-isp
#include <SPI.h>
#include "pins_arduino.h" // defines SS,MOSI,MISO,SCK
#define RESET SS
#define LED_HB 9
#define LED_ERR 8
#define LED_PMODE 7
#define HWVER 2
#define SWMAJ 1
#define SWMIN 18
// STK Definitions
#define STK_OK 0x10
#define STK_FAILED 0x11
#define STK_UNKNOWN 0x12
#define STK_INSYNC 0x14
#define STK_NOSYNC 0x15
#define CRC_EOP 0x20 //ok it is a space...
void pulse(int pin, int times);
void setup() {
Serial.begin(19200);
pinMode(7, OUTPUT);
pulse(7, 2);
pinMode(8, OUTPUT);
pulse(8, 2);
pinMode(9, OUTPUT);
pulse(9, 2);
pinMode(SS, OUTPUT);
pinMode(MISO, INPUT);
pinMode(MOSI, OUTPUT);
pinMode(SCK, OUTPUT);
// SPI.setClockDivider(SPI_CLOCK_DIV128);
}
int error=0;
int pmode=0;
// address for reading and writing, set by 'U' command
int here;
uint8_t buff[256]; // global block storage
#define beget16(addr) (*addr * 256 + *(addr+1) )
typedef struct param {
uint8_t devicecode;
uint8_t revision;
uint8_t progtype;
uint8_t parmode;
uint8_t polling;
uint8_t selftimed;
uint8_t lockbytes;
uint8_t fusebytes;
int flashpoll;
int eeprompoll;
int pagesize;
int eepromsize;
int flashsize;
}
parameter;
parameter param;
// this provides a heartbeat on pin 9, so you can tell the software is running.
uint8_t hbval=128;
int8_t hbdelta=8;
void heartbeat() {
if (hbval > 192) hbdelta = -hbdelta;
if (hbval < 32) hbdelta = -hbdelta;
hbval += hbdelta;
analogWrite(LED_HB, hbval);
delay(40);
}
void loop(void) {
// is pmode active?
if (pmode) digitalWrite(LED_PMODE, HIGH);
else digitalWrite(LED_PMODE, LOW);
// is there an error?
if (error) digitalWrite(LED_ERR, HIGH);
else digitalWrite(LED_ERR, LOW);
// light the heartbeat LED
heartbeat();
if (Serial.available()) {
avrisp();
}
}
uint8_t getch() {
while(!Serial.available());
return Serial.read();
}
void readbytes(int n) {
for (int x = 0; x < n; x++) {
buff[x] = Serial.read();
}
}
#define PTIME 30
void pulse(int pin, int times) {
do {
digitalWrite(pin, HIGH);
delay(PTIME);
digitalWrite(pin, LOW);
delay(PTIME);
}
while (times--);
}
void spi_init() {
/*uint8_t x;
SPCR = 0x53;
x=SPSR;
x=SPDR;*/
}
void spi_wait() {
do {
}
while (!(SPSR & (1 << SPIF)));
delay(100);
}
//unsigned char msk[] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};
unsigned char msk[] = {0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1};
#define PCK() (bits[0] << 7 | bits[1] << 6 | bits[2] << 5 | bits[3] << 4 | bits[4] << 3 | bits[5] << 2 | bits[6] << 1 | bits[7])
uint8_t spi_send(uint8_t b) {
uint8_t reply=0;
char bits[8] = {0, 0, 0, 0, 0, 0, 0, 0};
/*SPDR=b;
spi_wait();
reply = SPDR;
return reply;*/
// digitalWrite(SS, LOW);
// delayMicroseconds(20);
//cli();
for(uint8_t _bit = 0;_bit < 8;_bit++){
digitalWrite(MOSI, !!(b & msk[_bit]));
delayMicroseconds(50);
digitalWrite(SCK, HIGH);
delayMicroseconds(50);
bits[_bit] = digitalRead(MISO);
delayMicroseconds(50);
digitalWrite(SCK, LOW);
delayMicroseconds(50);
// delayMicroseconds(50);
}
// digitalWrite(SS, HIGH);
delayMicroseconds(50);
reply = PCK();
return reply;
}
uint8_t spi_transaction(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
uint8_t n;
spi_send(a);
n=spi_send(b);
//if (n != a) error = -1;
n=spi_send(c);
return spi_send(d);
}
void empty_reply() {
if (CRC_EOP == getch()) {
Serial.print((char)STK_INSYNC);
Serial.print((char)STK_OK);
}
else {
Serial.print((char)STK_NOSYNC);
}
}
void breply(uint8_t b) {
if (CRC_EOP == getch()) {
Serial.print((char)STK_INSYNC);
Serial.print((char)b);
Serial.print((char)STK_OK);
}
else {
Serial.print((char)STK_NOSYNC);
}
}
void get_version(uint8_t c) {
switch(c) {
case 0x80:
breply(HWVER);
break;
case 0x81:
breply(SWMAJ);
break;
case 0x82:
breply(SWMIN);
break;
case 0x93:
breply('S'); // serial programmer
break;
default:
breply(0);
}
}
void set_parameters() {
// call this after reading paramter packet into buff[]
param.devicecode = buff[0];
param.revision = buff[1];
param.progtype = buff[2];
param.parmode = buff[3];
param.polling = buff[4];
param.selftimed = buff[5];
param.lockbytes = buff[6];
param.fusebytes = buff[7];
param.flashpoll = buff[8];
// ignore buff[9] (= buff[8])
//getch(); // discard second value
// WARNING: not sure about the byte order of the following
// following are 16 bits (big endian)
param.eeprompoll = beget16(&buff[10]);
param.pagesize = beget16(&buff[12]);
param.eepromsize = beget16(&buff[14]);
// 32 bits flashsize (big endian)
param.flashsize = buff[16] * 0x01000000
+ buff[17] * 0x00010000
+ buff[18] * 0x00000100
+ buff[19];
}
void start_pmode() {
spi_init();
// following delays may not work on all targets...
pinMode(RESET, OUTPUT);
digitalWrite(RESET, HIGH);
pinMode(SCK, OUTPUT);
digitalWrite(SCK, LOW);
delay(50);
//delay(250);
digitalWrite(RESET, LOW);
delay(50);
//delay(250);
pinMode(MISO, INPUT);
pinMode(MOSI, OUTPUT);
spi_transaction(0xAC, 0x53, 0x00, 0x00);
pmode = 1;
}
void end_pmode() {
pinMode(MISO, INPUT);
pinMode(MOSI, INPUT);
pinMode(SCK, INPUT);
pinMode(RESET, INPUT);
pmode = 0;
}
void universal() {
int w;
uint8_t ch;
for (w = 0; w < 4; w++) {
buff[w] = getch();
}
ch = spi_transaction(buff[0], buff[1], buff[2], buff[3]);
breply(ch);
}
void flash(uint8_t hilo, int addr, uint8_t data) {
spi_transaction(0x40+8*hilo,
addr>>8 & 0xFF,
addr & 0xFF,
data);
}
void commit(int addr) {
spi_transaction(0x4C, (addr >> 8) & 0xFF, addr & 0xFF, 0);
}
//#define _current_page(x) (here & 0xFFFFE0)
int current_page(int addr) {
if (param.pagesize == 32) return here & 0xFFFFFFF0;
if (param.pagesize == 64) return here & 0xFFFFFFE0;
if (param.pagesize == 128) return here & 0xFFFFFFC0;
if (param.pagesize == 256) return here & 0xFFFFFF80;
return here;
}
uint8_t write_flash(int length) {
if (param.pagesize < 1) return STK_FAILED;
//if (param.pagesize != 64) return STK_FAILED;
int page = current_page(here);
int x = 0;
while (x < length) {
if (page != current_page(here)) {
commit(page);
page = current_page(here);
}
flash(LOW, here, buff[x++]);
flash(HIGH, here, buff[x++]);
here++;
}
commit(page);
return STK_OK;
}
uint8_t write_eeprom(int length) {
// here is a word address, so we use here*2
// this writes byte-by-byte,
// page writing may be faster (4 bytes at a time)
for (int x = 0; x < length; x++) {
spi_transaction(0xC0, 0x00, here*2+x, buff[x]);
delay(45);
}
return STK_OK;
}
void program_page() {
char result = (char) STK_FAILED;
int length = 256 * getch() + getch();
if (length > 256) {
Serial.print((char) STK_FAILED);
return;
}
char memtype = getch();
for (int x = 0; x < length; x++) {
buff[x] = getch();
}
if (CRC_EOP == getch()) {
Serial.print((char) STK_INSYNC);
if (memtype == 'F') result = (char)write_flash(length);
if (memtype == 'E') result = (char)write_eeprom(length);
Serial.print(result);
}
else {
Serial.print((char) STK_NOSYNC);
}
}
uint8_t flash_read(uint8_t hilo, int addr) {
return spi_transaction(0x20 + hilo * 8,
(addr >> 8) & 0xFF,
addr & 0xFF,
0);
}
char flash_read_page(int length) {
for (int x = 0; x < length; x+=2) {
uint8_t low = flash_read(LOW, here);
Serial.print((char) low);
uint8_t high = flash_read(HIGH, here);
Serial.print((char) high);
here++;
}
return STK_OK;
}
char eeprom_read_page(int length) {
// here again we have a word address
for (int x = 0; x < length; x++) {
uint8_t ee = spi_transaction(0xA0, 0x00, here*2+x, 0xFF);
Serial.print((char) ee);
}
return STK_OK;
}
void read_page() {
char result = (char)STK_FAILED;
int length = 256 * getch() + getch();
char memtype = getch();
if (CRC_EOP != getch()) {
Serial.print((char) STK_NOSYNC);
return;
}
Serial.print((char) STK_INSYNC);
if (memtype == 'F') result = flash_read_page(length);
if (memtype == 'E') result = eeprom_read_page(length);
Serial.print(result);
return;
}
void read_signature() {
if (CRC_EOP != getch()) {
Serial.print((char) STK_NOSYNC);
return;
}
Serial.print((char) STK_INSYNC);
uint8_t high = spi_transaction(0x30, 0x00, 0x00, 0x00);
Serial.print((char) high);
uint8_t middle = spi_transaction(0x30, 0x00, 0x01, 0x00);
Serial.print((char) middle);
uint8_t low = spi_transaction(0x30, 0x00, 0x02, 0x00);
Serial.print((char) low);
Serial.print((char) STK_OK);
}
//////////////////////////////////////////
//////////////////////////////////////////
////////////////////////////////////
////////////////////////////////////
int avrisp() {
uint8_t data, low, high;
uint8_t ch = getch();
switch (ch) {
case '0': // signon
empty_reply();
break;
case '1':
if (getch() == CRC_EOP) {
Serial.print((char) STK_INSYNC);
Serial.print("AVR ISP");
Serial.print((char) STK_OK);
}
break;
case 'A':
get_version(getch());
break;
case 'B':
readbytes(20);
set_parameters();
empty_reply();
break;
case 'E': // extended parameters - ignore for now
readbytes(5);
empty_reply();
break;
case 'P':
start_pmode();
empty_reply();
break;
case 'U':
here = getch() + 256 * getch();
empty_reply();
break;
case 0x60: //STK_PROG_FLASH
low = getch();
high = getch();
empty_reply();
break;
case 0x61: //STK_PROG_DATA
data = getch();
empty_reply();
break;
case 0x64: //STK_PROG_PAGE
program_page();
break;
case 0x74: //STK_READ_PAGE
read_page();
break;
case 'V':
universal();
break;
case 'Q':
error=0;
end_pmode();
empty_reply();
break;
case 0x75: //STK_READ_SIGN
read_signature();
break;
// expecting a command, not CRC_EOP
// this is how we can get back in sync
case CRC_EOP:
Serial.print((char) STK_NOSYNC);
break;
// anything else we will return STK_UNKNOWN
default:
if (CRC_EOP == getch())
Serial.print((char)STK_UNKNOWN);
else
Serial.print((char)STK_NOSYNC);
}
}
Взято отсюда.
Если что-то не будет получатся, всегда есть верный способ — Как восстановить неправильно выставленные фьюзы в ATtiny.
Поддерживаемые функции:
* = Partial support
- map()
- random()
- randomSeed()
- millis()
- micros()
- delay()
- delayMicroseconds() *
- analogRead()
- analogWrite()
- pinMode()
- digitalRead()
- digitalWrite()
- pulseIn() (Untested)
- shiftIn() (Untested)
- shiftOut() (Untested)
P.S. За ссылки отдельное спасибо товарищу grigorym.
Привет! Воспользовался твоим ядром (версия 0.22), и при прошивке контроллера и установке фьюзов столкнулся с кучей ошибок и предупреждений.
Исправил, и заодно причесал меню (вынес выбор частоты в отдельное меню, как это сделано для ардуиновских плат).
Закинул вот сюда: github.com/orlv/at13
Изменения в файлах boards.txt и platform.txt
Насчёт ошибок в соединении с attiny13 при установке частоты ниже 1 МГц — можно использовать более свежий ArduinoISP, тот, что идёт в комплекте со средой (у меня среда версии 1.6.6).
Для этого в нём надо изменить одну строчку:
#define SPI_CLOCK (1000000/6)
меняем на:
#define SPI_CLOCK (128000/6)
После этого всё прошивается и работает.
Исправил, и заодно причесал меню (вынес выбор частоты в отдельное меню, как это сделано для ардуиновских плат).
Закинул вот сюда: github.com/orlv/at13
Изменения в файлах boards.txt и platform.txt
Насчёт ошибок в соединении с attiny13 при установке частоты ниже 1 МГц — можно использовать более свежий ArduinoISP, тот, что идёт в комплекте со средой (у меня среда версии 1.6.6).
Для этого в нём надо изменить одну строчку:
#define SPI_CLOCK (1000000/6)
меняем на:
#define SPI_CLOCK (128000/6)
После этого всё прошивается и работает.
Sign up to leave a comment.
Прошивка и программирование ATtiny13 при помощи Arduino UPD 17.03.2016