基于RS485主从结构通信单片机代码

发布者:MysticalEssence最新更新时间:2020-08-21 来源: 51hei关键字:RS485  主从结构通信  单片机 手机看文章 扫描二维码
随时随地手机看文章

RS485主从结构通信代码,用于组网内部通信

单片机源程序如下:

#ifndef        _485MON_H                                 // 防止485Mon.h被重复引用

#define        _485MON_H


#include                             // 引用标准库的头文件

#include

#include


#define uchar unsigned char

#define uint unsigned int


#define ACTIVE          0x11

#define GETDATA          0x22

#define READY                  0x33

#define SENDDATA        0x44        


#define RECFRMMAXLEN 16                 // 接收帧的最大长度,超过此值认为帧超长错误

#define STATUSMAXLEN 10                        // 设备状态信息最大长度         


uchar DevNo;                                        // 设备号

xdata uchar StatusBuf[STATUSMAXLEN];


//为简化起见,假设了10位固定的采集数据

#define DATA0          0x10

#define DATA1          0x20

#define DATA2          0x30

#define DATA3          0x40

#define DATA4          0x50

#define DATA5          0x60

#define DATA6          0x70

#define DATA7          0x80

#define DATA8          0x90

#define DATA9          0xA0

sbit DE = P1^6;                        //驱动器使能,1有效

sbit RE = P1^7;                        //接收器使能,0有效

void init();                                        // 系统初始化

void Get_Stat();                                // 简化的数据采集函数

bit Recv_Data(uchar *type);                // 接收数据帧函数

void Send(uchar m);                                        // 发送单字节数据

void Send_Data(uchar type,uchar len,uchar *buf);                                // 发送数据帧函数        

void Clr_StatusBuf();                        //  清除设备状态信息缓冲区函数   

/****************************************/

/* Copyright (c) 2005, 通信工程学院     */

/* All rights reserved.                 */

/****************************************/


#include "485Mon.h"

void main(void)

{

        uchar type;


        /* 初始化 */

        init();

        

        while (1)

        {

                if (Recv_Data(&type)==0)                        // 接收帧错误或者地址不符合,丢弃

                        continue;

                switch (type)

                {

                        case ACTIVE:                                // 主机询问从机是否在位

                                Send_Data(READY,0,StatusBuf);        // 发送READY指令

                                break;

                        case GETDATA:                                // 主机读设备请求

                                Clr_StatusBuf();

                                Get_Stat();                                // 数据采集函数

                                Send_Data(SENDDATA,strlen(StatusBuf),StatusBuf);

                                break;

                        default:

                                break;                                        // 指令类型错误,丢弃当前帧

                }

        }

}


/* 初始化 */

void init(void)

{

        P1 = 0xff;

        DevNo = (P1&0x00111111);                        // 读取本机设备号


        TMOD = 0x20;

        SCON = 0x50;

        TH1 = 0xfd;

        TL1 = 0xfd;

        TR1 = 1;

        PCON = 0x00;                                                // SMOD=0

        EA = 0;

                                                

}


/* 接收数据帧函数,实际上接收的是主机的指令 */

bit Recv_Data(uchar *type)

{

        uchar tmp,rCount,i;

        uchar r_buf[RECFRMMAXLEN];                        // 保存接收到的帧

        uchar Flag_RecvOver;                                // 一帧接收结束标志        

        uchar Flag_StartRec;                                // 一帧开始接收标志

        uchar CheckSum;                                                // 校验和

        uchar DataLen;                                                // 数据字节长度变量

               

        /* 禁止发送,允许接收 */

        DE = 0;

        RE = 0;


        /* 接收一帧数据 */

        rCount = 0;

        Flag_StartRec = 0;

    Flag_RecvOver = 0;

        while (!Flag_RecvOver)

        {

                RI = 0;

                while (!RI);

                tmp = SBUF;

                RI=0;


                /* 判断是否收到字符',其数值为0x24 */         

                if ((!Flag_StartRec) && (tmp == 0x24))

                {

                        Flag_StartRec = 1;        

                }


                if (Flag_StartRec)

                {

                        r_buf[rCount] = tmp;

                        rCount ++;               

                        

                        /* 判断是否收到字符'*',其数值为0x2A,根据接收的指令设置相应标志位 */

                        if (tmp == 0x2A)

                                Flag_RecvOver = 1;

                }


                if (rCount == RECFRMMAXLEN)                // 帧超长错误,返回0

                        return 0;

        }

        

        /* 计算校验和字节 */

        CheckSum = 0;

        DataLen = r_buf[3];

        for (i=0;i++;i<3+DataLen)

[1] [2]
关键字:RS485  主从结构通信  单片机 引用地址:基于RS485主从结构通信单片机代码

上一篇:单片机+XPT2046+MQ135室内空气净化系统
下一篇:12864万年历+温度计+闹钟+温度检测

推荐阅读最新更新时间:2024-11-17 03:19

AVR单片机驱动无源蜂鸣器C程序
/* 内部1 M晶振。 定时器实险,周期信号驱动无源蜂鸣器,些实验基于定时器的CTC模式,由硬件产生频率信号。 程序中实现单一频率的周期性提示音。 程序采用单任务方式,软件延时。 */ #include iom16v.h /*延时函数*/ void delay_ms(unsigned char i) { unsigned char a, b; for (a = 1; a i; a++) { for (b = 1; b; b++) { ; } } } void main(void) { unsigned char i; DDRA = 0x00; /*方向输入*/ PORTA = 0xFF; /*打开上拉*/
[单片机]
13-基于51单片机酒精浓度检测报警系统
具体实现功能 由STC89C51单片机+MQ-3酒精传感器+ADC0832模块+LCD1602模块+报警模块+电源构成。 具体功能: 1、LCD1602实时显示酒精浓度; 2、可以按键设置报警值,实现声光报警;三个按键:设置键、加键、减键。 3、当浓度未超过阀值时,绿灯闪烁;当超过阈值时,红灯闪烁并蜂鸣器报警。 设计背景 近年来,我国越来越多的人有了自己的私家车,而酒后驾车造成的交通事故也频繁发生。为此,我国将酒驾列入刑法范围内,所以需要设计一智能仪器能够检测驾驶员体内酒精含量。本课程设计研究的是一种以气敏传感器和单片机A/D转换器为主,检测驾驶员呼出气体的酒精浓度,并具有声光报警功能的空气酒精浓度监测仪。其可
[单片机]
13-基于51<font color='red'>单片机</font>酒精浓度检测报警系统
51单片机的工作流程及原理解析
1.ROM:只读存储器,单片机的只读存储区大多用于存储程序固又称程序存储器。 51单片机是EPROM,所谓的EPROM是可擦除的只读存储器。可以把原来的程序擦除了,再写一个新的进去。 断电后是可以保存的,数据存储器(RAM)是不能保存的。 RAM只能在程序执行的时候不断地重新存储定义的变量。如int x,int y 可以通过code这个指令来将定义的变量放在ROM,而不是RAM中,节省RAM资源 2.RAM:随机存取存储器,用于存储定义的变量等,速度快 51单片机的RAM存储容量远小于ROM,但是速度非常之快 内部详细图示 内部的结构看似十分复杂,但是大致上可以分为两个部分:运算器(红色框)和控制器(蓝色框
[单片机]
51<font color='red'>单片机</font>的工作流程及原理解析
视频解码芯片SAA7113的初始化与控制
   引言:   SAA7113是飞利浦公司视频解码系列芯片的一种,非常具有代表性,在很多视频产品如电视卡、MPEG2、MPEG4中都有应用,熟悉了7113的原理后,对其它系列芯片SAA7114、7115、7118就会很容易理解。SAA7113的主要作用是把输入的模拟视频信号解码成标准的“VPO”数字信号,相当于一种“A/D”器件。7113兼容全球各种视频标准,在我国应用时必须根据我国的视频标准来配置内部的寄存器,即初始化,否则7113就不能按要求输出,可以说对7113进行研发的主要工作就是如何初始化。对7113初始化需要通过I2C总线进行,本文给出用51单片机控制的例子。   1.SAA7113的基本原理与应用   SAA71
[家用电子]
PIC单片机(PIC16F873)小项目二(工艺文件)
1.零部件安装顺序表 此称重板对零件安装顺序无特别要求,可遵循先小后大原则,先焊接小元器件,后焊接大元器件。结合自己焊接习惯安排零部件焊接顺序。 2.产品出厂老化试验 (1)输入110%的额定输入电压连续通电24小时。 (2)高温测试 (3)输入突变电压。 3.产品合格判定标准 (1)系统上电蜂鸣器响声一次,LED灯交互闪动四次。 (2)自学习过程中,LED灯闪动,学习完成后蜂鸣器响声两次。 (3)系统自学习完成后,随着输入变化,输出0V-10V或者0.5V-3.5V电压。 若产品满足以上两个要求,并无出现其它异样。则产品是合格产品。 4.程序下载步骤 1.连接好PIC程序下载工具m
[单片机]
32位单片机分析
为什么选择32位单片机? 主流32位单片机基本被ARM平台占据,原因是开发方便,工具齐全。随着就是各大单片机厂家的升级产品比如Atmel/Microchip等。而 ARM授权的单片机就遍布全球了,基本做数字的厂家都有在做相关的芯片。ARM在指令密度等等更具优势,而传统单片机厂家要求芯片针对性强,没有版权费用,成本相对较低。各类单片机功耗基本不相伯仲,主要以应用为导向 功耗并不是单片机的问题,而是原厂以及工艺决定的。在应用方案中,32位的单片机主要体现其高性能以及资源丰富等特点,同时方便的开发环境吸引着越来越多的软件工程师,因此开发难度的降低也是32位单片机迅速崛起的主要原因之一。 32位单片机,工程师最关注什么? 32位单片机由于其
[单片机]
如何在ATE中集成对PIC单片机的编程烧写功能
做ATE,要对DUT内部的PIC单片机进行在线烧写, 在网上看到别人的一个说法(作者 Claud Zhang),内容如下: --------------------------------------------------------- 一种简单高效低成本的Microchip MCU编程方法 Claud Zhang 对于一些研发工程师来说,工厂的的MCU编程有时候是个比较头疼的问题.在研发过程中,大家都和习惯于用仿真器去编程,这个对工程师来说是个非常简单的过程,但是在工厂生产,工厂认为太复杂了。工厂希望是个傻瓜式的过程。最好的方法是通过ATE自动编程,不需人工参与。 在以往的通常有2种方法
[单片机]
基于ATC51的新型数控直流电源设计
在各种电子设备中,电源是一种必不可少的仪器。随着科技的进步,电子设备逐渐综合化,复杂化,对电源部分使用的灵活性和精度都提出了更高的要求。 目前所用的电源大多是只有固定电压输出(例如常用的有:±5 V、±12 V或±15 V),其缺点是输出电压不可人为地改变,输出精度和稳定性都不高;在测量上,传统的电源一般采用指针式或数字式来显示电压或电流,搭配电位器调整所要的电压及电流输出值。若要调整精确的电压输出,须搭配精确的显示仪表监测;又因电位器的阻值特性非线性,在调整时,需要花费一定的时间,而且会产生漂移。市场上销售的数字可调电源成本较高,使用也不方便。 针对这一现象,本文提出了一种基于AT98C51单片机的新型数控直流电源。
[单片机]
基于ATC51的新型数控直流电源设计
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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