Jump to content

STELLER

Members
  • Content Count

    6
  • Joined

  • Last visited

Community Reputation

0 Обычный

About STELLER

  • Rank
    Новенький

Информация

  • Город
    Москва

Электроника

  • Стаж в электронике
    Менее года
  1. Спасибо) Я так понял по обвязке только пару конденсаторов по питанию и все?
  2. там написано "2) Почему используют часто эти микросхемы а не опторазвязку?" хотя бы целым предложением цитируйте а не куском. что уже другой смысл имеет. да и лучше целиком прочитать. в чем я прошу растолковать. у меня мк и драйвер способны от одного уровня работать. это на тему вАпрОсА пАчАму
  3. Не было у меня "вАпроса пАчАму". Это ваша лепта уже. Я задал вопрос не про согласование уровней. пАчАму вы мне это нАпЯчАтали я не пАниМАю
  4. я начинающий и пытаюсь разобраться в теме ШД по управлением микроконтроллера. Затронул сейчас тему изоляции линии микроконтроллера от силовых линий питания самого ШД и его драйвера. Вопрос: 1) В интернете часто используется микросхемы логики помещённая между МК и драйвером ШД. часто вижу что используется буфер с не инвертирующим выходом 74HC541 или 74HC244. Подобный буфер я так понимаю просто не пропускает сигнал в обратную сторону тем самым защищает цепь МК? У меня к сожалению пока нет на руках данной микросхемы, но я сделал уже заказ и относительно скоро получится пощупать. Если я питаю микросхему тем же питанием что и МК то не объединит ли эта микросхема 2 моих источника питания по линии GND? 2) Почему используют часто эти микросхемы а не опторазвязку? если я правильно понял то скорости даже у PC817 хватит для того чтобы управлять линиями STEP и DIR. Ведь при этом у нас получается нормальная изоляция источников питания МК и ШД. я знаю что минусами называют габариты цепи опторазвязки и ее скорость. Но в интернете я нахожу дорогие контроллеры от серьезных фирм которые так же вставляют либо инверторы либо буфер в цепь. Был бы признателен за объяснение. Приложил свою схему которую накидал. Скорее всего она с ошибками из-за отсутствия обвязки 74HC541 но думаю разберусь уж как-нибудь со временем.
  5. Я ж не на ардуино делаю. Откуда у меня millis и библиотеки. На самом деле я разобрался уже. Формирование ШИМ сигнала нужно делать отдельно от общей программы. Я сделал через таймер1 с корректировкой частоты. Теперь влияния общей программы на работу двигателя нет. Своими словами излагаю как понимаю (любитель от слова совсем). Осталось разобраться со значениями ICR1 и OCR1 в данном режиме. Пока выставил примерно ( в попугаях) значения. Все работает. Может найду где точнее считаются
  6. Здраствуйте. Помогите пожалуйста разобраться начинающему самоучке. Хотел разобраться в управлении ШД. Не могу пока понять как корректно управлять ШД через МК. Если просто дергать через таймер ногу STEP драйвера то в принцепе двигатель оживает. Направление так же меняется без проблем. Но при моем варианте кода при раоте двигателя он реагирует на любой шорох в программе. Как только я совершу действие кнопкой или энкодером, то даже по звуку слышно изменение скорости двигателя. Получается реагирует на любое изменение программы. Возможно есть какой то иной способ управления? Подскажите пожалуйста. Заранее спасибо. Прилагаю код. Не весь функционал я еще прописал, хочется решить проблему. Устройство по сути обычный слайдер для видео камеры. Старт стоп для двигателя. Направление двигателя. И регулировка скорости двигатателя. Все. Использовал ATMega16 потому что пока есть она. Хочу переделать потом на Mega8. #define F_CPU 12000000UL #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> int MotorSpeed = 0; int MotorWork = 0; unsigned int OverflowsRemainMotorWork = 0; //Переменные для энкодера enum { State0, StateA, StateB, StateAB }; //состояния энкодера static char EncPrev; //предыдущее состояние энкодера static char EncPrevPrev; //пред-предыдущее состояние энкодера unsigned char R1=0, R2=0, R3=0; unsigned int OverflowsRemainStartButton = 0; int StartSet = 0; int StartButtonPressed = 0; unsigned int OverflowsRemainLeftButton = 0; int LeftSet = 0; int LeftButtonPressed = 0; unsigned int OverflowsRemainRightButton = 0; int RightSet = 0; int RightButtonPressed = 0; //=========================================Энкодеры================================================= void Encoder_Init(void) { DDRC &= ~(1<<PC3) | ~(1<<PC4); //настройка портов на ввод PORTC |= (1<<PC3) | (1<<PC4); //включение подтягивающих резисторов EncPrev = State0; //инициализация предыдущего состояния EncPrevPrev = State0; //инициализация пред-предыдущего состояния } void To_Do_Step_Up() { MotorSpeed++; if (MotorSpeed>=100) MotorSpeed = 100; } void To_Do_Step_Dn() { MotorSpeed--; if (MotorSpeed<=0) MotorSpeed = 0; } void Encoder(void) { char EncCur = 0; if(!(PINC&(0b00001000))) EncCur = StateA; //опрос фазы 1 энкодера if(!(PINC&(0b00010000))) EncCur |= StateB; //опрос фазы 2 энкодера if(EncCur != EncPrev) //если состояние изменилось, { if(EncPrev == StateAB && //если предыдущее состояние StateAB EncCur != EncPrevPrev ) //и текущее и пред-предыдущее не равны, { if(EncCur == StateB) //если текущее состояние StateB, To_Do_Step_Up(); //шаг вверх else //иначе To_Do_Step_Dn(); //шаг вниз } EncPrevPrev = EncPrev; //сохранение пред-предыдущего состояния EncPrev = EncCur; //сохранение предыдущего состояния } } //=========================================SPI================================================= void SPI_init(void) { DDRB |= ((1<<PORTB4)|(1<<PORTB5)|(1<<PORTB7)); //ножки SPI на выход PORTB &= ~((1<<PORTB4)|(1<<PORTB5)|(1<<PORTB7)); //низкий уровень SPCR |= ((1<<SPE)|(1<<MSTR));//включим шину, объ¤вим ведущим } //=========================================Таймеры================================================= void timer0_ini(void) { // Установка предделителя /256 TCCR0 = (1 << CS02); // Обнуляем счетчик таймера 0 TCNT0 = 0; // Разрешение прерывания таймера 0 по переполнению TIMSK |= (1 << TOIE0); } void timer1_ini(void) { TCCR1A |= 0; TCCR1B |= (1<<CS11) | (1<<WGM12); // Делитель: Clk/64 TIMSK |= (1 << OCIE1B); // Прерывание при переполнении: Вкл. OCR1B = 100; // границы скрости 6 - 255 TCNT1 = 0; // Предустановленное значение: 0 } void timer2_ini(void) { TCCR2 |= (1<<WGM21); // устанавливаем режим СТС (сброс по совпадению) TIMSK |= (1<<OCIE2); //устанавливаем бит разрешения прерывания 1ого счетчика по совпадению с OCR2 OCR2 = 255; //записываем в регистр число 255 для сравнения TCCR2 |= (1<<CS20) | (1<<CS22);//установим делитель 128. } //=========================================Индикатор================================================= void segchar (unsigned char seg) { switch(seg) { case 1: SPDR = 0b00010100; break; case 2: SPDR = 0b11001101; break; case 3: SPDR = 0b01011101; break; case 4: SPDR = 0b00011110; break; case 5: SPDR = 0b01011011; break; case 6: SPDR = 0b11011011; break; case 7: SPDR = 0b00010101; break; case 8: SPDR = 0b11011111; break; case 9: SPDR = 0b01011111; break; case 0: SPDR = 0b11010111; break; case 10: SPDR = 0b001000000; break; // Точка case 11: SPDR = 0b000000000; break; // Пустота case 12: SPDR = 0b010001011; break; // F } } void ledprint(unsigned int number) { if (MotorSpeed > 0) { R1 = number%10; if (number < 10) R2 = 11; else R2 = number%100/10; if (number < 100) R3 = 11; else R3 = number%1000/100; } else { R1 = 12; R2 = 12; R3 = 0; } } //=========================================Обработчик таймера================================================= ISR (TIMER0_OVF_vect) { OverflowsRemainStartButton++; OverflowsRemainLeftButton++; OverflowsRemainRightButton++; } ISR (TIMER1_COMPB_vect) { OverflowsRemainMotorWork++; } unsigned char n_count=0; ISR (TIMER2_COMP_vect) { if(n_count==0) { SPDR = 0b11111101; while(!(SPSR & (1<<SPIF)));//подождем пока данные передадутся segchar(R1); while(!(SPSR & (1<<SPIF)));//подождем пока данные передадутся //сгенерируем отрицательный фронт для записи в STORAGE REGISTER PORTB |= (1<<PORTB4); //высокий уровень PORTB &= ~(1<<PORTB4); //низкий уровень } if(n_count==1) { SPDR = 0b11111011; while(!(SPSR & (1<<SPIF)));//подождем пока данные передадутся segchar(R2); while(!(SPSR & (1<<SPIF)));//подождем пока данные передадутся //сгенерируем отрицательный фронт для записи в STORAGE REGISTER PORTB |= (1<<PORTB4); //высокий уровень PORTB &= ~(1<<PORTB4); //низкий уровень } if(n_count==2) { SPDR = 0b11110111; while(!(SPSR & (1<<SPIF)));//подождем пока данные передадутся segchar(R3); while(!(SPSR & (1<<SPIF)));//подождем пока данные передадутся //сгенерируем отрицательный фронт дл¤ записи в STORAGE REGISTER PORTB |= (1<<PORTB4); //высокий уровень PORTB &= ~(1<<PORTB4); //низкий уровень } n_count++; if (n_count>2) n_count=0; } //=========================================drv8825================================================= void DRV8825_ini() { DDRD |= (1<<PD0) | (1<<PD1) | (1<<PD2); // Enable Step Dir PORTD |= (1<<PD0) | (0<<PD1) | (1<<PD2); // Enable Step Dir } //=========================================Кнопки================================================= void button_ini() { DDRC &= ~(1<<PC0) | ~(1<<PC1) | ~(1<<PC2); // Enable Step Dir PORTC |= (1<<PC0) | (1<<PC1) | (1<<PC2); // Enable Step Dir } //=========================================Светодиоды кнопок================================================= void led_ini() { DDRC |= (1<<PA0) | (1<<PA1) | (1<<PA2); // Enable Step Dir PORTC &= ~(1<<PA0) | ~(1<<PA1) | ~(1<<PA2); // Enable Step Dir } //=========================================Обработчик кнопок================================================= void StartButton() { if (!(PINC&0b00000010)) { TCCR0 |= (1 << CS02); TCNT0 = 0; if (OverflowsRemainStartButton > 10) { TCCR0 &= ~(1 << CS02); OverflowsRemainStartButton = 0; if (!(PINC&0b00000010)) { if (StartButtonPressed == 0) { if (StartSet == 0) StartSet = 1; else { StartSet = 0; RightSet = 0; LeftSet = 0; } } StartButtonPressed = 1; } } } else StartButtonPressed = 0; } void LeftButton() { if (!(PINC&0b00000001)) { TCCR0 |= (1 << CS02); TCNT0 = 0; if (OverflowsRemainLeftButton > 10) { TCCR0 &= ~(1 << CS02); OverflowsRemainLeftButton = 0; if (!(PINC&0b00000001)) { if (LeftButtonPressed == 0) { if (LeftSet == 0) LeftSet = 1; else LeftSet = 0; } LeftButtonPressed = 1; } } } else LeftButtonPressed = 0; } void RightButton() { if (!(PINC&0b00000100)) { TCCR0 |= (1 << CS02);; TCNT0 = 0; if (OverflowsRemainRightButton > 10) { TCCR0 &= ~(1 << CS02); OverflowsRemainRightButton = 0; if (!(PINC&0b00000100)) { if (RightButtonPressed == 0) { if (RightSet == 0) RightSet = 1; else RightSet = 0; } RightButtonPressed = 1; } } } else RightButtonPressed = 0; } void StartButtonProg() { if (StartSet==1) { if (LeftSet == 1 || RightSet== 1) { PORTA |= (1<<PA1); //Включаем лед PORTD &= ~(1<<PD0); //Включаем DRV8825 MotorWork = 1; } } if (StartSet == 0) { PORTA &= ~(1<<PA1); //Выключаем лед PORTD |= (1<<PD0); //Выключаем DRV8825 MotorWork = 0; } } void LeftButtonProg() { if (LeftSet==1) { PORTA |= (1<<PA0); //Включаем лед } else { PORTA &= ~(1<<PA0); } } void RightButtonProg() { if (RightSet==1) { PORTA |= (1<<PA2); //Включаем лед } else { PORTA &= ~(1<<PA2); } } void Motor() { if (LeftSet == 1 || RightSet== 1) { if (MotorWork == 1) { if (OverflowsRemainMotorWork == 1) { OverflowsRemainMotorWork = 0; if (LeftSet == 1) PORTD |= (1<<PD2); if (RightSet == 1) PORTD &= ~(1<<PD2); PORTD ^= (1<<PD1); TCNT1 = 0; } } } } int main(void) { timer0_ini(); timer1_ini(); timer2_ini(); Encoder_Init(); button_ini(); DRV8825_ini(); led_ini(); SPI_init(); sei(); while (1) { StartButton(); LeftButton(); RightButton(); StartButtonProg(); LeftButtonProg(); RightButtonProg(); Encoder(); Motor(); ledprint(MotorSpeed); } }
×
×
  • Create New...