历史上的今天
今天是:2025年01月08日(星期三)
2018年01月08日 | 多机通信的从机程序
2018-01-08 来源:eefocus
/* multi_s.c */
/* 多机通信的从机部分 */
#ifndef __MULTI_S_C__
#define __MULTI_S_C__
#include
#include
#define __MAX_LEN_ 64 // 数据最大长度
#define _MHz_ 11 // 设置 单片机 使用的晶振频率(11.0592MHz)
/* 以下为程序协议中使用的握手信号 */
#define __SUCC_ 0x0f // 数据传送成功
#define __ERR_ 0xf0 // 数据传送错误
void init_serial(); // 串口初始化
unsigned char recv_data(unsigned char *buf); // 接收数据
void Beep_ok(); // 蜂鸣表示数据接收ok,该函数代码未给出
void main()
{
char buf[__MAX_LEN_];
unsigned char i = 0;
unsigned char tmp = 0xff;
unsigned char addr; // 保存本机地址
/* 从P1口读取本机地址 */
P1 = 0xff;
addr = P1;
/* 串口初始化 */
init_serial(); // 初始化串口
EA = 0; // 关闭所有中断
/* 进入设备应答阶段 */
while(1)
{
SM2 = 1; // 只接收地址帧
/* 如果接收到的地址帧不是本机地址,则继续等待 */
tmp = addr-1;
while(tmp != addr)
{
RI = 0;
while(!RI);
tmp = SBUF;
RI = 0;
}
/* 发送应答信号,并做好接收数据的准备 */
TI = 0;
TB8 = 0; // 主机不检测该位
SBUF = addr;
while(!TI);
TI = 0;
SM2 = 0; // 允许接收数据信息
/* 数据接收 */
tmp = 0xff;
while(tmp == 0xff) // 如果数据校验失败则重新接收数据
{
tmp = recv_data(buf); // 校验失败返回0xff,检测到地址帧则返回0xfe,接收成功则返回0
}
if(tmp == 0xfe) // 在数据接收过程中,如果发现地址帧,则重新开始整个接收过程
continue;
Beep_ok(); // 蜂鸣表示数据接收成功
}
}
/* 初始化串口 */
void init_serial()
{
TMOD = 0x20; //定时器T1使用工作方式2
TH1 = 250; // 设置初值
TL1 = 250;
TR1 = 1; // 开始计时
PCON = 0x80; // SMOD = 1
SCON = 0xd0; //工作方式3,9位数据位,波特率9600bps,允许接收
}
/* 接收数据,注意该函数使用buf指向的缓冲区保存数据,在数据末尾使用’\0’表示数据结束
* 返回值为0,数据校验成功,返回值为0xfe,接受过程中接收到地址帧,返回值为0xff,数据校验失败
*/
unsigned char recv_data(unsigned char *buf)
{
unsigned char len; // 该字节用于保存数据长度
unsigned char ecc; // 该字节用于保存校验字节
unsigned char i,tmp;
/* 接收数据长度 */
RI = 0;
while(!RI);
if(RB8 == 1) // 若当前接收为地址帧则返回0xfe
return 0xfe;
len = SBUF;
RI = 0;
/* 使用len的值为校验字节ecc赋初值 */
ecc = len;
/* 接收数据 */
for(i=0; i
while(!RI);
if(RB8 == 1) // 若当前接收为地址帧则返回0xfe
return 0xfe;
*buf = SBUF; // 接收数据
ecc = ecc^(*buf); // 进行字节校验
RI = 0;
buf++;
}
*buf = 0; // 表示数据结束
/* 接收校验字节 */
while(!RI);
if(RB8 == 1) // 若当前接收为地址帧则返回0xfe
return 0xfe;
tmp = SBUF;
RI = 0;
/* 进行数据校验 */
ecc = tmp^ecc;
if(ecc != 0) // 校验失败
{
*(buf-len) = 0; // 清空数据缓冲区
TI = 0; // 发送校验失败信号
TB8 = 0;
SBUF = __ERR_;
while(!TI);
TI = 0;
return 0xff; // 返回0xff表示校验错误
}
TI = 0; // 校验成功
TB8 = 0;
SBUF = __SUCC_;
while(!TI);
TI = 0;
return 0; // 校验成功,返回0
}
#endif
上一篇:单片机双机点对点通信的从机程序
下一篇:多机通信的主机部分程序
史海拾趣
|
IGBT负载短路下的几种后果 (1) 超过热极限:半导体的本征温度极限为250℃,当结温超过本征温度,器件将丧失阻断能力,IGBT负载短路时,由于短路电流时结温升高,一旦超过其热极限时,门级保护也相应失效. (2) 电流擎住效应:正常工作电流下,IGBT由于薄 ...… 查看全部问答> |
|
条码手持终端应用程序开发!!! 本人在条码行业有多年的工作经验,一直从事条码手持终端应用程序的开发 开发过多种设备: CASIO DT900,DT300,DTX10; Cipher 711 ; SYMBOL MC50,MC1000,PPT8800; Intermec 700系列 有需要的请联系本人 QQ:6 ...… 查看全部问答> |
|
急!!!如何在PC机上实现对单片机的控制(用VC++6.0编程) 小弟正在想弄一个在PC机上实现对单片机的控制,但不知道从哪个方面入手? 希望各位达人给予小弟一些指点.发个程序给小弟参考参考(用C语言编写的)… 查看全部问答> |
|
经历了很多推销的宣传,今天买了10片样品,准备把以前ATMEL8的东西都移植过来. 有几个问题,一直没搞明白: 1. STM8S103K3会不会象ATMEL那样,1000元就能把代码都读出来?STM8S103K3的 解密难度有多大? 2. 以前一直用ICC和KEIL开 ...… 查看全部问答> |
|
2812程序烧到片内flash中运行,能否用CCS和仿真器观察内部变量 2812程序烧到片内flash中运行,能否用CCS和仿真器观察内部变量, 调试电机程序,使用仿真器容易跑飞,希望能烧到flash中运行,同时也希望能像在ccs里仿真一样观察几个关键变量,听有的工程师说是能实现的,希望有能得到指点?… 查看全部问答> |
|
这是个试验程序,就是把整页写入同一个数据,,另外ID什么都可以读出来,,个人感觉数据是可以读出来的,,但读出来的全是FF,2112个FF后是64个0x15,我把读命令改错的话,读出来的是那个输入的数据,说明内部没把数据读出来,这是不是说明FF读出来 ...… 查看全部问答> |
|
在整个APF中基准电流的产生方法是核心环节,只有产生正确的基准电流信号才能很好的补偿谐波和无功电流。当只是补偿谐波电流时只需获取负载电流中的谐波分量即可,当补偿谐波及无功时除了要获取谐波电流信号外还需获取基波电流中的无功分量。基准电 ...… 查看全部问答> |




