ATtiny13A 101 применение
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- …
- следующая ›
- последняя »
- Войдите на сайт для отправки комментариев
Итак, уже давненько появился способ программировать маленькие, дешёвые, маложрущие и доступные микрухи ATtiny13A.
Тут я Вам расскажу как можно зашивать дуиновские скетчи.
Итак, для начала нам нужно скачать данный архив(взято отсюда) положить файлы по адресу "\Documents\Arduino\hardware\" должно получится чтото типо "C:\Users\Администратор\Documents\Arduino\hardware\attiny13\cores\core13". Потом ну и в настройках платы выбрать attiny13 9.6 мГц, на других частотах почему то все задержки не такие как задаю, на 128 кГц всё в 2-3 раза быстрее.
Далее нам нужна сама микруха :) Имеете? отлично. Теперь нам нужно узнать как при помощи Arduino прошить тиньку, более подробней здесь.
Итак, зашили blink - работает, отлично, я Вас поздравляю, "это маленький шаг для человека и большой шаг для человечества" :) Как вы уже заметили скетч стал заметно легче ежели для UNO, это связано тем что урезаны большинство дуиновских функций.
100% поддержываются следущие:
pinMode()
digitalWrite()
digitalRead()
analogRead()
analogWrite()
shiftOut()
pulseIn()
millis()
micros()
delay()
delayMicroseconds()
Итак как мы ещё увидели доступно всего 1024 байта, но ведь это мало? "Вы есть много кушать" :) большинству радиолюбителей для небольшой задач типо всяких мигалок, простеньких индикаторов или прочей мелочи - более чем достаточно. Чтобы научится экономить рекомендую ознакомится, а ещё лучше изучайте AVR и Cи, я вот когда смогу побороть лень начну :)
Если будут какие-то вопросы их задавайте тут, хвастайтесь своими проектами на этой замечательной микрухе, я только за, интересно же.
Вот мой первый проект, там я получил несколько советов по оптимизации кода аля уменьшения размера скетча при той же функциональности.
Вот ещё товарищ подтянулся.
Сейчас хочу этот проект перенести на тиньку, но времени маловато, чёт работать не хочет программном моделировании, нужно спаять всё, так как бредборда не имею :( но куплю, обязательно.
Распиновка из даташита:
Нипаняятна? PB5 это тоже что и pin 5 или просто 5. Аналоговые входы все на которых пишет ADC* ШИМ поддерживают порты 0 и 1 ану-ка найдите их на картинке? PB5 использовать и не прибегая к танцам с бубоном не выйдет :( но если вам удастся обуздать эту ногу пишите, мне будет интересно, но незабываем что это форум Arduino.ru
Вкратце наверное всё :) всем удачи, и удачных проектов.
ЗЫ для 5 В питания просто идеально подходит линейный стабилизатор 78L05, они просто созданы друг для друга :) тоже такой дешёвый, маленький и доступный.
Для начинающих рекомендую посетить http://sotvorimvmeste.ru/viewtopic.php?f=36&t=74 .
Статья по прошивке тиньки при помощи arduino http://razniepodelki.blogspot.com/2014/05/attiny13-arduino.html или же более детальная статья на geektimes https://geektimes.ru/post/254970/ .
UPD1 17.03.2016 Файлы ядра ищите теперь тут:
https://geektimes.ru/post/254970/#comment_8943030
Для экономии памяти первым делом научитесь пользоваться директивой препроцессора #define, к примеру код:
int
led = 13;
//#define led 13
void
setup
() {
pinMode(led, OUTPUT);
}
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
}
//Размер скетча в двоичном коде: 384 байт (из 1 024 байт максимум)
Можно записать немного иначе:
//int led = 13;
#define led 13
void
setup
() {
pinMode(led, OUTPUT);
}
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
}
//Размер скетча в двоичном коде: 376 байт (из 1 024 байт максимум)
Экономия при этом будет 8 байт а код будет работать так же.
Функции ардуино на Си:
pinMode(2, OUTPUT); будет DDRB |= (1<<2);
// устанавливаем вывод PB2 как выход
pinMode(2, INPUT); - DDRB &= ~(1<<2);
// устанавливаем вывод PB2 как вход
digitalWrite(2, HIGH); - PORTB |= (1<<2);
// устанавливаем высокий уровень на выводе PB2
digitalWrite(2, LOW); - PORTB &= ~(1<<2);
// устанавливаем низкий уровень на выводе PB2
//Чтение состояния(лог. 1) на порту ввода вывода:
if
(digitalRead(4) == HIGH){
...
}
if
(PINB & (1<<PINB4)){
...
}
//Чтение состояния(лог. 0) на порту ввода вывода:
if
(digitalRead(4) == LOW){
...
}
if
(!(PINB & (1<<PINB4))){
...
}
Например стандартный код:
void
setup
() {
pinMode(0, OUTPUT);
// устанавливаем вывод PB0 как выход
}
void
loop
() {
digitalWrite(0, HIGH);
// устанавливаем высокий уровень на выводе PB0
delay(1000);
// ждем 1000 миллисекунд
digitalWrite(0, LOW);
// устанавливаем низкий уровень на выводе PB0
delay(1000);
// ждем 1000 миллисекунд
}
// Размер скетча в двоичном коде: 376 байт (из 1 024 байт максимум)
Можно записать вот так:
#include <avr/io.h> // принято подключать
#include <util/delay.h> // нужна для функции _delay_ms();
int
main(
void
)
{
// всё что до while(1){ выполняется один раз при старте
DDRB |= (1<<0);
// устанавливаем вывод PB0 как выход
while
(1){
// вечный цыкл, тоже самое что и void loop(){
PORTB |= (1<<0);
// устанавливаем высокий уровень на выводе PB0
_delay_ms(1000);
// ждем 1000 миллисекунд
PORTB &= ~(1<<0);
// устанавливаем низкий уровень на выводе PB0
_delay_ms(1000);
// снова ждем 1000 миллисекунд
}
// конец вечного цикла
return
0;
}
// Размер скетча в двоичном коде: 116 байт (из 1 024 байт максимум)
При этом нехило сэкономить память.
Функция analogRead(); записывается следующим образом:
int
Volts = 0;
// Вольтметр
void
setup
()
{
}
void
loop
()
{
Volts = analogRead_C(2);
// РВ4 в ATtiny13
}
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;
}
EEPROM.write(addr, val); и EEPROM.read(address);:
#include <avr/eeprom.h> // не забываем подключить
int
Address = 0;
byte
Data = 255;
// для экономии рекомендую использовать тип byte(диапазон 0-255)
void
setup
()
{
}
void
loop
()
{
EEPROM_read(Address);
EEPROM_write(Address, Data);
}
void
EEPROM_write(unsigned
int
uiAddress, unsigned
char
ucData)
{
while
(EECR & (1<<EEWE));
/*Ждать завершения предыдущей записи*/
EEAR = uiAddress;
/*Проинициализировать регистры*/
EEDR = ucData;
EECR |= (1<<EEMWE);
/*Установить флаг EEMWE*/
EECR |= (1<<EEWE);
/*Начать запись в EEPROM*/
}
unsigned
char
EEPROM_read(unsigned
int
uiAddress)
{
while
(EECR & (1<<EEWE));
/*Ждать завершения предыдущей записи*/
EEAR = uiAddress;
/* Проинициализировать регистр адреса*/
EECR |= (1<<EERE);
/*Выполнить чтение*/
return
EEDR;
}
А вот так можно писать числа в EEPROM до 65534:
#include <avr/eeprom.h> // не забываем подключить
int
Address = 0;
unsigned
int
Data = 65534;
//0...65534
void
setup
()
{
}
void
loop
()
{
EEPROM_read(Address);
EEPROM_write(Address, Data);
}
//Функции (с) Кэп
void
EEPROM_write(
int
uiAddress,
char
ucData)
{
while
(EECR & (1<<EEWE));
/*Ждать завершения предыдущей записи*/
EEAR = uiAddress;
/*Проинициализировать регистры*/
EEDR = ucData;
EECR |= (1<<EEMWE);
/*Установить флаг EEMWE*/
EECR |= (1<<EEWE);
/*Начать запись в EEPROM*/
}
char
EEPROM_read(
int
uiAddress)
{
while
(EECR & (1<<EEWE));
/*Ждать завершения предыдущей записи*/
EEAR = uiAddress;
/* Проинициализировать регистр адреса*/
EECR |= (1<<EERE);
/*Выполнить чтение*/
return
EEDR;
}
void
EEPROMWriteInt(
int
p_address,
int
p_value)
// принимает 2 параметра, адресс и число 0...65534
{
// забирает 2 ячейки, так что использовать ячейки 0, 2, 4, 6...
byte
lowByte = ((p_value >> 0) & 0xFF);
byte
highByte = ((p_value >> 8) & 0xFF);
EEPROM_write(p_address, lowByte);
EEPROM_write(p_address + 1, highByte);
}
int
EEPROMReadInt(
int
p_address)
//Считывает число в диапазоне 0...65534
{
// использует 2 ячейки, так что считывает ячейки 0, 2, 4, 6...
byte
lowByte = EEPROM_read(p_address);
byte
highByte = EEPROM_read(p_address + 1);
return
((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
}
Взято:
http://www.myrobot.ru/articles/p_avrgcc_ver.php
http://nuzhen-sovet.ru/content/optimiziruem-kod-v-arduino // отличный туториал по программированию на С
http://myrobot.ru/forum/topic.php?forum=3&topic=239
Ещё полезные ссылки:
Как записать числа больше 255 в EEPROM
http://habrahabr.ru/post/152299/ // Програмный ШИМ
http://habrahabr.ru/post/249967/ // Как восстановить неправильно выставленные фьюзы в ATtiny
http://habrahabr.ru/post/251141/ // Программный юарт на ATtiny13
...
Будет обновляться.
К сожалению вынужденная мера. Студенты задавали вопросы, а затем удаляли содержимое первого поста, чтобы преподаватели не нашли. В результате ответы повисали в воздухе
Может какой-то добрый модер поправит их, ато сюда народ направлять будете и каждый раз будут в меня пальцем тикать что я безграмотная сволоч...
Я ведь даже не русский, а по русском языке у меня была двойка.
Уберите пожалуйста "...если у Вас нету таких папок создайте..." и поправте цитату Армстронга "это маленький шаг для человека и большой шаг для человечества"
Готово, поправил. В любом случае никто пальцем тыкать не будет, это ведь не форум лингвистов.
Спасибо, жду пополнений проектов на сабжовой микрухе.
что за девайс на фотке? мне бы схемку аль чертёж... В скетче пин 13, это которая нога?
хочу дуину на работу принести, еле сдерживаю себя.
Первая картинка с гугла, скорей всего при нажатии на кнопку горит какой-то светодиод, или же они образуют какой-то цвет... так безделушка на рандоме...
Скетч из примера в IDE, чисто для наглядности.
Где работаешь? Arduino как программатор не совсем актуально имхо http://dmitrstas.ucoz.ru/publ/chasy/programmatory/avr_usbasp/8-1-0-74
Вопросы топикстартеру и тем у кого получилось.
1. Не получается интегрировать Tiny13 в Arduino IDE. По ссылкам на проекты с 45 и 85 тинькой все пучком, а 13 не встает. У кого вышло - поделитесь куда что клали, плиз. У топикстартера - не очевидно.
2. Я НЕ хочу пользовать Ардуину как программатор. Хочу пользовать дуиновский язык и оболочку и шить напрямую через USBasp. Это возможно?
Спасибо.
Вопросы топикстартеру и тем у кого получилось.
1. Не получается интегрировать Tiny13 в Arduino IDE. По ссылкам на проекты с 45 и 85 тинькой все пучком, а 13 не встает. У кого вышло - поделитесь куда что клали, плиз. У топикстартера - не очевидно.
2. Я НЕ хочу пользовать Ардуину как программатор. Хочу пользовать дуиновский язык и оболочку и шить напрямую через USBasp. Это возможно?
Спасибо.
Итак, для начала нам нужно скачать данный архив(взято отсюда) положить файлы по адресу "\Documents\Arduino\hardware\" должно получится что-то типо "C:\Users\Администратор\Documents\Arduino\hardware\attiny13\cores\core13". Потом ну и в настройках платы выбрать attiny13 9.6 мГц, на других частотах почему то все задержки не такие как задаю, на 128 кГц всё в 2-3 раза быстрее.
Кстати первый пост читали?
Приветствую. Все прочитал. Интересно, что дома под 7 все встало, а на работе под ХР не встает....
Спасибо. Что наваяю - буду постить сюда.
По поводу задержек - разберитесь со фьюзами в файле boards.
ИМХО там хрень какая-то.
###########################################################################
attiny13int.name=Attiny13 @ 128 KHz (internal watchdog oscillator)
attiny13int.upload.using=arduino:arduinoisp
attiny13int.upload.maximum_size=1024
attiny13int.upload.speed=250 # important for not losing connection to a slow processor
attiny13int.bootloader.low_fuses=0x7B - делитель на 8 отключен [CKDIV8=1]. Частота RC - 128 kHz
attiny13int.bootloader.high_fuses=0xFF
attiny13int.bootloader.unlock_bits=0x3F - это еще нахрена?
attiny13int.bootloader.lock_bits=0x3F - аналогично?
attiny13int.build.mcu=attiny13
attiny13int.build.f_cpu=128000 - частота честная
attiny13int.build.core=core13
###############################################################
attiny13at4.name=ATtiny13 @ 4.8MHz (internal 4.8 MHz clock)
attiny13at4.upload.using=arduino:arduinoisp
attiny13at4.bootloader.low_fuses=0x69 - тут делитель на 8 включен [CKDIV8=0]. Частота RC - 4,8 MHz
attiny13at4.bootloader.high_fuses=0xff
attiny13at4.upload.maximum_size=1024
attiny13at4.build.mcu=attiny13
attiny13at4.build.f_cpu=600000 - частота установлена правильно (поскольку включен делитель)
attiny13at4.build.core=core13
###############################################################
attiny13.name=ATtiny13 @ 9.6MHz (internal 9.6 MHz clock)
attiny13.upload.using=arduino:arduinoisp
attiny13.bootloader.low_fuses=0x7a - отключен делитель на 8 ([CKDIV8=1]). Дефолт - 0x6a
attiny13.bootloader.high_fuses=0xff
attiny13.upload.maximum_size=1024
attiny13.build.mcu=attiny13
attiny13.build.f_cpu=1200000 - при этом частота МК таки делится на 8 !!!
attiny13.build.core=core13
###############################################################
ИМХО - непонятки с задержками именно отсюда.
Приветствую!
На работе тоже все получилось. Есть подозрение, что беда была в том, что каталог с core/core13 был назван Attiny13 с Большой буквы. Стер все, переставил - заработало.
Самое главное, что получилось шить через USBasp! Но там выскакивает Warning - avrdude: warning: cannot set sck period. please check for usbasp firmware update.
На это надо просто забить, т.к. все шьется замечательно.
Немного геморройно с названиями выводов, надо помнить распиновку, что вывод 1 это pin 5, вывод 2 - это pin 3 и т.п.
Теперь можно Дуиновским языком писать под тиньку 13.
Теперь надо бы разобраться с таймингами, понять чему равен delay в зависимости от частоты и т.п.
Поморгал диодом, поморгал диодом с кнопки. Короче работает!
Практика показывает, что на Attiny13 с дуиновскими функциями далеко не уедешь... уж слишком они объемные.
Абсолютно согласен, но Дуина - это среда для разработки своих мозгов (а не железа), посему, как завещал Ильич, которому скоро стукнет кста - "Учиться, учиться и еще раз учиться".
Бум учиться на малом, а потом и к старикам Кернигану с Ричем, глядишь подойдем. Хотелось бы. Но ASM уж точно ниасилю.
Нет, про среду я ничего не говорю, она кстати, не имеет практически никаких ограничений - хоть на асме пишите, а вот некоторые дуиновские функции... все равно в итоге от них откажитесь.
Кстати, про среду.
Посмотрев указанные в топике примеры хочу задать дурацкий вопрос. Как среда переваривает/понимает инструкции для работы с портами AVR типа - DDRB или PORTB?
Гдето внутрях смотрит в io.h?
Насчёт фюзов спросите тут правда если владеете английским.
Кстати, про среду.
Посмотрев указанные в топике примеры хочу задать дурацкий вопрос. Как среда переваривает/понимает инструкции для работы с портами AVR типа - DDRB или PORTB?
Гдето внутрях смотрит в io.h?
Да, это можно найти в файле iotn13a.h (hardware/tools/avr/avr/include/avr)
Например, DDRB
Мой новый проект http://arduino.ru/forum/proekty/prostaya-velofara-pod-upravleniem-attiny13a
Всем привет, стоит задача на сабже сделать генератор импульсов на частоте 22-60 кГц(тоесть нарастающая, с шагом в 1 кГц за секунку) потом нужно замолкнуть на 2 минуты и цикл повторяется.
С схемотехникой как бы всё понятно:
Я как неопытный программист тут немного запутался, как задать частоту я разобрался:
1
digitalWrite(0, HIGH);
2
delayMicroseconds(f);
3
digitalWrite(0, LOW);
4
delayMicroseconds(f);
А как сделать чтобы переменная f через некоторое время принимала значение скажем f+1, потом и ещё +1...
Пробовал задать циклом:
01
int
main(
void
)
02
{
03
DDRB = 0b11111;
04
05
while
(1){
06
// for(int f1 = 100; f1 < 1000; f1++){
07
for
(
byte
f = 22; f < 8; f--){
// 8 микросекунд это и будет частота в ~ 60 кГц, а 22 - 22 кГц
08
digitalWrite(0, HIGH);
09
delayMicroseconds(f);
10
digitalWrite(0, LOW);
11
delayMicroseconds(f);
12
}
13
//delayMicroseconds(f1);
14
//}
15
}
16
return
0;
17
}
Но это не то, это вообще баловство, может мне подскажет кто в какую сторону смотреть?
Это будет "отпугиватель птиц" для огорода, всё что я напаяю/моделирую/на программирую, я всё выложу сюда на форум в свободный доступ, главное разобраться с прошивкой, тини идеально подходит для таких проектов...
Ну почему же балавство... если тиня больше ничего не делает то можно и ножкой дергать в цикле, но конечно не digitalWrite'ом, а через регистры.
01
#define F_CPU 9600000UL // 9.6 MHz
02
#include <util/delay.h>
03
04
int
main(
void
)
05
{
06
DDRB = 1;
07
08
while
(1)
09
{
10
for
(
byte
f = 22; f < 8; f--)
// 8 микросекунд это и будет частота в ~ 60 кГц, а 22 - 22 кГц
11
{
12
long
time = 1000000/2/f;
13
for
(
long
t = 0; t < time; t++)
14
{
15
PORTB = 1;
16
_delay_us(f);
17
PORTB = 0;
18
_delay_us(f);
19
}
20
}
21
_delay_ms(120000);
22
}
23
return
0;
24
}
А смотреть вам надо в сторону таймера/счетчика.
С схемотехникой как бы всё понятно:
По классике, транзистор должен находиться под нагрузкой, или быть другой проводимости.
Ага, динамик должен стоять в цепи коллектора.
Ну это поправимо, вот меня волнует то, как будет вести себя динамик на меандре?
Постоянно цокает динамик, что-то не так... Кстати пока код отрабатываю на Arduino:
01
//#define F_CPU 9600000UL // 9.6 MHz
02
#include <util/delay.h>
03
04
int
main(
void
)
05
{
06
DDRB |= (1<<4);
07
08
while
(1)
09
{
10
for
(
int
f = 22; f > 8; f--)
// 8 микросекунд это и будет частота в ~ 60 кГц, а 22 - 22 кГц
11
{
12
PORTB &= ~(1<<4);
13
long
time = 1000000/2/f;
14
for
(
long
t = 0; t < time; t++)
15
{
16
PORTB |= (1<<4);
17
_delay_us(f);
18
PORTB &= ~(1<<4);
19
_delay_us(f);
20
}
21
}
22
_delay_ms(5000);
// 5 сек пауза, для тестов
23
}
24
return
0;
25
}
Используется 12-й пин дуинки. Вот схема как будет выглядеть когда что-то получится:
Транзистор первый который попался под руку - КТ829Б.
Пробовал частоту опускать с 22-60 кГц до 2.2-6 кГц - признаюсь честно - невыносимо долго, глушит!
Не совсем ясно о чем вы, а ваш динамик вообще в таком диапазоне частот работает? Ведь для ультразвука специальные излучатели применяют ,а не обычные колонки.
Вот, что-то получилось
http://www.youtube.com/watch?v=pvzx2UyAC6s
Частота уменьшенная в 10 раз, тоесть 2.2-6 вместо 22-60 кГц для того чтобы было слышно как оно работает, больше деталей будет днём.
Вот думаю, стоит ли усложнять схему или нет?
Случайно наткнуся на http://we.easyelectronics.ru/AVR/uart-programmnyy-na-atiny13a.html и думаю, неплохо было бы сделать юсб вольтметр для всяких поделок с сабжа + старый юсб кабель от сименса.
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
volatile uint8_t uart;
uint8_t temp;
volatile uint8_t count;
volatile uint8_t start;
volatile uint8_t c;
volatile uint8_t uart_data;
volatile uint8_t Rece_bit;
volatile uint8_t rec;
volatile uint8_t usart_r;
volatile uint8_t coef;
ISR(INT0_vect){
rec=1;
}
// Прерывание чисто для определения стартового бита при приеме,
// используется редко, можно сюда повесить что-либо еще
ISR(TIM0_COMPA_vect){
TIMSK0=0x00;
TCCR0B=0x00;
// Единственный Таймер, используется для формирования четких промежуток
OCR0A=0;
// между битами, как при приеме так и при передачи
c=1;
TCNT0=0;
TIMSK0=0x04;
TCCR0B=0x02;
// Значение "сброс при совпадении" загружается каждый раз из переменной
OCR0A=coef;
// Можно быстро менять скорости UART
Rece_bit=1;
}
int
lov (uint8_t data2) {
if
(count>=8){
PORTB|=(1<<4);
start=0;
temp=0;
c=0;
count=0;
TIMSK0=0;
TCCR0B=0;
OCR0A=0;
goto
nah;
}
if
(c==1){
if
(start==0){
temp=0x80;
start=1;
count--;
goto
razvet;
}
temp=data2;
temp=temp>>count;
temp=temp<<7;
razvet:
switch
(temp){
case
0x80 :
PORTB&=~(1<<4);
break
;
case
0x00 :
PORTB|=(1<<4);
break
;
}
count++;
c=0;
}
nah:;
}
int
UART_trans(uint8_t data){
uint8_t f;
data=~data;
coef=115;
TIMSK0=0x04;
TCCR0B=0x02;
for
(f=0;f<10;f++){
while
(c==0);
lov(data);
}
start=0;
temp=0;
c=0;
count=0;
TIMSK0=0;
TCCR0B=0;
OCR0A=0;
coef=0;
}
int
UART_receiv(
void
){
uint8_t a;
usart_r=0;
MCUCR=0x02;
// INT0 Interrupt
GIMSK=0x40;
// INT0 Interrupt
while
(rec==0);
// Ждать, пока не случится стартовый бит
MCUCR=0;
// INT0 Interrupt
GIMSK=0;
// INT0 Interrupt
coef=115;
TIMSK0=0x04;
TCCR0B=0x02;
rec=0;
TCNT0=0xDC;
for
(a=0; a<9; a++){
while
(Rece_bit==0);
if
(bit_is_set(PINB,1)){
usart_r |=(1<<7);
}
else
{
usart_r &=~(1<<7);
}
usart_r=usart_r>>1;
Rece_bit=0;
}
}
int
main(
void
)
{
DDRB&=~(1<<1);
//
DDRB|=(1<<4);
//
asm(
"sei"
);
while
(1)
{
UART_receiv();
// Сперва принимаем байт
_delay_ms(10);
// Пауза для наглядности
UART_trans(ADC_READ());
// Отправляем обратно
}
}
unsigned
int
ADC_READ(){
// ініціалізуємо АЦП
ADMUX = 3;
// 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;
}
Всё компилируется, но при подключении к Rx и Tx пишет всякую ерунду типо:
яяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяшяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяюяяяяяяюяяяяяяюяяяяяяяяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяшяяяяяяяяяяяяяяяяяяяяяяяяяяяяяшяяяяяяяяяяяяяяяяяяяяяяюяяяяяяяяяяяяяяююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяшяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяюяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяряяяяяяяяяяяяяяяяяяяяяяшяяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяряяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяряяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяьяяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяяяяяяяяяяюяяяяяяшяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяьяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяьяяяяяяюяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяряяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяюяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяя
Может кто больше знает подскажет можно ли что-то исправить, и как это сделать?
Стоит ли создавать новую тему в этом разделе по отпугивателю?
http://www.youtube.com/watch?v=QcZWOzvpV8k
На видео зашил скетч Debounce из IDE.
Прошу помощи, есть идея сделать так чтобы тинька запоминала последнее состояние, тоесть я нажал на кнопку, галогенки включились, отключил зажигание(отрубил питание МК), включаю зажигание и тинька вспоминает что я галогенки оставил включёнными и включает их опять, тоесть мне не нужно второй раз лезть к кнопке включение фар.
Схема класика, резистор на ресете 10 кОм, подтягивает его к +,на 0 пине "висит" реле для фар, кнопка подключена к 3-му пину. Я так понимаю тут нужно EEPROM но я ещё никогда с ним не работал, прошу помощи с решением.
Ну вот набросал немного на Arduino пока, но почему-то неработает, светодиод постоянно мигает.
#include <EEPROM.h>
int
address = 1;
byte
value;
const
int
buttonPin = 2;
const
int
ledPin = 13;
int
buttonState = 0;
void
setup
() {
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT);
}
void
loop
() {
value = EEPROM.read(address);
if
(value == 1)
// считаем EEPROM, если 1 то вкл лампу, 0 - выкл.
{
digitalWrite(ledPin, HIGH);
}
else
{
digitalWrite(ledPin, LOW);
}
buttonState = digitalRead(buttonPin);
if
(buttonState == HIGH)
{
if
(value == 1)
{
EEPROM.write(address, 0);
}
else
{
EEPROM.write(address, 1);
}
}
delay(500);
}
01
#include <EEPROM.h>
02
03
#define buttonPin 2
04
#define ledPin 13
05
#define address 1
06
07
bool
value = 0, buttonState = 0;
08
09
void
setup
()
10
{
11
pinMode(ledPin, OUTPUT);
12
value = EEPROM.read(address);
13
digitalWrite(ledPin, value);
14
}
15
16
void
loop
()
17
{
18
if
(digitalRead(buttonPin) && !buttonState)
19
{
20
value = !value;
21
EEPROM.write(address, value);
22
digitalWrite(ledPin, value);
23
buttonState = 1;
24
delay(100);
25
}
26
if
(!digitalRead(buttonPin) && buttonState)
27
{
28
buttonState = 0;
29
delay(50);
30
}
31
}
Спасибо, работает на тини:
http://www.youtube.com/watch?v=dbsgm2SHg-4
Я так понимаю с этого момента отсчёт пошёл на 100 000 нажатий?
http://arduino.ru/forum/programmirovanie/kak-sokhranit-znachenie-pered-sbrosom#comment-18498
http://arduino.ru/forum/programmirovanie/kak-sokhranit-znachenie-pered-sbrosom#comment-18524
Незнаю как с микроконтроллерами, а с флешками дела хуже, не доживают они до своих 100 000.
Спасибо за помощь.
Вот ещё вопрос, всегда было интересно, если скажем я захочу зашить прошивку в HEX формате при помощи стороннего программатора, скажем USBASP или "Программатором Громова" то какие фюзы нужно мне будет выставить для тини13 чтобы зашить HEX файл который сгенерировала ARDUINO IDE ?
Вот ещё вопрос, всегда было интересно, если скажем я захочу зашить прошивку в HEX формате при помощи стороннего программатора, скажем USBASP или "Программатором Громова" то какие фюзы нужно мне будет выставить для тини13 чтобы зашить HEX файл который сгенерировала ARDUINO IDE ?
Фьюзы - можете подсмотреть в файле Boards.txt для своей платы.
А можете проще. Пойти в File/Preferences
И поставить галочку "Show verboase output during [] Compilation". Тогда внизу в окошке будет видно как и с какими параметрами ArduinoIDE вызывает avrdude для заливки. Можете это "подсмотреть скопировать" и пользоватся уже без ArduinoIDE.
Спасибо ещё раз.
Спасибо ещё раз.
Ой... а я вас обманул. Нужно галочку ставить не возле Compilation (тогда вы будете видеть "как скомпилировать без ArduinoIDE"), а возле Upload - тогда будет виден вызов дудки (как заливать).
Или ставте обе. Тогда будуте "видеть все". В том числе и где сам .hex взять. Что-бы заливать его в будущем.
Открыв boards.txt я обнаружил там следующие строчки:
attiny13.name=ATtiny13 @ 9.6MHz (interne 9.6 MHz clock)
attiny13.upload.using=arduino:arduinoisp
attiny13.bootloader.low_fuses=0x7a
attiny13.bootloader.high_fuses=0xff
attiny13.upload.maximum_size=1024
attiny13.build.mcu=attiny13
attiny13.build.f_cpu=1200000
attiny13.build.core=core13
Погуглил и попал на калькулятор фюзов и ввёл low_fuses и high_fuses и получил:
Тоесть когда я буду кому-то давать прошивку в НЕХ формате которую я вынул из временой папки IDE, то чтобы тот человек з с правильным программатором, не дуинкой, верно запрограммировал тиньку ему нужно выставить такие галочки, я всё верно понял?
И ещё вопрос по включении нагрузки одной кнопкой:
Итак, кнопка схематически выглядит вот так:
Нужно чтоды светодиоды светились(подключены к 12 В), подсветка кнопки и индикация роботы дальних фар, тоже питается от 12 В.
Схема того что я вчера напаял выглядит вот так:
Итак, как я понял мне нужно резистор который "прижимал" кнопку к земле перепаять на + и изменить в коде buttonState = 1; тогда получится я как бы инвертирую вход, если кнопку что на первом рисунке нажать то порт микроконтроллера "прижимается" к земле.
Я всё верно понимаю? Я так решу данную задачу?
С фьзами все верно. А с кодом нет - нужно из 26 строки восклицательный знак перед digitalRead перенести в 18 строку, а резистор можно вообще убрать и включить внутреннюю подтяжку.
Спасибо, а внутренюю подтяжку можно включить путём выставления порта на выход?
Кстати, я тут пиркупил солнечную панельку на 20 ватт, вот и думаю сделать контроллер на тиньке, как в народе говорят PWM типа, тоесть уменьшать ток зарядки при помощи ШИМ на 12/24 В с автоопределением, стоит ли создавать отдельную тему по нему в разделе проекты?
Хоть и мой алгоритм заряда довольно примитивен но тут как мне кажется всё будет путаться...
http://arduino.ru/Reference/DigitalWrite
Интересно интересно...
Вот такой код работает как надо:
#include <EEPROM.h>
#define buttonPin 3
#define ledPin 0
#define address 0
bool
value = 0, buttonState = 0;
void
setup
()
{
pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);
value = EEPROM.read(address);
digitalWrite(ledPin, value);
}
void
loop
()
{
digitalWrite(buttonPin, HIGH);
if
(!digitalRead(buttonPin) && !buttonState)
{
value = !value;
EEPROM.write(address, value);
digitalWrite(ledPin, value);
buttonState = 1;
delay(100);
}
if
(digitalRead(buttonPin) && buttonState)
{
buttonState = 0;
delay(50);
}
}
Я тут вот что подумал, а что если кнопка западёт, несколько часов и ячейка памяти выйдет из строя, было бы неплохо добавить в первом ифе ещё один иф, типо если кнопка всё ещё нажата то подождём ещё секунд 10 и тогда уже продолжим выполнение цикла.
Думаю имеет место быть.
Или Вы это предусмотрели? Смотрю в протеусе записывает один раз когда кнопка нажата, держи сколько влезет, индикатор записи в епром негорит.
Вы уж меня простите, если что.
Зачем же в лупе включать подтяжку, можно это сделать один раз в сетапе и не надо настраивать выводы на вход - они и так по умолчанию настроены на вход.
01
#include <EEPROM.h>
02
03
#define buttonPin 3
04
#define ledPin 0
05
#define address 0
06
07
bool
value = 0, buttonState = 0;
08
09
void
setup
()
10
{
11
digitalWrite(buttonPin, HIGH);
12
pinMode(ledPin, OUTPUT);
13
value = EEPROM.read(address);
14
digitalWrite(ledPin, value);
15
}
16
17
void
loop
()
18
{
19
if
(!digitalRead(buttonPin) && !buttonState)
20
{
21
value = !value;
22
EEPROM.write(address, value);
23
digitalWrite(ledPin, value);
24
buttonState = 1;
25
delay(100);
26
}
27
if
(digitalRead(buttonPin) && buttonState)
28
{
29
buttonState = 0;
30
delay(50);
31
}
32
}
Вы чуть-чуть вникните в код и посмотрите сколько раз происходит запись в ЕЕПРОМ пока кнопка удерживается. А что бы вникнуть ознакомьтесь: Работа с кнопками. В помощь новичку.
подскажите пожалуйста по пинам на тиньке. не понял какие пины чему соответствуют
нашел только
вывод 1 - это pin 5
вывод 2 - это pin 3
вопрос снимается
вроде нашел решение. не проверял еще работает или нет. указывать напрямую выводы проще
01
int
duration;
02
03
void
setup
()
04
{
05
pinMode(PB5, INPUT);
06
pinMode(PB0, OUTPUT);
07
}
08
09
void
loop
()
10
11
{
12
duration = 10;
13
digitalWrite(PB0, LOW);
14
if
(duration < 1500)
15
{
16
digitalWrite(PB0, HIGH);
17
}
18
}
и нашел еще такую картинку
// +-\/-+
// ADC0 (D 5) PB5 1| |8 Vcc
// ADC3 (D 3) PB3 2| |7 PB2 (D 2) ADC1
// ADC2 (D 4) PB4 3| |6 PB1 (D 1) PWM1
// GND 4| |5 PB0 (D 0) PWM0
PB5 это ресет, использовать его неполучится если фюзы не сменить, кстати, у меня получается использовато только ногу PB3 в качестве АЦП, другие почуму-то нехотят.