标题:
消洗台单片机源程序 RS485和Modbus协议的寄存器读取和单寄存器写入操作
[打印本页]
作者:
NH6496
时间:
2017-3-15 16:09
标题:
消洗台单片机源程序 RS485和Modbus协议的寄存器读取和单寄存器写入操作
分享一个消洗台的单片机程序源码:
0.png
(75.04 KB, 下载次数: 76)
下载附件
2017-3-15 22:56 上传
完整源码下载:
modbus通讯.zip
(74.71 KB, 下载次数: 64)
2017-3-15 16:07 上传
点击文件名下载附件
下载积分: 黑币 -5
部分源码预览:
/*
*******************************************************************************
*
*
* 文件名:main.c
* 描 述:RS485的Modbus
*
* 备 注:
* 支持Modbus协议的寄存器读取和单寄存器写入操作
*******************************************************************************
*/
#include <reg52.h>
#include "i2c.h"
#define KEY P1
typedef unsigned int uint;
typedef unsigned char u8;
unsigned char addr;
unsigned char dat;
int s=0,m=1,sa=0,ma=2,num;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit OUTa=P2^5;
sbit OUT=P2^6;
sbit LE=P2^7;
uint a[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0到9
uint sg,ss,mg,ms,sga,ssa,mga,msa,K=0;
sbit BUZZ = P1^5;
bit flagBuzzOn = 0;
unsigned char KH,KL;
unsigned char T0RH = 0;
unsigned char T0RL = 0;
unsigned char regGroup[5];
unsigned char MODADD=0X01;
void ConfigTimer0(unsigned int ms);
extern void UartDriver();
extern void ConfigUART(unsigned int baud);
extern void UartRxMonitor(unsigned char ms);
extern void UartWrite(unsigned char *buf, unsigned char len);
extern unsigned int GetCRC16(unsigned char *ptr, unsigned char len);
extern void zhu();
extern void DigDisplay();
extern void Timer1Init();
extern void delay(uint i);
extern int Keypros();
extern void At24c02Write(unsigned char addr,unsigned char dat) ;
extern unsigned char At24c02Read(unsigned char addr);
void main()
{
unsigned char x=~OUT,y=~OUTa;
m=At24c02Read(1);
delay(1000);
ma=At24c02Read(2);
while (1)
{
while((OUT&OUTa)==1)
{
EA = 1;
ConfigTimer0(1);
ConfigUART(9600);
while ((KEY&0x0f)!=0x01)
{
DigDisplay();
UartDriver();
Keypros();
if((KEY&0x0f)==0x01)
{
delay(3000);
if((KEY&0x0f)==0x01)
OUT=0;
return;
}
}
}
if((m||ma)!=0)
{
zhu();
KL=At24c02Read(4);
delay(1000);
KH=At24c02Read(3);
delay(1000);
K=(KH<<8)+KL;
DigDisplay();
K++;
KH=K>>8;
KL=K&0X00FF;
At24c02Write(4,KL);
delay(1000);
while(K==100){DigDisplay();}
At24c02Write(3,KH);
delay(1000);
}
}
}
void UartAction(unsigned char *buf, unsigned char len)
{
unsigned char i;
unsigned char cnt;
unsigned int crc;
unsigned char crch, crcl;
MODADD=At24c02Read(0);
if (buf[0] !=MODADD ) //本机地址设定为0x01,
{
return;
}
crc = GetCRC16(buf, len-2);
crch = crc >> 8;
crcl = crc & 0xFF;
if ((buf[len-2]!=crch) || (buf[len-1]!=crcl))
{
return;
}
switch (buf[1])
{
case 0x03:
if ((buf[2]==0x00) && (buf[3]<=0x05))
{
if (buf[3] <= 0x04)
{
regGroup[0]=At24c02Read(0);
regGroup[1]=At24c02Read(1);
regGroup[2]=At24c02Read(2);
regGroup[3]=At24c02Read(3);
regGroup[4]=At24c02Read(4);
i = buf[3];
cnt = buf[5];
buf[2] = cnt*2;
len = 3;
while (cnt--)
{
buf[len++] = 0x00;
buf[len++] = regGroup[i++];
}
}
else
{
buf[2] = 2;
buf[3] = 0x00;
buf[4] = flagBuzzOn;
len = 5;
}
break;
}
else
{
buf[1] = 0x83;
buf[2] = 0x02;
len = 3;
break;
}
case 0x06:
if ((buf[2]==0x00) && (buf[3]<=0x05))
{
if (buf[3] <= 0x04)
{
switch(buf[3])
{
case 0:
i = buf[3];
regGroup[i] = buf[5];
MODADD = regGroup[i];
At24c02Write(0,MODADD);
case 1:
i = buf[3];
regGroup[i] = buf[5];
m = regGroup[i];
At24c02Write(1,m);
case 2:
i = buf[3];
regGroup[i] = buf[5];
ma = regGroup[i];
At24c02Write(2,ma);
}
}
else
{
flagBuzzOn = (bit)buf[5];
}
len -= 2;
break;
}
else
{
buf[1] = 0x86;
buf[2] = 0x02;
len = 3;
break;
}
default:
buf[1] |= 0x80;
buf[2] = 0x01;
len = 3;
break;
}
crc = GetCRC16(buf, len);
buf[len++] = crc >> 8;
buf[len++] = crc & 0xFF;
UartWrite(buf, len);
}
/* 配置并启动T0 */
void ConfigTimer0(unsigned int ms)
{
unsigned long tmp;
tmp = 11059200 / 12;
tmp = (tmp * ms) / 1000;
tmp = 65536 - tmp;
tmp = tmp + 33;
T0RH = (unsigned char)(tmp>>8);
T0RL = (unsigned char)tmp;
TMOD &= 0xF0;
TMOD |= 0x01;
TH0 = T0RH;
TL0 = T0RL;
ET0 = 1;
TR0 = 1;
}
/* T0中断服务函数,执行串口接收监控和蜂鸣器驱动 */
void InterruptTimer0() interrupt 1
{
TH0 = T0RH;
TL0 = T0RL;
if (flagBuzzOn)
BUZZ = ~BUZZ;
else
BUZZ = 1;
UartRxMonitor(1);
}
/*******************************************************************************
* 函 数 名 : delay
* 函数功能 : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(uint i)
{
while(i--);
}
/*******************************************************************************
* 函数名 :Keypros()
* 函数功能 :按键处理函数
* 输入 : 无
* 输出 : 键值
*******************************************************************************/
int Keypros()
{
if ((OUT&OUTa)!=0)
{
if((KEY&0x0f)==0x05)
{
m--;
delay(30000);
if(m<=1)
m=1;
}
if((KEY&0x0f)==0x06)
{
m++;
delay(40000);
if(m>30)
m=30;
}
if((KEY&0x0f)==0x08)
{
ma--;
delay(40000);
if(ma<=1)
ma=1; //现在第1次ma减到0会死机---------------------------------------
}
if((KEY&0x0f)==0x09)
{
ma++ ;
delay(30000);
if(ma>30)
ma=30;
}
if((KEY&0x0f)==0x0a)
{
delay(1000);
if((KEY&0x0f)==0x0a)
{
At24c02Write(1,m);
delay(1000); // 等待写完。
At24c02Write(2,ma);
}
}
if((KEY&0x0f)==0x0c)
{
delay(1000);
if((KEY&0x0f)==0x0c)
{
num=At24c02Read(1); //读取EEPROM地址1内的数据保存在num中
m=num;
delay(1000);
num=At24c02Read(2);
ma=num;
}
}
}
return(m,ma);
}
/***************************************************
动态置LEDCOM口低电平
**********************/
void DigDisplay()
{
u8 i;
sg=s%10;
ss=s/10;
mg=m%10;
ms=m/10;
sga=sa%10;
ssa=sa/10;
mga=ma%10;
msa=ma/10;
for(i=0;i<8;i++)
{
switch(i)
{
case(0):
LSA=0;LSB=0;LSC=0; P0=a[sg]; break;//显示第0位
case(1):
LSA=1;LSB=0;LSC=0; P0=a[ss]; break;//显示第1位
case(2):
LSA=0;LSB=1;LSC=0; P0=a[mg]; break;//显示第2位
case(3):
LSA=1;LSB=1;LSC=0; P0=a[ms];break;//显示第3位
case(4):
LSA=0;LSB=0;LSC=1; P0=a[sga]; break;//显示第4位
case(5):
LSA=1;LSB=0;LSC=1; P0=a[ssa];break;//显示第5位
case(6):
LSA=0;LSB=1;LSC=1; P0=a[mga];; break;//显示第6位
case(7):
LSA=1;LSB=1;LSC=1; P0=a[msa]; break;//显示第7位
}
delay(10); // 增减亮度。
P0=0x00;//消隐
}
}
/*******************************************************************************
* 函 数 名 : Timer1Init
* 函数功能 : 定时器1初始化
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Timer1Init()
{
TMOD=0X11;
ET1=1;
EA=1;
TR1=1;
}
/*******************************************************************************
* 函 数 名 : void Timer1() interrupt 3
* 函数功能 : 定时器1中断函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Timer1() interrupt 3
{
static uint i;
TH1=0X3c; //给定时器赋初值,定时50ms
TL1=0Xb0;
i++;
if((s||m)!=0)
{
if(i==20) //中断次数
{
{
i=0;
s--;
}
if(s<=-1&&(m!=0))
{
s=59;
m--;
}
}
}
else
{
if((sa||ma)!=0)
{
if(i==20)
{
{
i=0;
sa--;
}
if(sa<=-1&&(ma!=0))
{
sa=59;
ma--;
}
else{ ma-=0; if(ma<=-1) { ma=0; }}
}
else{ sa-=0; if(sa<=-1) { sa=0; }}
if((sa||ma)!=0)
{
OUTa=0; OUT=1;
}
if((sa||ma)==0)
{OUTa=1; OUT=1;TR1=0;}
}
}
}
/*******************************************************************************
* 函 数 名 : zhu
* 函数功能
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void zhu()
{ while(ma||sa)
{
if((KEY&0x0f)!=0x01)
{
Keypros();
DigDisplay();
}
else
{
{
if((KEY&0x0f)==0x01)
delay(1000);
if((KEY&0x0f)==0x01)
{
num=At24c02Read(1); //读取EEPROM地址1内的数据保存在num中
m=num;
delay(1000);
num=At24c02Read(2);
ma=num;
while (sa||ma!=0)
{ DigDisplay();
Timer1Init();
}
}
}
}
}
}
复制代码
作者:
pangjineng
时间:
2018-1-21 10:12
陋习,一点注释没有。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1