基于modbus协议的温度采集系统程序清单#include //定义头文件
#define uchar unsigned char //习惯性用法宏定义
sfr AUXR=0X8E; //定义特殊功能寄存器,其地址为8EH
uchar Prg; //定义变量
sbit Clk164=P0^1; //在bdata区定义可寻址变量Clk164,74LS164的脉冲
端接P0.1
sbit Data164=P0^2; //在bdata区定义可寻址变量Data 164,74LS164的
数据端接P0.2
int Tempture; //定义变量
int ...
#include
//定义头文件
#define uchar unsigned char //习惯性用法宏定义
sfr AUXR=0X8E; //定义特殊功能寄存器,其地址为8EH
uchar Prg; //定义变量
sbit Clk164=P0^1; //在bdata区定义可寻址变量Clk164,74LS164的脉冲
端接P0.1
sbit Data164=P0^2; //在bdata区定义可寻址变量Data 164,74LS164的
数据端接P0.2
int Tempture; //定义变量
int AdV alue;
uchar CovertCount;
uchar xdata DispBuf[4]; //在xdata区定义一个数据缓冲区
uchar code shapeCode[10]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6}; //字型码
extern bit fig_10ms; //定义一个外部位标量
extern void initUart(void); //外部定义
extern void initTimer(void);
extern int AdSample();
extern uchar Store0;
extern uchar Store1;
extern uchar Store2;
extern uchar Store3;
extern uchar Store4;
extern uchar Store5;
extern bit bMaySendData;
uchar xdata RecBuff[10]; //接受数据缓冲区
uchar xdata SendBuff[10]; //发送数据缓冲区
extern bit fig_10ms;
void RecProcess(uchar InData); //接受
void SendPrepare(); //发送准备函数
extern int AdSample(); //AD转换函数
//###############################字型码送显示子程序############################
void Diap(unsigned char InData)
{
unsigned char j; //定义局部变量
char i;
j=~InData; //采用共阳数码管,取反
for(i=0;i<8;i++) //循环移入寄存器74LS164
{
Clk164=0;
if((j&0x01)==0x01) //按位与
Data164=1;
else
Data164=0;
Clk164=1; //上升沿脉冲
j>>=1; //j右移一位
}
}
//############################温度值送显示缓冲区###########################
void TempToDispBuf(int Temp)
{
uchar xdata j;
j= Temp/1000; //得到温度值的最高位
DispBuf[3]=j ; //温度值的最高位送显示缓冲区
Temp= Temp%1000; //温度值取余,
j= Temp/100; //得到温度值的次高位
DispBuf[2]=j ; //温度值的次高位送显示缓冲区
Temp= Temp%100; //取余
j= Temp/10; //得到温度值的次低位
DispBuf[1]=j ; //温度值的次低位送显示缓冲区
j= Temp%10; //得到温度值的低位
DispBuf[0]=j ; //温度值的低位送显示缓冲区
}
//########################显示调用字码子程序##################################
void Disp4(uchar Dot)
{
uchar i;
uchar j;
for(j=0;j<4;j++) //循环取显示缓冲区的数值四次,并将显示缓冲区的数按照字型码
送显
{
i=DispBuf[j];
i=shapeCode[i]; //调出与显缓区数值相应的字型码
if(j==(3-Dot))
i|=0x01; //固定第二个数码管的小数点保持点亮
Diap(i); //对应字型码送显示
}
}
//###############################A/D转换子程序###############################
int AdV alueComplex() //将AD转换出来的BCD码转换成一个对应的千位数
{
int Result;
Result=(int)Store3*1000+ (int)Store2*100+ (int)Store1*10+ (int)Store0;
return(Result);
}
//############################A/D值转换成温度值子程序##########################
int AdV alueToTemp(float SampleAd )
{
float TempV ale; //定义一个浮点型
int Wen; //定义一个整型数
TempV ale=SampleAd/20; //转换成温度值
Wen=TempV ale*100; //温度值放大一百倍变成整型
return(Wen); //返回放大后的温度值
}
//#################################主程序################################### main()
{
AUXR=0X01;
initTimer() ; //定时器初始化
initUart(); //串行口初始化
while(1)
{
if(fig_10ms==1) //位标量判断
{
fig_10ms=0;
switch (Prg) //实时控制系统
{
case 0:
// Tempture=AdV alue;
break;
case 1:
TempToDispBuf(Tempture) ; //温度值送显示缓冲区
Disp4(1); //显示数值
break;
case 2:
CovertCount++;
if( CovertCount>10)
{
CovertCount=0;
AdSample(); //MC14433转换BCD码
AdV alue= AdV alueComplex(); //BCD码转换
Tempture=AdV alueToTemp(AdV alue); //转换成实际温度值
}
break;
case 3:
default:
break;
}
Prg++;
if(Prg>3)
Prg=0;
}
}
}
#include
int Tick10MsCount;
unsigned char Tick1MsCount;
bit fig_10ms; //位标量定义
extern int Tempture;
extern uchar xdata RecBuff[10];
extern uchar xdata SendBuff[10];
bit bMaySendData; //位标量定义
sbit CTRL485=P0^0; //在bdata区定义一个可位寻址变量CTRL485,75LBC184
使能端接P0.0
void initTimer(void) //定时器初始化
{
TMOD=0x01; //定时器0工作方式1,计数不受外输入引脚控制
TH0=-4000/256; //4ms初值
TL0=-4000%256;
ET0=1; //T0溢出中断允许
TR0=1; //允许T0计数
EA=1; //开放所有中断
}
//###############################定时器子程序##################################
void Timer0_ISR (void) interrupt 1 using 1 //使用定时器0中断和第2个寄存器
{
static unsigned char Count10ms; //定义局部静态变量
TH0=-4000/256; //4ms初值
TL0=-4000%256;
Tick1MsCount++;
if( Tick1MsCount>2) //循环
{
Tick1MsCount=0;
}
if (Count10ms) Count10ms--; //循环
else
{
fig_10ms=1; //产生位标量标志
Count10ms=5;
Tick10MsCount++;
}
}
//###############################延时子程序##################################
void Delay_T(uchar i)
{
uint j;
for(;i>0;i--)
for(j=0;j<1000;j++); //循环延时1ms
}
//##################################串口初始化################################
//波特率为4800
void initUart(void)
{
CTRL485=0; //75LBC184使能端处于接受状态
TMOD|=0x20; //定时器1方式2
SCON=0x50; //串行接受、发送中断标志置0,工作方式1,8位异步通信接口,波特率
可变,允许串行接受位
PCON|=0x80; //SMOD=1,N=16
TH1=-13;//0xf9; //设置波特率初值为4800
TL1=-13;//0xf9;
ES=1; //串行口中断允许
TR1=1; //定时器1允许T1计数
}
#define C_RecAddr 0 //宏定义
#define C_RecCom 1
#define C_RecLen 2
#define C_RecData 3
#define C_RecCrcHi 4
#define C_RecCrcLow5
#define C_MyAddr 2
//##############################接收数据子程序#################################
void RecProcess(uchar InData)
{
static uchar Index;
static uchar RecCount;
static uchar state=C_RecAddr;
switch(state) //开关语句
{
case C_RecAddr: //判断地址状态
Index=0;
if( InData==C_MyAddr) //若地址正确,不正确则退出
{
RecBuff[Index]=InData; //将地址数据送接受缓冲区
state=C_RecCom; //转态转命令判断
Index++; //缓冲器指针加1
}
break;
case C_RecCom:
RecBuff[Index]=InData; //接受命令数据
state=C_RecLen;
Index++;
break;
case C_RecLen:
RecBuff[Index]=InData; //接受数据长度数据
state=C_RecLen;
Index++;
if(InData==0) //若数据长度为0
state=C_RecCrcLow; //直接判断校验位低位
else
{
state=C_RecData ; //若数据长度不为0则转数据接受状态
RecCount=0; //置初值为0
}
break;
case C_RecData:
RecBuff[Index]=InData;
Index++;
RecCount++;
if(RecCount==RecBuff[2]) //根据数据长度接受数据个数
state=C_RecCrcLow;
break;
case C_RecCrcLow: //校验位低位校验
state=C_RecCrcHi;
break;
case C_RecCrcHi: //校验位高位校验
state=C_RecAddr;
bMaySendData=1;
default:
break;
}
}
//#############################准备发送数据子程序############################# void SendPrepare()
{
if(bMaySendData)
{
//所有数据打包准备发送
SendBuff[0]=RecBuff[0];
SendBuff[1]=RecBuff[1];
SendBuff[2]=2;
//Tempture=0x1234; //调试时曾用,现在为无效数据
SendBuff[3]=Tempture/256; //温度值准备发送
SendBuff[4]=Tempture%256;
SendBuff[5]=0;
SendBuff[6]=0;
SBUF=SendBuff[0]; //缓冲区数据送发送寄存器
}
}
//#############################串行口中断程序############################
void SeailInt1(void) interrupt 4 //使用串行口中断
{
static unsigned char Temp;
if(RI) //判断主机是否有数据发过来,监视总线
{
RI=0; //置0
if(bMaySendData==0) //无数据发送的话则接受,进入接受判断数据子程序
{
Temp=SBUF;
RecProcess(Temp);
}
if(bMaySendData==1) //有数据发送,进入准备发送状态
{
SendPrepare();
Temp=0;
}
}
else
{ CTRL485=1; //打开75LBC184处于发送状态
Delay_T(1); //延时1MS
TI=0;
if(bMaySendData==1) //有数据发送,则进入数据包循环发送
{
if(Temp
; uchar Store0=0;
; uchar Store1=0;
; uchar Store2=0;
; uchar Store3=0;
; uchar Store4=0;
; uchar Store5=0;
AdSample:
P1_int1: MOV A,P1
JNB Acc.4,P1_int1 ;检测DS1位选通否
JB Acc.0,LP_1 ;判超、欠量程
MOV Store5,00H ;未超、欠量程
SJMP LP_2
LP_1: MOV Store5,#01H ;有超欠量程
LP_2:
JB ACC.2,LP_3 ;判输入信号极性
MOV Store4,#01H ;结果为负
SJMP LP_4
LP_3: MOV Store4,#00H ;结果为正
LP_4: JB ACC.3 ,LP_5 ;判千位的值
MOV Store3,#01H ;Q3=0,千位=1,
SJMP LP_6
LP_5: MOV Store3, #00H ;Q3=1,千位=0
LP_7: MOV A,P1
JNB ACC.5,LP_7 ;等待百位选通信号DS2
ANL A,#0FH ;取百位Q3~Q0
MOV Store2,A;存入百位单元
LP_8: MOV A,P1
JNB ACC.6,LP_8 ;等待十位选通信号DS3
ANL A,#0FH ;取十位Q3~Q0
MOV Store1,A;存入十位单元
LP_9: MOV A,P1
JNB ACC.7,LP_9 ;等待个位选通信号DS4
ANL A,#0FH
MOV Store0,A;取个位Q3~Q0
RET
END
本文档为【基于modbus协议的温度采集系统程序清单】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑,
图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。