单片机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();
}
}
‘’’