×
单片机 > 单片机程序设计 > 详情

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

发布时间:2020-05-26 发布时间:
|
#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();   
    }   
}  

关键字:51单片机  MODBUS通信  C语言程序 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
C51 特殊功能寄存器SFR的名称和地址