设计一个单片机之间的通信系统

作者&投稿:桓肢 (若有异议请与网页底部的电邮联系)
设计一个单片机双机通信系统,并编写通信程序~

串口调试助手是PC端的软件,用来从PC的串口发送和接收数据的。我们调试PC和单片机之间通讯的时候用来模拟PC端应用软件给单片机发送数据和接收单片机发送的数据的。你调试的是单片机和单片机之间的通讯,不适合用串口调试助手的。
但是单片机和单片机通讯不容易知道实际通讯的数据,所以存在很大的调试难度。如果条件允许的话,一般是通过单片机连PC串口,让PC模拟模块收发数据来验证串口通讯是否正常(PC端能够直接看到单片机发送的数据,从而判断程序是否符合同模块的通讯要求),再把PC换成模块进行通讯。这样调试比较方便。

你和模块通讯也是单纯的串口通讯。
我又仔细分析了一下你的系统,按你的意思应该是拿51单片机做上位机。习惯上我们把PC称为上位机,所以刚才没明白。

1、SMOD是用来给串口波特率硬件倍频的。在串口模式1,2,3下,如果SMOD=0波特率是4800,那么SMOD=1时波特率是9600。它存在的理由就是:如果要求的波特率非常快,在给定晶振条件下SMOD=0已经满足不了,才需要SMOD=1倍频。
比如你11.0592MHZ在SMOD=0时波特率最大28800bps达不到要求的57600bps,所以你要用SMOD=1倍频才能实现。
你串口要选择模式1,波特率是可变的,取决于定时器1的溢出速率:
波特率=(2SMOD÷32)×定时器1 溢出速率
通常会使用定时器1 工作在定时器工作模式2下,这时定时值中的TL1 做为计数,TH1 做为自动重装值 ,这个定时模式下,定时器溢出后,TH1 的值会自动装载到TL1,再次开始计数,这样可以不用软件去干预,使得定时更准确。在这个定时模式2 下定时器1 溢出速率的计算公式如下:
溢出速率=(计数速率)/(256-TH1) ;
计数速率= 11.0592M/12;
算了一下是TH1=255(#0FFH);就是计数器走一个计数周期。

2、你不用关心什么叫做数据包,只是一种形象的叫法。把一串数据作为一次通讯的内容,这一串数据就是一个包了。那个2位和4位只是写法上便于你理解的,
如01H +0000H + 01H + 03H + 0005H
对应上面的包格式解释0000H是地址码保留字0005H是校验和。
而串口通讯一帧只能发送一个字节。发送的时候只能 01H + 00H +00H + 01H + 03H + 00H + 05H 依序发送。
用汇编写的话流程就是 写入第一个字节01H到SBUF,等待直到TI=1,发送第二个字节00H,等待直到TI=1,发送第三个字节00H,如此循环直到发送完05H为止。

3、类似发送,应答8181H也是81H+81H两个字节回复的。可以用中断,也可以用查询。例如2的发送通讯中05H发送完之后就要开始查询RI直到RI=1,然后就把 SBUF中的字节读出来,是81H,清RI后再查询RI直到RI=1,把 SBUF中的字节读出来,是81H,清RI。如果判断两个接收的都是81H那就表明收包正确。

4、串口通讯一帧只能发送一个字节。这个就不是问题了。

+我hi交流,不留Q,不留程序。

//两个51单片机,两机的串口交叉连线,双机互发数据
//接收方采用两位数显示收到的数据
//下列双机通信程序,适用于双方同时使用
//经过编译、仿真成功
//显示函数应该根据自己的设备进行改写
//===============================
#include
#define uchar unsigned char
#define uint unsigned int
uchar Rbuf = 0;
uchar code dis_7[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x00};//共阴段码
//段码表 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, off
//-------------------------------
void delay(uint k)
{
uint i, j;
for(i = 0; i < k; i++) for(j = 0; j < 200; j++);
}
//-------------------------------
void Display(uchar x)
{
P0 = dis_7[x / 16]; //输出高四位
P2 = 0xFE;
delay(2);
P0 = dis_7[x % 16]; //输出低四位
P2 = 0xFD;
delay(2);
}
//-------------------------------
void UART()interrupt 4
{
if(RI) {
RI = 0; //清除中断标志
Rbuf = SBUF;
}
if(TI) {
TI = 0; //清除中断标志
}
}
//-------------------------------
void main() //主函数
{
uchar t1, i;
SCON = 0x50; //串口工作在方式1
PCON &= 0x7F; //SMOD=0
TMOD = 0x20; //定时器1当做波特率发生器
TH1 = 0xFD; //初值, 9600 @ 11.0592MHz
TL1 = 0xFD;
TR1 = 1;
while (1){
for (i = 0; i < 250; i++) Display(Rbuf);
SBUF = t1; //发送数据
t1++;
}
}
//===============================

/*----------------------------------------

ComFun+.c 

C51串口输出输入函数

外部声明 ComFun.h

----------------------------------------*/

#include <reg52.h>

void InitCom(unsigned char BaudRate);  //串口初始化

void ComOutChar(unsigned char OutData);  //输出一个字符

void ComOutEnter(void);   //输出回车换行

void ComOutStr(unsigned char *Str);   //输出字符串

unsigned char ComInChar();     //接收一个字符

void ComInStr(unsigned char *Str);   //接收定长字符串

            

//串口初始化 晶振为11.0592M 方式1 波特率300-57600

void InitCom(unsigned char BaudRate)

{

unsigned char THTL;

switch (BaudRate)

{

case 1: THTL = 64; break; //波特率300

case 2: THTL = 160; break; //600

case 3: THTL = 208; break; //1200

case 4: THTL = 232; break; //2400

case 5: THTL = 244; break; //4800

case 6: THTL = 250; break; //9600

case 7: THTL = 253; break; //19200

case 8: THTL = 255; break; //57600

default: THTL =  243;//晶振为12M,波特率4800.

}

SCON = 0x50; //串口方式1,允许接收

TMOD = 0x20; //定时器1定时方式2

TCON = 0x40; //设定时器1开始计数

TH1 = THTL;

TL1 = THTL;

PCON = 0x80; //波特率加倍控制,SMOD位

RI = 0; //清收发标志

TI = 0;

TR1 = 1; //启动定时器

}

//向串口输出一个字符(非中断方式)

void ComOutChar(unsigned char OutData)

{

SBUF = OutData; //输出字符

while(!TI); //空语句判断字符是否发完

TI = 0; //清TI

}

//向串口输出一个回车换行

void ComOutEnter(void)

{

SBUF = 0x00;

while(!TI);

TI = 0;

SBUF = 0x0A;

while(!TI);

TI = 0;

}

//向串口输出一个字符串(非中断方式)

void ComOutStr(unsigned char *Str)

{

//while(*Str != 0x00) //判断是否到了字符串的尾部

   unsigned int i=0;

   for (i=0;i<16;i++)

{

SBUF = *Str; //输出字符

while(!TI); //空语句判断字符是否发完

TI = 0; //清TI

Str++; //字符串指针加一

}

// ComOutEnter();

}

//从串口接收一个字符(非中断方式)

unsigned char ComInChar()

{

unsigned char InData;

while(!RI); //空语句判断字符是否收完

InData = SBUF; //保存COM缓冲字符

RI = 0; //清RI

return (InData); //返回收到的字符

}

//从串口接收一个定长字符串(非中断方式,只用于字符需有一个的idata字符串数组)

//如unsigned char *Str;

//unsigned char i[]="abcd";

//InHandStr = &i;

void ComInStr(unsigned char *Str)

{

//while(*Str != 0x00) //判断是否到了字符串的尾部 

   unsigned int i=0;

   for (i=0;i<16;i++)

{

while(!RI); //空语句判断字符是否收完

*Str = SBUF; //保存字符

RI = 0; //清RI

Str++; //字符串指针加一

}

}



这个很简单的,应当自己多动手,才能学到东西;

学校真的很强大


单片机 一个脉冲的上升沿下降沿期间,定时器所计的时T=...
单片机 一个脉冲的上升沿下降沿期间,定时器所计的时T=(THO*256+TLO)*1.085为什么是一个信号的周期扫描二维码下载 下载知道APP10分钟有问必答! 建议:可使用微信的“扫一扫”功能扫描下载 分享到: 2013-09-18 00:20 提问者采纳 这个很容易理解,设计这个代码的人,使用的单片机晶振是11.0592MHz的,那么12分频后,...

怎么用单片机实现一个计数器
图中反馈网络应该是与非门,不是与门,以下按与非门做。M = 0 ,预置数 = 1011 = 11 ,即计数器的初始值;计数器最大值:1001 = 9 ;计数范围:11、12、13、14、15、0、1、2、3、4、5、6、7、8、9,共15个状态,是15进制计数器。状态转换图就是画15个圈,头尾相连的循环,圈内标...

用c语言循环语句怎么写一个51单片机的时钟啊,用8个数码管显示时间...
for(i=0;i<x;i++)for(j=0;j<120;j++);}void dischg(){disdat[0]=sec%10;disdat[1]=sec\/10;disdat[2]=10;disdat[3]=min%10;disdat[4]=min\/10;disdat[5]=10;disdat[6]=hour%10;disdat[7]=hour\/10; }void flash(){switch(flashbit){case 0:break;case 1:disdat[6]...

设计一个以单片机为核心的8位竞赛抢答器,要求如下:
8路抢答器,这种题目,在百度上真是泛滥成灾了,随便一搜就能搜到一大堆,有仿真图和程序全部资料的。或者百度文库里也同样可以搜索到,还是毕业论文,更是详细。下图是一个8路抢答器的仿真图。

求一个关于单片机定时器和计数器的c语言程序!大神出现吧~~~_百度知...
sbit p11=P1^1;uchar y,z,c;\/*时间中断程序*\/ void int1() interrupt 1\/\/时间为50MS { TH0=0X4C;TL0=0X00;z++;if(z==10){z=0;p11=~p11;y++;} if(y==2) \/\/既一高一低,2次计数才为一个周期 {y=0;c++;if(c==10) \/\/满十归0 c=0;} P0=LED7Code[c];} void main...

一个基于单片机精确计时的电源开关程序的设计与实现,各位大哥,我的论文...
一个基于单片机精确计时的电源开关 控制程序的设计与实现 摘要 由于精确计时在当前工业控制,日常生活等领域有广泛应用,本设计采用MCS-51系列单片机为核心器件,辅以相应的外围电路,设计制作出了基于单片机的精确计时控制硬件系统,并通过继电器外接被控制端,可以实现用较小的电流去控制较大电流的目的。在...

用单片机设计一个两位LED显示的秒表,按下计时键时,进行60s倒计时显示...
sbit P3_5 =P3^5;unsigned char code dispcode[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0x00};unsigned char second=60;unsigned char keycnt;unsigned int tcnt;void main(void){ unsigned char i,j;TMOD=0x02;ET0=1;EA=1;...

单片机与相位计的RS232串口通信编程问题。 硬件已经没有问题,c程序存 ...
2、你现在的串口接收函数执行了也收不到数据,因为单片机串口只有一个字节的缓冲,所以一般用中断方式来接收数据,每次有一个字节收到后,通过中断来将收到的字节放入程序缓冲去。还有接收变量怎么会写成float的?单字节用char 。如果是相位计的数据发过来是float类型,那需要你自己程序转换,串口发送的只...

求一个51单片机内部中断1最简单的倒计时源程序。30秒倒计时。
uchar code table[ ]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};unsigned int i;void init( );void display;void delay(uchar z){ uint x,y;for(x = z;x>0;x--)for(y = 110;y>0;y--)} void main(){ init( );i = 30;while(1){ if(i ==50000){ i...

单片机80c51设计一个两位计数器,能对外部的脉冲进行计数,能进行复位...
2011-12-18 20:36异度清风 | 分类:工程技术科学 | 浏览301次 主程序中滚动显示两位数字,当输入脉冲未来到之前并保持不变。在中断服务程序中,每当来一个外来脉冲时,需要显示的数字加一。单片机复位时,需要显示的数字是00。主程序中,开INT0中断。需要设置:(1)选用外部中断0 中断,没.0 ...

长治县15930618396: 设计一个单片机之间的通信系统 -
历胞黄氏: /*----------------------------------------ComFun+.c C51串口2113输出输入函数外部声明 ComFun.h----------------------------------------*/#include <reg52.h>void InitCom(unsigned char BaudRate); //串口初5261始化void ComOutChar(unsigned char OutData); ...

长治县15930618396: 单片机与单片机之间如何进行串行通信 -
历胞黄氏: 1、将两个单片机的RXD与TXD相连2、根据需要传输的数据编写传输协议3、编写串行通信程序,将自己需要发送的数据按照协议进行发送4、编写接收程序,按照协议进行接收5、将两个程序分别写入两个单片机,运行.

长治县15930618396: 单片机多机通讯系统的设计 -
历胞黄氏: 200米以上用485接口嘛 问题的提出 在工业控制及测量领域较为常用的网络之一就是物理层采用RS-485通信接口所组成的工控设备网络.这种通信接口可以十分方便地将许多设备组成一个控制网络.从目前解决单片机之间中长距离通信的诸多方...

长治县15930618396: 两个单片机之间怎么实现通信 -
历胞黄氏: 很近距离的话可以TTL电平直接通信.稍远一些建议用RS232通信.

长治县15930618396: 两个单片机做一个系统,单片机之间用什么方式通信最好啊!! -
历胞黄氏: 1、一般采用单片机串口通讯就可以.2、串口通讯采用什么信号,要根据实际情况确定.3、如果单片机之间通讯距离远的话,可以采用RS485通讯方式;如果单片机之间通讯距离近的话,两个单片机串口可以直接通讯.4、如果对通讯速度要求不高的话,也可以用单片机的普通口做,通过外搭电路,实现两个单片机的通讯.5、不论采用什么方式的通讯,通讯协议都是自己定义.

长治县15930618396: 单片机与单片机之间怎么通信? -
历胞黄氏: 单片机 与 单片机 通讯, 直接串口对接 就可以( TXD1 - RXD2 , RXD1 - TXD2 ). 多机 通讯 设置一主机 ,( TXD1 - RXD2 - RXD3 --- RXDn , RXD1 - TXD2 - TXD3 --- TXDn ). 方式与 PC 与 单片机 相似.注意 波特率 要相同.

长治县15930618396: 设计一个单片机双机通信系统,并编写通信程序 -
历胞黄氏: ;=============================== 发送子程序如下: START:MOV SCON, #80H ;设定串行通讯方式2ORL PCON, #80H ;SMOD置1, 波特率为主频的1/32MOV R0, #30H ;数据起始地址.MOV R3, #16 ;数据共16字节, 循环16次. ...

长治县15930618396: 怎样实现两片单片机之间的并行通信 -
历胞黄氏: 1.直接使用一个8位口就可以实现. 2.使用8位口以及一个中断和使能端,每个单片机使用10个端口 3.使用8位口以及一个时钟输出和使能端,每个单片机使用10个端口 你也可以参照一些ad/da的使用.

长治县15930618396: 串口通信—多机通信系统 一、任务: 设计实现多台单片机系统之间的串行通信 二、基本要求 (1)设计一个主 -
历胞黄氏: 展开全部1)用51即可.每台从机设置固定地址.2)用max485,485总线连接.(用232也行)3)自定协议,主机轮询发出指令,应答机接命令后,按协议格式返回AD结果.主机显示.

长治县15930618396: 两个单片机之间的无线传输 -
历胞黄氏: 选择通讯模块完成传输1:用rf905进行数据传输,两块单片机都通过串口将数据发送给905,然后通过905发送出去.2:用PT2262发也可以,如果你不考虑成本的话,你可以用51的一个端口控制一个继电器当按键用 建议nrf24l01这个模块,spi协议,程序不是很难写

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网