В данном эксперименте попробуем исследовать такой замечательный модуль PIC микроконтроллеров как CCP(Capture/Compare/PWM).
Ну в общем приступим…
Исходя из названия модуля можно предположить, что он может:
1. Захватить
2. Сравнить
3. Зашимить
Продолжение внутри.
Главный здесь регистр ССP1CON:
CCP1X:CCP1Y — биты, про которые будет рассказано слегка попозже
CCP1M<3:0> — выбор режима:
0000 = все вырублено
0100 = захват, каждый ниспадающий импульс0101 = захват, по каждому возрастающему фронту
0110 = захват, по каждому 4 возрастающему фронту
0111 = захват, по каждому 16 возрастающему фронту
1000 = сравнение, перевод выходного пина в 1 при совпадении
1001 = сравнение, очистка выходного пина при совпадении
1010 = сравнение, генерация софтового прерывания
1011 = сравнение, переключение специального события (сам пока толком не понял что это за зверь)
11хх = режим ШИМ
Для начала рассмотрим модуль захвата:
В этом режиме содержимое регистров TMR1H и TMR1L копируется в регистры CCPR1H и CCP1L в следующих ситуациях: По каждому спаду на RB3 По каждому возрастающему импульсу на RB3 По каждому 4 возрастающему импульсу на RB3 По каждому 16 возрастающему импульсу на RB3 Для корректной работы модуля нужно соблюсти два условия: Пин RB3 должен быть сконфигурирован как вход TMR1 должен работать как таймер или как счетчик
По записи может происходить прерывание (флаг ССP1IF). Пример программы приводить не буду, т.к. тут надо еще подумать как извлекать инфу нужную (подключать дисплей и т.д., а это засорит код).
Сравнение: В этом режиме значение регистра CCP1 сравнивается со значением в регистре таймера TMR1. В случае совпадения величин может изменяться состояние порта RB3 или генерироваться прерывание Для корректной работы режима нужно обеспечить следующие условия: Порт RB3 должен быть сконфигурирован как выход Таймер TMR1 синхронизируется внутренним тактированием (Focs/4)
Составим небольшую программку для проверки работы компаратора, в данном примере будем генерировать импульсы шириной 1 мс. #include <htc.h> #define _XTAL_FREQ 4000000 __CONFIG(WDTDIS & UNPROTECT & MCLREN & LVPDIS); void main() { unsigned char x; __delay_ms(100); TRISB = 0x00; PORTB = 0x00; CCPR1H = 0b00000011; CCPR1L = 0b11101000; // 1000 in CCPR1 CCP1M3 = 1; // Сравнение, при совпадении генерим прерывание CCP1M2 = 0; CCP1M1 = 1; CCP1M0 = 0; T1CKPS1 = 0; T1CKPS0 = 0; // Prescaler = 0 T1OSCEN = 0; TMR1CS = 0; // Fosc/4 TMR1ON = 1; T1SYNC = 0; GIE = 1; PEIE = 1; CCP1IE = 1; for (;;) { } } void interrupt isr() { if (CCP1IF) { RB3 = !RB3; TMR1H = 0x00; TMR1L = 0x00; CCP1IF = 0; } }
Результат на осциллограмме из протеуса:
Источник: http://diymicro.ru/?p=90 |