单片机pic24GPIO模拟uart发送

本文介绍了一种在资源受限的PIC24单片机上利用GPIO口和定时器模拟UART通信的方法,详细展示了初始化配置和收发处理过程。

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

}
‘’’

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值