Это программный ШИМ не каждому подойдет, добавить еще пару строк кода и выход уже будет не таким.
Есть же апартный таймер с выходом как раз на два порта и совсем не занимает вычислительную мощность МК, при запуске настраиваете его парой строк а дальше весь килобайт под программу ваш!
вот простой пример
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);//установка шим на пине
}
Да мне пока не надо до 40 мегагерц, синусоиды не надо, да и полторы штуки жалко. Мой генератор на быдлокоде работает от 117 килогерц и ниже, что мне и нужно. Пока поиграюсь с ним.
Да мне пока не надо до 40 мегагерц, синусоиды не надо, да и полторы штуки жалко. Мой генератор на быдлокоде работает от 117 килогерц и ниже, что мне и нужно. Пока поиграюсь с ним.
Не зная поставленной задачи или Тех. Задания, тяжело давать советы.
Есть расписанная цель, Вам дадут кокнретный совет относительно поставленной цели.
А не зная цели, увы, будет тоже самое, Вам совет, а Вы "да мне совсем другое надо и хватает того, что есть".
Если нужен чёткий прямоугольный импульс, то с повышением частоты Вы получите и
повышение процента искажений.
А специализированные железки, как по ссылке выше, этим не болеют, вернее, искажения конечно есть,
но в процентном соотношении "земля и небо" по сравнению с программной реализацией на attiny.
И вычислительные мощности при этом не задействованы.
Сегодня подключал свой генератор к драйверу управления эл.двигателями L293d. С тиньки идет сигнал на два входа микросхемы input, input2. Сигнал снимаю с output1, output2. На ногу "Питание двигателя" подаю 12 в. С выходов снимаю меандр с размахом амплиттуды +12в - -12в. В описании микросхемы написано, что скорость переключения до 5 килогерц, но.....Пробовал сигнал до 25 килогерц. Работает. Погонял....ни чего не греется. Правда меандр немного корявенький (может из-за моего осцилографа, завтра попробую на соседском). Попробовал подключить к выходу кондер, ну чтобы форму сигнала изменить. Ток на блоке питания сразу подскочил до 1 ампера, а микросхема мгновенно разогрелась. Форма сигнала стала по амплитуде раза в два меньше и по форме очень на синусоиду похожа.
Когда на выход подключаю звуковой излучатель (пьезо), ток на блоке питания незначительный (на стрелочном амперметре с ценой деления 0.2 ампера сложно сказать какой). При подключении излучателя стрелка амперметра поднимается меньше чем на пол деления, а амплитуда сигнала на выходе по осцилографу уменьшается процентов на 3-5.
Выходы PB0 и PB1 дают сигнал в противофазе. Таймер настроен в режим сброс по совпадению (СТС) , регистром OCR0A задаётся рабочая частота. Скважность в данном режиме регулировать невозможно, она всегда 50% Частота рассчитывается так: тактовая частота контроллера F_CPU /2 / divider/ (OCR0A+1) для тактовой 9,6МГц с данными параметрами получится примерно 25кГц. Если в 4 строке поменять CS01 на CS00 то делитель будет =1, и будут доступны выходные частоты вплоть до F_CPU/2
dimax, спасибо! Ваши рекомендации, как всегда по-делу. Уже много раз, заблудившись в дебрях программирования, нахожу спасение в Ваших подсказках и рекомендациях. Изучу, постараюсь осмыслить. Сделаю, испытаю.
Господа и товарищи, подскажите пожалуйста. Одна хорошая девочка попросила сделать ей искусственный огонь в игрушечный камин. Я подумал, что это раз плюнуть, тем более тиньки13 есть в наличии. Решил сделать на трех светиках. Два светика рандомно притухают и разгораются, один светик (искорки) с рандомными паузами делает очень короткие вспышечки. Начал творчество с искорок и не справился. Если писать ардуиновскими операторами, скетч в тиньку по размеру не лезет (а это всего лишь один светик пока). Написал с портами. 99% от памяти!!!!!
Понимаю, что, наверное быдлокод.
Возможно ли на тиньке13 решить такую задачу, или надо мегу2560?
dimax, спасибо. Посмотрел, попробую разобраться. Правда там для WinAVR написано, как-то непривычно...Но попробую разобраться. Я понял, что на тиньке 13 это возможно :)
Посмотрел, попробую разобраться. Правда там для WinAVR написано, как-то непривычно...Но попробую разобраться. Я понял, что на тиньке 13 это возможно :)
Тот проект легко вставляется в ардуино ide и компилится, 790 байт получается. Даже не нужно setup() и loop() делать. Сейчас влил в тиню -работает.
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);
}
}
А никто не поделится кодом 3-х канального ШИМ для Тиньки 13?
Ну или как в Arduino IDE щпределить прерывание по таймеру, что самому длительность импульсов ШИМ выставлять?
sav13, посмотрите код в #672 там именно то, о чём вы спрашиваете.
Я залил скетч, поигрался с параметрами. Что-то у меня не получается что-то изменить. Ощущение такое, что диодики просто моргают с разным периодом. Добиться плавного угасания и разгорания мне пока не удалось.
Я залил скетч, поигрался с параметрами. Что-то у меня не получается что-то изменить. Ощущение такое, что диодики просто моргают с разным периодом. Добиться плавного угасания и разгорания мне пока не удалось.
Я тут тестирую немного другой скетч
#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МГц - все более менее плавно стало работать
Joiner, не видел что вам уже sav13 предложил вариант, накатал свой :) Для примера взял порт B3, можно добавлять другие по аналогии. Светик на B3 плавно загорается и гаснет.
Собственно, сламалась елочка ос световодами. Там была лампочка галогеновая 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мс
}
}
}
Попробовал....не понимаю. Вот в пустой скетч вставляю единственную строчку
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 байта? Чудеса...
Joiner, ну да, эта очень жоркая функция. Можно без дуиновских причуд, будет чуть меньше. В том скетче эта функция столько-же кушает. Оставшийся код там на 200 байт максимум ))
Joiner, можно попробовать использовать счётный регистр таймера как генератор чисел от 0 до 255, uint8_t n=TCNT0; этот вариант точно займёт минимум памяти)
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 байта, которые занимает одна строчка с рандомом?!!!! Ни че не понимаю!!!! Наверное пора отдохнуть:)
Joiner случайным это не будет, т.к. цифры инкременируются быстро от 0 до 255, но если запрос будет не очень частым, то получится аналог рандома. По поводу 2-го вопроса -будьте внимательнее, в 23 строке не хватает скобочек ()
С ВЧ шимом, оно понятно (исходя из последних 2 страниц),
а как быть с НЧ ШИМом, к примеру при тактовой частоте 4.8 мгц (можно и 9.6мгц)
необходимо получить ШИМ частотой от 70-150 Гц с регулируемой скважностью, естественно.
(мощная нагрузка, управляется полевиками, те в свою очередь от Тини13. Частота ШИМ получается сильно большая, полевики греются, не успевают нормально закрыться или хз, короче, надо частоту ШИМа понизить попробовать для начала, чтобы выяснить причину нагрева полевиков, по паспортному току нагрузки, у полевиков запас по мощности большой, а по факту градусов 70 нагреваются. 3 штуки IRF7425 в параллели, ток менее 10 А)
Но у меня к сожалению не получается сделать частоту ШИма ниже 300 гц
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. при OCR0A=0 сигнал в данном скетче на B0 должен быть LOW, есть специальный бит COM0A0 что бы инвертировать шим. Тогда будет HIGH при 0 и LOW при OCR=255.
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 уровень.
Есть вариант, инвертировать сигнал, и малость переделать код (везде поменять местами макс уровни и мин уровни) под инвертированный сигнал.
Joiner, можно попробовать использовать счётный регистр таймера как генератор чисел от 0 до 255, uint8_t n=TCNT0; этот вариант точно займёт минимум памяти)
А можно как-то также по-лёгкому сделать random(1,3)? Т.е. выбирать число от 1 до 3х (надо заполнить массив на 100 мест в случайном порядке этими тремя циферами)
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 строки в сетапе поменять частоту шима на нужную.
Попробовал простой пример, выдало ошибку -
Надо скачать библиотеку и установить.
https://code.google.com/p/arduino-pwm-frequency-library/downloads/list
Да, и под большим вопросом, заработает ли она для ATTINY13, а если заработает,
то выдаст ли те параметры на выходе, что может на Arduino 328p или тем более на Меге.
Спасибо, будем пробовать, качать........
Трудновато быть чайником :(
Спасибо, будем пробовать, качать........
Трудновато быть чайником :(
Чайник, этот тот, который не знает и не собирается знать, а Вы просто имеющий меньше опыта .
А то, в таком случае, все мы чайники, для тех, кто что-то знает на уровень больше.
Я не считаю себя начинающим,
но до сих пор, некоторые примеры в Ардуино ИДЕ от профи, меня ставят в ступор,
(делал как то железку на основе Ардуино Нано, за основу брал полуготовый образец чтения дампа
через специфический интерфейс другой железки, так автор, когда что-то не мог изобразить в коде ардуино,
просто напросто переходил на ассемблер. Короче, крыша поедет, пока разберёшься. )
Установил библиотеку...Опять не легче -
............ Короче, крыша поедет, пока разберёшься. )
Это точно :))))
Но за то - пища для мозгов. .......Только времени иногда жалко. Советы бывалых здорово выручают.
Я что-то не понял вы зачем PWM.h в тини суете?
Я же дал два примера высокочастотного ШИМа.
Первый для тини13
Это программный ШИМ не каждому подойдет, добавить еще пару строк кода и выход уже будет не таким.
Есть же апартный таймер с выходом как раз на два порта и совсем не занимает вычислительную мощность МК, при запуске настраиваете его парой строк а дальше весь килобайт под программу ваш!
вот простой пример
Второй с библиотекой более комфортный для Ардуино!
простой пример высокочастотного ШИМа на ардуино
Который простой пример для тини работает на частоте 4.5 килогерца, а мне нужно 20-25 килогерц, да еще чтобы 2 выхода было. Я же рисовал выше график.
Попробую задумку со своим генератором, если получится, то объясню подробней для чего мне это нужно.
Тогда лучше взять такой модуль :
http://ru.aliexpress.com/item/1PCS-AD9850-DDS-Signal-Generator-Module-for-Arduino-Free-Shipping/1742948429.html
присобачить его к Ардуино (или Tiny если получится)
и получить от 0 до 40 мгц
Скважность вроде тоже должна там регулироваться
Да мне пока не надо до 40 мегагерц, синусоиды не надо, да и полторы штуки жалко. Мой генератор на быдлокоде работает от 117 килогерц и ниже, что мне и нужно. Пока поиграюсь с ним.
Да мне пока не надо до 40 мегагерц, синусоиды не надо, да и полторы штуки жалко. Мой генератор на быдлокоде работает от 117 килогерц и ниже, что мне и нужно. Пока поиграюсь с ним.
Не зная поставленной задачи или Тех. Задания, тяжело давать советы.
Есть расписанная цель, Вам дадут кокнретный совет относительно поставленной цели.
А не зная цели, увы, будет тоже самое, Вам совет, а Вы "да мне совсем другое надо и хватает того, что есть".
Если нужен чёткий прямоугольный импульс, то с повышением частоты Вы получите и
повышение процента искажений.
А специализированные железки, как по ссылке выше, этим не болеют, вернее, искажения конечно есть,
но в процентном соотношении "земля и небо" по сравнению с программной реализацией на attiny.
И вычислительные мощности при этом не задействованы.
Сегодня подключал свой генератор к драйверу управления эл.двигателями L293d. С тиньки идет сигнал на два входа микросхемы input, input2. Сигнал снимаю с output1, output2. На ногу "Питание двигателя" подаю 12 в. С выходов снимаю меандр с размахом амплиттуды +12в - -12в. В описании микросхемы написано, что скорость переключения до 5 килогерц, но.....Пробовал сигнал до 25 килогерц. Работает. Погонял....ни чего не греется. Правда меандр немного корявенький (может из-за моего осцилографа, завтра попробую на соседском). Попробовал подключить к выходу кондер, ну чтобы форму сигнала изменить. Ток на блоке питания сразу подскочил до 1 ампера, а микросхема мгновенно разогрелась. Форма сигнала стала по амплитуде раза в два меньше и по форме очень на синусоиду похожа.
Когда на выход подключаю звуковой излучатель (пьезо), ток на блоке питания незначительный (на стрелочном амперметре с ценой деления 0.2 ампера сложно сказать какой). При подключении излучателя стрелка амперметра поднимается меньше чем на пол деления, а амплитуда сигнала на выходе по осцилографу уменьшается процентов на 3-5.
Joiner, генератор для тини13 не на быдлокоде :-)
Выходы PB0 и PB1 дают сигнал в противофазе. Таймер настроен в режим сброс по совпадению (СТС) , регистром OCR0A задаётся рабочая частота. Скважность в данном режиме регулировать невозможно, она всегда 50% Частота рассчитывается так: тактовая частота контроллера F_CPU /2 / divider/ (OCR0A+1) для тактовой 9,6МГц с данными параметрами получится примерно 25кГц. Если в 4 строке поменять CS01 на CS00 то делитель будет =1, и будут доступны выходные частоты вплоть до F_CPU/2
Joiner, генератор для тини13 не на быдлокоде :-
dimax, спасибо! Ваши рекомендации, как всегда по-делу. Уже много раз, заблудившись в дебрях программирования, нахожу спасение в Ваших подсказках и рекомендациях. Изучу, постараюсь осмыслить. Сделаю, испытаю.
Спасибо!
Господа и товарищи, подскажите пожалуйста. Одна хорошая девочка попросила сделать ей искусственный огонь в игрушечный камин. Я подумал, что это раз плюнуть, тем более тиньки13 есть в наличии. Решил сделать на трех светиках. Два светика рандомно притухают и разгораются, один светик (искорки) с рандомными паузами делает очень короткие вспышечки. Начал творчество с искорок и не справился. Если писать ардуиновскими операторами, скетч в тиньку по размеру не лезет (а это всего лишь один светик пока). Написал с портами. 99% от памяти!!!!!
Понимаю, что, наверное быдлокод.
Возможно ли на тиньке13 решить такую задачу, или надо мегу2560?
Joiner, Есть похожие проекты на тини с исходниками, можно немножко подправить под свои нужды.. Вот например.
dimax, спасибо. Посмотрел, попробую разобраться. Правда там для WinAVR написано, как-то непривычно...Но попробую разобраться. Я понял, что на тиньке 13 это возможно :)
Спасибо.
Joiner, генератор для тини13....................
Запустил генератор, работает! Изменил дивидер (CS00), на моей тиньке (вроде 1.2 мгц) частота получилась 24.3 килогерца.
Теперь будем готовиться к испытаниям. Посмотрим, понравится ли собакам эта частота? :)
Посмотрел, попробую разобраться. Правда там для WinAVR написано, как-то непривычно...Но попробую разобраться. Я понял, что на тиньке 13 это возможно :)
Тот проект легко вставляется в ардуино ide и компилится, 790 байт получается. Даже не нужно setup() и loop() делать. Сейчас влил в тиню -работает.
..... Сейчас влил в тиню -работает.
А можно подробней? Какой файл в IDE вставлять и компилировать? У меня чего-то не получилось :(
Joiner, вот, всё уже вставлено, только в IDE положить :)
Joiner, вот, всё уже вставлено, только в IDE положить :)
Закрузил Ваш код, все без проблем откомпилировалось. Вы где его качали.
По Вашей ссылке на статью, скачал оттуда, вчера весь вечер пытался разобраться, ни чего не получилось, не компилируется, и все тут.
Ни чего не понимаю
За код спасибо! :)
Joiner, источник там один -ссылка на архив в тексте статьи. Просто вставил код из обоих файлов, убрал иклуд на второй файл. и всё. ))
Joiner, источник там один -ссылка на архив в тексте статьи. Просто вставил код из обоих файлов, убрал иклуд на второй файл. и всё. ))
Жаль что я вэтом не разбираюсь :( В жизни бы не догадался.
Почитал скетч....Офигел.....Если когда-то разберусь, то наверное стану проф.программистом :)
P.S. Как работает скетч мне не понравилось. Сделаю немного иначе....когда разберусь :)
А за такой скетч огромное спасибо! Есть что погуглить
А никто не поделится кодом 3-х канального ШИМ для Тиньки 13?
Ну или как в Arduino IDE щпределить прерывание по таймеру, что самому длительность импульсов ШИМ выставлять?
sav13, посмотрите код в #672 там именно то, о чём вы спрашиваете.
sav13, посмотрите код в #672 там именно то, о чём вы спрашиваете.
Я залил скетч, поигрался с параметрами. Что-то у меня не получается что-то изменить. Ощущение такое, что диодики просто моргают с разным периодом. Добиться плавного угасания и разгорания мне пока не удалось.
Я залил скетч, поигрался с параметрами. Что-то у меня не получается что-то изменить. Ощущение такое, что диодики просто моргают с разным периодом. Добиться плавного угасания и разгорания мне пока не удалось.
Я тут тестирую немного другой скетч
Все хорошо, только мерцает при моей частоте 1.2МГц
p.s. Перепрошил на 9.6МГц - все более менее плавно стало работать
Joiner, не видел что вам уже sav13 предложил вариант, накатал свой :) Для примера взял порт B3, можно добавлять другие по аналогии. Светик на B3 плавно загорается и гаснет.
Собственно, сламалась елочка ос световодами. Там была лампочка галогеновая 12В и моторчик, крутивший разноцветный круг, меняющий цвета.
Вставил туда кусочек RGB-ленты, вот решил тиньку и применить, благо лежали несколько штук без дела.
Код плавного перехода одного цвета в другой:
............Светик на B3 плавно загорается и гаснет.
dimax, спасибо. Попробовал залить, выдало сообщение об ошибке. И вообще, что-то с Тинькой ни чего у меня не получается :(
У меня подозрение, что я пробую скетчи для Тиньки 9.6мгц, а моя тинька настроена на1.2мгц.
У меня ни каких плавных переключений не получается, а все моргание какое-то непонятное.
Попробовал перешитьна 9.6мгц, тоже что-то не получается.....Похожне надо сделать перерывчик...и начать с начала.
Да.....с ардуинкой гораздо проще :)
А как на тиньке получить случайную величину? Жеательно в каких-то пределах. На функцию random говорит что скетч слишком большой.
Joiner, в #672 замечательный пример использования random :) Скечи все на 9,6, у вас нужно программатором снять фуз галку с клокдивайдера CKDIV8.
Спасибо. Пойду, попробую понять :)
Попробовал....не понимаю. Вот в пустой скетч вставляю единственную строчку
И что за чухня? После компиляции пишет, что использовано 722 байта, 70%
Это нормально?
Кстати, компилирую Ваш пример, весь скетч получается 784 байта...практически столько же. Неужели одна строка занимает 722 байта, а все остальное 62 байта? Чудеса...
Joiner, ну да, эта очень жоркая функция. Можно без дуиновских причуд, будет чуть меньше. В том скетче эта функция столько-же кушает. Оставшийся код там на 200 байт максимум ))
Joiner, можно попробовать использовать счётный регистр таймера как генератор чисел от 0 до 255, uint8_t n=TCNT0; этот вариант точно займёт минимум памяти)
Joiner, можно попробовать использовать счётный регистр таймера как генератор чисел от 0 до 255, uint8_t n=TCNT0; этот вариант точно займёт минимум памяти)
А можно подробней? Это как? Это будет похоже на случайный характер?
И еще непонятка. Вот абстрактный кусок кода с этим же самым рандомом
Но почему это все при компиляции занимает 224 байта, не 722 байта, которые занимает одна строчка с рандомом?!!!! Ни че не понимаю!!!! Наверное пора отдохнуть:)
Joiner случайным это не будет, т.к. цифры инкременируются быстро от 0 до 255, но если запрос будет не очень частым, то получится аналог рандома. По поводу 2-го вопроса -будьте внимательнее, в 23 строке не хватает скобочек ()
dimax, спасибище!! Рандом заработал. Правда не совсем как я хотел. Видимо опять где-то, что-то не так написал.
Но наконец то работает. Завтра разберусь.
Иммитатор свечи, в качестве рандома берётся значение из счётного регистра таймера. 214 байт :) тактовая 9,6MHz
Привет всем.
Вот и меня "припёрло" с ШИМом.
С ВЧ шимом, оно понятно (исходя из последних 2 страниц),
а как быть с НЧ ШИМом, к примеру при тактовой частоте 4.8 мгц (можно и 9.6мгц)
необходимо получить ШИМ частотой от 70-150 Гц с регулируемой скважностью, естественно.
(мощная нагрузка, управляется полевиками, те в свою очередь от Тини13. Частота ШИМ получается сильно большая, полевики греются, не успевают нормально закрыться или хз, короче, надо частоту ШИМа понизить попробовать для начала, чтобы выяснить причину нагрева полевиков, по паспортному току нагрузки, у полевиков запас по мощности большой, а по факту градусов 70 нагреваются. 3 штуки IRF7425 в параллели, ток менее 10 А)
Но у меня к сожалению не получается сделать частоту ШИма ниже 300 гц
void loop()
{
Тут куча условий, нужно ли включать ШИМ и какой скважности.
Если OCR0A >0 то DDRB = 1 << DDB0;
Далее естественно OCR0A = х.
Если OCR0A =0, то добавляем ещё DDRB = 0 << DDB0;
}
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, которую вы непонятно зачем делали. "Причесал" ваш скетч, получилось следущее:
dimax, Спасибо огромное.
Я с регистрами напрямую недавно начал работать.
Ранее не было необходимости.
В коде используются В0 - как выход ШИМ, В3-как цифровой вход, В4 - как аналоговый вход.
В зависимости от состояния В3 и В4, выдаётся соответствующее состояние на В0
DDRB = 0 << DDB0 Делал вот для чего,
я не знаю почему так. но при OCR0A=0, у меня на нагрузке всё равно было напряжение,
а после DDRB = 0 << DDB0 это напряжение пропадает.
Может надо подтянуть В0 как раз, а я в процессе установил В2 и успешно забыл.... :)
Странно..... надо будт замерить осциллографом,
может что-то с подтяжками выходных ключей не так...
А нет ли у где-нибудь готовго кода таймера (нужен минутный таймер)
ATtiny13 + DS1307 (DS3231) ?
zilibob4ik. при OCR0A=0 сигнал в данном скетче на B0 должен быть LOW, есть специальный бит COM0A0 что бы инвертировать шим. Тогда будет HIGH при 0 и LOW при OCR=255.
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 уровень.
Есть вариант, инвертировать сигнал, и малость переделать код (везде поменять местами макс уровни и мин уровни) под инвертированный сигнал.
А можно как-то также по-лёгкому сделать random(1,3)? Т.е. выбирать число от 1 до 3х (надо заполнить массив на 100 мест в случайном порядке этими тремя циферами)
zilibob4ik, да, я забыл. Это же в ардуиновской функции analogWrite() сделано было.. Как вариант можно просто ивертировать шим. При OCR0A=255 будет чистый LOW. При OCR0A=0 будет HIGH с тонкими (1/256) выпадами к нолю.
Можно использовать стандартную ардуиновскую функцию, но командой из 5 строки в сетапе поменять частоту шима на нужную.
Увы, стандартной AnalogWrite не получится, памяти она жрёт больше гораздо.
У меня и так код 1022 байта
только в одном месте заменил OCR0A на AnalogWrite, код сразу стал 1188.
Так что, не влезет. Буду думать как переделать с инверсией.
Так что, не влезет. Буду думать как переделать с инверсией.
А что там думать-то? Пусть x подготовленное значение для нормального, неинвертированного шима, тогда обновлять ocr так: OCR0A = ~x ;