单片机pic24GPIO模拟uart发送

2019-04-15 11:57发布

单片机pic24GPIO模拟uart发送

我们经常遇到那种uart资源不够的情况,这时就需要使用gpio来模拟uart资源。下面就是使用两个定时器和两个gpio来完成模拟。
‘’’
void debug_uart_init (uint32_t baudrate)
{ // debug_uart_baudrate = baudrate; UartObjDebug.read_pos = UartObjDebug.recv_pos = 0; UartObjDebug.send_len = 0; T3CONbits.TON = 0; TMR3 = 0x0000; PR3 = 60000000ul/8/baudrate-1; //这里系统时钟是60M T3CON = 0x0010; IFS0bits.T3IF = 0; IEC0bits.T3IE = 0; T4CONbits.TON = 0; TMR4 = 0x0000; recv_div6_pr = 60000000ul/baudrate/6-1; recv_div3_pr = 60000000ul/baudrate/3-1; PR4 = recv_div6_pr; T4CON = 0x0000; IFS1bits.T4IF = 0; IEC1bits.T4IE = 0; IFS1bits.INT1IF = 0; INTCON2bits.INT1EP = 1; IEC1bits.INT1IE = 1; }
void debug_soft_uart_recv_restart(void)
{ T4CONbits.TON = 0; TMR4 = 0x0000; PR4 = recv_div6_pr; T4CON = 0x0000; IEC1bits.T4IE = 0; IFS1bits.INT1IF = 0; INTCON2bits.INT1EP = 1; IEC1bits.INT1IE = 1; } INT8U parity_even_bit(INT8U val)
{ val = ((val >> 4) | (val << 4)) ^ val; val = (val >> 2) ^ val; val = (val >> 1) ^ val; return (val & 0x01); }
INT8U parity_odd_bit(INT8U val)
{ val = ((val >> 4) | (val << 4)) ^ val; val = (val >> 2) ^ val; val = (val >> 1) ^ val; val = ~val; return (val & 0x01); }
void attribute ( ( interrupt, no_auto_psv ) ) _T3Interrupt ( )
{
//debug uart 发送处理 INT8U cur_byte,cur_bit,parity; static uint8_t send_state=0; cur_byte = *UartObjDebug.send_ptr; if(send_state == 0) { send_state ++; LATCbits.LATC9 = 0; } else if((send_state > 0) && (send_state < 9)) { cur_bit = ((cur_byte >> (send_state - 1)) & 0x01); send_state++; if(cur_bit == 1) { LATCbits.LATC9 = 1; } else { LATCbits.LATC9 = 0; } } else if(send_state == 9) { // if(InfraMode == USART_8N1)
// {
// LATCbits.LATC9 = 1;
// send_state += 2;
// }
// else if(InfraMode == USART_8O1)
// {
// send_state++;
// parity = parity_odd_bit(cur_byte);
// if(parity)
// {
// LATCbits.LATC9 = 1;
// }
// else
// {
// LATCbits.LATC9 = 0;
// }
// }
// else //???
{ send_state++; parity = parity_even_bit(cur_byte); if(parity) { LATCbits.LATC9 = 1; } else { LATCbits.LATC9 = 0; } } } else if(send_state <= 11) { send_state++; LATCbits.LATC9 = 1; } else { send_state = 0; UartObjDebug.send_ptr ++; UartObjDebug.send_len --; if(UartObjDebug.send_len == 0) { T3CONbits.TON = 0; IEC0bits.T3IE = 0; } } IFS0bits.T3IF = 0; } void attribute ( ( interrupt, no_auto_psv ) ) _T4Interrupt ( )
{ const INT8U samp_vas[8] = {0,0,0,1,0,1,1,1}; static uint8_t Infra_recv_state=0; INT8U recv_bit; static INT8U sample_bit; static INT8U bit_buf; static INT8U check_bit; IFS1bits.T4IF = 0; //debug uart 接收处理 recv_bit = PORTCbits.RC8; if((Infra_recv_state == 1)||(Infra_recv_state == 0)) { PR4 = recv_div3_pr; sample_bit = 0; if(recv_bit) { sample_bit++; } Infra_recv_state = 3; } else if(Infra_recv_state == 2) { sample_bit <<= 1; if(recv_bit) { sample_bit++; } Infra_recv_state++; } else if(Infra_recv_state == 3) { sample_bit <<= 1; if(recv_bit) { sample_bit++; } if(samp_vas[sample_bit] == 0) { bit_buf = 0; Infra_recv_state += 2; sample_bit = 0; } else { Infra_recv_state = 0; debug_soft_uart_recv_restart(); } } //state = 5,6,7,9,10,11,13,14,15......33,34,35; else if((Infra_recv_state > 3) && (Infra_recv_state < 37)) { sample_bit <<= 1; if((Infra_recv_state & 0x03) == 1) { Infra_recv_state++; if(recv_bit) { sample_bit++; } } else if((Infra_recv_state & 0x03) == 2) { Infra_recv_state++; if(recv_bit) { sample_bit++; } } else if((Infra_recv_state & 0x03) == 3) { Infra_recv_state += 2; bit_buf >>= 1; if(recv_bit) { sample_bit++; } if(samp_vas[sample_bit] == 1) { bit_buf |= 0x80; } sample_bit = 0; } else { Infra_recv_state = 0; debug_soft_uart_recv_restart(); } } else if((Infra_recv_state >= 37) && (Infra_recv_state < 40)) //43 { // if(InfraMode == USART_8N1)
// {
// Infra_recv_state = 41;
// }
// else { sample_bit <<= 1; if((Infra_recv_state & 0x03) == 1) { Infra_recv_state++; if(recv_bit) { sample_bit++; } } else if((Infra_recv_state & 0x03) == 2) { Infra_recv_state++; if(recv_bit) { sample_bit++; } } else if((Infra_recv_state & 0x03) == 3) { Infra_recv_state++; if(recv_bit) { sample_bit++; } if(samp_vas[sample_bit] == 1) { check_bit = 1; } else { check_bit = 0; } sample_bit = 0; } else { Infra_recv_state = 0; check_bit = 0; debug_soft_uart_recv_restart(); } } } else if((Infra_recv_state >= 40) && (Infra_recv_state < 41)) { Infra_recv_state ++; } else if(Infra_recv_state >= 41) { // if(InfraMode == USART_8N1)
// {
// DrvInfraChannel.recv_buffer[DrvInfraChannel.recv_ptr ++] = bit_buf;
// }
// if(InfraMode == USART_8O1)
// {
// if(check_bit == parity_odd_bit(bit_buf))
// {
// DrvInfraChannel.recv_buffer[DrvInfraChannel.recv_ptr ++] = bit_buf;
// }
// }
// else { if(check_bit == parity_even_bit(bit_buf)) { UartObjDebug.recv_buf[UartObjDebug.recv_pos] = bit_buf; UartObjDebug.recv_pos ++; if(UartObjDebug.recv_pos >= sizeof(UartObjDebug.recv_buf)) { UartObjDebug.recv_pos = 0; } } } Infra_recv_state = 0; debug_soft_uart_recv_restart(); } else { Infra_recv_state = 0; debug_soft_uart_recv_restart(); } }
‘’’