久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3316|回復: 0
收起左側

我現(xiàn)在正在研究基于avr,mega128的modbus 源碼

[復制鏈接]
ID:167315 發(fā)表于 2017-3-1 09:20 | 顯示全部樓層 |閱讀模式
我現(xiàn)在正在研究基于avr,mega128的modbus 做了個modbus   也是基于網(wǎng)友的代碼調試的  上傳

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

    status = UCSR0A;//ucsr0a賦值狀態(tài)標志
    data = UDR0;//接收的數(shù)據(jù)放入data變量
    usart0_rx_complete=0;//接收完成標志賦值0,還沒有完成


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

    {

    usart0_rx_count++;//接收緩沖區(qū)指針加一
    switch (usart0_rx_count)
   {
        case 1:
        if(data==add//第一個字節(jié)是地址,讀入內部本機地址進行比較
        {
           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功能碼,則清接收緩沖區(qū)指針
        {
         usart0_rx_count=0;
        }
        else//等于這幾個功能碼則進行,則將他放入接收數(shù)組,并預計接收數(shù)組長度,不是10碼時都是8個字節(jié)
        {
         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碼時接收的字節(jié)計數(shù)
        if (usart0_rx_buf[1]==0x10)
        {
         rx0_buf_size=9+usart0_rx_buf[6];
        }
        break;
        case 8:
        usart0_rx_buf[7]=data;//1,用10功能碼時有效的數(shù)據(jù)位,system_reg_data的數(shù)據(jù),這里規(guī)定最多接收26個字節(jié)(不帶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接收到了指定個數(shù)的數(shù)組則
            {
                usart0_rx_count=0;//接收緩沖區(qū)指針清零
                usart0_rx_complete=1;//串口0接收完標志
                time0_num=0;//串口0的中斷次數(shù)清零。它是超時控制的依據(jù)
                TIMSK0=0x00;//收到數(shù)據(jù)后則停止定時器0不進行超時控制
            }

    }
else
{
          usart0_rx_count=0;
}

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

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

    case 0x03://功能碼03

    要加入回傳數(shù)據(jù)

    break;

    case 0x05://05功能碼
    要加入回傳數(shù)據(jù)

    break;

    case 0x10://10功能碼
    要加入回傳數(shù)據(jù)

    break;
   }

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


回復

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 在线视频国产一区 | av三级| 精品久久影院 | 天天色综 | www.99精品| 亚洲国产精品成人 | 国产男女视频 | av福利网 | 中文字幕 在线观看 | 午夜在线免费观看 | 神马久久久久久久久久 | 亚洲免费av一区 | 久久久久久国产精品免费免费 | 久久国产成人 | 久久久久久久久久久久久91 | 欧美综合一区二区三区 | 国产丝袜一区二区三区免费视频 | 日本电影一区二区 | 国产精品久久久久久久久久久久久 | japan21xxxxhd美女| 亚洲一区二区av | 日本视频在线播放 | 精品国产一区二区在线 | 天堂资源最新在线 | 性欧美hd | 成人午夜在线视频 | 亚洲视频在线看 | 国产精品久久久久久久久久久久久 | 欧美一区二区三区在线免费观看 | 第一区在线观看免费国语入口 | 久久国产精品免费一区二区三区 | 亚洲区一区二区 | 欧美精品一区三区 | 密色视频 | 日本免费一区二区三区视频 | 久久丁香| 亚州毛片| 91精品国产91久久综合桃花 | 亚洲国产一区二区视频 | 国产精品视频www | 一区二区影院 |