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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

基于MODBUS協議的單片機主程序 測試通過

  [復制鏈接]
跳轉到指定樓層
樓主
基于MODBUS協議的單片機主程序,測試已通過


單片機源程序:
  1. #include"reg51.h"
  2. #include"lcd.h"
  3. #include"address.h"
  4. #include"intrins.h"
  5. #include"crc.h"

  6. #define uint unsigned int
  7. #define uchar unsigned char

  8. uchar code sendbuf[]={0x01,0x03,0x00,0x0b,0x00,0x01,0xf5,0xc8};          
  9. //0x01 從站地址,0x03功能碼,0x00寄存器地址高位,0x09寄存器地址低位,0x00數據個數高位,0x01數據個數低位,0x54CRC校驗碼高位,0x08CRC校驗碼低位
  10. uchar code tab[]={'0','1','2','3','4','5','6','7','8','9'};
  11. uchar code error[]={"error!"};
  12. uchar tem[5],tem1[8];
  13. uchar resvbuf[7];
  14. int i,j;
  15. uchar resvend,temp2;
  16. uint crctemp,temp,temp1;

  17. void convert10(uint dat)
  18. {
  19.   uchar i;
  20.   tem1[0]='U';
  21.   tem1[1]='=';
  22.   tem1[7]='V';
  23.   tem[0]=dat/10000;
  24.   dat=dat%10000;
  25.   tem[1]=dat/1000;
  26.   dat=dat%1000;
  27.   tem[2]=dat/100;
  28.   dat=dat%100;
  29.   tem[3]=dat/10;
  30.   tem[4]=dat%10;
  31.   for (i=0;i<5;i++)
  32.   {
  33.     tem1[i+2]=tab[tem[i]];
  34.   }
  35. }

  36. void serial_int() interrupt 4         using 1
  37. {
  38. if(RI)
  39. {
  40.    RI=0;
  41.    //temp2=SBUF;
  42.     resvbuf[j++]=SBUF;  
  43.    if(j==7)
  44.    {
  45.      j=0;
  46.          resvend=1;
  47.    }   
  48. }       
  49. }            

  50. void initserial        ()
  51. {
  52. resvend=0;
  53. TMOD=0x20;
  54. PCON=0x00;
  55. SCON=0xd8;
  56. TL1=0xfd;
  57. TH1=0xfd;
  58. TR1=1;
  59. ES=1;
  60. }

  61. void displayout()
  62. {
  63.    crctemp=crccheck(resvbuf,5);
  64.    temp=resvbuf[5];
  65.    temp=temp << 8 | resvbuf[6];
  66.    if(temp==crctemp)
  67.    {
  68.         temp1=0;
  69.             temp1 |=resvbuf[3];
  70.                 temp1= temp1<<8 | resvbuf[4];
  71.                 convert10(temp1);
  72.                 printf(tem1,8);
  73.     }
  74.   else
  75.    {
  76.       printf(error,16);
  77.    }
  78. }          

  79. void delay_10us(uchar n)
  80. {
  81.    do
  82.    {
  83.      _nop_();
  84.      _nop_();
  85.      _nop_();
  86.      _nop_();
  87.      _nop_();
  88.    }while(--n);
  89. }

  90. void delay_ms(uint n)
  91. {
  92.   do
  93.   {
  94.     delay_10us(131);
  95.    }while(--n);
  96. }


  97. void main()
  98. {
  99. initlcd();
  100. initserial();
  101. EA=1;
  102. while(1)
  103. {
  104.   i=0;


  105. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

下載:
modbus主機單片機程序.rar (35.81 KB, 下載次數: 136)

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

使用道具 舉報

沙發
ID:93224 發表于 2017-6-17 00:25 | 只看該作者
實物測試通過了嗎
回復

使用道具 舉報

板凳
ID:337808 發表于 2021-1-17 17:39 | 只看該作者
簡單,明了,可惜的是各種判斷都省略了,如果用在嚴謹的的場合,顯然是不適用的。
回復

使用道具 舉報

地板
ID:385637 發表于 2021-1-18 08:39 | 只看該作者
用在嚴謹場合不形,MODBUS最基本的一串數據接收完成的時間間隔判斷都沒有
回復

使用道具 舉報

5#
ID:929006 發表于 2021-7-25 13:55 | 只看該作者
大鍋,拷貝你得程序,LCD根本不顯示
回復

使用道具 舉報

6#
ID:929006 發表于 2021-7-25 20:37 | 只看該作者
為么我的程序,LCD不顯示
#include"reg51.h"
#include"address.h"
#include"intrins.h"
#include"crc.h"

#define LCD1602_DB  P0
sbit LCD1602_RS = P1^0;
sbit LCD1602_RW = P1^1;
sbit LCD1602_E  = P1^5;

void InitLcd1602();
void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);

#define uint unsigned int
#define uchar unsigned char

uchar code sendbuf[]={0x01,0x03,0x02,0x00,0x00,0x03,0x04,0x73};          
//0x01 從站地址,0x03功能碼,0x20寄存器地址高位,0x00寄存器地址低位,0x00數據個數高位,0x03數據個數低位,0x04CRC校驗碼高位,0x73CRC校驗碼低位
uchar code tab[]={'0','1','2','3','4','5','6','7','8','9'};
uchar code error[]={"error!"};
uchar tem[5],tem1[8];
uchar resvbuf[10];
int i,j;
uchar resvend,temp2;
uint crctemp,temp,temp1;


void convert10(uint dat)
{
  uchar i;
  tem1[0]='U';
  tem1[1]='=';
  tem1[7]='V';
  tem[0]=dat/10000;
  dat=dat%10000;
  tem[1]=dat/1000;
  dat=dat%1000;
  tem[2]=dat/100;
  dat=dat%100;
  tem[3]=dat/10;
  tem[4]=dat%10;
  for (i=0;i<5;i++)
  {
    tem1[i+2]=tab[tem[i]];
  }
}

void serial_int() interrupt 4         using 1
{
if(RI)
{
   RI=0;
   //temp2=SBUF;
    resvbuf[j++]=SBUF;  
   if(j==7)
   {
     j=0;
         resvend=1;
   }   
}       
}            

void initserial        ()
{
resvend=0;
TMOD=0x20;
PCON=0x00;
SCON=0xd8;
TL1=0xfd;
TH1=0xfd;
TR1=1;
ES=1;
}

void displayout()
{
   crctemp=crccheck(resvbuf,9);
   temp=resvbuf[9];
   temp=temp << 8 | resvbuf[10];
   if(temp==crctemp)
   {
        temp1=0;
            temp1 |=resvbuf[3];
                temp1= temp1<<8 | resvbuf[4];
                convert10(temp1);
                LcdShowStr(0, 1, tem1);
                //printf(tem1,8);
    }
  else
   {
                LcdShowStr(0, 1,error );
      //printf(error,16);
   }
}          

void delay_10us(uchar n)
{
   do
   {
     _nop_();
     _nop_();
     _nop_();
     _nop_();
     _nop_();
   }while(--n);
}

void delay_ms(uint n)
{
  do
  {
    delay_10us(131);
   }while(--n);
}

/* 等待液晶準備好 */
void LcdWaitReady()
{
    unsigned char sta;
   
    LCD1602_DB = 0xFF;
    LCD1602_RS = 0;
    LCD1602_RW = 1;
    do {
        LCD1602_E = 1;
        sta = LCD1602_DB; //讀取狀態字
        LCD1602_E = 0;
    } while (sta & 0x80); //bit7等于1表示液晶正忙,重復檢測直到其等于0為止
}
/* 向LCD1602液晶寫入一字節命令,cmd-待寫入命令值 */
void LcdWriteCmd(unsigned char cmd)
{
    LcdWaitReady();
    LCD1602_RS = 0;
    LCD1602_RW = 0;
    LCD1602_DB = cmd;
    LCD1602_E  = 1;
    LCD1602_E  = 0;
}
/* 向LCD1602液晶寫入一字節數據,dat-待寫入數據值 */
void LcdWriteDat(unsigned char dat)
{
    LcdWaitReady();
    LCD1602_RS = 1;
    LCD1602_RW = 0;
    LCD1602_DB = dat;
    LCD1602_E  = 1;
    LCD1602_E  = 0;
}
/* 設置顯示RAM起始地址,亦即光標位置,(x,y)-對應屏幕上的字符坐標 */
void LcdSetCursor(unsigned char x, unsigned char y)
{
    unsigned char addr;
   
    if (y == 0)  //由輸入的屏幕坐標計算顯示RAM的地址
        addr = 0x00 + x;  //第一行字符地址從0x00起始
    else
        addr = 0x40 + x;  //第二行字符地址從0x40起始
    LcdWriteCmd(addr | 0x80);  //設置RAM地址
}
/* 在液晶上顯示字符串,(x,y)-對應屏幕上的起始坐標,str-字符串指針 */
void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str)
{
    LcdSetCursor(x, y);   //設置起始地址
    while (*str != '\0')  //連續寫入字符串數據,直到檢測到結束符
    {
        LcdWriteDat(*str++);  //先取str指向的數據,然后str自加1
    }
}
/* 初始化1602液晶 */
void InitLcd1602()
{
    LcdWriteCmd(0x38);  //16*2顯示,5*7點陣,8位數據接口
    LcdWriteCmd(0x0C);  //顯示器開,光標關閉
    LcdWriteCmd(0x06);  //文字不動,地址自動+1
    LcdWriteCmd(0x01);  //清屏
}


void main()
{
InitLcd1602();
initserial();
EA=1;
while(1)
{
  i=0;
  while(i<8)
  {
   SBUF=sendbuf[i];
   while(!TI);
   delay_10us(50);
   TI=0;
   i++;
  }
delay_ms(1000);
if(resvend)
  {
    resvend=0;
        displayout();
  }          
       

  }       
}  
回復

使用道具 舉報

7#
ID:929006 發表于 2021-7-26 12:30 | 只看該作者
上面程序有點錯誤,改了一下。還是不顯示
#include"reg51.h"
#include"intrins.h"
#include"crc.h"

#define LCD1602_DB  P0
sbit LCD1602_RS = P1^0;
sbit LCD1602_RW = P1^1;
sbit LCD1602_E  = P1^5;

void InitLcd1602();
void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);

#define uint unsigned int
#define uchar unsigned char

uchar code sendbuf[]={0x01,0x03,0x02,0x00,0x00,0x03,0x04,0x73};          
//0x01 從站地址,0x03功能碼,0x20寄存器地址高位,0x00寄存器地址低位,0x00數據個數高位,0x03數據個數低位,0x04CRC校驗碼高位,0x73CRC校驗碼低位
uchar code tab[]={'0','1','2','3','4','5','6','7','8','9'};
uchar code error[]={"error!"};
uchar tem[5],tem1[9];
uchar resvbuf[11];
int i,j;
uchar resvend,temp2;
uint crctemp,temp,temp1;


void convert10(uint dat)
{
  uchar i;
  tem1[0]='U';
  tem1[1]='=';
  tem1[7]='V';
  tem1[8]='\0';
  tem[0]=dat/10000;
  dat=dat%10000;
  tem[1]=dat/1000;
  dat=dat%1000;
  tem[2]=dat/100;
  dat=dat%100;
  tem[3]=dat/10;
  tem[4]=dat%10;
  for (i=0;i<5;i++)
  {
    tem1[i+2]=tab[tem[i]];
  }
}

void serial_int() interrupt 4         using 1
{
if(RI)
{
   RI=0;
   //temp2=SBUF;
    resvbuf[j++]=SBUF;  
   if(j==11)
   {
     j=0;
         resvend=1;
   }   
}       
}            

void initserial        ()
{
resvend=0;
TMOD=0x20;
PCON=0x00;
SCON=0xd8;
TL1=0xfd;
TH1=0xfd;
TR1=1;
ES=1;
}

void displayout()
{
   crctemp=crccheck(resvbuf,9);
   temp=resvbuf[9];
   temp=temp << 8 | resvbuf[10];
   if(temp==crctemp)
   {
        temp1=0;
            temp1 |=resvbuf[3];
                temp1= temp1<<8 | resvbuf[4];
                convert10(temp1);
                LcdShowStr(0, 1, tem1);
                //printf(tem1,8);
    }
  else
   {
                LcdShowStr(0,1,error);
      //printf(error,16);
   }
}          

void delay_10us(uchar n)
{
   do
   {
     _nop_();
     _nop_();
     _nop_();
     _nop_();
     _nop_();
   }while(--n);
}

void delay_ms(uint n)
{
  do
  {
    delay_10us(131);
   }while(--n);
}

/* 等待液晶準備好 */
void LcdWaitReady()
{
    unsigned char sta;
   
    LCD1602_DB = 0xFF;
    LCD1602_RS = 0;
    LCD1602_RW = 1;
    do {
        LCD1602_E = 1;
        sta = LCD1602_DB; //讀取狀態字
        LCD1602_E = 0;
    } while (sta & 0x80); //bit7等于1表示液晶正忙,重復檢測直到其等于0為止
}
/* 向LCD1602液晶寫入一字節命令,cmd-待寫入命令值 */
void LcdWriteCmd(unsigned char cmd)
{
    LcdWaitReady();
    LCD1602_RS = 0;
    LCD1602_RW = 0;
    LCD1602_DB = cmd;
    LCD1602_E  = 1;
    LCD1602_E  = 0;
}
/* 向LCD1602液晶寫入一字節數據,dat-待寫入數據值 */
void LcdWriteDat(unsigned char dat)
{
    LcdWaitReady();
    LCD1602_RS = 1;
    LCD1602_RW = 0;
    LCD1602_DB = dat;
    LCD1602_E  = 1;
    LCD1602_E  = 0;
}
/* 設置顯示RAM起始地址,亦即光標位置,(x,y)-對應屏幕上的字符坐標 */
void LcdSetCursor(unsigned char x, unsigned char y)
{
    unsigned char addr;
   
    if (y == 0)  //由輸入的屏幕坐標計算顯示RAM的地址
        addr = 0x00 + x;  //第一行字符地址從0x00起始
    else
        addr = 0x40 + x;  //第二行字符地址從0x40起始
    LcdWriteCmd(addr | 0x80);  //設置RAM地址
}
/* 在液晶上顯示字符串,(x,y)-對應屏幕上的起始坐標,str-字符串指針 */
void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str)
{
    LcdSetCursor(x, y);   //設置起始地址
    while (*str != '\0')  //連續寫入字符串數據,直到檢測到結束符
    {
        LcdWriteDat(*str++);  //先取str指向的數據,然后str自加1
    }
}
/* 初始化1602液晶 */
void InitLcd1602()
{
    LcdWriteCmd(0x38);  //16*2顯示,5*7點陣,8位數據接口
    LcdWriteCmd(0x0C);  //顯示器開,光標關閉
    LcdWriteCmd(0x06);  //文字不動,地址自動+1
    LcdWriteCmd(0x01);  //清屏
}


void main()
{
InitLcd1602();
initserial();
EA=1;
while(1)
{
  i=0;
  while(i<8)
  {
   SBUF=sendbuf[i];
   while(!TI);
   delay_10us(50);
   TI=0;
   i++;
  }
delay_ms(1000);
if(resvend)
  {
    resvend=0;
        displayout();
  }          
       

  }       
}  

回復

使用道具 舉報

8#
ID:768666 發表于 2021-8-6 21:59 | 只看該作者
不知道這個程序能不能用,學飛一下
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩精品一区二区三区中文字幕 | 国产1区| 国产精品久久久久一区二区三区 | 日本午夜免费福利视频 | 欧美jizzhd精品欧美巨大免费 | 欧美性猛片aaaaaaa做受 | 拍拍无遮挡人做人爱视频免费观看 | 国内精品久久久久久久 | 国产va| 一级片免费观看 | 成人在线免费视频 | 欧美日韩在线一区二区 | 成人午夜在线 | 亚洲高清视频在线观看 | 国产精品毛片久久久久久久 | 欧美一区二区视频 | 国产成人免费一区二区60岁 | 亚洲视频欧美视频 | 久久综合久色欧美综合狠狠 | 久久精品国产久精国产 | 中文字幕在线中文 | 日本a在线| 国产激情在线看 | 久久精品国产99国产精品 | 米奇成人网 | 国产成人免费视频 | 999久久久| a级黄色网 | 在线资源视频 | 全部免费毛片在线播放网站 | 日韩午夜网站 | jizz在线免费观看 | 中文在线一区 | 国产在线不卡 | 精品一级| 久久精品欧美一区二区三区麻豆 | 亚洲一区二区三区免费在线观看 | 欧美一区二区三区在线看 | 欧美日韩中文在线 | 福利av在线 | 日日射影院|