写一个遵循dl/t645-2007通信规约的51单片机c语言程序
时间: 2024-01-20 16:02:19 浏览: 34
以下是一个简单的遵循DL/T645-2007通信规约的51单片机C语言程序,可以用于读取电表数据:
```c
#include <reg51.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
sbit RS485_EN = P1^0; // RS485使能控制引脚
void init_uart()
{
TMOD = 0x20;
SCON = 0x50;
PCON = 0x80;
TH1 = 0xFD;
TL1 = 0xFD;
TR1 = 1;
}
void init_rs485()
{
RS485_EN = 0;
}
void send_byte(uchar dat)
{
SBUF = dat;
while (!TI);
TI = 0;
}
uchar recv_byte()
{
uchar dat;
while (!RI);
dat = SBUF;
RI = 0;
return dat;
}
void send_frame(uchar *buf, uint len)
{
uint i;
RS485_EN = 1;
for (i = 0; i < len; i++)
{
send_byte(buf[i]);
}
RS485_EN = 0;
}
uint recv_frame(uchar *buf, uint len)
{
uint i = 0;
while (i < len)
{
buf[i] = recv_byte();
if (i == 0 && buf[0] != 0x68)
{
continue;
}
i++;
if (buf[0] == 0x68 && i == 12)
{
break;
}
if (buf[0] == 0x10 && i == 2)
{
break;
}
}
return i;
}
void read_meter()
{
uchar cmd[] = {0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0x68, 0x11, 0x04, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x16};
uchar buf[256];
uint len;
send_frame(cmd, sizeof(cmd));
len = recv_frame(buf, sizeof(buf));
if (len > 0 && buf[0] == 0x68 && buf[2] == 0x91 && buf[21] == 0x16)
{
uint meter_value = buf[15] << 24 | buf[14] << 16 | buf[13] << 8 | buf[12];
printf("Meter Value: %u\n", meter_value);
}
}
void main()
{
init_uart();
init_rs485();
while (1)
{
read_meter();
delay(500);
}
}
```
该程序使用51单片机自带的UART模块和GPIO控制RS485芯片,发送读取电表数据的命令,接收电表返回的数据,并打印出来。你可以根据自己的实际情况修改串口波特率及RS485芯片使能控制引脚等参数。