#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