roboforum.ru

Технический форум по робототехнике.

Помогите с таймерами пожалуйста =)

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

Помогите с таймерами пожалуйста =)

Сообщение Ramzez » 07 янв 2010, 02:02

Вобщем на меге16 мигаю 3 светодиодами в 2 разных режимах, все они стоят на PORTA(выход) на 0, 2, 4 ногах. Есть так же входы на PORTB, 0 нога pull-up, к ней кнопка соединяющая с землей. При нажатии кнопки должно переходить из одного режима в другой , но не переходит =( помогите разобраться, только начинаю осваивать все. Почему то не работает условие PINB==0b00000001 (проверка высокого уровня на нулевой ноге) . Может что-то не понял пока, помогите! Без нажатия кнопки ничего вобще не мигает, не выполняется ни одно условие в циклах while , ну, разьве что while (1 ) :D
Код: Выделить всёРазвернуть
#define F_CPU 4000000UL  // 4 MHz
   #include <avr/io.h>
   #include <avr/delay.h>
   
   int main(void)              // начало основой программы
   {
   
   DDRA = 0xff; //выходы
   DDRB=0x00; //входы
  PORTB=0b00000001 ;  //pull-up на нулевую ногу
   
   
unsigned int i ;
while (1)
{



while (PINB == 0b00000001) {      // пока на нулевой ноге 1       
for (i=0; i<5; i++)
{


PORTA = 0b00000001;   //Быстрое мигание 5 раз
_delay_ms(10);
PORTA = 0x00 ;
_delay_ms(10);


}

PORTA = 0b00010000; // медленное мигание 1 раз
_delay_ms(100);
PORTA = 0x00 ;
_delay_ms(100);

   
}     


while (PINB ==0b00000000) {   //пока все ноги на нуле         
PORTA = 0b00000001 ;
_delay_ms(6);
PORTA = 0x00;
_delay_ms(6);
PORTA = 0b00000100 ;    //мигание поочереди 3 светодиодами
_delay_ms(6);
PORTA = 0x00;
_delay_ms(6);
PORTA = 0b00010000 ;
_delay_ms(6);
PORTA = 0x00;
_delay_ms(6);


   
}     
}   
}
Последний раз редактировалось Ramzez 09 янв 2010, 19:51, всего редактировалось 1 раз.
Аватара пользователя
Ramzez
 
Сообщения: 28
Зарегистрирован: 13 фев 2009, 18:37
Откуда: Петрозаводск

Re: Помогите с вводом

Сообщение =DeaD= » 07 янв 2010, 02:05

Потому что проверка высокого уровня на 0 ноге делается так:
(PINB & 0x01 != 0)
Проект [[Open Robotics]] - Универсальные модули для построения роботов
Аватара пользователя
=DeaD=
 
Сообщения: 24218
Зарегистрирован: 06 окт 2004, 18:01
Откуда: Ебург
прог. языки: C++ / PHP / 1C
ФИО: Антон Ботов

Re: Помогите с вводом

Сообщение avr123.nm.ru » 07 янв 2010, 02:05

Советую ножку к кнопке подключать через резистор 200-500 Ом.
Читайте !
Аватара пользователя
avr123.nm.ru
отсылающий читать курс
 
Сообщения: 14195
Зарегистрирован: 06 ноя 2005, 04:18
Откуда: Москва
Предупреждения: -8

Re: Помогите с вводом

Сообщение Ramzez » 07 янв 2010, 02:08

Спасибо большое за исправление! но с такой логикой у меня туго на начальном уровне, хотелось бы как нибуть попроще если можно, можете хотябы обьяснить почему не работает PINB == 0b00000001 ? результат же истина получается вроде как
Аватара пользователя
Ramzez
 
Сообщения: 28
Зарегистрирован: 13 фев 2009, 18:37
Откуда: Петрозаводск

Re: Помогите с вводом

Сообщение avr123.nm.ru » 07 янв 2010, 02:18

Потому что вы все ножки опрашиваете а вам одну надо.

Поcмотрите Си для микроконтроллеров - там есть примерчики и толкование - http://proavr.narod.ru/05.htm
Читайте !
Аватара пользователя
avr123.nm.ru
отсылающий читать курс
 
Сообщения: 14195
Зарегистрирован: 06 ноя 2005, 04:18
Откуда: Москва
Предупреждения: -8

Re: Помогите с вводом

Сообщение Ramzez » 07 янв 2010, 02:23

Но, насколько я понимаю, даже если опрашивать все ножки, выражение должно быть истинно , или для while нужно как то по-другому действовать? просто увидел гдето пример с if
Код: Выделить всёРазвернуть
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
    DDRB = 0xFF;
    PORTC = 0xFF;
    while(1)
    {
        if(PINC == 0xFF){
            PORTB = 0x00;
        }else{
            PORTB = 0xFF;
        };
    };
    return 0;
}


тут вроде тоже все опрашивают и пример из учебника, вот я и сделал по аналогии
Аватара пользователя
Ramzez
 
Сообщения: 28
Зарегистрирован: 13 фев 2009, 18:37
Откуда: Петрозаводск

Re: Помогите с вводом

Сообщение avr123.nm.ru » 07 янв 2010, 02:58

но у вас то кнопка не ко всему порту подключена а к одной ножке.
Читайте !
Аватара пользователя
avr123.nm.ru
отсылающий читать курс
 
Сообщения: 14195
Зарегистрирован: 06 ноя 2005, 04:18
Откуда: Москва
Предупреждения: -8

Re: Помогите с вводом

Сообщение Ramzez » 09 янв 2010, 19:49

Спасибо, вроде разобрался =)
Помогите теперь пожалуйста понять таймеры, очень хочется сделать ШИМ чтобы управлять серво, но пока не понятно как это происходит. Читаю курс AVR123 не могу разобраться,там сразу слишком много информации для начинающего, вчера весь вечер разбирался с битами, что и куда устанавливается, помог только даташит на русском к меге 128. пишу на WIN AVR , поэтому частенько приходится перелопачивать все что нахожу под свой компилятор(не всегда получается, все используют свои библиотеки и макросы. даже не обьявляя их в коде и порой это запутывает до конца). А конкретный вопрос вот в чем, не могли бы вы подсказать алгоритм установки таймера , без кода, а может просто словами (или блок схемой) , и про прерывания и какую роль в них играет таймер (как взаимодействует с ними). КодВизард не кактит, хочется самому втыкнуть как все это работает :oops: для начала на примере 8 битного, пожалуйста :)

Код: Выделить всёРазвернуть
DDRD=0x20; // 00100000 PD5(OC1A)-PWM Timer1 OUT
// ножку PD5 назначить выходом


// Настройка TIMER1 для генерации ШИМ

//TIMER1 initialize
//prescale:1  clock 7.37 MHz
// WGM: 7) PWM 10bit fast, TOP=0x03FF
// actual value: 7200,000Hz (100,0%)
// последнее - это частота ШИМ сигнала

TCCR1B = 0x00; //stop Timer

TCNT1H = 0xFC; // 11111100 
TCNT1L = 0x01; // 00000001 

/* значение в 16 битном регистре OCR1A определяет величину генерируемого ШИМ сигнала на ножке PD5 - если поделить ее  на 10.23 то получим PWM в процентах*/

OCR1AH = 0x03; // PWM(PD5) = OCR1A / 10.23
OCR1AL = 0xFF; // 0x03FF это число 1023

/* регистр OCR1A состоит из двух 8-ми битных регистров OCR1AH и OCR1AL запись в них нужно проводить в указанной последовательности! */

OCR1BH = 0x03;
OCR1BL = 0xFF;

ICR1H = 0x03;
ICR1L = 0xFF;

TCCR1A = 0x83; // 10000011 

TCCR1B = 0x09; // 00001001 - start Timer

// Теперь ШИМ 100% - т.е. на ножке PD1 лог. "1"


Буду по порядку задавать вопросы:
1)
Код: Выделить всёРазвернуть
TCCR1B = 0x00; //stop Timer
-таймер остановлен, не работает пока его настраивают дальше? зачем это делается, если он выключен?

2)
Код: Выделить всёРазвернуть
TCNT1H = 0xFC; // 11111100  
TCNT1L = 0x01; // 00000001

, в этом регистре пишем до куда считать , получается до 64513, вроде понятно =)

3)
Код: Выделить всёРазвернуть
/* значение в 16 битном регистре OCR1A определяет величину генерируемого ШИМ сигнала на ножке PD5 - если поделить ее  на 10.23 то получим PWM в процентах*/

OCR1AH = 0x03; // PWM(PD5) = OCR1A / 10.23
OCR1AL = 0xFF; // 0x03FF это число 1023
вот тут очень непонятно, почему он определяет велечину генерируемого ШИМ ?
небольшое отступление:
я имею таковое представление о работе таймера в качестве ШИМ. прошу направьте на путь истинный =)
TCNT увеличивается , пока не сравняется с регистром OCR. Как только он сравнивается с ним, происходит прерывание, в нем на определенный порт выводится 1, потом 0, и от паузы между ними зависит велечина ШИМ, но как она может зависеть от велечины OCR не понятно, я думал что OCR определяет период, прошу подсказать =)

4)
Код: Выделить всёРазвернуть
OCR1BH = 0x03;
OCR1BL = 0xFF;


Это второй регистр сравнения, какую функцию он выполняет, если его значение такое же как и у первого?

Отступление:
Кажется я начинаю понимать суть, но нужно знать еще тонкости. В этом примере на выходе мы получаем 100% шим, может быть потому, что 2 регистра сравнения имеют одинаковые значения?


5)
Код: Выделить всёРазвернуть
ICR1H = 0x03;
ICR1L = 0xFF;
регистр захвата, что это и с чем его едят? какую функцию он здесь выполняет? можно линк на страницу даташита, буду не против, так же буду благодарен если на русский даташит атмеги 128



6)
Код: Выделить всёРазвернуть
TCCR1A = 0x83; // 10000011  

TCCR1B = 0x09; // 00001001 - start Timer

Почему тут 2 регистра управления, как я понял, одним таймером? чем они отличаются? или они обьеденены в один?
Аватара пользователя
Ramzez
 
Сообщения: 28
Зарегистрирован: 13 фев 2009, 18:37
Откуда: Петрозаводск

Re: Помогите с вводом

Сообщение avr123.nm.ru » 09 янв 2010, 20:16

Конкретно пример управления servo сервами на Си есть в задаче 13 курса по AVR - http://proavr.narod.ru/z13.htm - кода там совсем не много по-моему.

Настройка таймеров в задачах 6 и 8 - http://proavr.narod.ru/06.htm

Русский даташит на ATmega128 можно увидеть внизу странички 2 курса - Устройство микроконтроллера AVR - http://proavr.narod.ru/02.htm - прямо смотрите разделы по таймерам или по тем модулям которые вас интересуют.

Добавлено спустя 5 минут 34 секунды:
Ramzez писал(а):Читаю курс AVR123 не могу разобраться, там сразу слишком много информации для начинающего


Много ? да вы ж еще до ВТОРОЙ странички не дошли если спрашиваете где даташит на мегу128 на русском ! ибо не заметить этого просто не возможно :Bravo: скрин ниже.
-

Добавлено спустя 5 минут 37 секунд:
Ramzez писал(а):КодВизард не кактит, хочется самому втыкнуть как все это работает


Мастер ни как не может помешать втыкать, он ведь сам не включается. Ко всему коду он дает коментарии обычно и ГАВНОЕ - ни кто вам не мешает, а я в курсе даже рекомендую обязательно по даташиту разобрать что делает каждая строка кода созданого мастером.

Мастер просто помогает когда вы этого желаете и умеете объяснить ему что вы желаете получить.

Добавлено спустя 2 минуты 46 секунд:
Re: Помогите с таймерами пожалуйста =)
Ramzez писал(а):
Код: Выделить всёРазвернуть
TCCR1A = 0x83; // 10000011  
TCCR1B = 0x09; // 00001001 - start Timer

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

2 регистра потому что битов для управления этим таймером надо более 8 и в один регистр их не поместить. Отличаются они названием, назначением и адресом.

Добавлено спустя 3 минуты 27 секунд:
Re: Помогите с таймерами пожалуйста =)
Ramzez писал(а):1)
Код: Выделить всёРазвернуть
TCCR1B = 0x00; //stop Timer
-таймер остановлен, не работает пока его настраивают дальше? зачем это делается, если он выключен ?
Обычно останавливают так как тиканье может вызвать не нужные события - например установку флаго в прерываний.
Остановка не обязательна, это воля программиста как и вся прога целиком на его совести.

2)
Код: Выделить всёРазвернуть
TCNT1H = 0xFC; // 11111100  
TCNT1L = 0x01; // 00000001

, в этом регистре пишем до куда считать , получается до 64513, вроде понятно =)[/quote]

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

Добавлено спустя 3 минуты 8 секунд:
Re: Помогите с таймерами пожалуйста =)
по п. 3 - у тамера МНОГО режимов счета, если посмотреть в даташите или в мастере компилятора ICC - задача 6 курса - то около 16 режимов вроде. И в этих режимах разные регистра и числа определяют перод и события возникающие по ходу счета.

По PWM ШИМ - задача 8 курса.

Добавлено спустя 2 минуты 58 секунд:
Re: Помогите с таймерами пожалуйста =)
Ramzez писал(а):можно страницу даташита о регистре


откройте PDF и в поиск вставьте название регистра - он вам найдет его быстро, лтбо в закладках слева по оглавлению пройдитесь.

Как работать с даташитом - страница 1 курса.
Вложения
avr proavr.narod.ru atmega.png
Читайте !
Аватара пользователя
avr123.nm.ru
отсылающий читать курс
 
Сообщения: 14195
Зарегистрирован: 06 ноя 2005, 04:18
Откуда: Москва
Предупреждения: -8

Re: Помогите с таймерами пожалуйста =)

Сообщение Ramzez » 09 янв 2010, 20:57

непонятки у нас возникают с вами )
даташит на мегу скачан русский, я по нему выяснял что делают биты, наприммер в TCCR, но не могу найти про ICR , просил дать номер странички где можно про него почитать )

В том то и проблема, что где я не ищу ШИМ на си, там везде засунут UART, передача данных на комп или сразу 8 серво, а нужно то всего одно чтобы разобраться! а когда поймешь одно, можно и 8 будет делать самому. Я прочитал весь курс AVR123, и про серво читал) но , к сожалению не понял, поэтому решил создать эту темку о помощи =)

Знаний у меня пока хватило мигать светодиодами в разных режимах по кнопкам, сделал программную реализацию ШИМ, смог управлять серво приводом (поворачивать плавно из крайнего левого положения в правое) , так же получилось сделать прерывание. Следующий шаг -таймеры, основная проблема в непонимании синтаксиса других программистов

Добавлено спустя 11 минут 57 секунд:
Я был бы очень вам благодарен, если бы вы обьяснили на примере одной сервы настройку таймера и ШИМ , без всякой обвески , например чтобы передвинуть серво в одно единственное положение, это будет отправной точкой в дальнейшем изучении МК для меня, моего товарища и еще многих, поскольку запрос на форуме "управление серво" выдает очень много однообразных тем, где всем дают линки на AVR123 .

Так же не могли бы вы подсказать, стоит ли мне дальше использовать WIN AVR , или переходить на CVAVR , с его мастером генерирования начального кода?
Аватара пользователя
Ramzez
 
Сообщения: 28
Зарегистрирован: 13 фев 2009, 18:37
Откуда: Петрозаводск

Re: Помогите с таймерами пожалуйста =)

Сообщение Grofus » 09 янв 2010, 21:21

Для начала разберись с начинкой контроллера, правда придётся прочитать много скучных букав.
Пример с 1 сервой : насраиваеш таймер в режим нормал и выставляеш необходимое время через которое вызывается прерывание , потом ставиш на ноге нужный уровень, а в прерывании возвращаеш ногу в исходное сосотяние. и т.д..(Если ошибся поправте)
А когда серв много строиться конвеер(RTOS)...
Алокоголизм - излечим, пьянство - нет.
Peace-death.
Аватара пользователя
Grofus
 
Сообщения: 104
Зарегистрирован: 25 июл 2009, 16:35
Откуда: Ессентуки
прог. языки: ASM , Lisp , C# :)
ФИО: Алексей

Re: Помогите с таймерами пожалуйста =)

Сообщение avr123.nm.ru » 09 янв 2010, 22:08

Ramzez писал(а):стоит ли мне дальше использовать WIN AVR , или переходить на CVAVR , с его мастером генерирования начального кода?


Конечно используйте WinAVR, а пока учитесь мастера CVAVR и ICC вам помогут.

Пример в мастере cvavr 2 настройка AVR под servo

1) выбираешь чип мега16 и частоту 4 Мгц

2) таймер 1 настраичваешь на счет 500 Кгц т.е. за 20 мС он насчитает до 10 000 - это число занесем ( после генрации кода вручную ) в регистр ICR1 - таймер будет постоянно считать от 0 до 10000 и снова с нуля ...

3) вкл. выход ШИМ "А" OC1A не инвертированый. Теперь когда таймер будет в "0" на выходе OC1A будет появляться "1" а когда таймер досчитает до OCR1 то на OC1A появится "0".

4) 2 мкС будет 1 тик таймера при частоте 500 Кгц

Значит для среднего положения сервы надо вписать: 1500 мкС / 2 мкС = 750 ( это 2eeh) в OCR1

левое положение servo OCR1 = 550; правое положение servo OCR1 = 950;

5) Теперь - "Програм Превью" при генерации кода мастер предложит назначить ножку ШИМ выходом - жми ОК.

Зашуршало в PROTEUS !
Вложения
servo.png
servo.rar
файл мастера кода CVAVR 2
(2.89 КиБ) Скачиваний: 10
Последний раз редактировалось avr123.nm.ru 09 янв 2010, 22:40, всего редактировалось 1 раз.
Читайте !
Аватара пользователя
avr123.nm.ru
отсылающий читать курс
 
Сообщения: 14195
Зарегистрирован: 06 ноя 2005, 04:18
Откуда: Москва
Предупреждения: -8

Re: Помогите с таймерами пожалуйста =)

Сообщение Ramzez » 09 янв 2010, 22:29

Большое всем спасибо! буду пробовать !
Аватара пользователя
Ramzez
 
Сообщения: 28
Зарегистрирован: 13 фев 2009, 18:37
Откуда: Петрозаводск

Re: Помогите с таймерами пожалуйста =)

Сообщение avr123.nm.ru » 09 янв 2010, 22:43

Проект в CVAVR 2 и скрин мастера с настройкой таймер AVR для управления servo
Вложения
servo.rar
Проект в CVAVR 2 таймер AVR для управления servo
(18.52 КиБ) Скачиваний: 12
avr_servo.png
Читайте !
Аватара пользователя
avr123.nm.ru
отсылающий читать курс
 
Сообщения: 14195
Зарегистрирован: 06 ноя 2005, 04:18
Откуда: Москва
Предупреждения: -8

Re: Помогите с таймерами пожалуйста =)

Сообщение Ramzez » 10 янв 2010, 20:02

Вот что у меня получилось для WIN AVR , начальный код генерировал CVAVR, потом переносил )
Пока еще не проверял на практике ( с эмуляторами не стал разбираться пока )

Код: Выделить всёРазвернуть
#define F_CPU 1000000UL  // 1 MHz
   #include <avr/io.h>
   #include <avr/interrupt.h>

// Declare your global variables here

void main(void)
{

PORTD=0x00;     
DDRD=0x20;    //выход таймера
DDRA = 0xff; //выходы
DDRB=0x00; //входы
PORTB=0b00000001 ;  //pull-up на нулевую ногу

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
// Mode: Normal top=FFFFh
// OC1A output: Set
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0xC0;
TCCR1B=0x02;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x09;
ICR1L=0xc4;
OCR1AH=0x00;
OCR1AL=0xBC;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

while (1)
{

while(PINB & 0x01 != 0) {      //пока нажата кнопка
if (OCR1AL<250)        //если серво не в крайнем правом положении
{
OCR1AL++;             //разворот вправо
PORTA = 0b00000001;  //синий светодиод
}

}

if (OCR1AL>140)      //если серво не в крайнем левом положении
{
OCR1AL--;            //разворот влево
PORTA=0b00010000;    //красный светодиод
}
}
}


Вопрос: обязателен ли данный кусок кода
Код: Выделить всёРазвернуть
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

если прерывания, вроде как, в таймере я не использовал ?

Добавлено спустя 3 минуты 2 секунды:
Прога должна при нажатии кнопки перегонять серво постепенно из крайнего левого в крайнее правое положение, при этом загораются соответствующие светодиоды на выходах PORTB=00010001
Последний раз редактировалось Ramzez 10 янв 2010, 21:14, всего редактировалось 4 раз(а).
Аватара пользователя
Ramzez
 
Сообщения: 28
Зарегистрирован: 13 фев 2009, 18:37
Откуда: Петрозаводск

След.

Вернуться в Новичкам или основы основ роботостроения.

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8