Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Генератор импульсов на Attiny 45
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
mamuka60
Форумчане, здравствуйте! Простите за нубский вопрос. Спасите меня. Сам я разработчик-схемотехник, но в программировании микроконтроллеров понимаю мало, а дело срочное.
Итак, у меня есть всё аппаратное и программное обеспечение: распаянный на колодке контроллер Attiny45 без кварца, программатор SM-4, софт asisp для чтения и записи флеш и еепром, (т.е. сам я прошить-считать-стереть и.т.д. умею). Есть установленная Atmel Studio 6.0. Есть всё. Знаний про написание кода нет.
Требуется: получить с 2х ножек контроллера меандр скважностью 2, частота 50 кГц. Меандры должны идти в противофазе. т.е. если на одной ноге 0 то на другой в это время должен быть 1. Вот и всё, вот и вся задача. Подал питание - и нарубается меандр. Я чувствую, что это просто, а Си и Ассемблер забыл)))) Или чем вы его там пишите...
Ещё конкретнее: как написать программу, компилировать, а лучше, простите за наглость, дайте текст или уже готовую прошивку, но с исходником, чтобы я мог менять частоту и длительность импульсов. Горю, ребята., спасите, на самостоятельное изучение этого вопроса нет времени, но я займусь.
Пишите прямо тут, а ещё лучше - прямо мне в мыло ofts@yandex.ru
Спасибо всем заранее.
kovigor
Цитата(mamuka60 @ Oct 30 2012, 21:56) *
Пишите прямо тут, а ещё лучше - прямо мне в мыло ofts@yandex.ru

Если допустим небольшой джиттер и вам нужно не ровно 50 КГц, а плюс-минус доли процента, то вот вам готовый пример:
http://zalil.ru/33910003
Кварц на 10 МГц, компилятор - CodeVision (начните с него, для новичка он подходит идеально). После включения питания на PORTB.0 и PORTB.1 появятся противофазные меандры.

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

Литература по программированию AVR вот здесь:
http://lord-n.narod.ru/walla.html

P.S.
Можно вообще без прерываний - цикл с delay(). Или даже вместо delay() использовать несколько десятков "nop" - ов, поскольку вам нужна довольно большая частота. Проще не придумать:

Код
PORTB.0 = 0;
PORTB.1 = 1;
while(1)
{
PORTB = (PORTB ^ 0x03);
delay_us(10);
}

или вот так:

Код
PORTB.0 = 0;
PORTB.1 = 1;
while(1)
{
PORTB = (PORTB ^ 0x03);
#asm("nop")
#asm("nop")
...
#asm("nop")
}
mamuka60
[quote name='kovigor' date='Oct 31 2012, 00:44' post='1107114']
Если допустим небольшой джиттер и вам нужно не ровно 50 КГц, а плюс-минус доли процента, то вот вам готовый пример:

Спасибо, товарищ, выручил.
kovigor
Цитата(mamuka60 @ Oct 31 2012, 22:26) *
Спасибо, товарищ, выручил.

Подошло такое решение ?
mamuka60
Цитата(kovigor @ Nov 1 2012, 01:46) *
Подошло такое решение ?


Поскольку кварца на 10 мГц у нас нет, мы прошили Вашим файлом HEX контроллер, и всё заработало. НО! - не на частоте 50 кГц, как надо, а на частоте 33 кГЦ. Как это изменить?
Второй вопрос. Мы скачали рекомендуемый Вами CodeVision, и попробовали вставить туда приведённые Вами кусок (только его)

PORTB.0 = 0;
PORTB.1 = 1;
while(1)
{
PORTB = (PORTB ^ 0x03);
delay_us(10);
}
но в данном случае компилятор ругается вот так, что мол он не понимает delay_us

А AtmelStudio ругается так:


Error 1 expected ';' before numeric constant C:\Users\Отд 120\Documents\Atmel Studio\GccApplication1\GccApplication1\GccApplication1.c 15 13 GccApplication1

И ещё одна деталь. Прилагаю файл, как должны выглядеть осциллограммы. Скважность там не 2, а 2.5


Нажмите для просмотра прикрепленного файла
Valek
Цитата(mamuka60 @ Nov 1 2012, 10:57) *
PORTB.0 = 0;
PORTB.1 = 1;
while(1)
{
PORTB = (PORTB ^ 0x03);
delay_us(10);
}
но в данном случае компилятор ругается вот так, что мол он не понимает delay_us


Попробуйте перед delay_us(10); поставить подчеркивание _
kovigor
Цитата(mamuka60 @ Nov 1 2012, 10:57) *
Поскольку кварца на 10 мГц у нас нет, мы прошили Вашим файлом HEX контроллер, и всё заработало. НО! - не на частоте 50 кГц, как надо, а на частоте 33 кГЦ. Как это изменить?
Второй вопрос. Мы скачали рекомендуемый Вами CodeVision, и попробовали вставить туда приведённые Вами кусок (только его) но в данном случае компилятор ругается вот так, что мол он не понимает delay_us

И правильно делает, что ругается. Вам надо в самых первых строках программы включить в нее файл "delay.h":
Код
#include <delay.h>

Осциллограмму посмотрел. Вам хорошо подойдет вариант не с прерыванием, а с "nop"ами:

Код
PORTB.0 = 0;
PORTB.1 = 0;
while(1)
{
//Отрабатываем первые 2 мкС
#asm("nop") //Задержка на первые 2 мкС.
#asm("nop") //Насколько я помню, "nop" выполняется за один машинный цикл.
...
#asm("nop") //Исходя из этого рассчитайте или подберите с помощью осциллографа нужное вам кол-во "nop"ов

//Теперь отрабатываем 8 мкС
PORTB.0 = 1;
#asm("nop")
#asm("nop")
#asm("nop")
...
#asm("nop")

//Теперь отрабатываем 2 мкС
PORTB.0 = 0;
#asm("nop")
#asm("nop")
...
#asm("nop")

//Теперь отрабатываем 8 мкС
PORTB.1 = 1;
#asm("nop")
#asm("nop")
#asm("nop")
...
#asm("nop")

//Теперь отрабатываем 2 мкС, для чего начинаем новый виток цикла
PORTB.1 = 0;

//Один цикл колебаний завершен. Выполняем новый цикл, и так продолжаем, пока не выключат питание
}

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

P.S. Выяснил. "nop" выполняется за один период резонатора (кварца). Соотетственно, с такой точностью и можно подстраивать осциллограмму. Т.е., для 10 МГц это будет 100 нС, и для 2-х мкС потребуются 20 "nop"ов ...

P.P.S. Компилировать советую в CodeVision. Выкладываю проект:
http://zalil.ru/33914939
ae_
Цитата(mamuka60 @ Oct 31 2012, 03:56) *
Подал питание - и нарубается меандр...

Нажмите для просмотра прикрепленного файла
В tiny45 есть timer1 с такой функцией. Программировать, т.е. составлять алгоритм, вообще не нужно. Текст программы - лишь инициализация таймера, портов в/в. Частота, скважность и dead time - всё записывается в регистры управления timer1 и deadtime generator, далее сигналы на выводах формируются аппаратно. Программа - пустой бесконечный цикл.
mamuka60
Спасибо всем, друзья! Завтра попробуем. Выложу результат. Ещё раз спасибо всем.
kovigor
Цитата(ae_ @ Nov 1 2012, 16:02) *
В tiny45 есть timer1 с такой функцией.

Так это же еще с таймером надо разбираться, что для новичка (а иногда и не только для новичка, ибо таймеры в AVR многофункциональны и весьма сложны) довольно сложно. В моем варианте все гораздо проще. Если никаких других задач от МК выполнять не требуется, то вариант с "nop"ами вполне жизнеспособен ...
mamuka60
Большое спасибо всем и особенно kovigor, мы получили то, что хотели. мы освоили фокусы с нопами и ещё, что особенно расширяет влияние на частоту, комбинации с fuse - битами (как-то так). Всё получили без применения внешнего резонатора (кварца). Правда, пришлось поэкспериментировать, но в целом, инструмент освоен, начало положено, рухнула глухая стена непонимания процессов.
Но жажда эксперимента заставляет меня задать вопрос: какую операцию в код надо вставить, чтобы при появлении, например, на portb2 логической 1, программа глохла и колебания выключались? Или, например, при появлении 1 на portb2, программа перескакивала, например, на другую подпрограмму, в которой, например, мы могли бы задать другое колебание?
_Артём_
Цитата(mamuka60 @ Nov 2 2012, 17:23) *
Но жажда эксперимента заставляет меня задать вопрос: какую операцию в код надо вставить, чтобы при появлении, например, на portb2 логической 1, программа глохла и колебания выключались? Или, например, при появлении 1 на portb2, программа перескакивала, например, на другую подпрограмму, в которой, например, мы могли бы задать другое колебание?

Код
if (PINB&(1<<1)) {// на PB1 - 1
  // вариант действий 1
}
else {// на PB1 - 0
  // вариант действий 0
}
kovigor
Цитата(mamuka60 @ Nov 2 2012, 18:23) *
Большое спасибо всем и особенно kovigor, мы получили то, что хотели. мы освоили фокусы с нопами и ещё, что особенно расширяет влияние на частоту, комбинации с fuse - битами (как-то так). Всё получили без применения внешнего резонатора (кварца). Правда, пришлось поэкспериментировать, но в целом, инструмент освоен, начало положено, рухнула глухая стена непонимания процессов.
[b] Но жажда эксперимента заставляет меня задать вопрос: какую операцию в код надо вставить, чтобы при появлении, например, на portb2 логической 1, программа глохла и колебания выключались?

1. Без кварца частота будет плыть с температурой, и весьма сильно. Вас это не смущает ?
2. Например, так:

Код
PORTB.0 = 0;
PORTB.1 = 0;
while(PINB.2 == 0) //Условие остановки генерации
{
//Отрабатываем первые 2 мкС
#asm("nop") //Задержка на первые 2 мкС.
#asm("nop") //Насколько я помню, "nop" выполняется за один машинный цикл.
...
#asm("nop") //Исходя из этого рассчитайте или подберите с помощью осциллографа нужное вам кол-во "nop"ов

//Теперь отрабатываем 8 мкС
PORTB.0 = 1;
#asm("nop")
#asm("nop")
#asm("nop")
...
#asm("nop")

//Теперь отрабатываем 2 мкС
PORTB.0 = 0;
#asm("nop")
#asm("nop")
...
#asm("nop")

//Теперь отрабатываем 8 мкС
PORTB.1 = 1;
#asm("nop")
#asm("nop")
#asm("nop")
...
#asm("nop")

//Теперь отрабатываем 2 мкС, для чего начинаем новый виток цикла
PORTB.1 = 0;

//Один цикл колебаний завершен. Выполняем новый цикл, и так продолжаем, пока не выключат питание
}

//PINB.2 = 1. Останавливаем генерацию
PORTB.0 = 0;
PORTB.1 = 0;

Книжку Крупника по Си почитайте. И мануал к CodeVision просмотрите ...
20AmpMax
Здравствуйте.

У меня те-же "грабли" что и у автора, и мне очень полезна эта тема для освоения.

Предыстория:
На одном из англо-язычных форумах наткнулся на одну схему с описанием и "исходником" устройства на Attiny85 которое может
мне помочь так как нужно портативное устройство. Автор, так-же как и я не разбирается в программировании, а в нашем
городе на радио рынке Attiny нет но есть Atmega16A и Atmega8. Я пытался пере компилировать в CVAVR код но не получается

Код
/*****************************************************
Project      : Sweeper generator
Version      : 1.0
Date         : 28/02/2012
Author       :
Chip type    : ATtiny85
Clock freq.  : 8,000000 MHz (Internal)
*****************************************************/

#include <ATtiny85.h>
#include <inavr.h>

// Standard defines +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

#define HIGH                    1
#define LOW                     0

#define TRUE                    1
#define FALSE                   0

#define ON                      0
#define OFF                     1

#define BIT0                    0x01
#define BIT1                    0x02
#define BIT2                    0x04
#define BIT3                    0x08
#define BIT4                    0x10
#define BIT5                    0x20
#define BIT6                    0x40
#define BIT7                    0x80

#define MIN_FREQ                10      // 3,2Khz
#define MAX_FREQ                1000    // 32Hz

// I/O Port pins ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++          

#define LED_ON        PORTB &= (~BIT3)
#define LED_OFF       PORTB |= BIT3

#define PWM_HIGH      PORTB |= BIT0
#define PWM_LOW       PORTB &= (~BIT0)

#define BUTTON_IN     PINB & BIT4

// Global variables +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

volatile unsigned long pwm_step;
volatile unsigned int pwm_counter, pwm_frequency;
volatile unsigned char direction;

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++
// ++ Interrupts
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++

void timer0_ovf_isr(void) __interrupt[TIMER0_OVF_vect] //error missing"{"
{
  if (pwm_counter)
  {
    pwm_counter++;
  
    if (pwm_counter > (pwm_frequency/2))
      PWM_HIGH;
    else
      PWM_LOW;
      
    if (pwm_counter >= pwm_frequency)
      pwm_counter=0;
  }
}

void timer1_ovf_isr(void) __interrupt[TIMER1_OVF_vect]
{
  if (!pwm_counter)
  {
    if (direction)
    {
      pwm_frequency++;
  
      if (pwm_frequency >= MAX_FREQ)
        direction=0;
    }
    else
    {
      pwm_frequency--;
  
      if (pwm_frequency <= MIN_FREQ)
        direction=1;
    }

    pwm_counter=1;
  }

  if (pwm_step)
    pwm_step--;
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++
// ++ Main
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++

void main(void)
{
  // Ports initialization
  PORTB=0x3F;
  DDRB=0x09;
  
  // Timer/Counter 0 initialization
  TCCR0A=0x00;
  TCCR0B=0x01;
  TCNT0=0x00;
  OCR0A=0x00;
  OCR0B=0x00;
  
  // Timer/Counter 1 initialization
  PLLCSR=0x00;
  TCCR1=0x01;
  GTCCR=0x00;
  TCNT1=0x00;
  OCR1A=0x00;
  OCR1B=0x00;
  OCR1C=0x00;
  
  // External Interrupts initialization
  GIMSK=0x00;
  MCUCR=0x00;
  
  // Timers/Counters Interrupts initialization
  TIMSK=0x06;
  
  // Universal Serial Interface initialization
  USICR=0x00;
  
  // Analog Comparator initialization
  ACSR=0x80;
  ADCSRB=0x00;

  // Main loop
  while (1)
  {
    __disable_interrupt();
    LED_OFF;

    while (BUTTON_IN);
    
    LED_ON;
    pwm_step=1832000;       // 1 Min. count
    pwm_counter=1;          // Start counter
    pwm_frequency=MIN_FREQ; // Min. start freq.
    direction=0;            // Count up

    __enable_interrupt();

    while (pwm_step);
  }
}


Ошибка missing"{"

Принцип работы такой:
при подаче питания на устройство лампа (PB3) не горит устройство в режиме ожидания
при нажатии кнопки (PB4) лампа загорается и с вывода (PB0) генерируется сигнал ~3.2 кГц на 1 минуту.
От автора "It's designed to sweep from 32Hz to 3,2Khz for 1 minute when you press the button."

Помогите пере компилировать для Atmega16A
kovigor
Цитата(20AmpMax @ Nov 23 2012, 14:12) *
Помогите пере компилировать для Atmega16A

Перекомпилировать не стану, а новое напишу. Если совсем по-простому, то вот:

http://zalil.ru/33993241

Компилятор - Codevision ...

P.S. Кстати, оно и не перекомпилируется, ибо это разные МК, у них по-разному сделаны таймеры, и проч. Надо вникать, разбираться. А зачем ? Да и PWM здесь не нужна, т.к. нужна не точная частота, а "примерно 3.2 КГц" ...
20AmpMax
А вот все равно Спасибо !



А вот все равно Спасибо !

Может кому нибудь когда нибудь поможет

схема
kovigor
Цитата(20AmpMax @ Nov 23 2012, 17:08) *
А вот все равно Спасибо !

Подойдет вариант без ШИМ ?
20AmpMax
Конечно любой главное чтоб генерировал
kovigor
Цитата(20AmpMax @ Nov 23 2012, 17:14) *
Конечно любой главное чтоб генерировал

Если ширину импульсов менять не нужно, а достаточно меандра, то без ШИМ можно обойтись. Иначе придется изучать документацию на МК и использовать ШИМ, но у меня сейчас нет такой возможности ...

P.S. Доработал программу в соответствии с предоставленной вами схемой:
http://zalil.ru/33993664
20AmpMax
вот спасибо спасибо спасибо.
А с чем Attiny85 больше всего схож ?

Мне все равно изучать и сравнивать ну и/или attiny85 найти.чем сейчас и занимаюсь
и научится пользоваться такими словами как меандр.

kovigor
Цитата(20AmpMax @ Nov 23 2012, 17:36) *
вот спасибо спасибо спасибо.
А с чем Attiny85 больше всего схож ?

Мне все равно изучать и сравнивать ну и/или attiny85 найти.чем сейчас и занимаюсь
и научится пользоваться такими словами как меандр.



Если для обучения, то возьмите что-нибудь более серьезное, чем Тини85. Хотя бы ту же Мегу16.
Тини85 (и не только) можно купить без проблем, связавшись с любым доступным вам продавцом по Email.
Меандр:
http://ru.wikipedia.org/wiki/%D0%9C%D0%B5%...B8%D0%BA%D0%B0)
20AmpMax
biggrin.gif


Если будет интересно то линк на описание проблемы
http://www.carhelp.info/forums/showthread....1461#post981461

kovigor
Цитата(20AmpMax @ Nov 23 2012, 17:49) *
Если будет интересно то линк на описание проблемы

Я не специалист по автомобилям, но очень возможно, что там нужен именно ШИМ. Но сейчас у меня этим заняться, к сожалению, нет возможности ...
20AmpMax
Работает !!!!!!!!!!!!!!

динамик подключил и слышно как работает


это старый трюк с BIOS очень давно видел такое из серии закоротить A14+A15 = crash mode и в результате
пытается восстановить BIOS через FDD crash mode BIOS upgrade но у машины нет FDD

много много раз СПАСИБО !
kovigor
Цитата(20AmpMax @ Nov 23 2012, 18:18) *
Работает !!!!!!!!!!!!!!
Динамик подключил и слышно как работает

Динамик не может не работать. Я так и не понял, вам эта схема + прошивка помогла решить проблему с автомобилем, или нет ?
20AmpMax
Да но не совсем нужна ешё техническая доработка (отрезать нужный провод)
динамиком проверяю наличие сигнала объективно просто что-бы убедится.

Подключил по инструкции "включил" машину подождал 20 сек. (инициализация) нажал кнопку
и ДА работает что-то происходит вентилятор крутится реле переключаются похоже на внутреннею калибровку
определённо реагирует на это устройство !




Manual (PDF) похожего устройства для примера принципа работы
http://www.reno.ro/index.php?act=Attach&am...p;id=1627792701
kovigor
Цитата(20AmpMax @ Nov 23 2012, 20:32) *
Manual (PDF) похожего устройства для примера принципа работы
http://www.reno.ro/index.php?act=Attach&am...p;id=1627792701

Да, тут надо разбираться, а я в автомобилях не силен. Если эта прошивка не поможет - скажете, я попробую реализовать ШИМ ...
20AmpMax
Завелась. Работает.

Да я сам не вожу у меня и прав нет. Сам уже почти неделю учусь и еше долго сидел-бы.

(танцую)
Кто самый лучший на татами
Он нам сложит оригами
Он спасет нас от цунами
это kovigor
kovigor
Цитата(20AmpMax @ Nov 23 2012, 20:10) *
Завелась. Работает.

Поздравляю. От души.
Кстати, у меня тоже прав нет, и водить я не умею. Ну да ладно, это уже к делу не относится sm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.