OTP单片机调试工具之—单线数据编码

发布于:2025-03-16 ⋅ 阅读:(24) ⋅ 点赞:(0)

         OTP单片机调试工具在实现过程中离不开单线数据的传输,那么使用哪一种方式的数据编码会比较好呢?

       我所了解的主要有以下三种:

       1.UART(串口),这种方式在单片机和pc之间进行传输都非常常见,效率比较高,但是受标准波特率的条件限制,必须配合相应的晶体才能达到比较高的速率;其实要是单片机与单片机之前进行数据传输,那么可以无视标准波特率限制,可以自定义波特率。

这里用应广单片机为例,用应广的IDE可以生成通信代码。

/*这一段是通过宏定义和预编译,检测在当前时钟下,是否可以实现标准波特率通信*/
System_Clock    =>    8000000;
FPPA_Duty        =>    _SYS(INC.FPPA_NUM);    // Single FPPA = 1, Mult FPPA = 2 or 4/8/...
.errnz    FPPA_Duty > 2    //    Only for 1 /2 FPPA, not for more FPPAs

Baud_Rate        =>    115200;
/*
UART_Delay        =>    (System_Clock / FPPA_Duty) / Baud_Rate;

    if    System_Clock    =    8,000.000 Hz
        FPPA_Duty        =    /16
    so    FPPA_Clock        =    System_Clock / FPPA_Duty    =    500.000    Hz

    if    Baud_Rate        =    19200
    so    UART_Delay        =    500.000 / 19200 = 26.0416...
    so    match, 26 cycles send one bit.    < 0.5%

    if    Baud_Rate        =    38400
    so    UART_Delay        =    500.000 / 38400 = 13.02083...
    so    match, 13 cycles send one bit.    < 0.5%

    if    Baud_Rate        =    56000
?    so    UART_Delay        =    500.000 / 56000 = 8.9285...        <    1.0%

    if    Baud_Rate        =    57600
X    so    UART_Delay        =    500.000 / 57600 = 8.6805...        :    fail
*/
UART_Delay        =>    ( (System_Clock / FPPA_Duty) + (Baud_Rate/2) ) / Baud_Rate;
//    + (Baud_Rate/2) : to round up or down

Test_V0            =>    System_Clock / 1000 * 995;
Test_V1            =>    UART_Delay * Baud_Rate * FPPA_Duty;
Test_V2            =>    System_Clock / 1000 * 1005;

#if    (Test_V1 < Test_V0) || (Test_V1 > Test_V2)
    .echo    %Test_V0 <= %Test_V1 <= %Test_V2
    .error    Baud_Rate do not match to System Clock
#endif

UART_Out        BIT    PB.0;
UART_In            BIT    PB.1;

/*实际发送代码*/

static    void    UART_Send (void)
{
    BYTE    cnt;
    BYTE    UART_Data_Out;

    UART_Data_Out    =    A;

    //    Start Bit
    set0    UART_Out;                //    1

    #if    FPPA_Duty == 1
        cnt    =    8;                        //    2 ~ 3
        .Delay    3;                        //    4 ~ 6
        do
        {    //    Data Bit * 8
            .Delay    UART_Delay - 10;
            sr        UART_Data_Out;        //    7
            if (CF)
            {
                nop;                    //    10
                UART_Out    =    1;        //    1
            }
            else
            {
                UART_Out    =    0;        //    1
                .delay    2;                //    2 ~ 3
            }
        } while (--cnt);                //    4 ~ 6
        .Delay    UART_Delay - 5;
    #else
        .Delay    UART_Delay - 4;
        cnt    =    8;                        //    2 ~ 3

        //    Data Bit * 8
        do
        {
            sr        UART_Data_Out;        //    4        4
            swapc    UART_Out;            //            1
            .Delay    UART_Delay - 4;
        } while (--cnt);                //            2, 3

        .Delay    2;                        //            3 ~ 4
    #endif

    //    Stop Bit
    set1    UART_Out;                //    1
    .Delay    2 * UART_Delay - 2;
}                                    //    2

       主要是为了能够适配标准波特率,看起来代码不少,实际核心代码不多。如果是自定义波特率,那么会简单很多,只要是时序对得上就好了。这种方式的好处就是效率比较高,但是要求收发双方要时钟同步。

2,使用类1-wire总线协议,实现方式如下


/*1wire 发送*/
void  Wire1_Send_Byte(void)
{
     byte ucCnt;
     ucCnt=8;
     while(ucCnt)
     {
          /*起始位*/
          UART_Tx=1;
          /*移位*/
          src UartTxBuf;
          
          /*根据需要传输的数据输出对应电平*/
          swapc UART_Tx;
          .delay 6;
          
          /*输出低电平*/
          UART_Tx=0;
          ucCnt--;
      }    
}

这种方式是使用了归零码,这种方式的好处就是能够自同步,方便接端进行解码。但是效率不高

3.使用红外遥控编码,其实这种方式和上述类单总线方式很相像,感觉好像是高低电平反过来就是了。

发送实现方式:用这个Wire1_Send_Byte()代码改一下就好了。

以上就是3种常见的单线数据传输方式,可以根据实际需要,选择其中一种方式作为数据传输使用。感谢!


网站公告

今日签到

点亮在社区的每一天
去签到