新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 基于51單片機的RS-485的多機通信

        基于51單片機的RS-485的多機通信

        作者: 時間:2016-11-27 來源:網絡 收藏
        //-----------------------函數聲明,變量定義---------------------

        #include

        本文引用地址:http://www.104case.com/article/201611/322565.htm

        sbit RE_DE=P1^0;

        #define COUNT 10 // 定義接收緩沖區大小

        #define Slaver_NUM 10

        unsignedcharbdata flag;//在可位尋址去定義一個標志變量

        sbit time_over_flag =flag^0;//接收超時標志

        unsignedcharbuffer[COUNT];//定義緩沖區

        unsignedcharpoint;//定義緩沖區位置指示

        unsignedcharSlave_AD[Slaver_NUM];//定義有效地址存放區

        unsignedcharADD_num;//有效地址個數

        unsignedcharidata count_10ms;//用于表示有多少次10ms中斷

        unsignedcharidata send_data[7]={

        0x31,0x32,0x33,0x34,0x35,0x36,0x37};//與定義發送數據,共7位

        voidUART_init();//串口初始化函數

        voidCOM_send(void);//串口接收函數

        unsignedcharCLU_checkdata(void);//計算校驗位函數

        //---------------------------------------------------------------

        // 函數名稱: UART_init()串口初始化函數

        // 函數功能: 在系統時鐘為11.059MHZ時,設定串口波特率為9600bit/s

        // 串口接收中斷允許,發送中斷禁止,設定定時器中斷允許

        //---------------------------------------------------------------

        voidUART_init()

        {

        //初始化串行設置

        SCON =0x58;//選擇串口工作方式為1,打開接收允許,TB8=1

        TMOD =0x21;//定時器1工作在方式2,定時器0工作在方式1

        TR1 =1;//啟動定時器T1

        ES=1;//允許串行口中斷

        PS=1;//設計串行口中斷優先級

        //初始化定時器1

        TH1 =0xfd;//實現波特率9600(系統時鐘11.0592MHZ)

        ET1 =0;//定時器1中斷禁止

        }

        //---------------------------------------------------------------

        // 函數名稱: timer0_init()初始化定時器0

        // 函數功能: 設置timer0工作模式

        //---------------------------------------------------------------

        voidtimer0_init()

        {

        time_over_flag=0;

        count_10ms=0;

        ADD_num=0;

        TL0=0x0F0;//T0用于產生10ms的中斷

        TH0=0x0D8;//50次T0中斷產生1次超時溢出

        ET0=1;//允許定時器0中斷

        }

        //---------------------------------------------------------------

        // 函數名稱: system_init()系統初始化

        // 函數功能: 調用串口、定時器初始化函數,完成系統初始化

        //---------------------------------------------------------------

        voidsystem_init(void)

        {

        //系統總設置

        UART_init();

        timer0_init();

        EA =1;//單片機中斷允許

        }

        //---------------------------------------------------------------

        // 函數名稱: com_interrup()串口接收中斷處理函數

        // 函數功能: 接收包括起始位"S"在內的十位數據到數據緩沖區

        //---------------------------------------------------------------

        com_interrupt(void) interrupt 4using3

        {

        unsignedcharRECEIVR_buffer;

        if(RI)//處理接收中斷

        {RI=0;//清除中斷標志位

        RECEIVR_buffer=SBUF;//接收串口數據

        if(point==0)//如果還沒有接收到起始位

        {

        if(RECEIVR_buffer==0xFE)//判斷是否起始標志位

        {

        buffer[point++]=RECEIVR_buffer;//把接收到的數據放入接收緩存區

        }

        else

        point=0;//不是,繼續等待起始位

        }

        elseif(point>0&&point<10)//判斷是否接收夠十位數據

        buffer[point++]=RECEIVR_buffer;//不夠,把接收到的數據放入接收緩存區

        elseif(point==10)

        {

        if(RECEIVR_buffer==0xEF)//判斷結束標志位是否正確

        {

        buffer[point]=RECEIVR_buffer;//把接收到的數據放入接收緩存區

        Slave_AD[ADD_num++]=buffer[2];//把接收到的地址放到地址存儲器

        //表示該地址有有效設備

        }

        else

        point=0;//不是,繼續等待起始位

        }

        elsepoint=0;//緩沖區已滿,清除緩存區內數據重新接收

        }

        if(TI)//串口發送中斷

        {

        TI=0;//清除發送中斷

        }

        }

        //---------------------------------------------------------------

        // 函數名稱: timer0_interrup()

        // 函數功能:定時器T0中斷服務程序

        // 函數說明:T0枚10ms中斷一次,連續中斷50次置time_over_flag=1;

        //---------------------------------------------------------------

        timer0_interrupt(void) interrupt 1using2

        {

        count_10ms++;

        if(count_10ms==50)

        {

        ET0=0;//關閉定時器T0中斷

        TR0=0;//停止定時器T0

        time_over_flag=1;//設置接收超時標志

        count_10ms=0x00;//10ms計數器復位

        }

        else

        {

        TL0=0x0F0;//重裝定時器初始值

        TH0=0x0D8;

        }

        }

        //---------------------------------------------------------------

        // 函數名稱: COM_send()串口發送函數

        // 函數功能: 把數據緩沖區的十位數據發送出去

        //---------------------------------------------------------------

        voidCOM_send(void)

        {

        RE_DE=1;//設置MAX483進入發送狀態

        for(point=0;point=10,TI=1;point++)//連續發送十位數據

        //把緩存區的數據都發送到串口

        {

        SBUF=buffer[point];

        TI=0;

        }

        RE_DE=0;//設置MAX483進入接收狀態

        }

        //---------------------------------------------------------------

        // 函數名稱: write_buffer()

        // 函數功能: 寫發送緩沖區十位數據

        //---------------------------------------------------------------

        voidwrite_buffer(unsignedcharslaver_add)

        {

        unsignedchari;

        TB8=1;//打開多機通信方式

        buffer[0]=0xFE;

        buffer[1]=slaver_add;

        for(i=2;i<9;i++)//連續發送十位數據

        //把緩存區的數據都發送到串口

        {

        buffer[i]=send_data[i-2];

        }

        buffer[9]=0xEF;

        }

        //---------------------------------------------------------------

        // 函數名稱: 主函數

        // 函數功能: 調度個子函數,完成通信過程

        //---------------------------------------------------------------

        voidmain(void)

        {

        unsignedchari=0;

        system_init();//系統初始化

        do{//查旬0到10好地址有沒有對應設備

        write_buffer(i++);//寫查詢第i號設備的發送信息

        COM_send();//調用發送函數,完成發送

        timer0_init();//完成一次查詢,重新初始定時器0,準備下一次查詢

        }

        while(time_over_flag&&i<10);

        }



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 广安市| 微山县| 柯坪县| 东台市| 乌海市| 扶沟县| 奈曼旗| 韶关市| 区。| 徐水县| 仪征市| 铜鼓县| 涪陵区| 保亭| 张家川| 丹寨县| 黔东| 华亭县| 罗平县| 南川市| 亳州市| 读书| 黄龙县| 郓城县| 崇明县| 彝良县| 郑州市| 易门县| 大安市| 米易县| 互助| 兴宁市| 咸阳市| 吉水县| 梁平县| 大足县| 错那县| 阳山县| 揭西县| 寿光市| 永康市|