ATtiny13A 101 применение

MaksMS
Offline
Зарегистрирован: 11.03.2013

При прошивке аттини через программатор необходимо выбирать в меню пункт "с помощью программатора"

DimaP.
Offline
Зарегистрирован: 21.04.2013

Так вот именно это я и нажимаю выдает вот такое сообщение(

 

DimaP.
Offline
Зарегистрирован: 21.04.2013

И так при выводе такого сообщения 

please define PAGEL and BS2 signals in the configuration file for part

советую прочитать вот эту статью

http://bigbarrel.ru/error_attiny4585/

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013
DimaP.
Offline
Зарегистрирован: 21.04.2013

Мужики ну может кто знает почему не происходит нормального чтения АЦП, если я пытаюсь прочитать только 8 бит( ADLAR = 1)

получается вроде как в переменную записывается значение либо 255 либо 0 вот код


byte light_time = 0;                   // управления выдержкой на включение 


 
void setup() { 
  
  DDRB |=(1<<0);//PB3 установить как выход
  ADMUX |=(1<<ADLAR);//читаем только ADCH ! 8 бит разрешение
}


void loop()
{
         // если разрешено считывание АЦП , то
  
   light_time = Read_ADC(3); 
   PORTB |=(1<<0);
   delay(light_time);
   PORTB &= ~(1<<0);
}

  byte Read_ADC(byte channel)//функция для чтения АЦП
  {  
  ADMUX = channel; // ADC pin
  ADCSRA |= 1<<ADEN;
  ADCSRA |= 1<<ADSC;
  while(!(ADCSRA & (1<<ADIF)));
  ADCSRA |= 1<<ADIF;
  ADCSRA &= ~(1 << ADEN);  // отключаем АЦП, для уменьшения энергопотребления
  return ADCH;

}

 

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Функцыя с другого поста:

unsigned int analogRead_C(byte channel){ 
  ADMUX = channel; // ADC pin
  ADCSRA |= 1<<ADEN;
  ADCSRA |= 1<<ADSC;
  while(!(ADCSRA & (1<<ADIF)));
  ADCSRA |= 1<<ADIF;
  byte low  = ADCL;
  byte high = ADCH;
  //ADCSRA &= ~(1 << ADEN);  // отключаем АЦП, для уменьшения энергопотребления
  return (high << 8) | low;
}

И результат делите на 4, Боже, зачем заморачиваться с этим adlar?

toc
Offline
Зарегистрирован: 09.02.2013

>> Считать когда фаза будет переходить через ноль не лучшая идея, частота не всегда ровно 50 герц

Точную частоту в розетке (в России) можно посмотреть на сайте http://so-ups.ru/
Насколько я помню, во всей стране есть несколько синхронных зон.

DimaP.
Offline
Зарегистрирован: 21.04.2013

HWman пишет:

Функцыя с другого поста:



unsigned int analogRead_C(byte channel){ 
  ADMUX = channel; // ADC pin
  ADCSRA |= 1<<ADEN;
  ADCSRA |= 1<<ADSC;
  while(!(ADCSRA & (1<<ADIF)));
  ADCSRA |= 1<<ADIF;
  byte low  = ADCL;
  byte high = ADCH;
  //ADCSRA &= ~(1 << ADEN);  // отключаем АЦП, для уменьшения энергопотребления
  return (high << 8) | low;
}

И результат делите на 4, Боже, зачем заморачиваться с этим adlar?

Да я знаю что можно на 4 разделить, но тут просто попытка понять))

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

У Вас есть протеус?

DimaP.
Offline
Зарегистрирован: 21.04.2013

Да есть но я не знаю как туда ардуиновские проги кидать?

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Как будет время покажу что и как, правда это извращение ещё то, но можно вполне отладить что-то без наличия железа.

DimaP.
Offline
Зарегистрирован: 21.04.2013

Все вроде дописал я прогу димера, немного подкоректировал схему, да и в коде пришлось обойтись без ардуиновских функций, вообщем кто хочет повторить, милости прошу задавайте вопросы постораюсь растолковать)

Измененная схема

 

вот код

#include <avr/io.h> // чисто для приличия
#include <avr/interrupt.h> // биба для настройки прерываний
/////////////////////////////////////////////////////
volatile boolean ADC_stop = false;     //флаг остановки считывания АЦП при рыдержке времени
volatile byte counter = 0;                      //счетчик для отчета времени
byte light_time = 50; //переменная непосредственногог управления выдержкой на включение симистора
byte ADC_value = 0;

 
void setup() { 
  InitINT0(); // нужно
  DDRB |=(1<<4);//PB3 установить как выход
  DDRB &= ~(1<<1);//PB1 устанавливаем как вход
  PORTB |=(1<<4);//включаем симистор
}
void InitINT0() // Инициализация прерываний
{
  cli();
  TCCR0A = 0b00000010; // WGM01 WGM00 ! режим СТС
  TCCR0B = 0b00000010; // CS02 CS01 CS00 прескалинг на 8
  OCR0A =  120;        // частота прерываний 9600000/8/120 = 10000 Гц это 200 раз за период 20 мсек
  TIMSK0 |= (1<<OCIE0A);
  ADMUX = (1<<ADLAR)|(1<<MUX1)|(1<<MUX0);
  ADCSRA = 0b10000001;
  MCUCR |= (1<<ISC01) | (1<<ISC00);
  GIMSK |= (1<<INT0);
  sei();
} 
 
ISR(INT0_vect) // прерывание по вектору INT0(ножка РВ1), тоесть по изменению состояния вывода LOW on HIGH
{
 PORTB &=~(1<<4); //выключаем симистор 
 TIMSK0 |= (1<<OCIE0A); // запускаем таймер
 ADC_stop = true; // ставим запрет на считывание АЦП, это для того чтобы не менялось значение
                  // выдержки в процессе отсчета
}

ISR(TIM0_COMPA_vect)//если словили переход через ноль
{
  
  
  counter ++;// увеличиваем значение счетчика через каждые 100 мксек
  if(counter == light_time)
   {
    PORTB |=(1<<4);//включаем симистор
    TIMSK0 &= ~(1<<OCIE0A); // останавливаем таймер
    ADC_stop = false; //разрешаем читать АЦП
    counter = 0;
   } 
  
}
void loop()
{
  
   if(!ADC_stop)
   {
     ADC_value = Read_ADC();
     light_time = map_byte(ADC_value, 0, 255, 1, 99);
   }
}   
  byte Read_ADC()
  { 
  ADCSRA |= (1<<ADSC);
  while((ADCSRA & 0x10)==0); //ждем, пока АЦП закончит преобразование (ADIF = 0)
  ADCSRA|=0x10;//устанавливаем ADIF
  return ADCH;//возращаем только ADCH, ADCL  нам не нужно
}

byte map_byte(byte x, byte in_min, byte in_max, byte out_min, byte out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

 

Размер скетча в двоичном коде: 506 байт (из 1 024 байт максимум)

nik071
Offline
Зарегистрирован: 03.07.2013

Привет!!! Возник вот такой вопрос?? чтобы не лепить много обвязки ! сколько можно подцепить транзисторов параллельно напрямую к ноге шима тиньки транзисторы 10n03L , буква L в конце затвор логик левел
 http://www.chipfind.ru/datasheet/infineon/ipp10n03l.htm мне надо моторам на 300 ват 12 вольт 30 ампер по рулить как насчет 3 транзисторов параллельно к тини напрямую
Транзисторы 100 ват 73 амп 30 вольт??????????????????

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

ну рискните. сожгете порт тини возможно. а полевики вообще скорее всего

nik071
Offline
Зарегистрирован: 03.07.2013

я тоже так думаю .думал может порадует кто!!!!
емкость затвора 1200 пик 5 вольт  как правильно подсчитать время заряда и ток????

с одним таким транзистором через резистор на 200 ом и подтяжкой к земле 10 ком работает прекрасно и не греется!!!(55 ват авто лампа)

может шим программный намутить на 3 ноги????

nik071
Offline
Зарегистрирован: 03.07.2013

и еще один вопрос я буду задействовать команду пульсин ей мерить количество импульсов и в зависимости от числа управлять мотором шимом все срастется ведь таймер один????   ( устал кипеть мотор охлаждения S80 его реостат принимает шим сигнал я его померил 9000 импульсов 1 скорость 6000 им 2 скорость 3000 3 скорость  управлял мотором тоже шимом ) как лучше поступить????
решил намутить на тиньке с минимальной обвязкой????

DimaP.
Offline
Зарегистрирован: 21.04.2013

подскажите а почему я не получается применять ватчдог на аттини 13? я читал в этой ветке вы писали про сторжевой таймер, и как вам ужалось наладить его?

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

/*я тоже так думаю .думал может порадует кто!!!!

емкость затвора 1200 пик 5 вольт  как правильно подсчитать время заряда и ток????

с одним таким транзистором через резистор на 200 ом и подтяжкой к земле 10 ком работает прекрасно и не греется!!!(55 ват авто лампа)

может шим программный намутить на 3 ноги????*/

Выставьте небольшую частоту ШИМ, до 100 Гц.

Думаю по 50 ватт на транзистор будет норм, не забывайте про толщину проводов и ширину дорожек на плате, 30 А - "это вам не это".

Как намутите программный ШИМ - поделитесь.

/*подскажите а почему я не получается применять ватчдог на аттини 13? я читал в этой ветке вы писали про сторжевой таймер, и как вам ужалось наладить его?*/

Что именно не получается? Посмотрите тут.

nik071
Offline
Зарегистрирован: 03.07.2013

Как намутите программный ШИМ - поделитесь.

Может я что не так написал , но если запустить таймер  проверять его , и чтобы 3 ноги работали сразу напрямую в регистр 1 байт ( я не знаю ка правильно 8 бит) писать , и к та муже мне показалось что на 9.6 мегагерц

  • delay()
  • работала очень корректно можно ей через интервал (да проблема в остальной программе ????? в смысле время исполнение) прерывания рулят   блин все что-то сложно по новой изучать вроде не дурак но без драйвера походу не как!!!!!
  • как шим на 100 мег поправить???????
DimaP.
Offline
Зарегистрирован: 21.04.2013

HWman пишет:

Что именно не получается? Посмотрите тут.

Да пробовал пример вот сам тут набросал, по аналогии с вашим, но ватчдог не перезагружает, т.е, выдержка прошла как и положенно, произошел ресет, а потом ичего не происходит, молчит((

#include <avr/wdt.h>
#define MIG 0
int counter=0;
void setup(){
   wdt_disable(); // запретили как можно скорее собаку, что-бы не уйти в бесконечный ребут
   pinMode(MIG, OUTPUT);
   
  
  delay(1000); // что-бы четче видеть рестар скетча
  
 
 

  
}



void loop(){
  
   wdt_enable(WDTO_4S); // активировали таймер, каждые 4-ре секунды его нужно сбрасывать
   
   counter++;
   
   if(counter==5){
      while(true)
    {
      digitalWrite(MIG, HIGH);
      delay(500);
       digitalWrite(MIG, LOW);
       delay(500);
    } // создаем зависание, через 4 секунды должен произойти ресет, так как не вызывается wdt_reset();
   }
   delay(500);
  wdt_reset(); // говорим собаке что "В Багдаде все спокойно", начинается очередной отсчет 4-х секунд.
}

 

DimaP.
Offline
Зарегистрирован: 21.04.2013

Сори, но все заработало из примера выше, просто закоментировал, 9 строчку и все пошло, если есть мысли поделитесь кто нибудь))

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

/*как шим на 100 мег поправить???????*/

Здесь поищите http://sotvorimvmeste.ru/viewtopic.php?f=36&t=74

 

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

5 (пятая) строка бессмыссленна- зачем запрещать то, чего нет,

выполняется один раз как раз тогда, когда wdt еще не включён.

Единственно когда это может понадобится ( а может и нет) когда  wdt таймер разрешен с помощью фьюза, что делать  особого смысла нет, и без него можем включать-выключать wdt таймер в программе

leshak
Offline
Зарегистрирован: 29.09.2011

trembo пишет:

5 (пятая) строка бессмыссленна- зачем запрещать то, чего нет,

К сожалению есть.

выполняется один раз как раз тогда, когда wdt еще не включён.

trembo пишет:

Единственно когда это может понадобится ( а может и нет) когда  wdt таймер разрешен с помощью фьюза,

Неверно. (см. ниже)

trembo пишет:

делать  особого смысла нет, и без него можем включать-выключать wdt таймер в программе

Ситуация: фьюз не выставлен. включили програмно.... контроллер ребутнулся по вачдогу. Каково состояние вачдога? Ответ: ВКЛЮЧЕН. И если мы его быстренько не сбросим или выключим - он опять отправит нам камень в ребут.

Именно это и является причиной проблемы с некоторыми загрузчиками. Как только срабатывает вачдок - плата уходит в бесконечный ребут. Не успевает добраться до wdt_disable() в setup(); и вачдог повторно срабатывает еще в самом бутлоадере.

Поэтому для нормальной работы либо загрузчик должен выполнятся быстрее чем таймаут вачдога (что-бы успеть вырубить его в setup(), но тогда через загрузчик не выйдет скетчи заливать, так как это явно дольше), либо, по хорошему, вот это wdt_disable() должно быть в первых строчках самого загрузчика.

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

То есть мы в "предыдушей жизни" включили вачдогу, она сработала  по каким-то причинам  и после ребута получаем влючённый вачдог ?  То есть при ребуте никто никаких регистров не чистит? И что, переменные, объявленные как static, после всего этого еще и сохраняют свои значения, Прямо реинкарнация какая-то получается.

leshak
Offline
Зарегистрирован: 29.09.2011

trembo пишет:

То есть мы в "предыдушей жизни" включили вачдогу, она сработала  по каким-то причинам  и после ребута получаем влючённый вачдог ? 

Точно.

Именно это и является причиной жалоб "дуина мигает светиком  часто-часто-часто... и скетчи не заливаются".

trembo пишет:

То есть при ребуте никто никаких регистров не чистит? И что, переменные, объявленные как static, после всего этого еще и сохраняют свои значения, Прямо реинкарнация какая-то получается.

Не знаю. Не проверял. Вачдог - это точно. Остальное - либо пробовать, либо даташит курить. Думаю не сбрасывает (по крайней мере самим камнем, что-там бутлоадер чистит - неведомо, правильный и вачдог чистит, неправильный..... ну вы поняли). Думаю и static переменные сохранят свое значение (если вы конечно, не делаете им инициализацию при объявлении). Особенно если они объявлены как volatile.

Мне кажется ресет по вачдогу он как-бы "софт ресет". Передали управление куда там фьюзы сказали. Сбросили стек и кучу.... и все.

Но.. еще раз - это мои догадки. Я проверял только вачдог, на atmega1280 с каким-то древним бутлоадером.

P.S. В какой-то степени это даже хорошо. Что не сбрасывается. Это, теоретически, позволяет написать кастомный бутлоадер, который может определять по какой причине произошел ресет, аппаратно или по вачдогу..

 

zsm@nxt.ru
Offline
Зарегистрирован: 27.05.2013

Друзья, подскажите пожалуйста, чтобы на сабже использовать первую ногу (RESET) на выход обязательно использовать высоковольтный программатор?

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Нет, но программироваться МК будет только 1 раз - если у Вас конечно нету высоковольтный программатора.

zsm@nxt.ru
Offline
Зарегистрирован: 27.05.2013

спасибо , как раз так и нужно http://fusecalc.mirmk.net/ нашол такой калькулятор очень наглядно всё.

отключил резет залил hex сейчас буду проверять не намудрил ли чего)

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

/*отключил резет залил hex сейчас буду проверять не намудрил ли чего)*/

Какой hex залили? При таких раскладах заливаеться что-нибудь только раз, хотите ещё или покупайте ВВ программатор или паяйте его.

MaksMS
Offline
Зарегистрирован: 11.03.2013

Да там паять-то.. надо ардуину ,программатор(или другую ардуину для прошивки) и 3 транзистора..

zsm@nxt.ru
Offline
Зарегистрирован: 27.05.2013

Hex для готового устойства, больше перепрошивать не нужно :)

Всё заработало спасибо)

 

 

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Тут кто-то интересовался как моделировать ардуино в протеусе, вот:

https://www.youtube.com/watch?v=gj5koMNtKwI

minamonra
Offline
Зарегистрирован: 18.06.2014

Нужен выход 0-5 вольт, для управления зарядным током.
Насколько я понимаю можно сделать примерно так
Так вот - на какие ноги выход можно посадить, и как такую функцию реализовать?
Упс. Дошло.
Завтра попробую.

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

А задумка то интересная.

minamonra
Offline
Зарегистрирован: 18.06.2014

Чтобы было понятно, для чего - тыц раз, тыц два. Еще можно применить для регулировки яркости светодиодов, схема получается копеечная, идея взята тут. Опробованный (подачей напряжения на R5) вариант для зарядки:

s_1404485084_4848305_69b58e6c3e.gif

Правда схеме присущи минусы источника тока на полевике.

minamonra
Offline
Зарегистрирован: 18.06.2014

Оказалось всё проще. С ноги тини - резистор 1k + конденсатор 0.1мкф, - RC фильтр, дальше к схеме, что выше, на R5.

analogWrite(CURRENT_PIN, 85 );

Получил ток ~ 700mA, при 180 - 150-170mA, 255 - выкл, что меня удовлетворяет. Код бесперебойника впритык влез на ардуиновских функциях - 970 байт, в идеале конечно добавить засыпание при разряде...

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

minamonra пишет:

...в идеале конечно добавить засыпание при разряде...

http://arduino.ru/forum/proekty/zashchita-ot-glubokogo-razryada-na-attin...

minamonra
Offline
Зарегистрирован: 18.06.2014

Спасибо, попробую разобраться что к чему... но пока туго доходит. ;_) Еще вопрос - pwm у attiny только PB0 и PB1 могут?

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Аппаратно - да.

avton
avton аватар
Offline
Зарегистрирован: 11.05.2014

HWman спасибо за материал,пригодилось в другой теме http://arduino.ru/forum/proekty/umnye-tualet-i-vannaya?page=8#comment-74196

DeathRider
Offline
Зарегистрирован: 25.07.2014

Возникла проблема с прошивкой Attiny13a-PU. Что я делаю: 

1. Собираю стандартную схему+к 4 ножке тини подключаю светодиод что бы потом проверить. Результат(для увеличения фото кликнуть по ним):

Полный размер,

2. Качаю по ссылке со второй страницы http://hwman.ho.ua/files/ATtiny13A101/attiny13.zip и заливаю в новосозданую папку hardware.(появляются Тини13 3 штуки)

3. Далее снимаю конденсатор 10uF (тот, что от GRN в RESET Arduino UNO). Ставлю плату:Arduino UNO програматор:AVRisp mkII(тут я не очень понял, что надо сразу ставить Arduino as ISP или на AVRisp mkII, но пробовал и так и так.). Открываю из примера: ArduinoISP. Тут вроде все нормально. По очереди пробегают все светодиоды и остается гореть зеленый.

// ArduinoISP version 04m3
// Copyright (c) 2008-2011 Randall Bohn
// If you require a license, see 
//     http://www.opensource.org/licenses/bsd-license.php
//
// This sketch turns the Arduino into a AVRISP
// using the following arduino pins:
//
// pin name:    not-mega:         mega(1280 and 2560)
// slave reset: 10:               53 
// MOSI:        11:               51 
// MISO:        12:               50 
// SCK:         13:               52 
//
// 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
//
// 23 July 2011 Randall Bohn
// -Address Arduino issue 509 :: Portability of ArduinoISP
// http://code.google.com/p/arduino/issues/detail?id=509
//
// October 2010 by Randall Bohn
// - Write to EEPROM > 256 bytes
// - Better use of LEDs:
// -- Flash LED_PMODE on each flash commit
// -- Flash LED_PMODE while writing EEPROM (both give visual feedback of writing progress)
// - Light LED_ERR whenever we hit a STK_NOSYNC. Turn it off when back in sync.
// - Use pins_arduino.h (should also work on Arduino Mega)
//
// 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 http://code.google.com/p/mega-isp

#include "pins_arduino.h"
#define RESET     SS

#define LED_HB    9
#define LED_ERR   8
#define LED_PMODE 7
#define PROG_FLICKER true

#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(LED_PMODE, OUTPUT);
  pulse(LED_PMODE, 2);
  pinMode(LED_ERR, OUTPUT);
  pulse(LED_ERR, 2);
  pinMode(LED_HB, OUTPUT);
  pulse(LED_HB, 2);
}

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(20);
}


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 fill(int n) {
  for (int x = 0; x < n; x++) {
    buff[x] = getch();
  }
}

#define PTIME 30
void pulse(int pin, int times) {
  do {
    digitalWrite(pin, HIGH);
    delay(PTIME);
    digitalWrite(pin, LOW);
    delay(PTIME);
  } 
  while (times--);
}

void prog_lamp(int state) {
  if (PROG_FLICKER)
    digitalWrite(LED_PMODE, state);
}

void spi_init() {
  uint8_t x;
  SPCR = 0x53;
  x=SPSR;
  x=SPDR;
}

void spi_wait() {
  do {
  } 
  while (!(SPSR & (1 << SPIF)));
}

uint8_t spi_send(uint8_t b) {
  uint8_t reply;
  SPDR=b;
  spi_wait();
  reply = SPDR;
  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 {
    error++;
    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 {
    error++;
    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])
  // 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);
  digitalWrite(RESET, LOW);
  delay(50);
  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;

  fill(4);
  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) {
  if (PROG_FLICKER) prog_lamp(LOW);
  spi_transaction(0x4C, (addr >> 8) & 0xFF, addr & 0xFF, 0);
  if (PROG_FLICKER) {
    delay(PTIME);
    prog_lamp(HIGH);
  }
}

//#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;
}


void write_flash(int length) {
  fill(length);
  if (CRC_EOP == getch()) {
    Serial.print((char) STK_INSYNC);
    Serial.print((char) write_flash_pages(length));
  } 
  else {
    error++;
    Serial.print((char) STK_NOSYNC);
  }
}

uint8_t write_flash_pages(int length) {
  int x = 0;
  int page = current_page(here);
  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;
}

#define EECHUNK (32)
uint8_t write_eeprom(int length) {
  // here is a word address, get the byte address
  int start = here * 2;
  int remaining = length;
  if (length > param.eepromsize) {
    error++;
    return STK_FAILED;
  }
  while (remaining > EECHUNK) {
    write_eeprom_chunk(start, EECHUNK);
    start += EECHUNK;
    remaining -= EECHUNK;
  }
  write_eeprom_chunk(start, remaining);
  return STK_OK;
}
// write (length) bytes, (start) is a byte address
uint8_t write_eeprom_chunk(int start, int length) {
  // this writes byte-by-byte,
  // page writing may be faster (4 bytes at a time)
  fill(length);
  prog_lamp(LOW);
  for (int x = 0; x < length; x++) {
    int addr = start+x;
    spi_transaction(0xC0, (addr>>8) & 0xFF, addr & 0xFF, buff[x]);
    delay(45);
  }
  prog_lamp(HIGH); 
  return STK_OK;
}

void program_page() {
  char result = (char) STK_FAILED;
  int length = 256 * getch();
  length += getch();
  char memtype = getch();
  // flash memory @here, (length) bytes
  if (memtype == 'F') {
    write_flash(length);
    return;
  }
  if (memtype == 'E') {
    result = (char)write_eeprom(length);
    if (CRC_EOP == getch()) {
      Serial.print((char) STK_INSYNC);
      Serial.print(result);
    } 
    else {
      error++;
      Serial.print((char) STK_NOSYNC);
    }
    return;
  }
  Serial.print((char)STK_FAILED);
  return;
}

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
  int start = here * 2;
  for (int x = 0; x < length; x++) {
    int addr = start + x;
    uint8_t ee = spi_transaction(0xA0, (addr >> 8) & 0xFF, addr & 0xFF, 0xFF);
    Serial.print((char) ee);
  }
  return STK_OK;
}

void read_page() {
  char result = (char)STK_FAILED;
  int length = 256 * getch();
  length += getch();
  char memtype = getch();
  if (CRC_EOP != getch()) {
    error++;
    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()) {
    error++;
    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
    error = 0;
    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':
    fill(20);
    set_parameters();
    empty_reply();
    break;
  case 'E': // extended parameters - ignore for now
    fill(5);
    empty_reply();
    break;

  case 'P':
    start_pmode();
    empty_reply();
    break;
  case 'U': // set address (word)
    here = getch();
    here += 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 't'
    read_page();    
    break;

  case 'V': //0x56
    universal();
    break;
  case 'Q': //0x51
    error=0;
    end_pmode();
    empty_reply();
    break;

  case 0x75: //STK_READ_SIGN 'u'
    read_signature();
    break;

    // expecting a command, not CRC_EOP
    // this is how we can get back in sync
  case CRC_EOP:
    error++;
    Serial.print((char) STK_NOSYNC);
    break;

    // anything else we will return STK_UNKNOWN
  default:
    error++;
    if (CRC_EOP == getch()) 
      Serial.print((char)STK_UNKNOWN);
    else
      Serial.print((char)STK_NOSYNC);
  }
}

4.Ставлю назад конденсатор(GND->Reset). Ставлю плату:Attine13 9.6 (пробовал на 1.2 и 4.8), программатор:Arduino as ISP. Загружаю стандартную прогу blink.  

/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.
 
  This example code is in the public domain.
 */
 
// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led = 4;

// the setup routine runs once when you press reset:
void setup() {                
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);     
}

// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second
}

Далее жму загрузить с помощью программатора(пробовал и просто загрузить) и получаю:

avrdude: please define PAGEL and BS2 signals in the configuration file for part ATtiny13
avrdude: stk500_program_enable(): protocol error, expect=0x14, resp=0x50
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.

avrdude: stk500_disable(): protocol error, expect=0x14, resp=0x51

Первая ошибки я так понимаю бывает т.к. платы иногда присылают нули т.е. впринципе это можно пережить. А вот насчет второй я так понял, что бывает когда плата мертва...Может кто-то подскажет что я делаю не так? Заранее спасибо.

П.С. С ардуиной играюсь 3 день, воэтому просьба сильно не ругать если где-то допустил детский ляп. Форум вроде почитал и решение пока не нашел.

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

https://www.youtube.com/watch?v=MS5i7fnlPBM

Интересно, теперь останутся вопросы?

avton
avton аватар
Offline
Зарегистрирован: 11.05.2014

Они остаются всегда :)

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

DeathRider пишет:

3. Далее снимаю конденсатор 10uF (тот, что от GRN в RESET Arduino UNO). Ставлю плату:Arduino UNO програматор:AVRisp mkII(тут я не очень понял, что надо сразу ставить Arduino as ISP или на AVRisp mkII, но пробовал и так и так.). Открываю из примера: ArduinoISP. Тут вроде все нормально. По очереди пробегают все светодиоды и остается гореть зеленый.

При загрузке скетча в дуину ArduinoISP программатор должен быть AVRisp mkII, уже после того как зашился ArduinoISP меняем тип программатора на Arduino as ISP и прошиваем тини при помощи кнопки "Прошить с помощью программатора".
Потом если захочется прошивать дуину не забывайте изменять тип программатора назад на 
AVRisp mkII.

PS Лично я обхожусь без конденсаторов земля-ресет на дуине.

avton
avton аватар
Offline
Зарегистрирован: 11.05.2014

всё таки удобнее всего шить с помошью этого ...

http://www.ebay.com/itm/USBASP-USBISP-AVR-Programmer-Adapter-10-Pin-Cabl...

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Согласен, это уже более серьёзный уровень.

minamonra
Offline
Зарегистрирован: 18.06.2014

Эти китайские usbasp - как карта ляжет, лежит такой, работать отказывается, плюнул, собрал сам. 

s_1406546836_1182605_c7307881a8.jpg

свой вариант печатки могу дать если надо.

//

Возвращаясь к attiny, - библиотека pwm.h тут не подойдет, как сделать шим, с частотой которую можно задавать в setup, на PB1 и duty cycle 0-255? Частоты нужны 15-100kHz.

Нашел раз, два... и совсем запутался.

avton
avton аватар
Offline
Зарегистрирован: 11.05.2014

Его просто надо перешить

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

minamonra пишет:

... как сделать шим, с частотой которую можно задавать в setup, на PB1 и duty cycle 0-255? Частоты нужны 15-100kHz.

Нашел раз, два... и совсем запутался.

Вот так попробуйте:

int led = 0;           // the pin that the LED is attached to
int brightness = 0;    // how bright the LED is
int fadeAmount = 1;    // how many points to fade the LED by

// the setup routine runs once when you press reset:
void setup()  { 

  /*
Setting Divisor Frequency PWM on 9.6, 4.8, 1.2 MHz CPU
   0x01 divisor is 1      37500, 18750, 4687 Hz
   0x02 divisor is 8      4687, 2344, 586 Hz
   0x03 divisor is 64     586, 293, 73 Hz
   0x04 divisor is 256    146, 73, 18 Hz
   0x05 divisor is 1024   36, 17, 5 Hz
   */
  TCCR0B = TCCR0B & 0b11111000 | 0x05; // 0x05 divisor is 1024   36, 17, 5 Hz

  pinMode(led, OUTPUT);
} 

// the loop routine runs over and over again forever:
void loop()  { 
  // set the brightness of pin 9:
  analogWrite(led, brightness);    

  // change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;

  // reverse the direction of the fading at the ends of the fade: 
  if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ; 
  }     
  // wait for 30 milliseconds to see the dimming effect    
  delay(30);                            
}


Где-то увидел, но еще не проверял работает или нет.

А протеусе вроде как работает.