STC12C5A60S2单片机双串口同时通讯的完整版modbus程序

发布者:雅致人生最新更新时间:2019-12-26 来源: 51hei关键字:STC12C5A60S2  单片机  双串口  看门狗 手机看文章 扫描二维码
随时随地手机看文章

电路原理图如下:
DSC_0211.JPGDSC_0212.JPG
/******************************
程序功能:    modbus RTU 模式设置读取十六个继电器状态,以及内部保持寄存器的设置读取 
硬件测试环境:单片机stc89C52RC十六继电器485接口控制板  
通信协议:    晶振:11.0592  波特率:9600  8位数据 1位停止位 偶校验   485通位接口P3.7控制方向端
控制板地址:  修改localAddr(变量)
线圈个数:16个  线圈地址范围:0x0000~0x000F
保持寄存器个数:16个(字节型) 寄存器地址:0x0000~0x000F
\******************************\
功能码简介:
02:读取单个线圈状态
03:读取多个保持寄存器
05:设置单个线圈状态
06:设置单个寄存器值
0F:设置多个线圈
10:设置多个保持寄存器
汇成科技
作者:yang
*******************************/
#include "hader\main.h"
uint32        dwTickCount,dwIntTick;        //时钟
uint8        idata sendBuf[32],receBuf[16]; //发送接收缓冲区
uint8        idata checkoutError;        // ==2 偶校验错  
uint8        idata receTimeOut;                //接收超时
uint8        idata c10ms;                        //10ms 计时
uint8   idata c200ms;
bit                b1ms,bt1ms,b10ms,bt10ms,b100ms,bt100ms;        //定时标志位


//定时处理
void timeProc(void)
{        
    b1ms = 0;
        if(bt1ms)        //如果1ms到
        {
                bt1ms = 0;
                b1ms = 1;
        if(receTimeOut>0)        //如果接收超时值>0
        {
            receTimeOut--;        //接收超时-1(1ms减1次)
            if(receTimeOut==0 && receCount>0)   //判断通讯接收是否超时
            {
            //    b485Send = 0;       //将485置为接收状态
                receCount = 0;      //将接收地址偏移寄存器清零
                                checkoutError = 0;
            }
        }
        }
}   // void TimerProc(void)
//初始化
void initInt(void)
{
    SCON = 0xd0;
        TMOD = 0x21;
        PCON = 0;
        TH0 = TIMER_HIGHT;
        TL0 = TIMER_LOW;
        TH1=  0xfd;        
        TL1 = 0xfd;                             //波特率 9600

        TR0 = 1;
        TR1=1;                        
    ET0 = 1;
        ES = 1;
        EA = 1;        

        //串口2设置        
        S2CON = 0xd0;                          //方式1,9位数据,波特率不可变  S2TB8 偶校验位
        BRT=0XFD;                                  //设置波特率9600
        AUXR=0x10;                                 //启动串口1波特率发生器
        IP=0x00;                                 //优先级默认                                         //开串口1中断
        IE2=0x01;                                 //开串口2中断                

//初始化
void initProg(void)
{        

   P4SW|=0x20;                   //配置P4.5为IO口
   P4M0|=0x10;                   //配置P4.4为IO口
   P4M1|=0x10;
   P0=P1=P2=P3=0xff;
   P4|=0x30;
        initInt(); //初始化定时器
//        b485Send = 0;
}
//上电时读取上次线圈状态,并设置
void forceMultipleCoils1() 

        uint8 tempAddr;
        uint8 i,k;
    uint8 Data;
        uint8  exit = 0;                                                        
        for(k=0;k<4;k++)
        {
           switch(k)
          {        
            case 0:Data=coilreg1; break;
                case 1:Data=coilreg2; break;
                case 2:Data=coilreg3; break;
                case 3:Data=coilreg4; break;
           }
                for(i=0;i<8;i++)
                {
                    if(        Data &0x01==1)
                           setCoilVal(tempAddr,0);
                        else
                           setCoilVal(tempAddr,1);

                        Data=Data>>1;        
                        tempAddr++;
                        if(tempAddr >=32)
                        {
                                exit = 1;
                                break;
                        }        
                }
                if(exit==1)
                        break;
        }
        }
void main(void)
{

        initProg();
        localAddr=EEPROMReadByte(0);     //从EERPOM的相对0地址读取数据
    coilreg1=EEPROMReadByte(1);
        coilreg2=EEPROMReadByte(2);
        coilreg3=EEPROMReadByte(3);
        coilreg4=EEPROMReadByte(4);
        forceMultipleCoils1();
        if(localAddr>=10)
        { 
          localAddr=1;
          EEPROMSectorErase(0);       //从EEPROM的相对0地址扇区擦除
      EEPROMWriteByte(0,localAddr);
          EEPROMWriteByte(1,coilreg1);
          EEPROMWriteByte(2,coilreg2);
          EEPROMWriteByte(3,coilreg1);
          EEPROMWriteByte(4,coilreg2);
        
        }
        WDT_CONTR =0x32;   //大概284.4ms
        while(1)
        {
                timeProc();
                checkComm0Modbus();
        }
}
//定时器0 1ms 中断
void timer0IntProc() interrupt 1
{
        TL0 = TIMER_LOW; 
    TH0 = TIMER_HIGHT;
    dwIntTick++;
        bt1ms = 1;
    c10ms++;
        c200ms++;
    if(c10ms >= 10) 
    {
        c10ms = 0;      //20ms计时器清零
        bt10ms = 1;
            WDT_CONTR =0x32;        //    
    }
}   // void Timer0IntProc()
// 串行中断1程序
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()
//串口2中断
void uart2_isr()  interrupt 8
{

        if( S2CON & 0x02 )
        {
                S2CON &= ~0x02;
                   if(sendPosi                {
                        sendPosi++;
                        ACC = receBuf[sendPosi];
                        if(P)
                           S2CON|=0x08;         //                                7      6      5      4      3      2     1     0        Reset Value
                             //sfr S2CON = 0x9A; //S2 Control  S2SM0  S2SM1  S2SM2  S2REN  S2TB8  S2RB8  S2TI  S2RI      00000000B
                        else
                           S2CON&=0xf7;
                        S2BUF =receBuf[sendPosi];
                }
                else //否则发送完毕,置接收状态
                {
//                        b485Send = 0;    //发送完后将485置于接收状态
                        receCount = 0;   //清接收地址偏移寄存器
                        checkoutError = 0;
                }
         }
        else if( S2CON & 0x01)//接收
        {
            S2CON &= ~0x01;
                receTimeOut = 10;    //通讯超时值
                receBuf[receCount] =S2BUF;
                ACC = receBuf[receCount];
//                if(P != RB8)
//                        checkoutError = 2;        //偶校验出错
                receCount++;          //接收地址偏移寄存器加1
                receCount &= 0x0f;    //最多一次只能接收16个字节
        }
}

[1] [1]
关键字:STC12C5A60S2  单片机  双串口  看门狗 引用地址:STC12C5A60S2单片机双串口同时通讯的完整版modbus程序

上一篇:单片机16*64LED点阵广告牌设计
下一篇:51单片机8X8点阵贪吃蛇游戏(带proteus仿真)

推荐阅读最新更新时间:2024-11-11 09:39

【51单片机快速入门指南】2.4:74HC595、LED点阵屏及其SPI控制
普中51-单核-A2 STC89C52 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 硬知识 选自《普中51单片机开发攻略_V1.2》 IO 口扩展方式-串转并 使用的芯片是 74HC595。开发板板载 1 个 74HC595 芯片,仅需单片机 3 个 IO 口即可扩展 8 个,如果需要还可以将 2 个 74HC595 级联扩展出 16 个 IO,这就实现用少数 IO 资源控制多个设备。 74HC595 芯片介绍 74HC595 是一个 8 位串行输入、并行输出的位移缓存器,其中并行输出为三 态输出(即高电平、低电平和高
[单片机]
【51<font color='red'>单片机</font>快速入门指南】2.4:74HC595、LED点阵屏及其SPI控制
用芯致远,复旦微电连推三款MCU新品
2023年6月27日,上海讯—— 上海复旦微电子集团股份有限公司今日举办线上发布会,推出车用MCU FM33FG0xxA系列、适用于BLDC电机驱动和显示面板控制应用的低功耗MCU FM33LF0xx系列,和基于 Arm Cortex-M33 内核的高性能MCU FM33FK50xx系列。 复旦微电子集团电力电子事业部技术总监翟金刚作开场介绍,公司是国内最早起步进行智能电能表专用 MCU 芯片研发、设计及应用的芯片设计公司之一,经过二十余年的行业积累,复旦微电陆续推出多个系列、百余种型号,截止目前 MCU 累计出货超过 6.5 亿颗。凭借在智能电表领域的多年技术积累,复旦微电MCU产品线拓展至公用事业(水气热表)、汽车电
[嵌入式]
用芯致远,复旦微电连推三款<font color='red'>MCU</font>新品
AVR单片机用progisp下载时报错Chip Enable Program Error
两块ATmega16总是下载不成功,无论是读芯片ID还是读FLASH都提示chip enable program error. 报错的“咣咣”声,震的头都蒙了。 查了网上的解决方案,分析有以下几种原因: 1、下载线的问题 2、固件有问题 3、下载器损坏 4、驱动没安装好 5、单片机供电电路,震荡电路,复位电路,有问题 6、熔丝位配置错误 也找到了几种解决方案,据他们说他们这么做好用了。 1、外加时钟就可以 2、要用老ATmega16把新ATmega16烧一遍, 再用 3、重启电脑 ,换一个USB口试一下 4、ATmega16默认是用内部1M RC起振,一般要用USBASP的低速模式,短接慢速下载就行了 本人比较倾向与解决方案的
[单片机]
PIC单片机实现8个数码管实现循环显示的设计
8个数码管滚动显示同一个数字 8个数码管显示多个不同的字符 8个数码管闪烁显示 8个数码管滚动显示数字串 #include __CONFIG(0x3B31); unsigned char tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7C,0x39,0x5E,0x79,0x71};//0-F--共阴极数码管 #defineLEDPORTB void delay1ms(unsigned int x) { unsigned char i; for(;x》0;x--) for(i=0;i《165;i++); } void init() { TRISB=
[单片机]
PIC<font color='red'>单片机</font>实现8个数码管实现循环显示的设计
采用PIC单片机芯片的三相半控整流电路设计
  三相半控整流桥电路结构是一种常见的整流电路,其容易控制,成本较低。本文中介绍了一种基于 PIC690单片机与专用集成触发芯片TC787的三相半控整流电路,它结合专用集成触发芯片和数字触发器的优点 ,获得了高性能和高度对称的触发脉冲。它充分利用单片机内部资源 ,集相序自适应、系统参数在线调节和各种保护功能于一体,可用于对负载的恒电压控制。主电路采用了三相半控桥结构,直流侧采用LC滤波结构来提高输出的电压质量。      系统总体设计   本系统通过PIC690单片机作为主控制芯片,用晶闸管作为主要开关器件。设计的目标是保持输出的直流电压稳定,输出电压纹波小,交流输出测电流THD较低,性能可靠。   系统主要电路包括:三相
[单片机]
采用PIC<font color='red'>单片机</font>芯片的三相半控整流电路设计
51单片机之音乐代码
世上只有妈妈好音乐源代码。 #include reg51.h sbit speaker = P3^7; unsigned char timer0h, timer0l, time; //-------------------------------------- //单片机晶振采用11.0592MHz // 频率-半周期数据表 高八位 本软件共保存了四个八度的28个频率数据 code unsigned char FREQH = { 0xF2, 0xF3, 0xF5, 0xF5, 0xF6, 0xF7, 0xF8, //低音1234567 0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xF
[单片机]
PIC单片机之I2C通信-主-从模式
主模式: 我们今天来讲I2C通信。那I2C通信的特点是什么能。我们一般使用的串口 (半双工异步串行通信)与I2C 有什么区别呢。 串口(半双工异步串行通信):就是好像朋友在对话。我可以主动和你讲话,你也可以主动和我讲话。 I2C:就好像上下级对话。一个领导面对一个或者多个员工。只有领导主动说话的份儿,下面的员工不能主动说话。只有领导问了,员工才能答。 I2C通信 I2C通信只需要两个引脚 一个数据线,一个时钟线。 数据线顾名思义就是用来传递数据的。时钟线是来决定数据传输的速度。当时钟线为高电平时,数据线上的数据才会被认为是有效的。 数据线的 数据有四种状态 : 高电平,低电平,下降沿(高电平变低电平),上
[单片机]
PIC<font color='red'>单片机</font>之I2C通信-主-从模式
基于单片机的USB主控器驱动设计
1 引言 在现代社会,嵌入式系统逐渐深入到人们生活的方方面面,各类嵌入式系统产品之间往往通过某种接口进行交互或数据传递。而现在,USB已经成为嵌入式数据交换的最主要的方式,可是各种USB接口的设备都是基于PC机系统的,所以,基于嵌入式系统的USB接口的研究具有实用的价值和意义,特别是起Master作用的HOST端接口的研究。 解决这一问题的根本办法就是在需要使用USB设备的嵌入式系统中扩展USB Host功能模块,使之具有与USB设备进行数据传输的能力。 USB协议按功能分为2部分,USB HOST(USB主协议)和USB SLAVE(USB从协议)分别应用于USB HOST CONTROLLER(USB主控制器)和US
[单片机]
基于<font color='red'>单片机</font>的USB主控器驱动设计
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved