//************************************************ ******** / / *********** PWM DC MOTOR CONTROL с ИК ************* //************************************************ ******** / / Контроллер: ATmega8 (1MHz внутренних Crystal) / / Компилятор: ICCAVR / / Автор: ЗАО Dharmani, Ченнаи (Индия) / / Дата: Dec 2008 //************************************************ ******** / / эта программа использует два из трех каналов PWM (OC1A И OC1B) / / Из ATmega8, для контроля скорости И направление двигателя / / В отдаленных от телевизора Sony был использован для передачи ИК-коды //************************************************ *********************** / / ************** Заголовочный файл PWM_main.h ***************** //************************************************ *********************** # определить DIRECTION_FORWARD! (PIND И 0x20) # определить DIRECTION_REVERSE (PIND И 0x20) # определить STOP_MOTOR TCCR1B = 0x00; TCCR1A = 0x00 # определить START_MOTOR TCCR1B = 0x09 # определить set_FORWARD TCCR1A = 0x81 # определить set_REVERSE TCCR1A = 0x21 # определить ENABLE_INT0 GICR | = 0x40 # определить DISABLE_INT0 GICR И = ~ 0x40 / / определение макросов для установления минимального и максимального значений PWM борьбе / / и размер шага для контроля напряжения, применяемые для МОП базы # определить COUNTER_LOWER_LIMIT 0x0070 # определить COUNTER_UPPER_LIMIT 0x00f8 # определить STEP_SIZE 0x0008 port_init недействительным (недействительными); timer0_init недействительным (недействительными); timer1_init недействительным (недействительными); Неподписанный INT read_IR (недействительными); недействительным motorControl (неподписанный код символа, символа неподписанными адрес); init_devices недействительным (недействительными); недействительным delay_ms (INT miliSec); # включить # включить # включить "PWM_main.h" //************************************************ *********************** / / ************** Исходный файл PWM_main.c ***************** //************************************************ *********************** //************************************************ ********************* / / Инициализация функции для портов, timer0 И Timer1 //************************************************ ********************* port_init недействительным (недействительными) ( PORTB = 0x00; DDRB = 0x06 / / PWM штырям OC1A И OC1B определяется как выход PORTC = 0x00; DDRC = 0x20 / / светодиодных для обнаружения ИК указание PORTD = 0x00; DDRD = 0x01 / / LED, для теста ) / / timer0 инициализации timer0_init недействительным (недействительными) ( / / 8-разрядных таймера для измерения времени между импульсами ИК TCCR0 = 0x03 / / CLK / 64 TCNT0 = 0; / / сброса таймера ) / / Инициализация Timer1 - prescale: 1 / / PWM частота: 1кГц timer1_init недействительным (недействительными) ( TCCR1B = 0x00; / / остановка TCNT1H = 0xFC / / установка TCNT1L = 0x18; OCR1A = COUNTER_LOWER_LIMIT; OCR1B = COUNTER_LOWER_LIMIT; ICR1H = 0x03; ICR1L = 0xE8; ) /************************************************* ************************* * Interrupt службе Регулярно для INT0 * Исполняла когда удаленный код распознается ************************************************** ************************/ # Pragma interrupt_handler int0_isr: 2 int0_isr недействительным (недействительными) ( Неподписанный символ рассчитывать, код, адрес; Неподписанный INT IR_input; TCNT0 = 0; в то время как (! (PIND И 0x04)); кол = TCNT0; если (кол <30) / / для начала проверить пульс (2,4 мс длинные) ( delay_ms (20); ENABLE_INT0; возвращение; ) PORTC | = 0x20; IR_input = read_IR (); Код = (беззнаковое знаков) ((IR_input И 0xff00)>> 8); адрес = (беззнаковое знаков) (IR_input И 0x00ff); motorControl (код, адрес); PORTC И = ~ 0x20; delay_ms (250); ) //************************************************ ********************* / / Функция чтения сообщений из ИК детектор / / Возвращаемое значение содержит код в верхнем байте и адрес в нижнем байт //************************************************ ********************* Неподписанный INT read_IR (вакуума) ( Неподписанный символ pulseCount = 0, код = 0, адрес = 0, timerCount; Неподписанный INT IR_input; а (pulseCount <7) ( а (PIND И 0x04); TCNT0 = 0; в то время как (! (PIND И 0x04)); pulseCount + +; timerCount = TCNT0; если (timerCount> 14) Код = код | (1 <<(pulseCount-1)); еще Код = код И ~ (1 <<(pulseCount-1)); ) pulseCount = 0; а (pulseCount <5) ( а (PIND И 0x04); TCNT0 = 0; в то время как (! (PIND И 0x04)); pulseCount + +; timerCount = TCNT0; если (timerCount> 14) адрес = адрес | (1 <<(pulseCount-1)); еще адрес адрес И = ~ (1 <<(pulseCount-1)); ) IR_input = (((беззнаковое INT-код)) <<8) | адрес; возвращение (IR_input); ) //************************************************ **************************** / / Функция контроля скорости автотранспортных И направление в зависимости onthe ИК код rceived / / Argumets имеют код и адрес ценности, полученные от ИК-детектор //************************************************ **************************** недействительным motorControl (неподписанный код символа, символа неподписанными адрес) ( статических характеристик неподписанными борьбы, реже, DIR1; если (адрес! = 1) / / обнаружить только ТВ отдаленных другие сигналы отклонили возвращение; если ((код == 16) | | (код == 17)) / / Канал + "или" Канал-кнопка нажата ( если (код == 16) / / Канал + реж = 0; другое / / канала реж = 1; если (реже! = DIR1) / / изменить направление ( STOP_MOTOR; delay_ms (500); если (реже == 0) set_FORWARD; еще set_REVERSE; START_MOTOR; DIR1 = реж; ) ) если (код == 18) / / Том-кнопка нажата ( если (счетчик> = COUNTER_UPPER_LIMIT) / / если скорость уже максимальная, не делайте ничего борьбы = COUNTER_UPPER_LIMIT; еще противодействия + = STEP_SIZE / / увеличить скорость за счет фиксированного шага OCR1A = борьбы; OCR1B = борьбы; ) если (код == 19) / / Том + кнопка нажата ( если (счетчик <= COUNTER_LOWER_LIMIT) / / если скорость уже минимум, не делать ничего борьбы = COUNTER_LOWER_LIMIT; еще -= борьбе STEP_SIZE / / уменьшить скорость за счет фиксированного шага OCR1A = борьбы; OCR1B = борьбы; ) если (код == 9) / /'0 'кнопка нажата ( OCR1A = COUNTER_LOWER_LIMIT; OCR1B = COUNTER_LOWER_LIMIT; STOP_MOTOR; ) если (код == 0) / /'1 'кнопка нажата ( OCR1A = COUNTER_LOWER_LIMIT; OCR1B = COUNTER_LOWER_LIMIT; TCCR1A = 0x81; START_MOTOR; ) ) //************************************************ ************ //*** Называем это обычные для инициализации все периферийные //************************************************ ************ init_devices недействительным (недействительными) ( / / остановить странствующий прерывания до тех пор, пока создали CLI (); / / Отключить все прерывания port_init (); timer0_init (); timer1_init (); MCUCR = 0x02; GICR = 0x40; TIMSK = 0x00 / / таймер прерывает источники SEI (); / / снова включить прерываниями / / все периферийные сейчас инициализированные ) //************************************************ ************ //***** Функции SOFTWARE задержки 1 мс (appx.) ******* //************************************************ ************ недействительным delay_ms (INT miliSec) / / 1 МГц для кристалла ( INT I, J; для (i = 0; I