设计一个单片机之间的通信系统
串口调试助手是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 ...
历胞黄氏: /*----------------------------------------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协议,程序不是很难写