Вот еще на днях сидел парился писал на ассеме
LIST P=PIC16F628A
#INCLUDE‹P16F628A.INC›
#INCLUDE"macro.asm" ;МАКРОСЫ ИНИЦИАЛИЗАЦИИ И СОХРАНЕНИЯ СТАТУСА И
;АКАМУЛЯТОРА ПРИ УХОДЕ В ПРЕРЫВАНИЯ
__CONFIG _INTRC_OSC_NOCLKOUT&_DATA_CP_OFF&_CP_OFF&_BODEN_OF F&_MCLRE_ON&_PWRTE_ON&_WDT_OFF&_LVP_OFF
;Программа для управления колектороного двигателя
;через ШИМ,можно управлять транзитором или оптопарой на тиристор.
;RB6,RB7-применяются для внутрисхемного програмирования
;RB1(RX),RB2(TX)-применяются для управления через компьютор
;RB3(CCP1)-выход с модуля шим
;Три кнопки вкл/выкл(RB4),'+'(RB5) и '-'(RB0)
;Светодиод показывает работу двигателя(мигает)RA2,
;при приеме от компа горит две сек постояно
;Внутрений генератор:при работе настроен на 4 Мгц,
;при останове двигателя и опросе кнопок 32Кгц
;ПЕРЕМЕНЫЕ
TEMP EQU 0X20
CBLOCK TEMP
VD_REG,USART_REG,HIM_REG,TEMP_2,TEMP_3
ENDC
STATUS_TEMP EQU 71H
W_TEMP EQU 72H
;Обозначим выводы
#DEFINE RX PORTB,1
#DEFINE TX PORTB,2
#DEFINE CCP PORTB,3
#DEFINE ON PORTB,4 ;ВКЛЮЧ И ВЫКЛЮЧ ДВИГАТЕЛЯ
#DEFINE PLUS PORTB,5
#DEFINE MINUS PORTB,0
#DEFINE OSC PCON,3 ;ВНУТРЕНИЙ ГЕНЕРАТОР
#DEFINE ZERO STATUS,Z
#DEFINE VDV VD_REG,0 ;ПО НЕМУ СМОТРЕМ ВКЛЮЧАТЬ ИЛИ НЕТ СВЕТОДИОД
#DEFINE VD1 PORTA,2
ORG 0
GOTO START
ORG 0X04
GOTO RET
;================================================= ======================
USART_INIT
;РАБОТАЕТ ТОЛЬКО НА ПРИЕМ И ОБРАБОТКУ ИНФОРМАЦИИ,ПРИ ВЫЗОВЕ ПРЕРЫВАНИЯ
;НАСТРОЙКА TXSTA
BANK_1
MOVLW 0X04 ; 04=0000 0100
MOVWF TXSTA
;НАСТРОЙКА СКОРОСТИ ПРИЕМА НА 9600 БИТ/СЕК
MOVLW .25
MOVWF SPBRG
;НАСТРОЙКА RCSTA
BANK_0
MOVLW 0X90 ; 90= 1001 0000
MOVWF RCSTA
;ВКЛЮЧАЕМ ПРЕРЫВАНИЕ ОТ USART
BANK_1
MOVLW 0X20 ; 20=0010 0000
MOVWF PIE1
BANK_0
MOVLW 0
MOVWF PIR1
MOVLW 0XC0 ; C0=1100 0000
MOVWF INTCON
RETLW 0
;================================================= ==============
HIM ;ВКЛЮЧЕНИЕ ШИМ
BANK_1
MOVLW .67 ; .67=0100 0011
MOVWF PR2 ;ЧАСТОТА 15 КГЦ
BSF PCON,OSCF ;ПЕРЕКЛЮЧАЕМ ГЕНЕРАТОР НА 4 МГЦ(RC)
MOVLW 0X04 ; 0X04=0000 0100
BANK_0
MOVWF T2CON
MOVLW 0X0C ; C=0000 1100
MOVWF CCP1CON
RETLW 0
;================================================= ===============
VD ;ВКЛЮЧАЕМ TMR1 ДЛЯ СВЕТОДИОДА ЧЕРЕЗ
MOVLW 0X31 ; 0X31=0011 0001 ;ПРЕРЫВАНИЯ
MOVWF T1CON
;ВКЛЮЧИМ ПРЕРЫВАНИЯ ОТ TMR1
BANK_1
MOVLW 0X01
IORWF PIE1
BANK_0
RETLW 0
;================================================= ===============
OFF ;ЕСЛИ НАЖАТА КНОПКА ON ТО ВЫКЛЮЧАЕМ ШИМ И ПРЕРЫВАНИЯ ОТ
;ТАЙМЕРА
BCF VD1 ;ВЫКЛЮЧЕНИЕ СВЕТОДИОДА
CLRW
MOVWF CCP1CON ;ОТКЛЮЧЕНИЕ ШИМ
BCF CCP
BANK_1
MOVLW 20H ; 20H=0010 0000
ANDWF PIE1 ; ОТКЛЮЧЕНИЕ ПРЕРЫВАНИЯ ОТ TMR1
BCF PCON,OSCF ;ПЕРЕКЛЮЧАЕМ ВНУТРЕНИЙ ГЕНЕРАТОР НА 32 КГЦ
BANK_0
GOTO SWITCH
;================================================= ================
ON_PLUS ;ПРИБАВЛЯЕМ ПО 5 К РЕГИСТРУ HIM_REG И ЗАПИСЫВАЕМ В
;ДВА МЛАДШИХ БИТА В CCP1CON,ОСТАЛЬНЫЕ В CCPR1L
MOVLW .270 ;ПРОВЕРЯЕМ РАВЕН ЛИ 70,ЕСЛИ ДА
SUBWF HIM_REG,W ;ТО БОЛЬШЕ НЕ ПРЕБАВЛЯЕМ
BZ END_PLUS
MOVLW .10
ADDWF HIM_REG,F
MOVF HIM_REG,W
MOVWF TEMP
BCF CCP1CON,5
BCF CCP1CON,4
;ПЕРВЫЙ СДВИГ И ПРОВЕРКА ФЛАГА С
RRF TEMP,F
SKPNC ;ПРОПУСК КОМАНДЫ ПРИ ОТСТУСТВИИ ПЕРЕНОСА
BSF CCP1CON,4
;ВОТРОЙ СДВИГ И ПРОВЕРКА ФЛАГА С
RRF TEMP,F
SKPNC ;ПРОПУСК КОМАНДЫ ПРИ ОТСТУСТВИИ ПЕРЕНОСА
BSF CCP1CON,5
;ПЕРЕНОС ОСТАВШЕГО ЧИСЛА В CCPR1L
BCF TEMP,6
BCF TEMP,7
MOVF TEMP,W
MOVWF CCPR1L
END_PLUS RETLW 0
;================================================= =====================
ON_MINUS;ОТНИМАЕМ ПО 5 К РЕГИСТРУ HIM_REG И ЗАПИСЫВАЕМ В
;ДВА МЛАДШИХ БИТА В CCP1CON,ОСТАЛЬНЫЕ В CCPR1L
MOVF HIM_REG,F ;ПРОВЕРЯЕМ РАВЕН ЛИ 70,ЕСЛИ ДА
;ТО БОЛЬШЕ НЕ ПРЕБАВЛЯЕМ
BZ END_MINUS
MOVLW .10
SUBWF HIM_REG,F
MOVF HIM_REG,W
MOVWF TEMP
BCF CCP1CON,5
BCF CCP1CON,4
;ПЕРВЫЙ СДВИГ И ПРОВЕРКА ФЛАГА С
RRF TEMP,F
SKPNC ;ПРОПУСК КОМАНДЫ ПРИ ОТСТУСТВИИ ПЕРЕНОСА
BSF CCP1CON,4
;ВОТРОЙ СДВИГ И ПРОВЕРКА ФЛАГА С
RRF TEMP,F
SKPNC ;ПРОПУСК КОМАНДЫ ПРИ ОТСТУСТВИИ ПЕРЕНОСА
BSF CCP1CON,5
;ПЕРЕНОС ОСТАВШЕГО ЧИСЛА В CCPR1L
BCF TEMP,6
BCF TEMP,7
MOVF TEMP,W
MOVWF CCPR1L
END_MINUS RETLW 0
;================================================= =======================
RET ;СОХРАНЯЕМ СТАТУС
PUSH
;ПРЕРЫВАНИЯ ОТ ПРИЕМНИКА USART И TMR1,ОПРЕДЕЛЯЕМ КАКОЕ ПРЕРЫВАНИЕ
CLRF STATUS ;БАНК НУЛЕВОЙ
BTFSC PIR1,0 ;ПРОВЕРЯЕМ БИТ ТАЙМЕРА TMR1
BZ TMR1_ON
USART_ON ;ЗНАЧИТ ПРЕРЫВАНИЕ ОТ USART
;POP
RETFIE
TMR1_ON ;ОБРАБОТКА ПРЕРЫВАНИЯ ОТ ТАЙМЕРА
INCF VD_REG
BTFSS VDV
BCF VD1 ;ВЫКЛЮЧЕНИЕ СВЕТОДИОДА
BTFSC VDV
BSF VD1
BCF PIR1,0
POP
retfie
;================================================= =========================
DELAY
;delay = 1'000'000 machine cycles
Pause movlw .254
movwf TEMP
movlw .17
movwf TEMP_2
movlw .6
movwf TEMP_3
wr decfsz TEMP, F
goto wr
clrwdt
decfsz TEMP_2, F
goto wr
decfsz TEMP_3, F
goto wr
nop
nop
RETLW 0
;================================================= ===========
START
;НАСТРОЙКА УПРАВЛЯЮЩИХ РЕГИСТРОВ
INIT ;МАКРОС УСТАНОВКИ СПЕЦ РЕГИСТОВ
;НАСТРОЙКА USART
CALL USART_INIT
CLRF VD_REG ;ОЧИСТКА РЕГИСТРА ДЛЯ СВЕТОДИОДА
CLRF HIM_REG ;ОЧИСТКА РЕГИСТРА ДЛЯ ШИМ
;ОПРОС КНОПОК..ВКЛ ЕСЛИ ХОТЬ ОДНА НАЖАТА ИЛИ ПОСТУПИЛА КОМАНДА
;С КОМПА
SWITCH BTFSS ON
GOTO ON_P
BTFSS PLUS
GOTO ON_P
BTFSS MINUS
GOTO ON_P
CLRWDT
GOTO SWITCH
;ВКЛЮЧАЕМ ШИМ И ОПРАШИВАЕМ КНОПКИ ОПЯТЬ
ON_P CALL HIM ;ВКЛЮЧЕНИЕ ШИМ,НАЧИНАЯ С НУЛЯ
CALL VD ;ВКЛЮЧИМ МИГАНИЕ СВЕТОДИОДА ЧЕРЕЗ ПРЕРЫВАНИЯ
;ТАЙМЕРА TMR1
MAIN ;ПРОВЕРКА НАЖАТАЙ КНОПКИ
BTFSS ON
GOTO OFF
BTFSS PLUS
CALL ON_PLUS
BTFSS MINUS
CALL ON_MINUS
CLRWDT
CALL DELAY
GOTO MAIN
END