#include <p18cxxx.h>
#include <delays.h>
#include <usart.h>
#include <timers.h>
#pragma config OSC=HS //20 MHz
#pragma config FCMEN=OFF
#pragma config IESO=OFF
#pragma config PWRT=OFF
#pragma config BOREN=OFF
#pragma config BORV=3
#pragma config WDT=OFF
#pragma config WDTPS=32768
#pragma config PBADEN=OFF
#pragma config LPT1OSC=OFF
#pragma config MCLRE=ON
#pragma config STVREN=ON
#pragma config LVP=OFF
#pragma config BBSIZ=1024
#pragma config XINST=OFF
#pragma config CP0=OFF
#pragma config CP1=OFF
#pragma config CPB=OFF
#pragma config CPD=OFF
#pragma config WRT0=OFF
#pragma config WRT1=OFF
#pragma config WRTC=OFF
#pragma config WRTB=OFF
#pragma config WRTD=OFF
#pragma config EBTR0=OFF
#pragma config EBTR1=OFF
#define RxPort PORTBbits.RB4
#define TxPort PORTBbits.RB0
#define RxTris TRISBbits.RB4
#define TxTris TRISBbits.RB0
//**********************************************************
#pragma udata
char BufferFromPC[13];
char cntLED;
char FlagRxD;
char RxBuffer;
#pragma code
void MyHighInt(void);
#pragma interrupt MyHighInt
#pragma code high_vector=0x08
void high_vector(void){
_asm GOTO MyHighInt _endasm
}
#pragma code
void MyLowInt(void);
#pragma interrupt MyLowInt
#pragma code low_vector=0x18
void low_vector(void){
_asm GOTO MyLowInt _endasm
}
#pragma code
void SetInterrupt(void);
void InitLedFlasher(void);
void Delay10400(void);
void TransmitUSART(char byte);
void InitUSART(void);
void DelayPol(void);
void main(void)
{
ADCON1=0x0f;
InitLedFlasher();
SetInterrupt();
InitUSART();
while(1)
{
if(FlagRxD)
{
TransmitUSART(RxBuffer);
FlagRxD=0;
}
}
}
void InitUSART(void)
{
RxPort=0;
TxPort=1;
RxTris=1;
TxTris=0;
FlagRxD=0;
INTCONbits.RBIE=1;
INTCONbits.GIE=1;
}
void TransmitUSART(char byte)
{
int i;
char shift=1;
INTCONbits.GIE=0;
TxPort=0;
Delay10400();
for(i=0;i<8;i++)
{
if(byte&shift) TxPort=1;
else TxPort=0;
Delay10400();
shift=shift<<1;
}
TxPort=1;
Delay10400();
INTCONbits.GIE=1;
}
void MyHighInt(void)
{
int i;
//Мигаем светодиодом
if(PIR1bits.TMR1IF)
{
PIR1bits.TMR1IF=0;
if(cntLED==18)
{
PORTCbits.RC3^=1;
cntLED=0;
}
cntLED++;
TMR1H=0x00;
TMR1L=0x00;
}
else if(INTCONbits.RBIF)
{
if(RxPort==0)
{
FlagRxD=1;
DelayPol();
for(i=0;i<8;i++)
{
Delay10400();
STATUSbits.C=0;
RxBuffer>>=1;
if(RxPort)
RxBuffer|=0x80;
}
Delay10400();
}
INTCONbits.RBIF=0;
}
}
void MyLowInt(void)
{
}
void InitLedFlasher(void)
{
TRISCbits.TRISC3=0;
TMR1H=0x00;
TMR1L=0x00;
T1CON=0b00110001;
cntLED=0;
}
//**************************************************************************************************
void SetInterrupt(void)
{
RCONbits.IPEN=1;
INTCONbits.GIE=1;
INTCONbits.PEIE=1;
PIE1bits.TMR1IE=1;
}
//**************************************************************************************************
void Delay10400(void)
{
Delay10TCYx(46);
}
void DelayPol(void)
{
Delay10TCYx(12);
}
;Скорость передачи 19200 бит в секунду
LIST P=16F628A
INCLUDE P16F628A.INC
__CONFIG _INTOSC_OSC_NOCLKOUT&_WDT_OFF&_PWRTE_ON&_MCLRE_OFF&_LVP_OFF
ERRORLEVEL -302
CBLOCK 20H
W_TEMP
STATUS_TEMP
TxByte
RxByte
Flags ;0-TxByte
;1-RxByte
;2-переполнение приемника
;3-ошибка приема
TxCount
RxCount
SCount
Byte
K
J
ENDC
Baudrate equ .10
#DEFINE TxPORT PORTB,0
#DEFINE RxPORT PORTB,4
#DEFINE TxTRIS TRISB,0
#DEFINE RxTRIS TRISB,4
BANK0 MACRO
BCF STATUS,RP0
BCF STATUS,RP1
ENDM
BANK1 MACRO
BSF STATUS,RP0
BCF STATUS,RP1
ENDM
ORG 0
GOTO START
ORG 4
CALL Recive
BCF INTCON,0
RETFIE
START MOVLW 7
MOVWF CMCON
CLRF PORTB
BSF TxPORT ; когда передачи нет - на линии висит 1
BANK1 ; Перейти в 1-й банк
BCF TxTRIS ; Настроить ножку на прием
BSF RxTRIS ; Настроить ножку на передачу
BANK0 ; Перейти в 0-й банк
CLRF Flags
BSF INTCON,RBIE ; Разрешить прерывания от RB4..RB7
BSF INTCON,GIE ; Разрешить все немаскированные прерывания
;****************** Основная часть программы ***************************************
MAIN
BTFSS Flags,1 ; ждем приема
GOTO MAIN
movfw RxByte ; считать принятый байт в аккумулятор
movwf Byte ; записать его в Byte
bcf Flags,1 ; сбросить флаг приемника
bcf INTCON,GIE ; запретить прерывания
movwf TxByte ; записать принятый байт в буффер передатчика
call Transmit ; передать байт
bsf INTCON,GIE ; разрешить прерывания
goto MAIN ; бесконечный цикл
;****************** Передача байта**************************************************
Transmit bsf Flags,0 ; устанавливаем флаг состояния передатчика в 1
movlw .8
movwf TxCount ; Счетчик переданных бит=8
bcf TxPORT ; Посылаем старт бит (=0)
Next_Tx call Delay ; Задержка соответствующая скорости передачи
btfss TxByte,0 ; Проверяем бит для посылки (посылаем биты от младшего к старшему)
goto Zero ; если 0 - идем сюда, если 1, пропуск-м эту команду
bsf TxPORT ; Посылаем единицу
goto One
Zero bcf TxPORT ; Посылаем ноль
One rrf TxByte,1 ; Переходим к следующему биту
decfsz TxCount,1 ; Уменьшаем счетчик переданных бит
goto Next_Tx ; Переходим к посылке следующего бита
call Delay ; Задержка для последнего бита
bsf TxPORT ; Посылаем стоп-бит
call Delay
clrf TxByte ; Очищаем регистр
bcf Flags,0 ; и сбрасываем флаг его состояния
return
Delay movlw Baudrate
movwf SCount
Next nop
decfsz SCount,F
goto Next
return
Delay2 movlw Baudrate
movwf SCount
bcf STATUS,0
rrf SCount,f
bcf STATUS,0
rrf SCount,1
Next2 nop
decfsz SCount,f
goto Next2
return
Delay1sec MOVLW 0xFF
MOVWF K
LOOPK MOVLW 0xFF
MOVWF J
LOOPJ DECFSZ J,F
GOTO LOOPJ
DECFSZ K,F
GOTO LOOPK
RETLW 0
;--- Прием байта (начинается автоматически после обнаружения старт-бита)
;--- после приема байта его надо считать из регистра приемника
;--- и сбросить флаг состояния приемника, иначе прием -----
;--- следующего байта вызовет переполнение ----------------
Recive MOVWF W_TEMP
SWAPF STATUS,W
BCF STATUS,RP0
MOVWF STATUS_TEMP
btfsc RxPORT ; если вход=0, то обнаружен старт-бит
goto Exit
btfsc Flags,1 ; проверяем - пуст ли приемник,
goto Err_overflow ; если нет - выставл. флаг переполн. и выходим
bsf Flags,1 ; ставим признак принятия посылки
movlw 8
movwf RxCount ; счетчик принятых бит=8
call Delay2 ; пауза = 1/4 длительности бита (чтобы
; читать бит ближе к середине, а не у фронта)
Next_Rx call Delay
bcf STATUS,C ; сбрасываем флаг cf
rrf RxByte ; сдвигаем регистр вправо
btfsc RxPORT ; если вход=1, то пишем 1, если нет - пропускаем
bsf RxByte,7 ; ставим бит=1
decfsz RxCount,F ; уменьш.счетчик и провер.- приняли 8 бит или нет
goto Next_Rx ; если нет - принимаем следующий бит
call Delay
btfsc RxPORT ; если вход=0, то стоп бит не пришел
goto Exit
bsf Flags,3 ; если стоп бит не пришел - ошибка приема
goto Exit
Err_overflow
bsf Flags,2 ; выставляем флаг переполнения
Exit
SWAPF STATUS_TEMP,W
MOVWF STATUS
SWAPF W_TEMP,F
SWAPF W_TEMP,W
RETURN
END