打印

51单片机读modbus仪表数据

[复制链接]
1344|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tongyajunlwj|  楼主 | 2016-4-9 19:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
dirtwillfly| | 2016-4-9 22:35 | 只看该作者
这个协议不难的,你卡在哪里了?

使用特权

评论回复
板凳
伏尔加的鱼| | 2016-4-10 11:09 | 只看该作者
看看协议,挺好弄的

使用特权

评论回复
地板
ningling_21| | 2016-4-10 13:02 | 只看该作者
先把仪表的通信数据格式弄清楚

使用特权

评论回复
5
oufuqiang| | 2016-4-10 15:22 | 只看该作者
先用电脑把数据读到手,再想办法用单片机去读。

使用特权

评论回复
6
xuyaqi| | 2016-4-10 20:19 | 只看该作者
仪表是你们的吗,如果是别人的问他们要例程。

使用特权

评论回复
7
tongyajunlwj|  楼主 | 2016-4-11 11:32 | 只看该作者
dirtwillfly 发表于 2016-4-9 22:35
这个协议不难的,你卡在哪里了?

#include <ioCC2530.h>
#include "type.h"
#include "hal_lcd.h"

//unsigned char uart[6]=0;
char tt[]="0103000c00020408";
//char TxData[TX_SIZE];        //存储发送字符串
char RxBuf=0;
char RxDate[51];
int count=0;
void HalLcd_HW_WaitUs(uint16 microSecs);
void InitUart(void)
{
    PERCFG = 0x00;           //外设控制寄存器 USART 0的IO位置:0为P0口位置1
    P0SEL = 0x0c;            //P0_2,P0_3用作串口(外设功能)
    P2DIR &= ~0xC0;          //P0优先作为UART0
   
    U0CSR |= 0x80;           //设置为UART方式
    U0GCR |= 8;                                       
    U0BAUD |= 59;           //波特率设为115200
    UTX0IF = 0;              //UART0 TX中断标志初始置位0
    U0CSR |= 0x40;           //允许接收
    IEN0 |= 0x84;            //开总中断允许接收中断
}
void UartSendString(char *Data, int len)
{
    int i;
    for(i=0; i<len; i++)
    {
        U0DBUF = *Data++;
        while(UTX0IF == 0);
        UTX0IF = 0;
    }
}

#pragma vector = URX0_VECTOR
__interrupt void UART0_ISR(void)
{
    URX0IF = 0;       // 清中断标志
    RxBuf= U0DBUF;                           
}

void main(void)
{   
   
    CLKCONCMD &= ~0x40;               //设置系统时钟源为32MHZ晶振
    while(CLKCONSTA & 0x40);          //等待晶振稳定为32M
    CLKCONCMD &= ~0x47;               //设置系统主时钟频率为32MHZ   
      
    InitUart();                       //调置串口相关寄存器
    HalLcd_HW_Init(); //初始化LCD   
    //memset(uart, 0, 50);       //数据清0
   // memcpy(uart, tt, sizeof(tt)); //复制发送字符串到TxData
    HalLcd_HW_WriteLine(1,tt);
    UartSendString(tt, sizeof(tt)); //串口发送数据
/*
    UartSendString("01", 2);
    UartSendString("03", 2);
    UartSendString("00", 2);
    UartSendString("0c", 2);
    UartSendString("00", 2);
    UartSendString("02", 2);
    UartSendString("04", 2);
    UartSendString("08", 2);
    */
   // HalLcd_HW_WaitUs(20);
   
   while(RxBuf!='\0')
   {
       RxDate[count++]=RxBuf;
   }
    HalLcd_HW_WriteLine(2,RxDate);
  //  HalLcd_HW_WriteLine(3,"i am");

}
以上是我的程序 通过查仪表的说明书 发送 01 03 00 0c 00 02 04 08给仪表 然后接收仪表的回传数据显示到12864上 但是没有显示任何东西

使用特权

评论回复
8
hbzjt2011| | 2016-4-11 11:36 | 只看该作者
你先确保12864驱动可用,然后在研究通讯的问题

使用特权

评论回复
9
一粒尘a_a| | 2016-4-11 11:36 | 只看该作者
其实我来这也是想要例程的。呵呵
没有的话就自己从头写呗。像这类通信的程序不要一上来就到仪表上测试,慢。最好用电脑的通信口通信,并截取通信数据(也是对仪表通信协议的学习和验证)。然后再将写的单片机程序与PC通信,查看是否满足通信协议。最后才是与仪表通信测试。

使用特权

评论回复
10
tongyajunlwj|  楼主 | 2016-4-11 12:51 | 只看该作者
hbzjt2011 发表于 2016-4-11 11:36
你先确保12864驱动可用,然后在研究通讯的问题

可以的 我最后一句 就是看 12864能不能显示

使用特权

评论回复
11
hbzjt2011| | 2016-4-11 13:20 | 只看该作者
tongyajunlwj 发表于 2016-4-11 12:51
可以的 我最后一句 就是看 12864能不能显示

那样的话,先用串口调试助手发送指定指令,看是否有正常数据返回,如果正常,记下通讯方式(波特率等),运行你的程序,同样可以先发给串口助手,看发送的数据是否正确

使用特权

评论回复
12
yklstudent| | 2016-4-11 13:25 | 只看该作者
估计楼主手册说明理解错了吧,发送的估计是十六进行的01 03 00 01 00 08 15 cc,楼主却发送字符
那样能正常通信就见鬼了

使用特权

评论回复
13
一粒尘a_a| | 2016-4-11 13:37 | 只看该作者
楼主,你的tt[]初始化是不是有问题?
你用的ASCII吗吗?若不是,是不是应该用下面的赋值:tt[]={0x01,0x03,0x00,0x0c,0x00,0x02,0x04,0x08}

使用特权

评论回复
14
tongyajunlwj|  楼主 | 2016-4-25 20:46 | 只看该作者
yklstudent 发表于 2016-4-11 13:25
估计楼主手册说明理解错了吧,发送的估计是十六进行的01 03 00 01 00 08 15 cc,楼主却发送字符
那样能正常 ...

我用电脑串口调试工具通过usb转485转换器读modbus仪表的数据 可以读的上来  但是我用单片机读好像数据都没有发过去,但是我的数据是发到串口的 数据格式改成16进制的了 usb转485的转换器的txd和rxd的灯都不亮 不知道为什么发不过去

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

18

帖子

0

粉丝