Re: SoftUART для PIC

 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

formatting link

Reply to
Dmitry Orlov
Loading thread data ...

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.