X-Virus-Scanned: amavisd-new at bezeqint.net
Hello, Alexey Belyaev! You wrote in conference fido7.ru.embedded to All on Tue, 28 Mar 2006 22:18:10 +0400:
AB> Мoжeт ecть y кoгo пpocтoй пpимepчик SoftUART для PIC? AB> Интepcyeт тoлкьo 1 линия AB> RX (пpиём инфы из внe co cтopoны МК). AB> Зapaнee cпacибo.
Вот из рабочего проекта надергал, мог чего-то недодергать, но идея ясна. Компилировалось для pic16 и pic18 в качестве второго uart'а.
typedef unsigned char byte;
#define RX_BUF_SIZE 16
static volatile byte rx_smpl_cntr; /* recevier sample counter */ static volatile byte rx_state; /* receiver state (bit number) */ static volatile byte rx_1; /* Rx One counter */ static volatile byte rx_0; /* Rx Zero counter */ static volatile byte rrx; /* receveing data */ static volatile byte tx_smpl_cntr; /* transmitter sample counter */ static volatile byte tx_state; /* transmitter state (bit number) */ static volatile byte txd; /* transmitted data */ static volatile char rx_buf[RX_BUF_SIZE]; /* receiver FIFO buffer */
static volatile byte rb_head; /* receiver FIFO buffer head pointer */ static volatile byte rb_tail; /* receiver FIFO buffer tail pointer */ static volatile bit rb_overlap; /* receiver FIFO buffer overlap flag */ static volatile bit rx_ok; /* 1 - receve complite */ static volatile bit tx_ok; /* 1 - transmit in progress */
void putch(byte c) { while (tx_ok == 1) { idle(); } txd = c; }
int tgetch(void) { int cx = -1;
/* get received byte from the fifo buffer */ if (rb_overlap == 0) /* get before head */ { if (rb_tail < rb_head) { cx = rx_buf[rb_tail]; rb_tail++; } /* else buffer_empty(); */ } else /* get after head */ { if (rb_head <= rb_tail) /* if there is byte(s) in the buffer */ { cx = rx_buf[rb_tail]; rb_tail++; } /* else buffer_empty(); */ if (rb_tail == RX_BUF_SIZE) /* cyling the buffer */ { rb_tail = 0; rb_overlap = 0; } } return cx; }
void interrupt sys_int(void) { volatile static byte __100msc; /* 100ms cyclic counter */ volatile static byte __70us; /* 70us resettable timer */ byte cc;
TMR0 = TMR0INIT + 8; /* Reload timer to 70us period */ T0IF = 0; /* Clear interrupt flag */
if (rx_ok == 0) { rx_smpl_cntr++;
if (TRx == 1) /* One detection */ { if (rx_1 < 255) rx_1++; /* One counter */ } else rx_1 = 0;
if (TRx == 0) /* Zero detection */ { if (rx_0 < 255) rx_0++; /* Zero counter */ } else rx_0 = 0;
if (rx_smpl_cntr == 0) { rx_state = 0; /* restart receiving */ rx_1 = 0; rx_0 = 0; rrx = 0; }
if (rx_state == 0) { rx_state = 1; /* start receiving */ rx_1 = 0; rx_0 = 0; rx_smpl_cntr = 0; rx_ok = 0; }
if ((rx_state == 1) && (rx_0 > 1) && (rx_smpl_cntr > 1)) { rx_state = 2; /* start bit detected */ rx_1 = 0; rx_0 = 0; rx_smpl_cntr = 0; }
/* data bits receiving */ if ((rx_state > 1) && (rx_state < 10) && (rx_smpl_cntr == 3)) { rx_state++; rrx >>= 1; if (rx_1 > 1) { rrx |= 0x80; /* Tst = 1; */ } rx_1 = 0; rx_0 = 0; rx_smpl_cntr = 0; }
if ((rx_state == 10) && (rx_smpl_cntr == 3)) /* stop bit detection */ { if (rx_1 > 1) { /* put received byte to fifo buffer */ if (rb_overlap == 0) /* put after tail */ { rx_buf[rb_head] = rrx; rb_head++; if (rb_head == RX_BUF_SIZE) /* cyling the buffer */ { rb_head = 0; rb_overlap = 1; } } else /* put before tail */ { if (rb_head < rb_tail) /* if thre is room for byte */ { rx_buf[rb_head] = rrx; rb_head++; } /* else buffer_full(); */ } } rx_state = 0; rx_1 = 0; rx_0 = 0; rx_smpl_cntr = 0; } }
/* mportb - PORTB mirror, MTx - Tx pin mask */ if (tx_ok == 1) { /* Start bit */ if ((tx_state == 0) && (tx_smpl_cntr == 1)) { /* TTx = 0; */ mportb &= ~MTx; }
/* data bits */ if ((tx_state > 0) && (tx_state < 9) && (tx_smpl_cntr == 1)) { if ((txd & 1) == 0) { /* TTx = 0; */ mportb &= ~MTx; } else { /* TTx = 1; */ mportb |= MTx; } txd >>= 1; }
/* first stop bit */ if ((tx_state == 9) && (tx_smpl_cntr == 1)) { /* TTx = 1; */ mportb |= MTx; }
/* second stop bit */ if ((tx_state == 11) && (tx_smpl_cntr == 1)) { /* TTx = 1; */ mportb |= MTx; tx_state = 0; tx_smpl_cntr = 0; tx_ok = 0; }
tx_smpl_cntr++; if (tx_smpl_cntr == 3) { tx_state++; tx_smpl_cntr = 0; } } else { /* keep Tx high after transmition */ tx_state = 0; tx_smpl_cntr = 0; /* TTx = 1; */ mportb |= MTx; }
}dima