亚洲春色中文字幕久久久-三上亚,一吻二脱三床四吻胸,国产真实伦对白视频全集,在线毛片观看,精品成品入口黄网,国产毛aⅴ片久久久,亚洲AV色香蕉一区二区三区老师,萧皇后A级艳片,色情日本视频更新,99久久亚洲精品日本无码

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3583|回復: 0
打印 上一主題 下一主題
收起左側

我現在正在研究基于avr,mega128的modbus 源碼

[復制鏈接]
跳轉到指定樓層
樓主
ID:167315 發表于 2017-3-1 09:20 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
我現在正在研究基于avr,mega128的modbus 做了個modbus   也是基于網友的代碼調試的  上傳

Avr單片機中使用modbus協議的方法
                                                             
有以下程序用gcc實現,單片機用avr單片機。
ISR(USART0_RX_vect)//串口0接收中斷服務程序
{
  volatile unsigned char status,data;
cli();//關中斷

    status = UCSR0A;//ucsr0a賦值狀態標志
    data = UDR0;//接收的數據放入data變量
    usart0_rx_complete=0;//接收完成標志賦值0,還沒有完成


    if ((status & (FRAMING_ERROR0 | PARITY_ERROR0 | DATA_OVERRUN0))==0)//如果各標志位正確則,執行以下

    {

    usart0_rx_count++;//接收緩沖區指針加一
    switch (usart0_rx_count)
   {
        case 1:
        if(data==add//第一個字節是地址,讀入內部本機地址進行比較
        {
           usart0_rx_buf[0]=data;
           TIMSK0=0x01;//啟動定時器0,進行超時控制
        }
         else
         {
           usart0_rx_count=0;

         }
         break;

        case 2:


        if (((data==0x03)||(data==0x01)||(data==0x05)||(data==0x10))==0)//如果第一位不等于讀指令0x03,01,05,10功能碼,則清接收緩沖區指針
        {
         usart0_rx_count=0;
        }
        else//等于這幾個功能碼則進行,則將他放入接收數組,并預計接收數組長度,不是10碼時都是8個字節
        {
         usart0_rx_buf[1]=data;
         if (data!=0x10)
         {
          rx0_buf_size=8;
         }
        }
        break;

        case 3:
          usart0_rx_buf[2]=data;
        break;
        case 4:
          usart0_rx_buf[3]=data;
        break;
        case 5:
            usart0_rx_buf[4]=data;
        break;
        case 6:
          usart0_rx_buf[5]=data;
        break;
        case 7:
        usart0_rx_buf[6]=data;//10碼時接收的字節計數
        if (usart0_rx_buf[1]==0x10)
        {
         rx0_buf_size=9+usart0_rx_buf[6];
        }
        break;
        case 8:
        usart0_rx_buf[7]=data;//1,用10功能碼時有效的數據位,system_reg_data的數據,這里規定最多接收26個字節(不帶crc)
        break;
        case 9:
        usart0_rx_buf[8]=data;//2
        break;
        case 10:
        usart0_rx_buf[9]=data;//3
        break;
        case 11:
        usart0_rx_buf[10]=data;//4
        break;
        case 12:
        usart0_rx_buf[11]=data;//5
        break;
        case 13:
        usart0_rx_buf[12]=data;//6
        break;
        case 14:
        usart0_rx_buf[13]=data;//7
        break;
        case 15:
        usart0_rx_buf[14]=data;//8
        break;
        case 16:
        usart0_rx_buf[15]=data;//9
        break;
        case 17:
        usart0_rx_buf[16]=data;//10
        break;
        case 18:
        usart0_rx_buf[17]=data;//11
        break;
        case 19:
        usart0_rx_buf[18]=data;//12
        break;
        case 20:
        usart0_rx_buf[19]=data;//13
        break;
        case 21:
        usart0_rx_buf[20]=data;//14
        break;
        case 22:
        usart0_rx_buf[21]=data;//15
        break;
        case 23:
        usart0_rx_buf[22]=data;//16
        break;
        case 24:
        usart0_rx_buf[23]=data;//17
        break;
        case 25:
        usart0_rx_buf[24]=data;//18
        break;
        case 26:
        usart0_rx_buf[25]=data;//19
        break;
        case 27:
        usart0_rx_buf[26]=data;//20
        break;
        case 28:
        usart0_rx_buf[27]=data;//21
        break;
        case 29:
        usart0_rx_buf[28]=data;//22
        break;
        case 30:
        usart0_rx_buf[29]=data;//23
        break;
        case 31:
        usart0_rx_buf[30]=data;//24
        break;
        case 32:
        usart0_rx_buf[31]=data;//25
        break;
        case 33:
        usart0_rx_buf[32]=data;//26
        break;
        case 34:
        usart0_rx_buf[33]=data;//27
        break;
        case 35:
        usart0_rx_buf[34]=data;//28
        break;
   }

            if(usart0_rx_count>=rx0_buf_size)//串口0接收到了指定個數的數組則
            {
                usart0_rx_count=0;//接收緩沖區指針清零
                usart0_rx_complete=1;//串口0接收完標志
                time0_num=0;//串口0的中斷次數清零。它是超時控制的依據
                TIMSK0=0x00;//收到數據后則停止定時器0不進行超時控制
            }

    }
else
{
          usart0_rx_count=0;
}

  sei(); //開中斷
}
以上中斷接收程序可以實現上位機發來的0x03,01,05,10功能碼指令,并且可以自動判斷上位機發來10功能碼的包長。大家首先要深入了解modbus通訊協議的內涵,仔細體會各行程序的含義。其中本人加入了對通訊的超時控制,實際應用中很有必要。
前面已經將上位機發來的命令,用中斷接收的方式存入了單片機的接收緩沖區,中斷服務程序不能執行太長時間,所以要將對指令的解讀放入了主程序里。
把對modbus指令的解讀程序列出,如下,只給出框架,因為每種應用是不一樣的,需自己加入。
void run_modbus(void)
{

switch (usart0_rx_buf[1])
   {
    //判斷主機發來的modbus 功能碼是什么
    case 0x01://讀繼電器輸出的當前狀
        要加入回傳數據
    break;

    case 0x03://功能碼03

    要加入回傳數據

    break;

    case 0x05://05功能碼
    要加入回傳數據

    break;

    case 0x10://10功能碼
    要加入回傳數據

    break;
   }

}
以上程序完全依賴一個提供給上位機數據的數組,自己要仔細排列好數據順序,定義好長度。


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表