Регулятор хода на attiny 13
| |
lorddroid | Дата: Пятница, 29.03.2013, 16:43 | Сообщение # 1 |
Рядовой
Группа: Проверенные
Сообщений: 9
Статус: Offline
| День добрый форумчане, меня зовут Андрей пишу на CVAVR строю в протеусе - всякие штуки.
сейчас задача такая - есть р\у аппаратура Futaba. с приемника снимаем сигнал и отправляем на тиньку , в зависимости от джойстика там 1 - 2 мс испульсы на выходе канала.
Вешаем туда attiny 13 и считаем ширину. в зависимости от нее уже на выход пошла нагрузка. схемку выложу и софт. Собственно вопрос то , в том как лучше входной сигнал получить. Амплитуда там 2.8-3.3 В , сегодня осцилом померю.
раньше я на 5 вольтовой логике все собирал, атут или согласовывать надо или по фронту ставить ..
Добавлено (29.03.2013, 15:16) --------------------------------------------- /***************************************************** This program was produced by the CodeWizardAVR V2.05.3 Standard Automatic Program Generator © Copyright 1998-2011 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpinfotech.com
Project : Version : Date : 18.03.2013 Author : PerTic@n Company : If You Like This Software,Buy It Comments:
Chip type : ATtiny13A AVR Core Clock frequency: 0,128000 MHz Memory model : Tiny External RAM size : 0 Data Stack size : 16 *****************************************************/
#include <tiny13a.h> #include <delay.h>
int i=2501, i1=0,ms02=0;
// Timer 0 output compare A interrupt service routine interrupt [TIM0_COMPA] void timer0_compa_isr(void) { // Place your code here ms02++; // 1/5 ms =0.2ms =5000 имп в сек if(PINB.1==1) {i1++;} // пока верхний уровень на входе считаем тики if (ms02==5000) { ms02=0;i=i1;i1=0;} // подсчитываем сколько импульсов пришло за 1 сек, обнляем счетчик
}
// Declare your global variables here
void main(void) { // Declare your local variables here
// Crystal Oscillator division factor: 1 #pragma optsize- CLKPR=0x80; CLKPR=0x00; #ifdef _OPTIMIZE_SIZE_ #pragma optsize+ #endif
// Input/Output Ports initialization // Port B initialization // Func5=Out Func4=Out Func3=Out Func2=Out Func1=In Func0=Out // State5=0 State4=0 State3=0 State2=0 State1=T State0=0 PORTB=0x00; DDRB=0x3D;
// Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 128,000 kHz // Mode: CTC top=OCR0A // OC0A output: Disconnected // OC0B output: Disconnected TCCR0A=0x02; TCCR0B=0x01; TCNT0=0x00; OCR0A=0x19; OCR0B=0x00;
// External Interrupt(s) initialization // INT0: Off // Interrupt on any change on pins PCINT0-5: Off GIMSK=0x00; MCUCR=0x00;
// Timer/Counter 0 Interrupt(s) initialization TIMSK0=0x04;
// Analog Comparator initialization // Analog Comparator: Off ACSR=0x80; ADCSRB=0x00; DIDR0=0x00;
// ADC initialization // ADC disabled ADCSRA=0x00;
// Global enable interrupts #asm("sei")
while (1) { // Place your code here
if (i < 2500) {PINB.0=1;PINB.2=1; PINB.3=0;PINB.4=0; delay_ms(50); }
else {PINB.0=0;PINB.2=0; PINB.3=1;PINB.4=1; delay_ms(50); }
// Place your code here
} }
ну если б 5В на входи сидело было б норм, и протеус ест. а по фронту я так понимаю на INT0 надо вешать . или вобще ка кто по другому считать лучше ширину импульса?
Добавлено (29.03.2013, 15:31) --------------------------------------------- Еще мысли в слух...
// External Interrupt 0 service routine interrupt [EXT_INT0] void ext_int0_isr(void) { // Place your code here
i1++;
}
тут процедура запускающая таймер Сколько частота нашего МК столько и измерений . А как понять начало и конец ?
Добавлено (29.03.2013, 16:42) --------------------------------------------- переписал так вроде в протеусе пашет.
#include <mega8.h> #include <delay.h> #include <lcd.h> #include <stdio.h> char lcd_buffer[33]; //массив с данными для экрана int i=0, i1=0,ms02=0,flag1=0,move1=0;
#asm .equ __lcd_port=0x18 #endasm
// External Interrupt 0 service routine interrupt [EXT_INT0] void ext_int0_isr(void)// прерывание на любое изменение сигнала { if(PINB.2==0)// нисходяший фронт 1->0 старт { TCCR0=0x02;// старт таймера с пределителем 8 на 8 МГц 1 Мгц TCNT0=0x00; } if(PINB.2==1)// восходяший фронт 0->1 стоп { TCCR0=0x00; //останавливаем таймер
i=TCNT0; // в мс время импульса
if(TCNT0==100) // если надо 100 мс { // наш импульс что то делаем
};
// Place your code here } } // Timer1 output compare A interrupt service routine interrupt [TIM1_COMPA] void timer1_compa_isr(void) { // Place your code here // ms02++; // 1/5 ms =0.2ms =5000 имп в сек // (PORTD.2==1) {i1++;} // пока верхний уровень на входе считаем тики // if (ms02==5000) { ms02=0;i=i1;i1=0;} // подсчитываем сколько импульсов пришло за 1 сек, обнляем счетчик
}
// Declare your global variables here
void main(void) { // Declare your local variables here
// Input/Output Ports initialization // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTB=0x00; DDRB=0x00;
// Port C initialization // Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTC=0x00; DDRC=0x00;
// Port D initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTD=0x00; DDRD=0x00;
// Timer/Counter 0 initialization // Clock source: System Clock // Clock value: Timer 0 Stopped //TCCR0=0x00; //TCNT0=0x00;
// Timer/Counter 1 initialization // Clock source: System Clock // Clock value: 125,000 kHz // Mode: CTC top=OCR1A // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: On // Compare B Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x0A; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x19; OCR1BH=0x00; OCR1BL=0x00;
// External Interrupt(s) initialization // INT0: On // INT0 Mode: Any change // INT1: Off // INT2: Off
GICR|=0x40; MCUCR=0x01; MCUCSR=0x00; GIFR=0x40;
// Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x10;
// USART initialization // USART disabled UCSRB=0x00;
// Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; SFIOR=0x00;
// // Global enable interrupts
lcd_init(16);
#asm("sei")
while (1) {
lcd_gotoxy(0,0); if (i < 2500) {sprintf(lcd_buffer,"Time = %i",i);} else {sprintf(lcd_buffer,"Time = %i",i);} lcd_puts(lcd_buffer); delay_ms(500); lcd_clear(); // Place your code here
} }
Добавлено (29.03.2013, 16:43) --------------------------------------------- ну под жкшку, у меня на ней макетная платка.
Сообщение отредактировал lorddroid - Пятница, 29.03.2013, 15:59 |
|
| |
ВитГо | Дата: Суббота, 30.03.2013, 10:22 | Сообщение # 2 |
Полковник
Группа: Администраторы
Сообщений: 2422
Статус: Offline
| по поводу согласования уровней: в принципе логическая единица на уровне 2.5-3.3 вольта будет нормально обрабатываться на авр с питанием 5 вольт
сейчас вопрос стоит в определении ширины импульса ?
тогда 3 пути:
1. ловить изменение сигнала на выводе int микроконтроллера по фронту, сбрасывать таймер, и по изменении сигнала на выводе int по спаду - брать значение таймера - это и будет длительностью импульса
2. использовать ICP режим таймера (правда нужно посмотреть есть ли такой режим у тини)- в этом случае копирование значения таймера tcnt при изменении на выводе int в регистр icp происходит автоматически - что дает хорошую точность при замерах длительностей..
можно еще посмотреть проект RC-switch на ATtiny13 от uwerty - он правда писал на асме, но реализовывал способ 1 либо посмотреть проект Реализация функционала тренер-ученик в RC от меня - там реализован способ 2
3. вы изобрели третий способ я сестно говоря о нем как то не задумывался :-)
оба способы имеют право на жизнь, все зависит от исходных условий и конечных задач.
в асме разобраться сможешь ?
Виталий (аka ВитГо)
|
|
| |
lorddroid | Дата: Суббота, 30.03.2013, 13:55 | Сообщение # 3 |
Рядовой
Группа: Проверенные
Сообщений: 9
Статус: Offline
| ВитГо, нет увы в асме совсем не силен . на делфи писал лет 5 , 1с и прос. ну си более менее знаю, синтаксис похож на делфи.
Вопрос еще такой , уже писал что макетная плата самодельная на меге 8 . У меги 8 есть таймер 0 , функционал как у вачдога те там ничего нет кроме самого таймера . Как выбрать режим таймера правильно для тини 13 ? Что то сразу не пошло в протеусе на тини, пока разбираюсь.
http://s019.radikal.ru/i607/1303/e2/267323f5c570.jpg
своего осцила, нет принесут только в воскресенье какой то маркер вроде еще пробегает в канале , значения меняются и после снова что надо встают.
по поводу методов, я вроде б и реализовал первый со второго раза.
interrupt [EXT_INT0] void ext_int0_isr(void)// прерывание на любое изменение сигнала { if(PINB.2==0)// нисходяший фронт 1->0 старт { TCCR0=0x02;// старт таймера с пределителем 8 на 8 МГц 1 Мгц TCNT0=0x00; } if(PINB.2==1)// восходяший фронт 0->1 стоп { TCCR0=0x00; //останавливаем таймер
i=TCNT0; // в мс время импульса
Сообщение отредактировал lorddroid - Суббота, 30.03.2013, 13:57 |
|
| |
ВитГо | Дата: Суббота, 30.03.2013, 14:00 | Сообщение # 4 |
Полковник
Группа: Администраторы
Сообщений: 2422
Статус: Offline
| что таймер 0 у тиньки 8ми битный помните ?
какой максимальный временной интервал им можно измерить - прикидывали ?
Виталий (аka ВитГо)
|
|
| |
ВитГо | Дата: Суббота, 30.03.2013, 14:04 | Сообщение # 5 |
Полковник
Группа: Администраторы
Сообщений: 2422
Статус: Offline
| кстати, а какой режим таймера вы используете ?
я увидел получается что максимальное значение счетчика в OCR...
лучше просто сделать обычный режим Normal
и потом уже работать способом 1 (ICP режима нет у тиньки13)
Виталий (аka ВитГо)
|
|
| |
lorddroid | Дата: Суббота, 30.03.2013, 14:17 | Сообщение # 6 |
Рядовой
Группа: Проверенные
Сообщений: 9
Статус: Offline
| interrupt [EXT_INT0] void ext_int0_isr(void)// прерывание на любое изменение сигнала { if(PINB.2==0)// нисходяший фронт 1->0 старт { // TCCR0=0x02;// старт таймера 0 с пределителем 8 на 8 МГц 1 Мгц =125кгц // TCNT0=0x00; TCCR1B=0x02; // старт таймера1 с пределителем 8 на 8 МГц 1 Мгц =125кгц TCNT1L=0x00;
} if(PINB.2==1)// восходяший фронт 0->1 стоп { //TCCR0=0x00; //останавливаем таймер 0 // i=TCNT0; // в мс время импульса
TCCR1B=0x00; //останавливаем таймер 1 i=TCNT1L;
} }
Вот сравниваю 0 и 1 теймер - 8 меги, какраз режим normal - протеус как то долго считает первый виток. те на 0 таймере быстро выводит а на 1 с задержкойДобавлено (30.03.2013, 14:17) --------------------------------------------- ну повторюсь с вопросом :
1 мгц - это интервал 10-6 секунды - это как считается ?
|
|
| |
lorddroid | Дата: Понедельник, 01.04.2013, 00:30 | Сообщение # 7 |
Рядовой
Группа: Проверенные
Сообщений: 9
Статус: Offline
| Перешел по совету на мегу 8 , после может и на 2313 попробую.
ICP осваивать начну завтра. мало ли по этому идеи есть
по замерам осцилографа с футабы: Все импульсы одинаковые Период %: 73Гц или 3.6мс , импульсы 1 /1,5/2 мс 3.0В АМплитуда ну при подстройке можно сдвигать немного импульсы. на 0.1 мс где то
|
|
| |
ВитГо | Дата: Понедельник, 01.04.2013, 08:40 | Сообщение # 8 |
Полковник
Группа: Администраторы
Сообщений: 2422
Статус: Offline
| период в 73 гц что то быстроват.. по идее 50 гц должно быть !
Виталий (аka ВитГо)
|
|
| |
lorddroid | Дата: Понедельник, 01.04.2013, 15:00 | Сообщение # 9 |
Рядовой
Группа: Проверенные
Сообщений: 9
Статус: Offline
| Цитата (ВитГо) период в 73 гц что то быстроват.. по идее 50 гц должно быть !
осцил вроде точно все мерил
Добавлено (01.04.2013, 14:34) --------------------------------------------- Рабочий алгоритм Попробуем и на других мк.
Chip type : ATmega8 AVR Core Clock frequency: 8,000000 MHz *****************************************************/
#include <mega8.h> #include <delay.h> #include <lcd.h> #include <stdio.h>
char lcd_buffer[33]; //массив с данными для экрана int i=0,x=0,n=0 ,y=0,EdgeF=0,EdgeR=0,schet=0; // n=0 подъем n=1 спад
#asm .equ __lcd_port=0x18 #endasm
// External Interrupt 0 service routine interrupt [EXT_INT0] void ext_int0_isr(void) {
if(PINB.2==1)// нисходяший фронт 1->0 старт {
TCCR0=0x04;// старт таймера с пределителем 256 на 8 МГц =31,250кгц TCNT0=0x00; // очистка счетчика 0
TCCR1B=0x04; TCNT1=0; // счетчик 1 не останавливаем просто обнуляем
} if(PINB.2==0)// восходяший фронт 0->1 стоп { TCCR0=0x00; //останавливаем таймер 0 TCCR1B=0x00;//останавливаем таймер 1
x= TCNT1; // TCNT1L+ TCNT1H;
if ((i<45)&& (i>30)) {PORTD.5=1;PORTD.6=0;PORTD.7=0;} // проверка положения джойстика без жк if ((i<59)&& (i>45)) {PORTD.5=0;PORTD.6=1;PORTD.7=0;} if ((i<100)&& (i>60)) {PORTD.5=0;PORTD.6=0;PORTD.7=1;}
}
i=TCNT0; // в мс время импульса будет от 36 до 64 ... 1-2мс
} // Declare your global variables here
void main(void) {
PORTB=0x00; DDRB=0xFF;
PORTC=0x00; DDRC=0x00;
PORTD=0x00; DDRD=0xE0;
// External Interrupt(s) initialization // INT0: On // INT0 Mode: Any change // INT1: Off GICR|=0x40; MCUCR=0x01; GIFR=0x40;
// Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; SFIOR=0x00;
// Global enable interrupts #asm("sei") lcd_init(16); while (1) {
lcd_gotoxy(0,0); sprintf(lcd_buffer,"Time = %i %i",i,x); // выводим оба счетчика на жк lcd_puts(lcd_buffer); delay_ms(1000); lcd_clear();
} }
Добавлено (01.04.2013, 14:35) --------------------------------------------- тут два счетчика считают пользоваться можно любым
протеуса сигнал для теста
Сообщение отредактировал lorddroid - Понедельник, 01.04.2013, 15:03 |
|
| |
ВитГо | Дата: Понедельник, 01.04.2013, 19:53 | Сообщение # 10 |
Полковник
Группа: Администраторы
Сообщений: 2422
Статус: Offline
| Прошу картинки пережимать в gif и выкладывать вкладывая файл в сообщение на форуме !
движок форума автоматом уменьшит картинку для предпоказа, и при клике - выведет ее полный размер...
Виталий (аka ВитГо)
|
|
| |
HamsterODP | Дата: Пятница, 17.05.2013, 06:22 | Сообщение # 11 |
Рядовой
Группа: Проверенные
Сообщений: 4
Статус: Offline
| Я так понял при Тини13 забыли?
Я вот так измерял импульс:
interrupt [PC_INT0] void pin_change_isr(void) { if (PINB.4 == 1) { i = TCNT0; } if (PINB.4 == 0) { z_pulse = i - TCNT0; } }
В Протеусе при выводе z_pulse на //TCCR0A=0x83; //OCR0A=z_pulse; длительность импульса входа равна была выходу.
|
|
| |
ВитГо | Дата: Пятница, 17.05.2013, 21:47 | Сообщение # 12 |
Полковник
Группа: Администраторы
Сообщений: 2422
Статус: Offline
| а там прерывание icp у таймера нет возможности использовать ? (даташит не смотрел)
Виталий (аka ВитГо)
|
|
| |
HamsterODP | Дата: Пятница, 17.05.2013, 22:07 | Сообщение # 13 |
Рядовой
Группа: Проверенные
Сообщений: 4
Статус: Offline
| У тини13 нет его.
И походу вопрос. Перед выводом на OCR0A ставлю PINB.2=1 у меня пульсация идет на выводе, не могу найти где. Может настройки протеуса?
http://s018.radikal.ru/i522/1305/b5/48b858e01775.png
// Global enable interrupts #asm("sei")
while (1) { PINB.2 = 1; //ВОТ ЗДЕСЬ! TCCR0A=0x83; OCR0A=z_pulse; } }
Сообщение отредактировал HamsterODP - Пятница, 17.05.2013, 22:12 |
|
| |
ВитГо | Дата: Суббота, 18.05.2013, 22:30 | Сообщение # 14 |
Полковник
Группа: Администраторы
Сообщений: 2422
Статус: Offline
| Цитата (HamsterODP) TCCR0A=0x83; а вот это что ?
распишите настройку по битам..
например uwrtey делает вот так (оцените насколько нагляднее и понятнее): Код ldi Temp,(1<<COM1A1)|(1<<COM1B1)|(1<<WGM11)|(1<<WGM10) out TCCR1A,Temp ; быстрый ШИМ с вершиной в OCR1A // очистить по совпадению, установить при сбросе ; *1 ( ШИМ с регулируемой частотой ) ; генерации на OC1A в этом режиме нет! по идее можно отключить!
; COM1A1 / поведение вывода OC1A // ; COM1A0 / поведение вывода OC1A // ; COM1B1 / поведение вывода OC1B // ; COM1B0 / поведение вывода OC1B // ; WGM11=1 / режим * ; WGM10=0 / режим *
если вы хотите сделать настройку вывода предварительно (при режиме ocr) - то для этого есть специальная последовательность команд.. и задавать напрямую состояние линии порта не правильно !
Виталий (аka ВитГо)
|
|
| |
HamsterODP | Дата: Суббота, 18.05.2013, 22:42 | Сообщение # 15 |
Рядовой
Группа: Проверенные
Сообщений: 4
Статус: Offline
| как это по битам?
регистр TCCR0A имеет 8 бит | COM0A1 | COM0A0 | COM0B1 | COM0B0 | – | – | WGM01 | WGM00 | Установлены первый и два последних или 0b10000011 или 0х83
COM01A - Compare Match Output A Mode WGM - Waveform Generation Mode
Ну вот, как то так. Не могу найти кто(или где) обнуляет порт. Вроде условие жесткое, в порт единицу. И отношения к ШИМу иметь не должно.
Сообщение отредактировал HamsterODP - Суббота, 18.05.2013, 22:46 |
|
| |
|