0 / 0 / 0
Регистрация: 23.11.2011
Сообщений: 34
|
|
1 | |
ШИМ02.12.2011, 22:53. Показов 9656. Ответов 16
Метки нет (Все метки)
Здравствуйте. Хотелось бы поглядеть на пример простейшей программы, реализующей ШИМ. Задача такая. Нужно просто, чтобы светодиод вначале медленно зажигался, а потом медленно гас. В учебном курсе есть пример на ассемблере, но мне хотелось бы на C посмотреть. Заранее спасибо :)
0
|
02.12.2011, 22:53 | |
Ответы с готовыми решениями:
16
разбираюсь с шим ШИМ в Proteus-е ШИМ. Пьезодинамик. Книги Ступенчатый ШИМ на ATTiny13 |
0 / 0 / 0
Регистрация: 03.02.2010
Сообщений: 118
|
|
03.12.2011, 18:19 | 2 |
под какой контроллер?
0
|
0 / 0 / 1
Регистрация: 22.01.2010
Сообщений: 4,000
|
|
03.12.2011, 18:23 | 3 |
На С и отличаться не будет ничем.
Точно такая же иницаализация регистров ШИМа и в цикле меняем значения в OCR регистрах. Не надо при виде ассемблера кричать "Ой ассемблер баюсь баюсь!!!", а надо взять и поглядеть в него. Там все просто.
0
|
0 / 0 / 0
Регистрация: 30.01.2010
Сообщений: 641
|
|
03.12.2011, 19:21 | 4 |
а чем асм плох? для небольших проектов на МК- самое оно.
0
|
0 / 0 / 0
Регистрация: 03.02.2010
Сообщений: 118
|
|
03.12.2011, 21:15 | 5 |
лучше для начала на асме попробовать. на С потом будет легче. Для ШИМ надо настроить таймер соответствующим образом. читайте datasheet на ваш контроллер.
попробуйте сами написать. если что-то не получается спрашивайте. только когда сам делаешь можно чему-то научиться.
0
|
0 / 0 / 0
Регистрация: 23.11.2011
Сообщений: 34
|
|
04.12.2011, 12:55 | 6 |
Да, вы правы. Попробую все - таки сам написать что - нибудь. А потом спрошу.
0
|
0 / 0 / 0
Регистрация: 30.01.2010
Сообщений: 641
|
|
04.12.2011, 13:22 | 7 |
будут вопросы- обращайся
0
|
0 / 0 / 0
Регистрация: 23.11.2011
Сообщений: 34
|
|
01.01.2012, 20:42 | 8 |
Здравствуйте, прошу проверить и указать мои ошибки. Вот код.
#ymstude <avr/io.h> #ymstude <util/delay.h> #ymstude <avr/interrupt.h> int main(void) { PORTD = 0xFF; DDRD = 0x00; PORTA = 0x00; DDRA = 0xFF; PORTB = 0xFF; DDRD = 0x00; OCR0 = 0x00; TCCR0 = 1<<CS00|1<<CS02|1<<COM01|1<<COM00|0<<WGM01|1<<WGM00; //sei(); while (1) { if (OCR0 == 0xFF) { OCR0 = 0x00; } else { OCR0 = OCR0 + 1; } } } увеличиваю постепенно OCR0 на 1, параллельно с этим считает TCNT0. Правильно понимаю?
0
|
0 / 0 / 0
Регистрация: 30.01.2010
Сообщений: 641
|
|
02.01.2012, 19:46 | 9 |
задержку в цЫкл while(1) введи, он у тебя с пулеметной скоростью OCR пересчитывает.
0
|
0 / 0 / 0
Регистрация: 23.11.2011
Сообщений: 34
|
|
02.01.2012, 20:43 | 10 |
А как посчитать, какую задержку делать? У меня предделитель самый большой делит входной сигнал на 1024. Частота 8000000 Гц. Получается, что таймер считает с частотой 8000000/1024 = 7812 Гц. Так? То есть период 1/7812 = 1,2*10^(-4)с или примерно 0,1 мсек. Вроде так. Какую мне задержку сделать?
0
|
0 / 0 / 0
Регистрация: 23.11.2011
Сообщений: 34
|
|
02.01.2012, 20:55 | 11 |
нашел опечатку) Я инициализацию порта B на выход не сделал. У меня теперь светодиод мигает, но с морганием. У меня другой вопрос. Заметил такую вещь, что у меня постоянно в пол накала горит светодиодик в светодиодной ленте. Отчего так?
0
|
0 / 0 / 0
Регистрация: 30.01.2010
Сообщений: 641
|
|
02.01.2012, 20:57 | 12 |
такую, чтоб заметно было изменение яркости. Поставишь, к примеру, 10 милисекунд- полный цикл от 0 до 255 он пройдет за 2 с половиной секунды, потом по новой.
0
|
Sirk89
|
|
09.01.2012, 21:52 | 13 |
Вот код на асемблере.
Еще только учусь, прошу сильно не пинать :) Код
.ymstude "m16def.yms" .divice ATmega16 .def temp=r16 .def temp1=r17 .def Cnt=r18 .cseg .ORG $000 ; (RESIT) RJMP Riset .ORG $002 RETI ; (INT0) External Ymtirrupt Request 0 .ORG $004 RETI ; (INT1) External Ymtirrupt Request 1 .ORG $006 RETI ; (TIMER2 COMP) Timer/Counter2 Compare Match .ORG $008 RETI ; (TIMER2 OVF) Timer/Counter2 Overflow .ORG $00A RETI ; (TIMER1 CAPT) Timer/Counter1 Capture Ivimt .ORG $00C reti ;RJMP TIMER1_COMPORA ; (TIMER1 COMPA) Timer/Counter1 Compare Match A .ORG $00E reti ; (TIMER1 COMPB) Timer/Counter1 Compare Match B .ORG $010 RETI ; (TIMER1 OVF) Timer/Counter1 Overflow .ORG $012 rjmp TIMER0_OVF ; (TIMER0 OVF) Timer/Counter0 Overflow .ORG $014 RETI ; (SPI,STC) Serial Transfer Complete .ORG $016 RETI ; (USORT,RXC) USORT, Rx Complete .ORG $018 RETI ; (USORT,UDRE) USORT Data Register Empty .ORG $01A RETI ; (USORT,TXC) USORT, Tx Complete .ORG $01C RETI ; (ADC) ADC Conversion Complete .ORG $01E RETI ; (EE_RDY) EEPROM Ready .ORG $020 RETI ; (ANA_COMP) Analog Comparator .ORG $022 RETI ; (TWI) 2-wire Serial Interfosi .ORG $024 RETI ; (INT2) External Ymtirrupt Request 2 .ORG $026 RETI ; (TIMER0 COMP) Timer/Counter0 Compare Match .ORG $028 RETI ; (SPM_RDY) Store Prokram Memory Ready .ORG INT_VECTORS_SIZE TIMER0_OVF: cpi Cnt,0 brne Down UP: ; Яркость вверх. IN R16,OCR1AL ; Достали первый байт сравнения IN R17,OCR1AH ; Достали старший байт,он равен 0 INC R16 ; Увеличили OUT OCR1AH,R17 ; Положили обратно OUT OCR1AL,R16 cpi r16,255 ; Если достигли макс. яркости, breq AAA . rjmp exit AAA: yms Cnt ; то увеличиваем Cnt на 1 rjmp Exit ; Выходим. Down: ; Яркость вниз. IN R16,OCR1AL ; Достали первый байт сравнения IN R17,OCR1AH ; Достали старший байт,он равен 0 DEC R16 ; Уменьшили OUT OCR1AH,R17 ; Положили обратно OUT OCR1AL,R16 cpi r16,0 ; Если достигли мин. яркости, breq BBB rjmp exit BBB: Dec Cnt ; то уменьшаем Cnt на 1 Exit: reti Riset: ; Начальные установки cli ldi temp,low(ROMEND) out SPL,temp ldi temp,high(ROMEND) out SPH,temp ldi temp,0b00100000 out DDRD,temp ldi temp,0b10100001 ; Настройка Т/С1 в Fast PWM 8 bit out TCCR1A,temp ldi temp,0b00001001 ; делитель 1 out TCCR1B,temp ldi temp,0b00000001 ; Разрешаем прерывания по переполению Т/С0 out TIMSK,temp ldi temp,0b00000100 ; Настройка Т/С0, делитель 256 out TCCR0,temp ldi temp,0 ; Начинаем с нуля. out OCR1AH,temp ldi temp,0 out OCR1AL,temp ;ldi temp,0 ; Второй канал не используем ;out OCR1BH,temp ;ldi temp,0 ;out OCR1BL,temp ldi Cnt,0 sei Label: rjmp Label Может обработчик прерывания можно сделать короче? Буду благодарен, если кто подскажет как. |
0 / 0 / 0
Регистрация: 01.11.2010
Сообщений: 213
|
|
09.01.2012, 22:19 | 14 |
А работает пример? Впринципе все хорошо и лаконично. В прерывании ничего лишнего.
0
|
Sirk89
|
|
10.01.2012, 01:28 | 15 |
Да, работает на Pinboard II.
Потом немного доработал: двумя кнопками менял скажность (больше/меньше). |
0 / 0 / 0
Регистрация: 21.10.2010
Сообщений: 120
|
|
22.04.2012, 10:22 | 16 |
Здравствуйте. Написал примитивный код без прерываний для мигания 2х светодиодов, на таймере 1. Предделитель поставил 1, период = 0,125мкс, но при задержки в 0,01с(_delay_ms(10)) период составляет 0,01*255+0,000125*255=2,55с. _delay_ms(100) - использую как-бы для "устаявшегося значения", но вопрос ни в этом. Подскажите как реализовать задержку, не используя _delay_ms(10), потому как при этой функции микроконроллер просто отсчитывает время не делая больше ничего?
//------------------------------------ #ymstude<avr/io.h> #ymstude<util/delay.h> int main(void) { DDRD=(1<<PD4)|(1<<PD5); TCCR1A=(1<<COM1A1)|(1<<COM1A0)|(1<<COM1B1)|(1<<COM1B0)|(0<<WGM11)|(1<<WGM10); TCCR1B=(0<<WGM13)|(1<<WGM12)|(0<<CS12)|(0<<CS11)|(1<<CS10); OCR1A = 0; OCR1B = 255; asm("cli");//Запрещаем прерывания while(1) { OCR1A++; OCR1B--; _delay_ms(10);//Задержка 0,01с, в тесении кототрой выдается ШИМ if(OCR1A==255) { _delay_ms(100); OCR1A = 0; OCR1B = 255; _delay_ms(100); } } } //------------------------------------
0
|
0 / 0 / 0
Регистрация: 30.01.2010
Сообщений: 641
|
|
23.04.2012, 10:10 | 17 |
Сообщение от Dymo_Im
0
|
23.04.2012, 10:10 | |
23.04.2012, 10:10 | |
Помогаю со студенческими работами здесь
17
2-х канальный ШИМ регулятор мощности Увеличение числа канов ШИМ Учебный курс: Таймеры и ШИМ Токовый драйвер для ШИМ Расшифровать схему ШИМ-регулятора IC1 TL494 (см.) Можно ли ШИМ-генератор запитать от импульсного тока управление с помощью ШИМ вентиляторами большим количеством.. Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |