Кто работал с PIC? В частности, с P12F683 - есть вопрос по ШИМ

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Приветствую!

Вчера долго и упорно бился с ШИМ на указанном камне, а именно P12F683. Задача простая - прочитать с АЦП (10 бит разрешение) и вдуть это в ШИМ, тоже 10 бит хочется. В даташите сказано, что десятибитное разрешение ШИМ достигается при помощи регистра CCPR1L и битов 5,4 регистра CCP1CON. Вроде бы всё просто, однако и на симуляции в протеусе, и в железе - ощущение, что шагов дискретности ШИМ всё равно остаётся 256. Собственно, вся "прошивка":

#include <P12F683.INC>
LIST        p=12F683    
__CONFIG    H'30C4'        
                                                
Sec           equ         0020h  
Sec1          equ         0021h

RST   code  0x0 
goto  Start

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Основная программа

Start         bsf         STATUS,RP0
              movlw       b'01100001'     ;установка тактовой частоты микроконтроллера 
              movwf       OSCCON          ;в 4 МГц, внутренний тактовый генератор
              bcf         STATUS,RP0      ;
                                          ;
              movlw       b'00100000'     ;запись нулей в выходные защелки
              movwf       GPIO            ;
                                          ;
              movlw       0x07            ;выключение компараторов
              movwf       CMCON0          ;
                                          ;
              bsf         STATUS,RP0      ;
              movlw       b'11001001'     ;настройка линии GP2 на выход для модуля ШИМ,  
              movwf       TRISIO          ;остальные линии на вход
              movlw       b'01010001'     ;установка времени преобразования для АЦП 
              movwf       ANSEL           ;Tad = 4мкс (Fosc/16), настройка линии
              bcf         STATUS,RP0      ;GP0(AN0) как аналоговый вход для АЦП, остальные
                                          ;линии цифровые входы

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;настройка модуля АЦП
                          
              movlw       b'00000000'     ;Установка левого выравнивания результата АЦП,  
              movwf       ADCON0          ;внутренний источник опорного напряжения от Vdd,
                                          ;выбор аналогового канала AN0, преобразование
                                          ;не запущено, модуль АЦП выключен

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;настройка модуля ШИМ

              bsf         STATUS,RP0      ;
              movlw       .255            ;запись числа 255 в регистр периода ШИМ 
              movwf       PR2             ; 
              bcf         STATUS,RP0      ;
                                          ;
              movlw       .0              ;запись нулей в регистры длительности импульса 
              movwf       CCPR1L          ;ШИМ, CCPR1L и CCP1CON(5:4)
              bcf         CCP1CON,4       ; 
              bcf         CCP1CON,5       ;
                                          ;
              movlw       b'00000110'     ;установка предделителя TMR2 (1:16) 
              movwf       T2CON           ;включение таймера TMR2
                                          ;
              movlw       b'00001100'     ;включение CCP1 модуля в режим ШИМ  
              movwf       CCP1CON         ;при этом ранее сброшенные младшие биты (5:4)
                                          ;длительности импульса ШИМ не меняем

              bsf         ADCON0,ADON
begin         bsf         ADCON0,GO_DONE

prov          btfsc       ADCON0,GO_DONE
              goto        prov 
             			 
			MOVF	ADRESH,W	; читаем старший байт с АЦП
			MOVWF	CCPR1L
			
             bcf         CCP1CON,4       ; очищаем два дополнительных бита разрядности ШИМ
             bcf         CCP1CON,5       ;

			BTFSC	ADRESL,7	; пишем первый бит
			BSF	CCP1CON,5
			BTFSC	ADRESL,6 ; пишем второй бит
			BSF	CCP1CON,4

            call        pause
            goto        begin
            

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;пауза 100 мс

pause         movlw       .130            ;
              movwf       Sec1            ;
p2            movlw       .255            ;
              movwf       Sec             ;
p1            decfsz      Sec,F           ;
              goto        p1              ; 
              decfsz      Sec1,F          ; 
              goto        p2              ;
              return                      ;
                                          ;   

              END

Ассемблер PIC'а в глаза увидел только вчера - друг попросил увеличить дискретность регулировки, бились вчера до полночи, какая-то хрень получается. Подозреваю, что я где-то чего-то не учёл из самого очевидного. Подскажите, плз, где и что.

ssss
Offline
Зарегистрирован: 01.07.2016

DIYMan пишет:

В даташите сказано, что десятибитное разрешение ШИМ достигается при помощи регистра CCPR1L и битов 5,4 регистра CCP1CON. Вроде бы всё просто, однако и на симуляции в протеусе, и в железе - ощущение, что шагов дискретности ШИМ всё равно остаётся 256.

А зачем гадать? Подключите анализатор или ослика и всё сразу станет ясно. Для начала можно убрать АЦП и вывести в ШИМ минимальное и максимальное значение. Никаких там подводных камней нет. Главное в банках не запутаться.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

ssss пишет:

А зачем гадать? Подключите анализатор или ослика и всё сразу станет ясно. Для начала можно убрать АЦП и вывести в ШИМ минимальное и максимальное значение. Никаких там подводных камней нет. Главное в банках не запутаться.

Мы, как у русских водится, гадаем - у мну нет PIC'а, зато я чуть-чуть могу разобраться, что к чему. У приятеля есть PIC, он сидит от меня за пару сотен км, и мы удалённо это дело пытаемся побороть. Он утверждает, что разницы со старым кодом, когда был 8-мибитный ШИМ - нет никакой. Вот что с него взять? :)

mnashe
Offline
Зарегистрирован: 29.08.2016

Ошибок не вижу.
Хотя я сам делаю не так. Вместо

        bcf     CCP1CON,4
        bcf     CCP1CON,5
        btfsc   ADRESL,7
        bsf     CCP1CON,5
        btfsc   ADRESL,6
        bsf     CCP1CON,4

у меня так:

        rrf     ADRESL,w
        movwf   temp_var
        rrf     temp_var,w
        andlw   0x30
        iorlw   0x0C
        movwf   CCP1CON

Но вроде и тот вариант должен работать.
Можно попробовать заменить на мой, если тот точно почему-то не работает.

А вообще, маловато данных. Вопрос, куда выводится PWM и откуда читается АЦП. Загвоздка может быть в разрешении аппаратуры. Я с таким сталкивался: ШИМ шёл на драйвер светодиодов AP3031, а драйвер светодиодов включался только начиная с некоторого минимального duty cycle (правда, разница между 5/1024 и 6/1024 всё же была заметна, просто драйвер полностью выключался при значениях меньше 5/1024).