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

Joiner
Offline
Зарегистрирован: 04.09.2014

Попробовал простой пример, выдало ошибку -

Arduino: 1.6.5 (Windows 7), Плата"Attiny 13A standalone 1.2mhz"
 
C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=attiny13 -DF_CPU=1200000L -DARDUINO=10605 -DARDUINO_AVR_ATTINY13C -DARDUINO_ARCH_AVR -IC:\Users\Sergey\Documents\Arduino\hardware\attiny13\avr\cores\core13 C:\Users\Sergey\AppData\Local\Temp\build8176076898243018856.tmp\sketch_oct26a.cpp -o C:\Users\Sergey\AppData\Local\Temp\build8176076898243018856.tmp\sketch_oct26a.cpp.o 
 
sketch_oct26a.ino:1:54: fatal error: PWM.h: No such file or directory
compilation terminated.
Ошибка компиляции.
Клапауций 911
Offline
Зарегистрирован: 18.10.2015
PWM.h: No such file or directory
zilibob4ik
Offline
Зарегистрирован: 02.06.2014

Joiner пишет:

sketch_oct26a.ino:1:54: fatal error: PWM.h: No such file or directory
compilation terminated.
Ошибка компиляции.

Надо скачать библиотеку и установить.

https://code.google.com/p/arduino-pwm-frequency-library/downloads/list

Да, и под большим вопросом, заработает ли она для ATTINY13, а если заработает,

то выдаст ли те параметры на выходе, что может на Arduino  328p или тем более на Меге.

Joiner
Offline
Зарегистрирован: 04.09.2014

Спасибо, будем пробовать, качать........

Трудновато быть чайником :(

zilibob4ik
Offline
Зарегистрирован: 02.06.2014

Joiner пишет:

Спасибо, будем пробовать, качать........

Трудновато быть чайником :(

Чайник, этот тот, который не знает и не собирается знать, а Вы просто имеющий меньше опыта .

А то, в таком случае, все мы чайники, для тех, кто что-то знает на уровень больше.

Я не считаю себя начинающим, 

но до сих пор, некоторые примеры  в Ардуино ИДЕ от профи, меня ставят в ступор,

(делал как то железку на основе Ардуино Нано, за основу брал полуготовый образец чтения дампа

через специфический интерфейс другой железки, так автор, когда что-то не мог изобразить в коде ардуино,

просто напросто переходил на ассемблер. Короче, крыша поедет, пока разберёшься. )

 

Joiner
Offline
Зарегистрирован: 04.09.2014

Установил библиотеку...Опять не легче -

Arduino: 1.6.5 (Windows 7), Плата"Attiny 13A standalone 1.2mhz"
 
Используем библиотеку PWM в папке: C:\Users\Sergey\Documents\Arduino\libraries\PWM (legacy)
 
 
 
C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=attiny13 -DF_CPU=1200000L -DARDUINO=10605 -DARDUINO_AVR_ATTINY13C -DARDUINO_ARCH_AVR -IC:\Users\Sergey\Documents\Arduino\hardware\attiny13\avr\cores\core13 -IC:\Users\Sergey\Documents\Arduino\libraries\PWM C:\Users\Sergey\AppData\Local\Temp\build5744517857435368715.tmp\sketch_oct26a.cpp -o C:\Users\Sergey\AppData\Local\Temp\build5744517857435368715.tmp\sketch_oct26a.cpp.o 
......................................................................
.......................................................................
C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-gcc -w -Os -Wl,--gc-sections -mmcu=attiny13 -o C:\Users\Sergey\AppData\Local\Temp\build5744517857435368715.tmp/sketch_oct26a.cpp.elf C:\Users\Sergey\AppData\Local\Temp\build5744517857435368715.tmp\sketch_oct26a.cpp.o C:\Users\Sergey\AppData\Local\Temp\build5744517857435368715.tmp\PWM\utility\ATimerDefs.cpp.o C:\Users\Sergey\AppData\Local\Temp\build5744517857435368715.tmp\PWM\utility\BTimerDefs.cpp.o C:\Users\Sergey\AppData\Local\Temp\build5744517857435368715.tmp/core.a -LC:\Users\Sergey\AppData\Local\Temp\build5744517857435368715.tmp -lm 
 
C:\Users\Sergey\AppData\Local\Temp\build5744517857435368715.tmp\sketch_oct26a.cpp.o: In function `setup':
C:\Program Files (x86)\Arduino/sketch_oct26a.ino:7: undefined reference to `InitTimersSafe()'
C:\Program Files (x86)\Arduino/sketch_oct26a.ino:8: undefined reference to `SetPinFrequencySafe(signed char, unsigned long)'
C:\Users\Sergey\AppData\Local\Temp\build5744517857435368715.tmp\sketch_oct26a.cpp.o: In function `loop':
C:\Program Files (x86)\Arduino/sketch_oct26a.ino:13: undefined reference to `pwmWrite(unsigned char, unsigned char)'
collect2.exe: error: ld returned 1 exit status
Ошибка компиляции.
 
Так и придется свой генератор использовать :)
Joiner
Offline
Зарегистрирован: 04.09.2014

zilibob4ik пишет:

............ Короче, крыша поедет, пока разберёшься. )

Это точно :))))

Но за то - пища для мозгов. .......Только времени иногда жалко. Советы бывалых здорово выручают.

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

Я что-то не понял вы зачем PWM.h в тини суете?

Я же дал два примера высокочастотного ШИМа.

Первый для тини13

 

bodriy2014 пишет:

Это программный ШИМ не каждому подойдет, добавить еще пару строк кода и выход уже будет не таким.

Есть же апартный таймер с выходом как раз на два порта и совсем не занимает вычислительную мощность МК, при запуске настраиваете его парой строк а дальше весь килобайт под программу ваш!

вот простой пример

int skv=100;
void setup()
{
   PORTB=0x00;
   DDRB=0b00000001;// устанавливаем порт PB0 как выход а остальные вход
   //DDRB &= ~(1<<4); // устанавливаем вывод PB2 как вход
   TCCR0A=0x83;TCCR0B=0x01;OCR0A=0x00;//Аппаратный   ШИМ   
}
void loop()
{

 OCR0A=skv;//устанавливаем скважность.
}
 

 

Второй с библиотекой более комфортный для Ардуино!

bodriy2014 пишет:

простой пример высокочастотного ШИМа на ардуино

#include <PWM.h>//библиотека для поднятия частоты ШИМ
int pwm = 100;  // PWM 0..255               //
int pinDOWN = 9;                //
int32_t frequency = 45000; //частота Hz
void setup()
{
InitTimersSafe();// запуск таймера 
bool successDOWN = SetPinFrequencySafe(pinDOWN, frequency);//установка пина повышенной частоты
}

void loop()
{
    pwmWrite(pinDOWN,pwm);//установка шим на пине     
}

 

Joiner
Offline
Зарегистрирован: 04.09.2014

Который простой пример для тини работает на частоте 4.5 килогерца, а мне нужно 20-25 килогерц, да еще чтобы 2 выхода было. Я же рисовал выше график.

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

zilibob4ik
Offline
Зарегистрирован: 02.06.2014

Тогда лучше взять такой модуль : 

http://ru.aliexpress.com/item/1PCS-AD9850-DDS-Signal-Generator-Module-for-Arduino-Free-Shipping/1742948429.html

присобачить его к Ардуино (или Tiny если получится)

и получить от 0 до 40 мгц 

Скважность вроде тоже должна там регулироваться

 

Joiner
Offline
Зарегистрирован: 04.09.2014

Да мне пока не надо до 40 мегагерц, синусоиды не надо, да и полторы штуки жалко. Мой генератор на быдлокоде работает от 117 килогерц и ниже, что мне и нужно. Пока поиграюсь с ним.

zilibob4ik
Offline
Зарегистрирован: 02.06.2014

Joiner пишет:

Да мне пока не надо до 40 мегагерц, синусоиды не надо, да и полторы штуки жалко. Мой генератор на быдлокоде работает от 117 килогерц и ниже, что мне и нужно. Пока поиграюсь с ним.

Не зная поставленной задачи или Тех. Задания, тяжело давать советы.

Есть расписанная цель, Вам дадут кокнретный совет относительно поставленной цели.

А не зная цели, увы, будет тоже самое, Вам совет, а Вы "да мне совсем другое надо и хватает того, что есть".

Если нужен чёткий прямоугольный импульс, то с повышением частоты Вы получите и

повышение процента искажений.

А специализированные железки, как по ссылке выше, этим не болеют, вернее, искажения конечно есть,

но в процентном соотношении "земля и небо" по сравнению с программной реализацией на attiny.

И вычислительные мощности при этом не задействованы.

Joiner
Offline
Зарегистрирован: 04.09.2014

Сегодня подключал свой генератор к драйверу управления эл.двигателями L293d. С тиньки идет сигнал на два входа  микросхемы input, input2. Сигнал снимаю с output1, output2. На ногу "Питание двигателя" подаю 12 в. С выходов снимаю меандр с размахом амплиттуды +12в -  -12в. В описании микросхемы написано, что скорость переключения до 5 килогерц, но.....Пробовал сигнал до 25 килогерц. Работает. Погонял....ни чего не греется. Правда меандр немного корявенький (может из-за моего осцилографа, завтра попробую на соседском). Попробовал подключить к выходу кондер, ну чтобы форму сигнала изменить. Ток на блоке питания сразу подскочил до 1 ампера, а микросхема мгновенно разогрелась. Форма сигнала стала по амплитуде раза в два меньше и по форме очень на синусоиду похожа.

Когда на выход подключаю звуковой излучатель (пьезо), ток на блоке питания незначительный (на стрелочном амперметре с ценой деления 0.2 ампера сложно сказать какой). При подключении излучателя стрелка амперметра поднимается меньше чем на пол деления, а амплитуда сигнала на выходе по осцилографу уменьшается процентов на 3-5.

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Joiner, генератор для тини13 не на быдлокоде  :-)

void setup() {
DDRB|=(1<<PB0)|(1<<PB1); //PB1,0- OUTPUT mode
TCCR0A=(1<<COM0B0)|(1<<COM0A0)|(1<<WGM01); // CTC mode, OC0A OC0B toggle enable 
TCCR0B=(1<<FOC0A)|(1<<CS01); //divider=8
OCR0A=23; 
}
void loop() {}

Выходы PB0 и PB1 дают сигнал в противофазе. Таймер  настроен в режим сброс по совпадению (СТС) , регистром OCR0A задаётся рабочая частота. Скважность в данном режиме регулировать невозможно, она всегда 50% Частота рассчитывается так:  тактовая частота контроллера F_CPU /2 / divider/ (OCR0A+1) для тактовой 9,6МГц с данными параметрами получится примерно 25кГц. Если в 4 строке поменять CS01 на CS00 то делитель будет =1, и будут доступны выходные частоты вплоть до F_CPU/2

 

 

Joiner
Offline
Зарегистрирован: 04.09.2014

dimax пишет:

Joiner, генератор для тини13 не на быдлокоде  :-

dimax, спасибо! Ваши рекомендации, как всегда по-делу. Уже много раз, заблудившись в дебрях программирования, нахожу спасение в Ваших подсказках и рекомендациях. Изучу, постараюсь осмыслить. Сделаю, испытаю.

Спасибо!

Joiner
Offline
Зарегистрирован: 04.09.2014

Господа и товарищи, подскажите пожалуйста. Одна хорошая девочка попросила сделать ей искусственный огонь в игрушечный камин. Я подумал, что это раз плюнуть, тем более тиньки13 есть в наличии. Решил сделать на трех светиках. Два светика рандомно притухают и разгораются, один светик (искорки) с рандомными паузами делает очень короткие вспышечки. Начал творчество с искорок и не справился. Если писать ардуиновскими операторами, скетч в тиньку по размеру не лезет (а это всего лишь один светик пока). Написал с портами. 99% от памяти!!!!!

Понимаю, что, наверное быдлокод.

Возможно ли на тиньке13 решить такую задачу, или надо мегу2560?

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Joiner, Есть похожие проекты на тини с исходниками, можно немножко подправить под свои нужды.. Вот например.

Joiner
Offline
Зарегистрирован: 04.09.2014

dimax, спасибо. Посмотрел, попробую разобраться. Правда там для WinAVR написано, как-то непривычно...Но попробую разобраться. Я понял, что на тиньке 13 это возможно :)

Спасибо.

Joiner
Offline
Зарегистрирован: 04.09.2014

dimax пишет:

Joiner, генератор для тини13....................

Запустил генератор, работает! Изменил дивидер (CS00), на моей тиньке (вроде 1.2 мгц) частота получилась 24.3 килогерца.

Теперь будем готовиться к испытаниям. Посмотрим, понравится ли собакам эта частота? :)

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Joiner пишет:

Посмотрел, попробую разобраться. Правда там для WinAVR написано, как-то непривычно...Но попробую разобраться. Я понял, что на тиньке 13 это возможно :)

Тот проект легко вставляется в ардуино ide и компилится, 790 байт получается. Даже не нужно setup() и loop() делать. Сейчас влил в тиню -работает.

Joiner
Offline
Зарегистрирован: 04.09.2014

dimax пишет:

..... Сейчас влил в тиню -работает.

А можно подробней? Какой файл в IDE вставлять и компилировать? У меня чего-то не получилось :(

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Joiner, вот, всё уже вставлено, только в IDE положить :)

#include <avr/io.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <util/delay.h>

/// Константа LOW определяет минимальную скважность ШИМ.
/// Чем меньше константа, тем визуально более "трепетное" пламя.
#define LOW     100
/// Константа STEP определяет шиг в микросекундах "мерцания" пламени.
/// Чем больше, тем пламя "спокойнее" и менее похожее на настоящее.
#define STEP    300
/// Константа MAXCANDLES определяет число независимых "свечей".
/// По умолчанию 6, т.е. используются все порты контроллера.
#define MAXCANDLES 6

/// Структура, описывающая одну "свечу".
typedef struct {
    uint8_t bright;     /// яркость (т.е. скважность ШИМ)
    int8_t period;      /// период смены яркости
} tcandle;


/// Массив описаний всех "свечек".
volatile tcandle candles[MAXCANDLES];

/** Получение случайного числа с ограничением минимального значения.
 * Функция возвращает случайный байт, не меньше LOW
*/
uint8_t rnd(void){
   uint8_t t;
   // извлекаются случайные числа до тех пор, 
   do t = random();
   // пока не получится больше LOW
   while (t<= LOW);           
   // это число и есть результат функции
   return t; 
}

/** Обработчик прерывания таймера по переполнению.
 * Реализует программный многоканальный ШИМ.
*/
ISR(TIM0_OVF_vect){
    static uint8_t CNT = 0;     // счетчик ШИМ
    uint8_t output = 0,         // состояние отдельных каналов
            mask = 1;           // маска канала

    // перебираются все "свечи"
    for(uint8_t i = 0; i < MAXCANDLES; i++){
        // и для каждой свечи проверяется ее яркость:
        // если она больше текущего значения счетчика,
        if(candles[i].bright > CNT)
            output |= mask;     // то в ее канал записывается 1
        // после чего подготавливается маска следующего канала
        mask <<= 1;
    }

    // сразу все каналы выводятся в порт
    PORTB = output; 
    // и увеличивается счетчик
    CNT++;
}

int main(void) {
  /// Все линии настраиваются на вывод.
    /// К любым линиям подключаются желтые (оранжевые)
    /// светодиоды с токоограничительными резисторами.
    /// При питании от 3В (2 батарейки) сопротивление резисторов
    /// может быть около 20-30 Ом, совсем без резисторов нежелательно.
    DDRB = 255; 

    // таймер работает без предделителя
    TCCR0B = _BV(CS00);
    // прерывания по переполнению таймера разрешены
    TIMSK0 = _BV(TOIE0);
    // глобально прерывания так же разрешены
    sei();

    // в главном цикле
  while(1){
        // осуществляется перебор всех "свечей" в массиве
        for(uint8_t i=0; i<MAXCANDLES; i++){
            // и для каждой "свечи" уменьшается ее период.
            if(candles[i].period-- < 0){
                // если период истек,
                // то обновляется яркость и значение периода "свечи"
                candles[i].bright = rnd();
                candles[i].period = random();
            }
        }
        // выполняется небольшая задержка
        _delay_us(STEP);
    }
}

 

Joiner
Offline
Зарегистрирован: 04.09.2014

dimax пишет:

Joiner, вот, всё уже вставлено, только в IDE положить :)

........................

Закрузил Ваш код, все без проблем откомпилировалось. Вы где его качали.

По Вашей ссылке на статью, скачал оттуда, вчера весь вечер пытался разобраться, ни чего не получилось, не компилируется, и все тут.

Ни чего не понимаю

За код спасибо! :)

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Joiner, источник там один -ссылка на архив в тексте статьи. Просто вставил код из обоих файлов, убрал иклуд на второй файл. и всё. ))

Joiner
Offline
Зарегистрирован: 04.09.2014

dimax пишет:

Joiner, источник там один -ссылка на архив в тексте статьи. Просто вставил код из обоих файлов, убрал иклуд на второй файл. и всё. ))

Жаль что я вэтом не разбираюсь :(  В жизни бы не догадался.

Почитал скетч....Офигел.....Если когда-то разберусь, то наверное стану проф.программистом :)

P.S. Как работает скетч мне не понравилось. Сделаю немного иначе....когда разберусь :)

А за такой скетч огромное спасибо! Есть что погуглить

 

sav13
sav13 аватар
Offline
Зарегистрирован: 17.06.2013

А никто не поделится кодом 3-х канального ШИМ для Тиньки 13?
Ну или как в Arduino IDE щпределить прерывание по таймеру, что самому длительность импульсов ШИМ выставлять?

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

sav13, посмотрите код в #672 там именно то, о чём вы спрашиваете.

Joiner
Offline
Зарегистрирован: 04.09.2014

dimax пишет:

sav13, посмотрите код в #672 там именно то, о чём вы спрашиваете.

Я залил скетч, поигрался с параметрами. Что-то у меня не получается что-то изменить. Ощущение такое, что диодики просто моргают с разным периодом. Добиться плавного угасания и разгорания мне пока не удалось.

sav13
sav13 аватар
Offline
Зарегистрирован: 17.06.2013

Joiner пишет:

Я залил скетч, поигрался с параметрами. Что-то у меня не получается что-то изменить. Ощущение такое, что диодики просто моргают с разным периодом. Добиться плавного угасания и разгорания мне пока не удалось.

Я тут тестирую немного другой скетч
 


#include <avr/io.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <util/delay.h>

uint8_t counter=0;
uint8_t lev_ch1, lev_ch2, lev_ch3;
uint8_t buf_lev_ch1, buf_lev_ch2, buf_lev_ch3;


ISR(TIM0_OVF_vect){

  if (++counter==0) //счетчик перехода таймера через ноль
  {
    buf_lev_ch1=lev_ch1; //значения длительности ШИМ
    buf_lev_ch2=lev_ch2;
    buf_lev_ch3=lev_ch3;
    PORTB |=(1<<PB0)|(1<<PB1)|(1<<PB2); //подаем 1 на все каналы
  }
  
  if (counter==buf_lev_ch1) PORTB&=~(1<<PB1); //подаем 0 на канал
  if (counter==buf_lev_ch2) PORTB&=~(1<<PB0); //по достижении
  if (counter==buf_lev_ch3) PORTB&=~(1<<PB2); //заданной длительности.

}

int main(void)
{
  DDRB=0b00000111; // установка PortB пины 0,1,2 выходы
    // таймер работает без предделителя
    TCCR0B = _BV(CS00);
    // прерывания по переполнению таймера разрешены
    TIMSK0 = _BV(TOIE0);
    // глобально прерывания так же разрешены
    sei();



  lev_ch1=0; //начальные значения
  lev_ch2=64; //длительности ШИМ
  lev_ch3=128; //трёх каналов

  while (1)       //бесконечная шарманка
  {
    for (uint8_t i=0;i<255;i++)
    {
      lev_ch1++; //увеличиваем значения
      lev_ch2++; //длительности ШИМ
      lev_ch3++; //каждого канала
      _delay_us(5000); //пауза 50мс
     }
   }
}

Все хорошо, только мерцает при моей частоте 1.2МГц

p.s. Перепрошил на 9.6МГц - все более менее плавно стало работать

 

 

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Joiner, не видел что вам уже sav13 предложил вариант, накатал свой :) Для примера взял порт B3, можно добавлять другие по аналогии. Светик на B3 плавно загорается и гаснет.

#include <util/delay.h>
volatile uint8_t pwm=0;
int main(void) {
DDRB| = (1<<PB3); 
TCCR0A= 0; TCCR0B = 1<<CS00;
TIMSK0 = 1<<TOIE0;
sei();
while(1){
    static byte dir=1;
     if (dir) {pwm< 255 ? pwm++ : dir=!dir  ; }
     if (!dir){pwm>0    ? pwm-- : dir=!dir  ; }
        _delay_ms(10);
        }
}

ISR(TIM0_OVF_vect){
static uint8_t cnt = 0; 
if(cnt==0){ PORTB|=1<<PB3; }
if (cnt==pwm) { PORTB&=~(1<<PB3); }
cnt++;
 }

 

sav13
sav13 аватар
Offline
Зарегистрирован: 17.06.2013

Собственно, сламалась елочка ос световодами. Там была лампочка галогеновая 12В и моторчик, крутивший разноцветный круг, меняющий цвета.
Вставил туда кусочек RGB-ленты, вот решил тиньку и применить, благо лежали несколько штук без дела.
 

Код плавного перехода одного цвета в другой:


#include <avr/io.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <util/delay.h>

uint8_t counter=0;
uint8_t lev_ch1, lev_ch2, lev_ch3;
uint8_t buf_lev_ch1, buf_lev_ch2, buf_lev_ch3;


ISR(TIM0_OVF_vect){

  if (++counter==0) //счетчик перехода таймера через ноль
  {
    buf_lev_ch1=lev_ch1; //значения длительности ШИМ
    buf_lev_ch2=lev_ch2;
    buf_lev_ch3=lev_ch3;
    PORTB |=(1<<PB0)|(1<<PB1)|(1<<PB2); //подаем 1 на все каналы
  }
  
  if (counter==buf_lev_ch1) PORTB&=~(1<<PB1); //подаем 0 на канал
  if (counter==buf_lev_ch2) PORTB&=~(1<<PB0); //по достижении
  if (counter==buf_lev_ch3) PORTB&=~(1<<PB2); //заданной длительности.

}

int main(void)
{
  DDRB=0b00000111; // установка PortB пины 0,1,2 выходы
    // таймер работает без предделителя
    TCCR0B = _BV(CS00);
    // прерывания по переполнению таймера разрешены
    TIMSK0 = _BV(TOIE0);
    // глобально прерывания так же разрешены
    sei();



  lev_ch1=0;   //Красный цвет
  lev_ch2=255; //Зеленый цвет
  lev_ch3=0;   //Синий цвет

  while (1)     //бесконечная шарманка
  {

    for (uint8_t i=0;i<255;i++) {
      lev_ch1++; //Красный увеличиваем
      lev_ch2--; //Зеленый уменьшаем
      _delay_us(5000); //Пауза 5мс 
    }
    for (uint8_t i=0;i<255;i++){
      lev_ch3++;  //Синий увеличиваем
      lev_ch1--;  //Красный уменьшаем
      _delay_us(5000); //Пауза 5мс 
    }
    for (uint8_t i=0;i<255;i++) {
      lev_ch2++; //Зеленый увеличиваем
      lev_ch3--; //Синий уменьшаем
      _delay_us(5000); //Пауза 5мс
    }

  }
}

 

Joiner
Offline
Зарегистрирован: 04.09.2014

dimax пишет:

............Светик на B3 плавно загорается и гаснет.

dimax, спасибо. Попробовал залить, выдало сообщение об ошибке. И вообще, что-то с Тинькой ни чего у меня не получается :(

У меня подозрение, что я пробую скетчи для Тиньки 9.6мгц, а моя тинька настроена на1.2мгц.

У меня ни каких плавных переключений не получается, а все моргание какое-то непонятное.

Попробовал перешитьна 9.6мгц, тоже что-то не получается.....Похожне надо сделать перерывчик...и начать с начала.

Да.....с ардуинкой гораздо проще :)

А как на тиньке получить случайную величину? Жеательно в каких-то пределах. На функцию random говорит что скетч слишком большой.

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Joiner, в #672 замечательный пример использования random :) Скечи все на 9,6,  у вас нужно программатором снять фуз галку с клокдивайдера  CKDIV8.

Joiner
Offline
Зарегистрирован: 04.09.2014

Спасибо. Пойду, попробую понять :)

Попробовал....не понимаю. Вот в пустой скетч вставляю единственную строчку

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:
int e=random();
}

И что за чухня? После компиляции пишет, что использовано 722 байта, 70%

Это нормально?

Кстати, компилирую Ваш пример, весь скетч получается 784 байта...практически столько же. Неужели одна строка занимает 722 байта, а все остальное 62 байта? Чудеса...

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Joiner, ну да, эта очень жоркая функция. Можно без дуиновских причуд, будет чуть меньше. В том скетче эта функция столько-же кушает. Оставшийся код там на 200 байт максимум ))


int main(void) {
  
while(1){
  int e=random();
}
}

 

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Joiner, можно попробовать использовать счётный регистр таймера как генератор чисел от 0 до 255,  uint8_t n=TCNT0; этот вариант точно займёт минимум памяти)

Joiner
Offline
Зарегистрирован: 04.09.2014

dimax пишет:

Joiner, можно попробовать использовать счётный регистр таймера как генератор чисел от 0 до 255,  uint8_t n=TCNT0; этот вариант точно займёт минимум памяти)

А можно подробней? Это как? Это будет похоже на случайный характер?

И еще непонятка. Вот абстрактный кусок кода с этим же самым рандомом

#include <avr/io.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <util/delay.h>

/// Константа LOW определяет минимальную скважность ШИМ.
/// Чем меньше константа, тем визуально более "трепетное" пламя.
#define LOW     1000//было100
/// Константа STEP определяет шиг в микросекундах "мерцания" пламени.
/// Чем больше, тем пламя "спокойнее" и менее похожее на настоящее.
#define STEP    300//было300
/// Константа MAXCANDLES определяет число независимых "свечей".
/// По умолчанию 6, т.е. используются все порты контроллера.
#define MAXCANDLES 3//было 6
int t=0;
void setup() {
  // put your setup code here, to run once:
//Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  rnd;
//Serial.println(t);
delay(1000);
}


uint8_t rnd(void){
  
   //uint8_t t;
   // извлекаются случайные числа до тех пор, 
   do t = random();
   
   // пока не получится больше LOW
   while (t<= LOW); 
   //Serial.println(t);          
   // это число и есть результат функции
   return t; 
}

Но почему это все при компиляции занимает 224 байта, не 722 байта, которые занимает одна строчка с рандомом?!!!! Ни че не понимаю!!!! Наверное пора отдохнуть:)

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Joiner случайным это не будет, т.к. цифры инкременируются быстро от 0 до 255, но если запрос будет не очень частым, то получится аналог рандома. По поводу 2-го вопроса -будьте внимательнее, в 23 строке не хватает скобочек ()

Joiner
Offline
Зарегистрирован: 04.09.2014

dimax, спасибище!! Рандом заработал. Правда не совсем как я хотел. Видимо опять где-то, что-то не так написал.

Но наконец то работает. Завтра разберусь.

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Иммитатор свечи, в качестве рандома берётся значение из счётного регистра таймера. 214 байт :)  тактовая 9,6MHz

void setup() {
PORTB&=~(1<<PB0); DDRB|=1<<PB0; //PB0- OUTPUT mode
TCCR0A= (1<<COM0A1)|(1<<WGM01)|(1<<WGM00);
TCCR0B=1<<CS00; //divider=1
}
void loop() {
OCR0A=TCNT0;
delay(TCNT0);
  
  }

 

zilibob4ik
Offline
Зарегистрирован: 02.06.2014

Привет всем.

Вот и меня "припёрло" с ШИМом.

С ВЧ шимом, оно понятно (исходя из последних 2 страниц),

 а как быть с НЧ ШИМом, к примеру при тактовой частоте 4.8 мгц (можно и 9.6мгц)

необходимо получить ШИМ частотой от 70-150 Гц с регулируемой скважностью, естественно.

(мощная нагрузка,  управляется  полевиками, те в свою очередь от Тини13. Частота ШИМ получается сильно большая, полевики греются, не успевают нормально закрыться или хз, короче, надо частоту ШИМа понизить попробовать для начала, чтобы выяснить причину нагрева полевиков, по паспортному току нагрузки, у полевиков запас по мощности большой, а по факту градусов 70 нагреваются. 3 штуки IRF7425 в параллели, ток менее 10 А)

Но у меня к сожалению не получается сделать частоту ШИма ниже 300 гц

setup
{  
DDRB =   (0 << DDB5) | (0 << DDB4) | (0 << DDB3) | (0 << DDB2) | (0 << DDB1) | (1 << DDB0); 
//напрвление: 0 - это вход, 1 - это выход

PORTB =  (0 << PORTB5) | (0 << PORTB4) | (0 << PORTB3) | (1 << PORTB2) | (0 << PORTB1) | (0 << PORTB0); 
// для входа: 1 - подключаем pull-up резистор, 0 - не подключаем
// для выхода: 1 - единица на выходе, 0 - ноль на выходе

  
TCCR0A |= (1 << COM0A1) | (0 << COM0A0) | (0 << COM0B1) | (0 << WGM02) | (0 << WGM01) | (1 << WGM00); 
TCCR0B |= (0 << CS02)   | (1 << CS01)   | (1 << CS00);               
TIMSK0 =  (0 << OCIE0B) | (0 << OCIE0A) | (1 << TOIE0);
DDRB = 0 << DDB0;
} 

void loop()

{

Тут куча условий, нужно ли включать ШИМ и какой скважности.

Если   OCR0A >0  то DDRB = 1 << DDB0;

Далее естественно OCR0A = х.  

Если OCR0A =0, то добавляем ещё  DDRB = 0 << DDB0;

}

 

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

zilibob4ik, ваш скетч "кишит" мелкими и крупными ошибками и неясностями типа "что же хотел изобразить художник". Начнём с мелких -  DDRB = (0 << DDB5) | (0 << DDB4) | (0 << DDB3) | (0 << DDB2) | (0 << DDB1) | (1 << DDB0); тут вы программируете пин B0 как выход. Кстати писать для остальных 0<<  нет смысла, в данной команде ноли туда запишутся в любом случае. В 14 строке вы зачем-то всё это отменяете. В  строке  PORTB = (0 << PORTB5) | (0 << PORTB4) | (0 << PORTB3) | (1 << PORTB2) | (0 << PORTB1) | (0 << PORTB0);  вы порт PB2 делаете как INPUT_PULLUP, но нигде в скетче этот порт не используете. В строке  TIMSK0 = (0 << OCIE0B) | (0 << OCIE0A) | (1 << TOIE0); вы настраиваете прерывание по переполнению, но нигде его не используете. В строке  TCCR0B |= (0 << CS02) | (1 << CS01) | (1 << CS00);  вы настраиваете делитель на 64. После этого сетуете, что ниже частоты не можете добиться, так такм ещё есть деление на 256 и на 1024. То,  что происходит в loop я вообще не понял. Но имейте ввиду, что командами  DDRB = 1 << DDB0; вы записывате помимо единицы в порт B0 также и ноли во все остальные биты порта. А командой DDRB = 0 << DDB0; вообще обнуляете весь порт B, и в том и другом случае скинется подтяжка с порта B2, которую вы непонятно зачем делали. "Причесал" ваш скетч, получилось следущее:

void setup() {  
DDRB|= 1 << DDB0;  //напрвление: 0 - это вход, 1 - это выход
PORTB|= 1<<PB2; // подтяжка порта B2 непонятно для чего
TCCR0A = (1 << COM0A1) | (1 << WGM00); // PWM Phase Correct (Mode 0)
TCCR0B = (1 << CS02); // делитель на 256 (при тактовой 9,6  ШИМ 75Герц )             
OCR0A=64; // начальная скважность
} 

void loop(){
// тут какая-то программа меняющая OCR0A
}

 

zilibob4ik
Offline
Зарегистрирован: 02.06.2014

dimax, Спасибо огромное.

Я с регистрами напрямую недавно начал работать.

Ранее не было необходимости.

В коде используются В0 - как выход ШИМ, В3-как цифровой вход, В4 - как аналоговый вход.

В зависимости от состояния В3 и В4, выдаётся соответствующее состояние на В0

DDRB = 0 << DDB0 Делал вот для чего,

я не знаю почему так. но при OCR0A=0, у меня на нагрузке всё равно было напряжение,

а после DDRB = 0 << DDB0 это напряжение пропадает.  

Может надо подтянуть В0 как раз, а я в процессе установил В2 и успешно забыл.... :)

Странно..... надо будт замерить осциллографом,

может что-то с подтяжками выходных ключей не так...

 

sav13
sav13 аватар
Offline
Зарегистрирован: 17.06.2013

А нет ли у где-нибудь готовго кода таймера (нужен минутный таймер)

ATtiny13 + DS1307 (DS3231) ?

 

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

zilibob4ik. при OCR0A=0 сигнал  в данном скетче на B0 должен быть LOW, есть специальный бит COM0A0 что бы инвертировать шим. Тогда будет HIGH при 0 и LOW при OCR=255.

zilibob4ik
Offline
Зарегистрирован: 02.06.2014

dimax пишет:

zilibob4ik. при OCR0A=0 сигнал  в данном скетче на B0 должен быть LOW, есть специальный бит COM0A0 что бы инвертировать шим. Тогда будет HIGH при 0 и LOW при OCR=255.

dimax, увы, к сожалению не я один заметил, что при OCR0A=0, сигнал не равен LOW,

встречал в кодах, в том числе и на чистом СИ для Атмел студии DDRB = 0 << DDB0

Сейчас специально убрал DDRB = 0 << DDB0,

и получил при OCR0A=0 остренький пик с частотой ШИМа .

вот доказательство с осциллографа и это при OCR0A=0, поэтому DDRB = 0 << DDB0 не зря писал,

когда надо было выклбчить сигнал, и писал DDRB = 1 << DDB0; когда надо было включить естественно.

Вот для примера ~50% скважность

Короче, я не знаю что это и как с этим бороться. но на глюк компилятора не похоже.

Ибо я я начал обнулять порт по примеру из другого кода, видимо его автор тоже устал разбираться

почему при OCR0A=0 , всё равно есть сигнал на выходе.

НО самое главное, при OCR0A=255 , естественно идёт просто HIGH уровень.

Есть вариант, инвертировать сигнал, и малость переделать код (везде поменять местами макс уровни и мин уровни) под инвертированный сигнал.

xorkrus
Offline
Зарегистрирован: 22.09.2013

dimax пишет:
Joiner, можно попробовать использовать счётный регистр таймера как генератор чисел от 0 до 255,  uint8_t n=TCNT0; этот вариант точно займёт минимум памяти)

А можно как-то также по-лёгкому сделать random(1,3)? Т.е. выбирать число от 1 до 3х (надо заполнить массив на 100 мест в случайном порядке этими тремя циферами)

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

zilibob4ik, да, я забыл. Это же в ардуиновской функции analogWrite() сделано было.. Как вариант можно просто ивертировать шим. При OCR0A=255 будет чистый LOW. При OCR0A=0 будет HIGH с тонкими (1/256) выпадами к нолю.

void setup() {  
DDRB|= 1 << DDB0;  //напрвление: 0 - это вход, 1 - это выход
PORTB|= 1<<PB2; // подтяжка порта B2 непонятно для чего
TCCR0A |= (1 << COM0A1)|(1 << COM0A0)| (1 << WGM00); // PWM Phase Correct (Mode 0)
TCCR0B = (1 << CS02); // делитель на 256 (при тактовой 9,6  ШИМ 75Герц )             
OCR0A=64; // начальная скважность
} 

void loop(){
// тут какая-то программа меняющая OCR0A
}

Можно использовать стандартную ардуиновскую функцию, но командой из 5 строки в сетапе поменять частоту шима на нужную.

zilibob4ik
Offline
Зарегистрирован: 02.06.2014

dimax пишет:
Можно использовать стандартную ардуиновскую функцию, но командой из 5 строки в сетапе поменять частоту шима на нужную.


Увы, стандартной AnalogWrite не  получится, памяти она жрёт больше гораздо.

У меня и так код 1022 байта

только в одном месте заменил OCR0A на AnalogWrite, код сразу стал 1188.

Так что, не влезет. Буду думать как переделать  с инверсией.

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

zilibob4ik пишет:

Так что, не влезет. Буду думать как переделать  с инверсией.

А что там думать-то? Пусть x  подготовленное значение для нормального, неинвертированного шима, тогда обновлять ocr так: OCR0A = ~x ;