微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 基于51单片机的MODBUS通信C语言程序(从机)

基于51单片机的MODBUS通信C语言程序(从机)

时间:11-28 来源:互联网 点击:
#include "reg52.h"

typedef unsigned char uint8;

typedef unsigned int uint16;

typedef unsigned long uint32;

#define TIMER_HIGHT 0xf8

#define TIMER_LOW 0xcd

sbit bRunLED =P3^4; //运行指示灯

sbit bWatchDog=P1^7; //看门狗复位

sbit b485Send= P1^3; //75LBC184 发送接收控制

uint32 dwTickCount,dwIntTick; //时钟

uint8 idata sendBuf[16],receBuf[16]; //发送接收缓冲区

uint8 idata checkoutError; // ==2 偶校验错

uint8 idata receTimeOut; //接收超时

uint8 idata c10ms; //10ms 计时

bit b1ms,bt1ms,b10ms,bt10ms,b100ms,bt100ms; //定时标志位

// 串行中断程序

void commIntProc() interrupt 4

{

if(TI)

{

TI = 0;

if(sendPosi < sendCount)

{

sendPosi++;

ACC = sendBuf[sendPosi];

TB8 = P; //加上校验位

SBUF = sendBuf[sendPosi];

}

else

{

b485Send = 0; //发送完后将485置于接收状态

receCount = 0; //清接收地址偏移寄存器

checkoutError = 0;

}

}

else if(RI)

{

RI = 0;

receTimeOut = 10; //通讯超时值

receBuf[receCount] = SBUF;

ACC = receBuf[receCount];

if(P != RB8)

checkoutError = 2; //偶校验出错

receCount++; //接收地址偏移寄存器加1

receCount &= 0x0f; //最多一次只能接收16个字节

}

} // void CommIntProc()

//定时器0 1ms 中断

void timer0IntProc() interrupt 1

{

TL0 = TIMER_LOW;

TH0 = TIMER_HIGHT;

dwIntTick++;

bt1ms = 1;

c10ms++;

if(c10ms >= 10)

{

c10ms = 0; //10ms计时器清零

bt10ms = 1;

}

} // void Timer0IntProc()

//外部中断0

void intEx0Proc(void) interrupt 0

{

}

//计数器1中断

void counter1IntProc(void) interrupt 3 using 1

{

}

//定时处理

void timeProc(void)

{

static uint8 c200ms;

bWatchDog = ~ bWatchDog; //看门狗取反

b1ms = 0;

b10ms = 0;

b100ms = 0;

ET0 = 0;

dwTickCount = dwIntTick;

ET0 = 1;

if(bt1ms)

{

bt1ms = 0;

b1ms = 1;

if(receTimeOut>0)

{

receTimeOut--;

if(receTimeOut==0 && receCount>0) //判断通讯接收是否超时

{

b485Send = 0; //将485置为接收状态

receCount = 0; //将接收地址偏移寄存器清零

checkoutError = 0;

}

}

}

if(bt100ms)

{

bt100ms = 0;

b100ms = 1;

}

if(bt10ms) //判断中断10ms标志位是否1

{

bt10ms = 0; //清中断10ms标志位

b10ms = 1;

c200ms++; //200ms计时器加1

if(c200ms >= 20) //判断是否计时到200ms

{

c200ms = 0; //清200ms计时器

bRunLED = ~bRunLED; //取反运行指示灯

}

}

} // void TimerProc(void)

//初始化串口

void initUart(void)

{

//T2 用于波特率 9600

T2CON = 0x30;

RCAP2H = 0xff;

RCAP2L = 0xb8;

TR2 = 1;

//偶校验

SCON = 0xd0;

PCON = 0;

ES = 1;

}//void initUart(void)

//初始化中断

void initInt(void)

{

TMOD = 0x51;

TH0 = TIMER_HIGHT;

TL0 = TIMER_LOW;

TR0 = 1;

ET0 = 1;

TH1 = 0; //9600

TL1 = 0;

TR1 = 0; //定时器1用于计数定时器2用于波特

ET1 = 1;

IT0 = 1;

IT1 = 1;

EX0 = 0;

PX0 = 1;

EX1 = 0;

initUart();

EA = 1;

} // void initInt(void)

//初始化

void initProg(void)

{

initInt();

b485Send = 0;

}

void main(void)

{

initProg();

while(1)

{

timeProc();

checkComm0Modbus();

}

}


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top