5695|15

73

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

AT89C51AC2的串口初始化和中断问题 [复制链接]

以下是我写的一个用timer2做串口波特率触发器的程序。
与PC通讯,接收回来的数据和发送的不一样,好象根本没执行中断发送部分。
struct SEND_STRUCT{
                     unsigned char data_idx;
                     unsigned char data_buf[10];
                }SEND;
struct RECEIVE_STRUCT{
                     unsigned char data_idx;
                     unsigned char data_buf[10];
                }RECEIVE;
/************************************************************/
void serial_init(void)
{
    PCON &= 7F;//no double baud rate, SMOD1=0 of PCON
    SCON = 0x50;//8-bit UART, mode 1
    T2CON &= 0xF0;//EXEN2=0, TR2=0, C/T2=0; CP/RL2=0
    T2CON |= 0x30;//RCLK=1, TCKL=1
    TH2 = 0xFF;
    TL2 = 0xDC;//[init value]=2^n-(Fosc/(baud*16*2)), Fosc=11.0592MHz, baud=9600
    RCAP2H = 0xFF;
    RCAP2L = 0xDC;//reload baud 9600
    REN = 1;//enable receive
    TX_EN = 1;//disenable send

    TR2 = 1;/startup T2
    ES = 1;//serial isr enable
}
/************************************************************/
void uart_isr(void) interrupt 4
{
    unsigned char rec_data;

    if(_testbit_(TI))
    {
        if(SEND.data_index<=9)//send all data
        {
            SUBF = SEND.data_buf[SEND.data_idx];
            ++SEND.data_idx;
        }
        else if(SEND.data_idx>9)
        {
            TI = 0;
            SEND.data_idx = 0;
            TX_EN = 1;//disenable send
            REN = 1;//enable receive
        }
    }//send end
    else if(_testbit_(RI))
    {
        rec_data = SBUF;//read serial data buf

        if(RECEIVE.data_idx==0)
        {
            if(rec_data==x0FF)//communication with PC, the first data is 0xFF
            {
                RECEIVE.data_buf[0] = rec_data;
                RECEIVE.data_buf[9] ^= rec_data;//checksum=data_buf[0]^data_buf[1]^...^data_buf[8]   
                                                //&0x7F
                RECEIVE.data_idx = 1;
            }
            else
            {
                RECEIVE.data_idx = 0;
            }
        }
        else if(RECEIVE.data_idx)
        {
            if(RECEIVE.data_idx<9)//receive 1~8 data and checksum=data_buf[0]^data_buf[1]^...
                                  //^data_buf[8]&0x7F
            {
                RECEIVE.data_buf[RECEIVE.data_idx] = rec_data;
                RECEIVE.data_buf[9] ^= rec_data;
                ++RECEIVE.data_idx;
            }
            else if((RECEIVE.data_idx==9) && ((RECEIVE.data_buf[9])&0x7F)==rec_data))
            {
                REN = 0;//disenable receive
                TX_EN = 0;//enable send
                RI = 0;
            }
            else
            {
                RECEIVE.data_idx = 0;
                RI = 0;
            }
        }
    }//receive end
}

最新回复

以上程序很好用  详情 回复 发表于 2008-4-6 20:59
点赞 关注

回复
举报

77

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
发的时候少用中断了...

呵呵

 
 

回复

84

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
发的时候少用中断了
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

4
 
程序没问题,是我用VB做的通讯的软件接收模式错了,数据接收到的都是乱七八糟的。
程序我简化了一点,如果有需要的,可以直接套用。
/*************************************************************************/
/************************************************************/
本串口程序是与PC通讯,timer2 作为波特率触发器,通讯模式:485,
如果注释了TX_EN用于232通讯。
/************************************************************/
#define SEND_LEN        10//发送数据长度
#define RECE_LEN        10//接收数据长度
struct SEND_STRUCT{
                     unsigned char data_idx;
                     unsigned char data_buf[SEND_LEN];
                }SEND;
struct RECEIVE_STRUCT{
                     unsigned char data_idx;
                     unsigned char data_buf[RECE_LEN];
                }RECEIVE;
/************************************************************/
void serial_init(void)
{
    PCON &= 0x7F;//no double baud rate, SMOD1=0 of PCON
    SCON = 0x50;//8-bit UART, mode 1
    T2CON &= 0xF0;//EXEN2=0, TR2=0, C/T2=0; CP/RL2=0
    T2CON |= 0x30;//RCLK=1, TCKL=1
    TH2 = 0xFF;
    TL2 = 0xDC;//初值=65536-(Fosc/(baud*16*2)), Fosc=11.0592MHz, baud=9600
    RCAP2H = 0xFF;
    RCAP2L = 0xDC;//reload baud 9600
    REN = 1;//enable receive
    TX_EN = 1;//disenable send(用于485通讯发送使能开关,如果用于232通讯注释了就OK)
              //高电平有效,由于加了个非门,所以高电平禁止发送,低电平允许发送)
    TR2 = 1;/startup T2
    ES = 1;//serial isr enable
}
/************************************************************/
void uart_isr(void) interrupt 4
{
    unsigned char rec_data;

    if(_testbit_(TI))//发送数据
    {
        if(SEND.data_index<=SEND_LEN-1)//send all data
        {
            SUBF = SEND.data_buf[SEND.data_idx];
            ++SEND.data_idx;
        }
        else if(SEND.data_idx>SEND_LEN-1)
        {
            TI = 0;
            SEND.data_idx = 0;
            TX_EN = 1;//disenable 485 send
            REN = 1;//enable receive
        }
    }//send end
    else if(_testbit_(RI))//接受数据
    {
        rec_data = SBUF;//read serial data buf

        if(RECEIVE.data_idx==0)
        {
            if(rec_data==0xFF)//PC 发送的第一个数据是0xFF
            {
                RECEIVE.data_buf[0] = rec_data;
                RECEIVE.data_buf[RECE_LEN-1] ^= rec_data//校验数据赋初值
                RECEIVE.data_idx = 1;
            }

            /*****接收除第一个数据,和校验数据外的数据*****/
            else if((RECEIVE.data_idx) && (RECEIVE.data_idx              {
                RECEIVE.data_buf[RECEIVE.data_idx] = rec_data;

                /**校验 = data_buf[0]^data_buf[1]^...^data_buf[8]&0x7F**/
                RECEIVE.data_buf[RECE_LEN-1] ^= rec_data;
                ++RECEIVE.data_idx;
            }

            /****接受最后一个数据(校验数据)****/
            else if((RECEIVE.data_idx==(RECE_LEN-1))&&((RECEIVE.data_buf[RECE_LEN-1])&0x7F)==rec_data))
            {
                REN = 0;//disenable receive
                TX_EN = 0;//enable 485 send
                RI = 0;
            }
            else
            {
                RECEIVE.data_idx = 0;
                RI = 0;
            }
        }
    }
}
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

5
 
程序没问题,是我用VB做的通讯的软件接收模式错了,数据接收到的都是乱七八糟的。
程序我简化了一点,如果有需要的,可以直接套用。
/************************************************************/
本串口程序是与PC通讯,timer2 作为波特率触发器,通讯模式:485,
如果注释了TX_EN用于232通讯。
/************************************************************/
#define SEND_LEN        10//发送数据长度
#define RECE_LEN        10//接收数据长度
struct SEND_STRUCT{
                     unsigned char data_idx;
                     unsigned char data_buf[SEND_LEN];
                }SEND;
struct RECEIVE_STRUCT{
                     unsigned char data_idx;
                     unsigned char data_buf[RECE_LEN];
                }RECEIVE;
/************************************************************/
void serial_init(void)
{
    PCON &= 0x7F;//no double baud rate, SMOD1=0 of PCON
    SCON = 0x50;//8-bit UART, mode 1
    T2CON &= 0xF0;//EXEN2=0, TR2=0, C/T2=0; CP/RL2=0
    T2CON |= 0x30;//RCLK=1, TCKL=1
    TH2 = 0xFF;
    TL2 = 0xDC;//初值=65536-(Fosc/(baud*16*2)), Fosc=11.0592MHz, baud=9600
    RCAP2H = 0xFF;
    RCAP2L = 0xDC;//reload baud 9600
    REN = 1;//enable receive
    TX_EN = 1;//disenable send(用于485通讯发送使能开关,如果用于232通讯注释了就OK)
              //高电平有效,由于加了个非门,所以高电平禁止发送,低电平允许发送)
    TR2 = 1;/startup T2
    ES = 1;//serial isr enable
}
/************************************************************/
void uart_isr(void) interrupt 4
{
    unsigned char rec_data;

    if(_testbit_(TI))//发送数据
    {
        if(SEND.data_index<=SEND_LEN-1)//send all data
        {
            SUBF = SEND.data_buf[SEND.data_idx];
            ++SEND.data_idx;
        }
        else if(SEND.data_idx>SEND_LEN-1)
        {
            TI = 0;
            SEND.data_idx = 0;
            TX_EN = 1;//disenable 485 send
            REN = 1;//enable receive
        }
    }//send end
    else if(_testbit_(RI))//接受数据
    {
        rec_data = SBUF;//read serial data buf

        if(RECEIVE.data_idx==0)
        {
            if(rec_data==0xFF)//PC 发送的第一个数据是0xFF
            {
                RECEIVE.data_buf[0] = rec_data;
                RECEIVE.data_buf[RECE_LEN-1] ^= rec_data//校验数据赋初值
                RECEIVE.data_idx = 1;
            }

            /*****接收除第一个数据,和校验数据外的数据*****/
            else if((RECEIVE.data_idx) && (RECEIVE.data_idx              {
                RECEIVE.data_buf[RECEIVE.data_idx] = rec_data;

                /**校验 = data_buf[0]^data_buf[1]^...^data_buf[8]&0x7F**/
                RECEIVE.data_buf[RECE_LEN-1] ^= rec_data;
                ++RECEIVE.data_idx;
            }

            /****接受最后一个数据(校验数据)****/
            else if((RECEIVE.data_idx==(RECE_LEN-1))&&((RECEIVE.data_buf[RECE_LEN-1])&0x7F)==rec_data))
            {
                REN = 0;//disenable receive
                TX_EN = 0;//enable 485 send
                RI = 0;
            }
            else
            {
                RECEIVE.data_idx = 0;
                RI = 0;
            }
        }
    }
}
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

6
 
程序没问题,是我用VB做的通讯的软件接收模式错了,数据接收到的都是乱七八糟的。
程序我简化了一点,如果有需要的,可以直接套用。
//////////////////////////////////////////////////////////////////
本串口程序是与PC通讯,timer2 作为波特率触发器,通讯模式:485,
如果注释了TX_EN用于232通讯。
//////////////////////////////////////////////////////////////////
#define SEND_LEN        10//发送数据长度
#define RECE_LEN        10//接收数据长度
struct SEND_STRUCT{
                     unsigned char data_idx;
                     unsigned char data_buf[SEND_LEN];
                }SEND;
struct RECEIVE_STRUCT{
                     unsigned char data_idx;
                     unsigned char data_buf[RECE_LEN];
                }RECEIVE;
//////////////////////////////////////////////////////////////////
void serial_init(void)
{
    PCON &= 0x7F;//no double baud rate, SMOD1=0 of PCON
    SCON = 0x50;//8-bit UART, mode 1
    T2CON &= 0xF0;//EXEN2=0, TR2=0, C/T2=0; CP/RL2=0
    T2CON |= 0x30;//RCLK=1, TCKL=1
    TH2 = 0xFF;
    TL2 = 0xDC;//初值=65536-(Fosc/(baud*16*2)), Fosc=11.0592MHz, baud=9600
    RCAP2H = 0xFF;
    RCAP2L = 0xDC;//reload baud 9600
    REN = 1;//enable receive
    TX_EN = 1;//disenable send(用于485通讯发送使能开关,如果用于232通讯注释了就OK)
              //高电平有效,由于加了个非门,所以高电平禁止发送,低电平允许发送)
    TR2 = 1;//startup T2
    ES = 1;//serial isr enable
}
//////////////////////////////////////////////////////////////////
void uart_isr(void) interrupt 4
{
    unsigned char rec_data;

    if(_testbit_(TI))//发送数据
    {
        if(SEND.data_index<=SEND_LEN-1)//send all data
        {
            SUBF = SEND.data_buf[SEND.data_idx];
            ++SEND.data_idx;
        }
        else if(SEND.data_idx>SEND_LEN-1)
        {
            TI = 0;
            SEND.data_idx = 0;
            TX_EN = 1;//disenable 485 send
            REN = 1;//enable receive
        }
    }//send end
    else if(_testbit_(RI))//接受数据
    {
        rec_data = SBUF;//read serial data buf

        if(RECEIVE.data_idx==0)
        {
            if(rec_data==0xFF)//PC 发送的第一个数据是0xFF
            {
                RECEIVE.data_buf[0] = rec_data;
                RECEIVE.data_buf[RECE_LEN-1] ^= rec_data//校验数据赋初值
                RECEIVE.data_idx = 1;
            }

            //接收除第一个数据,和校验数据外的数据
            else if((RECEIVE.data_idx) && (RECEIVE.data_idx              {
                RECEIVE.data_buf[RECEIVE.data_idx] = rec_data;

                /**校验 = data_buf[0]^data_buf[1]^...^data_buf[8]&0x7F**/
                RECEIVE.data_buf[RECE_LEN-1] ^= rec_data;
                ++RECEIVE.data_idx;
            }

            //接受最后一个数据(校验数据)
            else if((RECEIVE.data_idx==(RECE_LEN-1))&&((RECEIVE.data_buf[RECE_LEN-1])&0x7F)==rec_data))
            {
                REN = 0;//disenable receive
                TX_EN = 0;//enable 485 send
                RI = 0;
            }
            else
            {
                RECEIVE.data_idx = 0;
                RI = 0;
            }
        }
    }
}
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

7
 
程序没问题,是我用VB做的通讯的软件接收模式错了,数据接收到的都是乱七八糟的。
程序我简化了一点,如果有需要的,可以直接套用。
/****************************************************************************/
本串口程序是与PC通讯,timer2 作为波特率触发器,通讯模式:485,
如果注释了TX_EN用于232通讯。
/****************************************************************************/
#define SEND_LEN        10//发送数据长度
#define RECE_LEN        10//接收数据长度
struct SEND_STRUCT{
                     unsigned char data_idx;
                     unsigned char data_buf[SEND_LEN];
                }SEND;
struct RECEIVE_STRUCT{
                     unsigned char data_idx;
                     unsigned char data_buf[RECE_LEN];
                }RECEIVE;
/****************************************************************************/
void serial_init(void)
{
    PCON &= 0x7F;//no double baud rate, SMOD1=0 of PCON
    SCON = 0x50;//8-bit UART, mode 1
    T2CON &= 0xF0;//EXEN2=0, TR2=0, C/T2=0; CP/RL2=0
    T2CON |= 0x30;//RCLK=1, TCKL=1
    TH2 = 0xFF;
    TL2 = 0xDC;//初值=65536-(Fosc/(baud*16*2)), Fosc=11.0592MHz, baud=9600
    RCAP2H = 0xFF;
    RCAP2L = 0xDC;//reload baud 9600
    REN = 1;//enable receive
    TX_EN = 1;//disenable send(用于485通讯发送使能开关,如果用于232通讯注释了就OK)
              //高电平有效,由于加了个非门,所以高电平禁止发送,低电平允许发送)
    TR2 = 1;//startup T2
    ES = 1;//serial isr enable
}
/****************************************************************************/
void uart_isr(void) interrupt 4
{
    unsigned char rec_data;

    if(_testbit_(TI))//发送数据
    {
        if(SEND.data_index<=SEND_LEN-1)//send all data
        {
            SUBF = SEND.data_buf[SEND.data_idx];
            ++SEND.data_idx;
        }
        else if(SEND.data_idx>SEND_LEN-1)
        {
            TI = 0;
            SEND.data_idx = 0;
            TX_EN = 1;//disenable 485 send
            REN = 1;//enable receive
        }
    }//send end
    else if(_testbit_(RI))//接受数据
    {
        rec_data = SBUF;//read serial data buf

        if(RECEIVE.data_idx==0)
        {
            if(rec_data==0xFF)//PC 发送的第一个数据是0xFF
            {
                RECEIVE.data_buf[0] = rec_data;
                RECEIVE.data_buf[RECE_LEN-1] ^= rec_data//校验数据赋初值
                RECEIVE.data_idx = 1;
            }

            //接收除第一个数据,和校验数据外的数据
            else if((RECEIVE.data_idx) && (RECEIVE.data_idx              {
                RECEIVE.data_buf[RECEIVE.data_idx] = rec_data;

                /**校验 = data_buf[0]^data_buf[1]^...^data_buf[8]&0x7F**/
                RECEIVE.data_buf[RECE_LEN-1] ^= rec_data;
                ++RECEIVE.data_idx;
            }

            //接受最后一个数据(校验数据)
            else if((RECEIVE.data_idx==(RECE_LEN-1))&&((RECEIVE.data_buf[RECE_LEN-1])&0x7F)==rec_data))
            {
                REN = 0;//disenable receive
                TX_EN = 0;//enable 485 send
                RI = 0;
            }
            else
            {
                RECEIVE.data_idx = 0;
                RI = 0;
            }
        }
    }
}
 
 
 

回复

48

帖子

0

TA的资源

一粒金砂(初级)

8
 
程序没问题,是我用VB做的通讯的软件接收模式错了,数据接收到的都是乱七八糟的。
程序我简化了一点,如果有需要的,可以直接套用。
/****************************************************************************/
本串口程序是与PC通讯,timer2 作为波特率触发器,通讯模式:485,
如果注释了TX_EN用于232通讯。
/****************************************************************************/
#define SEND_LEN        10//发送数据长度
#define RECE_LEN        10//接收数据长度
struct SEND_STRUCT{
                     unsigned char data_idx;
                     unsigned char data_buf[SEND_LEN];
                }SEND;
struct RECEIVE_STRUCT{
                     unsigned char data_idx;
                     unsigned char data_buf[RECE_LEN];
                }RECEIVE;
/****************************************************************************/
void serial_init(void)
{
    PCON &= 0x7F;//no double baud rate, SMOD1=0 of PCON
    SCON = 0x50;//8-bit UART, mode 1
    T2CON &= 0xF0;//EXEN2=0, TR2=0, C/T2=0; CP/RL2=0
    T2CON |= 0x30;//RCLK=1, TCKL=1
    TH2 = 0xFF;
    TL2 = 0xDC;//初值=65536-(Fosc/(baud*16*2)), Fosc=11.0592MHz, baud=9600
    RCAP2H = 0xFF;
    RCAP2L = 0xDC;//reload baud 9600
    REN = 1;//enable receive
    TX_EN = 1;//disenable send(用于485通讯发送使能开关,如果用于232通讯注释了就OK),
    高电平有效,由于加了个非门,所以高电平禁止发送,低电平允许发送)
    TR2 = 1;//startup T2
    ES = 1;//serial isr enable
}
/****************************************************************************/
void uart_isr(void) interrupt 4
{
    unsigned char rec_data;

    if(_testbit_(TI))//发送数据
    {
        if(SEND.data_index<=SEND_LEN-1)//send all data
        {
            SUBF = SEND.data_buf[SEND.data_idx];
            ++SEND.data_idx;
        }
        else if(SEND.data_idx>SEND_LEN-1)
        {
            TI = 0;
            SEND.data_idx = 0;
            TX_EN = 1;//disenable 485 send
            REN = 1;//enable receive
        }
    }//send end
    else if(_testbit_(RI))//接受数据
    {
        rec_data = SBUF;//read serial data buf

        if(RECEIVE.data_idx==0)
        {
            if(rec_data==0xFF)//PC 发送的第一个数据是0xFF
            {
                RECEIVE.data_buf[0] = rec_data;
                RECEIVE.data_buf[RECE_LEN-1] ^= rec_data//校验数据赋初值
                RECEIVE.data_idx = 1;
            }

            /*接收除第一个数据,和校验数据外的数据*/
            else if((RECEIVE.data_idx) && (RECEIVE.data_idx              {
                RECEIVE.data_buf[RECEIVE.data_idx] = rec_data;

                /**校验 = data_buf[0]^data_buf[1]^...^data_buf[8]&0x7F**/
                RECEIVE.data_buf[RECE_LEN-1] ^= rec_data;
                ++RECEIVE.data_idx;
            }

            /*接受最后一个数据(校验数据)*/
            else if((RECEIVE.data_idx==(RECE_LEN-1))&&((RECEIVE.data_buf[RECE_LEN-1])&0x7F)==rec_data))
            {
                REN = 0;//disenable receive
                TX_EN = 0;//enable 485 send
                RI = 0;
            }
            else
            {
                RECEIVE.data_idx = 0;
                RI = 0;
            }
        }
    }
}
 
 
 

回复

52

帖子

0

TA的资源

一粒金砂(初级)

9
 
程序没问题,是我用VB做的通讯的软件接收模式错了,数据接收到的都是乱七八糟的。
程序我简化了一点,如果有需要的,可以直接套用。
 
 
 

回复

52

帖子

0

TA的资源

一粒金砂(初级)

10
 
怎么今天回不了帖,老提示‘/’服务器错误?
哪个串口程序没问题,我稍微优化了下,结果老是提示错误
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

11
 
程序没问题,是我用VB做的通讯的软件接收模式错了,数据接收到的都是乱七八糟的。
程序我简化了一点,如果有需要的,可以直接套用。
/****************************************************************************/
本串口程序是与PC通讯,timer2 作为波特率触发器,通讯模式:485,
如果注释了TX_EN用于232通讯。
/****************************************************************************/
#define SEND_LEN        10//发送数据长度
#define RECE_LEN        10//接收数据长度
struct SEND_STRUCT{
                     unsigned char data_idx;
                     unsigned char data_buf[SEND_LEN];
                }SEND;
struct RECEIVE_STRUCT{
                     unsigned char data_idx;
                     unsigned char data_buf[RECE_LEN];
                }RECEIVE;
/****************************************************************************/
void serial_init(void)
{
    PCON &= 0x7F;//no double baud rate, SMOD1=0 of PCON
    SCON = 0x50;//8-bit UART, mode 1
    T2CON &= 0xF0;//EXEN2=0, TR2=0, C/T2=0; CP/RL2=0
    T2CON |= 0x30;//RCLK=1, TCKL=1
    TH2 = 0xFF;
    TL2 = 0xDC;//初值=65536-(Fosc/(baud*16*2)), Fosc=11.0592MHz, baud=9600
    RCAP2H = 0xFF;
    RCAP2L = 0xDC;//reload baud 9600
    REN = 1;//enable receive
    TX_EN = 1;//disenable send(用于485通讯发送使能开关,如果用于232通讯注释了就OK),
    高电平有效,由于加了个非门,所以高电平禁止发送,低电平允许发送)
    TR2 = 1;//startup T2
    ES = 1;//serial isr enable
}
/****************************************************************************/
void uart_isr(void) interrupt 4
{
    unsigned char rec_data;

    if(_testbit_(TI))//发送数据
    {
        if(SEND.data_index<=SEND_LEN-1)//send all data
        {
            SUBF = SEND.data_buf[SEND.data_idx];
            ++SEND.data_idx;
        }
        else if(SEND.data_idx>SEND_LEN-1)
        {
            TI = 0;
            SEND.data_idx = 0;
            TX_EN = 1;//disenable 485 send
            REN = 1;//enable receive
        }
    }//send end
    else if(_testbit_(RI))//接受数据
    {
        rec_data = SBUF;//read serial data buf

        if(RECEIVE.data_idx==0)
        {
            if(rec_data==0xFF)//PC 发送的第一个数据是0xFF
            {
                RECEIVE.data_buf[0] = rec_data;
                RECEIVE.data_buf[RECE_LEN-1] ^= rec_data//校验数据赋初值
                RECEIVE.data_idx = 1;
            }

            /*接收除第一个数据,和校验数据外的数据*/
            else if((RECEIVE.data_idx) && (RECEIVE.data_idx              {
                RECEIVE.data_buf[RECEIVE.data_idx] = rec_data;

                /**校验 = data_buf[0]^data_buf[1]^...^data_buf[8]&0x7F**/
                RECEIVE.data_buf[RECE_LEN-1] ^= rec_data;
                ++RECEIVE.data_idx;
            }

            /*接受最后一个数据(校验数据)*/
            else if((RECEIVE.data_idx==(RECE_LEN-1))&&((RECEIVE.data_buf[RECE_LEN-1])&0x7F)==rec_data))
            {
                REN = 0;//disenable receive
                TX_EN = 0;//enable 485 send
                RI = 0;
            }
            else
            {
                RECEIVE.data_idx = 0;
                RI = 0;
            }
        }
    }
}
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

12
 
帮你顶
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

13
 
程序没问题,是我用VB做的通讯的软件接收模式错了,数据接收到的都是乱七八糟的。
程序我简化了一点,如果有需要的,可以直接套用。
/****************************************************************************/
本串口程序是与PC通讯,timer2 作为波特率触发器,通讯模式:485,
如果注释了TX_EN用于232通讯。
/****************************************************************************/
#define SEND_LEN        10//发送数据长度
#define RECE_LEN        10//接收数据长度
struct SEND_STRUCT{
                     unsigned char data_idx;
                     unsigned char data_buf[SEND_LEN];
                }SEND;
struct RECEIVE_STRUCT{
                     unsigned char data_idx;
                     unsigned char data_buf[RECE_LEN];
                }RECEIVE;
/****************************************************************************/
void serial_init(void)
{
    PCON &= 0x7F;//no double baud rate, SMOD1=0 of PCON
    SCON = 0x50;//8-bit UART, mode 1
    T2CON &= 0xF0;//EXEN2=0, TR2=0, C/T2=0; CP/RL2=0
    T2CON |= 0x30;//RCLK=1, TCKL=1
    TH2 = 0xFF;
    TL2 = 0xDC;//初值=65536-(Fosc/(baud*16*2)), Fosc=11.0592MHz, baud=9600
    RCAP2H = 0xFF;
    RCAP2L = 0xDC;//reload baud 9600
    REN = 1;//enable receive
    TX_EN = 1;//disenable send(用于485通讯发送使能开关,如果用于232通讯注释了就OK),
    高电平有效,由于加了个非门,所以高电平禁止发送,低电平允许发送)
    TR2 = 1;//startup T2
    ES = 1;//serial isr enable
}
/****************************************************************************/
void uart_isr(void) interrupt 4
{
    unsigned char rec_data;

    if(_testbit_(TI))//发送数据
    {
        if(SEND.data_index<=SEND_LEN-1)//send all data
        {
            SUBF = SEND.data_buf[SEND.data_idx];
            ++SEND.data_idx;
        }
        else if(SEND.data_idx>SEND_LEN-1)
        {
            TI = 0;
            SEND.data_idx = 0;
            TX_EN = 1;//disenable 485 send
            REN = 1;//enable receive
        }
    }//send end
    else if(_testbit_(RI))//接受数据
    {
        rec_data = SBUF;//read serial data buf

        if(RECEIVE.data_idx==0)
        {
            if(rec_data==0xFF)//PC 发送的第一个数据是0xFF
            {
                RECEIVE.data_buf[0] = rec_data;
                RECEIVE.data_buf[RECE_LEN-1] ^= rec_data//校验数据赋初值
                RECEIVE.data_idx = 1;
            }

            /*接收除第一个数据,和校验数据外的数据*/
            else if((RECEIVE.data_idx) && (RECEIVE.data_idx              {
                RECEIVE.data_buf[RECEIVE.data_idx] = rec_data;

                /**校验 = data_buf[0]^data_buf[1]^...^data_buf[8]&0x7F**/
                RECEIVE.data_buf[RECE_LEN-1] ^= rec_data;
                ++RECEIVE.data_idx;
            }

            /*接受最后一个数据(校验数据)*/
            else if((RECEIVE.data_idx==(RECE_LEN-1))&&((RECEIVE.data_buf[RECE_LEN-1])&0x7F)==rec_data))
            {
                REN = 0;//disenable receive
                TX_EN = 0;//enable 485 send
                RI = 0;
            }
            else
            {
                RECEIVE.data_idx = 0;
                RI = 0;
            }
        }
    }
}
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

14
 
程序没问题,是我用VB做的通讯的软件接收模式错了,数据接收到的都是乱七八糟的。
程序我简化了一点,如果有需要的,可以直接套用。
/****************************************************************************/
本串口程序是与PC通讯,timer2 作为波特率触发器,通讯模式:485,
如果注释了TX_EN用于232通讯。
/****************************************************************************/
#define SEND_LEN        10//发送数据长度
#define RECE_LEN        10//接收数据长度
struct SEND_STRUCT{
                     unsigned char data_idx;
                     unsigned char data_buf[SEND_LEN];
                }SEND;
struct RECEIVE_STRUCT{
                     unsigned char data_idx;
                     unsigned char data_buf[RECE_LEN];
                }RECEIVE;
/****************************************************************************/
void serial_init(void)
{
    PCON &= 0x7F;//no double baud rate, SMOD1=0 of PCON
    SCON = 0x50;//8-bit UART, mode 1
    T2CON &= 0xF0;//EXEN2=0, TR2=0, C/T2=0; CP/RL2=0
    T2CON |= 0x30;//RCLK=1, TCKL=1
    TH2 = 0xFF;
    TL2 = 0xDC;//初值=65536-(Fosc/(baud*16*2)), Fosc=11.0592MHz, baud=9600
    RCAP2H = 0xFF;
    RCAP2L = 0xDC;//reload baud 9600
    REN = 1;//enable receive
    TX_EN = 1;//disenable send(用于485通讯发送使能开关,如果用于232通讯注释了就OK),
    高电平有效,由于加了个非门,所以高电平禁止发送,低电平允许发送)
    TR2 = 1;//startup T2
    ES = 1;//serial isr enable
}
/****************************************************************************/
void uart_isr(void) interrupt 4
{
    unsigned char rec_data;

    if(_testbit_(TI))//发送数据
    {
        if(SEND.data_index<=SEND_LEN-1)//send all data
        {
            SUBF = SEND.data_buf[SEND.data_idx];
            ++SEND.data_idx;
        }
        else if(SEND.data_idx>SEND_LEN-1)
        {
            TI = 0;
            SEND.data_idx = 0;
            TX_EN = 1;//disenable 485 send
            REN = 1;//enable receive
        }
    }//send end
    else if(_testbit_(RI))//接受数据
    {
        rec_data = SBUF;//read serial data buf

        if(RECEIVE.data_idx==0)
        {
            if(rec_data==0xFF)//PC 发送的第一个数据是0xFF
            {
                RECEIVE.data_buf[0] = rec_data;
                RECEIVE.data_buf[RECE_LEN-1] ^= rec_data//校验数据赋初值
                RECEIVE.data_idx = 1;
            }

            /*接收除第一个数据,和校验数据外的数据*/
            else if((RECEIVE.data_idx) && (RECEIVE.data_idx              {
                RECEIVE.data_buf[RECEIVE.data_idx] = rec_data;

                /**校验 = data_buf[0]^data_buf[1]^...^data_buf[8]&0x7F**/
                RECEIVE.data_buf[RECE_LEN-1] ^= rec_data;
                ++RECEIVE.data_idx;
            }

            /*接受最后一个数据(校验数据)*/
            else if((RECEIVE.data_idx==(RECE_LEN-1))&&((RECEIVE.data_buf[RECE_LEN-1])&0x7F)==rec_data))
            {
                REN = 0;//disenable receive
                TX_EN = 0;//enable 485 send
                RI = 0;
            }
            else
            {
                RECEIVE.data_idx = 0;
                RI = 0;
            }
        }
    }
}
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

15
 
接收完需要发送的时候加一句 SBUF = SEND.data_buf[SEND.data_idx];
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

16
 
以上程序很好用
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
直播报名最后1周:艾迈斯欧司朗 OSP 开放协议,从氛围灯动态照明到传感器交互融合
直播时间:4月22日(周二)10:00
直播奖励:京东卡、蓝牙温湿度计、定制水杯

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网 8

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表