📄 rs232_receiver.c
字号:
#include <pic.h>
#include <conio.h>
#include <stdio.h>
#include "delay.c"
#include "delay.h"
__CONFIG(PWRTEN&WDTDIS&UNPROTECT&HS);
#define rx_pin GPIO1 // 1 wire input from RX module
/*************************************
* Tunable parameters
*/
/* Transmit and Receive port bits */
#define TxData GPIO2 /* bit2 in GP port */
#define RxData GPIO0 /* bit0 in GP port */
#define XTAL 4000000 /* Crystal frequency (Hz). */
#define BRATE 2400L /* Baud rate. */
#define RX_OVERSAMPLE 4 /* Amount of oversampling the receiver does.
Must be a power of two */
/*
* Don't change anything else
************************************/
#define TIMER_VALUE XTAL / (4 * BRATE * RX_OVERSAMPLE)
// 1 start bit + 8 data bits + 2 stop bits + safe.
#define TRANSMIT_NUM_BITS 13
#if ((TIMER_VALUE) < 90)
#error baud rate or oversample too high for crystal speed
#endif
#if ((TIMER_VALUE) > 256)
#error baud rate or oversample too low for crystal speed
#endif
#if (RX_OVERSAMPLE-1)&RX_OVERSAMPLE
#error RX_OVERSAMPLE_value must be a power of 2
#endif
// Receiver states.
enum receiver_state {
RS_HAVE_NOTHING,
RS_WAIT_HALF_A_BIT,
RS_HAVE_STARTBIT,
RS_WAIT_FOR_STOP = RS_HAVE_STARTBIT+8
};
static unsigned char sendbuffer; // Where the output char is stored.
static unsigned char receivebuffer; // Where the input char is stored as
// it is received.
static bit receivebufferfull; // 1 = receivebuffer is full.
static unsigned char send_bitno;
static unsigned char receivestate; // Initial state of the receiver (0)
static unsigned char skipoversamples; // Used to skip receive samples.
static unsigned char rxshift;
static bit tx_next_bit;
//////////////////////////
signed char e,f,g,k,z;
unsigned char rx_bitcount,rx_tempbyte,rx_status,id_status,crc_status;
bit rxbit,rxnewbyte,rxnewsequence;
unsigned char rxdelay,rxdelay_base;
unsigned char rx_byte_reg;
///////////////////////////
void rx_module_read(void); // rx module routines
void rx_get_bit(void);
void rx_seek_byte_start(void);
void rx_build_byte(void);
void rx_seek_sequence_start(void);
void del_count(void);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void putch(char c)
{
while(send_bitno)
continue;
tx_next_bit = 0;
sendbuffer = c;
send_bitno = TRANSMIT_NUM_BITS*RX_OVERSAMPLE;
}
char getch(void)
{
while(!receivebufferfull)
continue;
receivebufferfull = 0;
return receivebuffer;
}
/**
* serial_isr
*
* Transmits and receives characters which have been
* "putch"ed and "getch"ed.
*
* This ISR runs BRATE * RX_OVERSAMPLE times per second.
*
* */
interrupt void serial_isr(void)
{
// Reset Timer0 value
// This is added to TMR0 because there is a delay to get to the isr.
TMR0 += -TIMER_VALUE + 4; // +2 as timer stops for 2 cycles when writing
// to TMR0 +2 for tweak
T0IF = 0;
/*** RECEIVE ***/
if( --skipoversamples == 0) {
skipoversamples++; // check next time
switch(receivestate) {
case RS_HAVE_NOTHING:
// Check for start bit of a received char.
if(!RxData){
skipoversamples = RX_OVERSAMPLE/2;
receivestate++;
}
break;
case RS_WAIT_HALF_A_BIT:
if(!RxData) { // valid start bit
skipoversamples = RX_OVERSAMPLE;
receivestate++;
} else
receivestate = RS_HAVE_NOTHING;
break;
// case RS_HAVE_STARTBIT: and subsequent values
default:
rxshift = (rxshift >> 1) | (RxData << 7);
skipoversamples = RX_OVERSAMPLE;
receivestate++;
break;
case RS_WAIT_FOR_STOP:
receivebuffer = rxshift;
receivebufferfull = 1;
receivestate = RS_HAVE_NOTHING;
break;
}
}
/*** TRANSMIT ***/
/* This will be called every RX_OVERSAMPLEth time
* (because the RECEIVE needs to over-sample the incoming
* data). */
if(send_bitno) {
if((send_bitno & (RX_OVERSAMPLE-1)) == 0) {
TxData = tx_next_bit; // Send next bit.
tx_next_bit = sendbuffer & 1;
sendbuffer = (sendbuffer >> 1) | 0x80;
}
send_bitno--;
}
}
void main(void)
{ GIE = 0;
TRISIO=0x3B;
TxData=1;
CMCON0=0x07;
ANSEL=0;
receivestate = RS_HAVE_NOTHING;
skipoversamples = 1; // check each interrupt for start bit
receivebufferfull = 0;
// Set up I/O direction.
/* Set up the timer. */
T0CS = 0; // Set timer mode for Timer0.
TMR0 = (2-TIMER_VALUE); // +2 as timer stops for 2 cycles
// when writing to TMR0
T0IE = 1; // Enable the Timer0 interrupt.
rxdelay_base=52;
while(1) // continually
{
rx_module_read();
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// main rx_module_read subroutine:
void rx_module_read(void)
{
unsigned char rx_byte[3];
/*
rx_status=0; // reset rx_status to error code 0
id_status=0;
crc_status=0;
for (f=127;f>0;f--){ // loop ( CRC loop 127 f=127_ for hispeed f= minimum)
for (e=127;e>0;e--){
rx_seek_sequence_start();
if (rxnewsequence){e=0;f=0;} // end loop when rx_pin turns high
}
}
if (!rxnewsequence){rx_status=2;return;} // check: return if still no sequence_start, set rx_status to error code 2
*/
do {
rx_status=0;
id_status=0;
crc_status=0;
rx_seek_sequence_start();
} while(!rxnewsequence);
///////////////////////// receive & struct 5 bytes
for (g=0;g<3;g++){
rx_seek_byte_start();
if (rxnewbyte==0){rx_status=3;} // check: return if no rxnewbyte, set rx_status to error code 3
rx_build_byte();
rx_byte[g]=rx_tempbyte;
}
//rx_status=4; // set rx_status to code 4
if (rx_byte[0]==0xB6){crc_status=3;} else {crc_status=1;return;} // CRC MSB
if (rx_byte[1]==0xAC){crc_status=3;} else {crc_status=1;return;}
//rx_status=5; // set rx_status to code 5 // all data valid from here
rx_byte_reg=rx_byte[2];
GIE=1;
putch(rx_byte_reg);
GIE=0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void rx_seek_sequence_start(void) //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -