1、)主CPU回应ACK。或,1)主CPU发送命令,2)主CPU发送数据,3)从CPU回应ACK。命令格式:2字节同步码+1字节标记码1字节从CPU地址码1字节命令码2字节参数码1字节CRC校验码 数据格式:1字节数据长度码N字节数据ACK格式:1字节回应码(0x55表示接收正确,否则失败)侦错与纠错机制:靠同步码进行帧同步,靠CRC校验码进行帧检错,接收方发现错误丢弃错误帧,发送方等待数据超时重发,连续重发3次失败 放弃发送。协议2:竞争协议 借用以太网的机制,每个CPU都是平等地位,都可以随时发送数据。步骤如下,当任何一个CPU想发送数据时, 1)探听COM线1ms时间,之内若无数据接收,则转
2、2),否则继续探听。2)向COM线发送数据,同时接收回来,一旦发现接收数据和发送数据不相同,则转3),否则一直发送数据直到数据发送完毕,返回。3)停止发送,等待一个随机时间ms,转1)。发送数据格式:1字节源CPU地址码1字节目的CPU地址码靠同步码进行帧同步,靠CRC校验码进行帧检错,靠高层协议进行纠错,高层协议略。疑问解答:发送数据时Tx变成低电平,电源岂不对地短路啦?如果不接电感L1,COM又接地,确实会发生电源对地短路,但是接了L1后就不会了,COM接地相当于此时电源只接了L1一个负载,电源消耗的 电能随着L1电流增加变成了储存在L1中的磁能,当COM又变回高电平时,这部分磁场能量会随
3、着D2的泄压作用转移到电容C1中,变成电场能量, 最终被CPU消耗掉,是不是和升压DC-DC有点像?因此可以预期在通信期间,CPU供电电压(即C1电压)会有所升高。为何选择串口(Tx、Rx)作为数据收发口?从原理上看,调制信号占空比应该越大越好,占空比越大,每个周期内低电平时间相对越短,因DC-DC效应对CPU电源电压影响就越小;凡事 不能走极端,占空比也不能太小,否则抗干扰能力就差了。另外,通信速率也不宜太低,速率太低,造成发送1bit时COM线电平被拉低时间太长,L1电流过大,会造成L1储能饱和,电源效率降低。因此,使用串口不是最好选择,串口信号调制占空比为1100%可以,00%太小了;串
4、口速率普遍较低,最高才115Kbps。但是,因为单 片机上一般不集成有专门适用于我这个方案的硬件收发器,软件模拟或外挂CPLD又太麻烦,所以干脆用串口算了,硬件简单,成本还低,软件 也不复杂,直接操作串口就行了。/双MCU通讯的几种方法众所周知,单片机的硬件资源是非常有限的。因此一些设计者喜欢扩展总线,外挂一些专用芯片,其结果是造成系统臃肿,PCB布线费事费力,成本大幅度提高,而系统的稳定性却降低!本人曾见过一个设计:为了周期输出一个宽度400mS的脉冲(误差:0.1mS),而扩展了一片8155。借用8155的定时器输出脉冲。这种设计与再用一片MCU直接输出脉冲,哪个简单可靠呢?MCS51系列
5、单片机的UART口只有一个,因此扩展UART专用芯片的方法随处可见。而实际上完全可以采用双MCU的工作方式,为系统提供两个UART口,同时也提供了T0、T1、INT0、RAM等大量的硬件资源。现在介绍四种双MCU通讯的方法。一、模拟SPI串口方式 电路见图一,主、从MCU之间采用3线式通讯。主MCU负责系统的数据采集、计算、RS485通讯,而从MCU只负责显示数据。我们知道动态驱动多位LED数码管,将占用大量MCU的时间,如果这个任务也由主MCU完成,那么编程技巧是何等的重要!本人认为:在应用系统中,程序的可读性、易维护性应该比编程技巧更重要。采用双MCU系统后,主MCU只是在数据更新时,才与
6、从MCU通讯一次,其余时间可全部用于数据采集、处理上,这样不但程序流程简单,而且可由多人独立编制。从MCU的任务单一:动态扫描LED数码管。这样系统的实时性得以提高,而硬件成本并未大幅度提高!从MCU可以设计成一个通用LED数码管驱动器,应用于其它系统中!(附一:串口通讯源程序)二、并口方式电路见图二,这是一个远程打印机的接口电路。主MCU负责接收RS485通讯总线发来的数据,解析后通过P0口发送到从MCU。从MCU采用RS232通讯方式,再发送到打印机打印!虽然此电路可以用硬件代替,但是这种方法可以在不改动硬件的情况下,通过修改软件而应用于其它场合。双MCU采用并口通讯速度快、接口简单,但占
7、用较多的I/O线。(附二:并口通讯源程序)三、采用串口RAM芯片串口RAM芯片在市面上不易购买,但是可以利用一些带有RAM的专用芯片代替。见图三,利用DS1302内部的31个RAM字节做RAM缓存区。双MCU不分主次,均可访问DS1302,因此可方便地交换双MCU的数据。而且通讯速度高!访问DS1302时,必须通过“A线”判别访问权限。A=1说明无MCU访问DS1302,此时可以读写DS1302。置A=0!访问完毕后置A=1,释放访问权。如果A=0则必须等待!为了防止DS1302被单个MCU多次访问,而造成数据覆盖现象,在主程序中应该合理安排访问DS1302的次数。(附三:DS1302的读写子
8、程序)四、采用双端口RAM双端口RAM(如:IDT7134)是专门为双MCU系统设计的,其优点显而易见。但其价格昂贵,而且系统必须扩展总线,建议只有在不得已的情况下才使用,一般设计应尽量避免!附:1:所有电路图、波形图在TWOMCU.s01文件中附一:串口通讯程序;*Clk=p3.2:时钟脚Sda:数据脚Res:复位脚DataNumber:需发送的数据个数SendDataAdr:需发送的数据首地址SendData: clr Clk;启动时钟脚 mov r7,#01fh nop setb Clki2c_1: jnb Sda,i2c_next ;判别是否有应答 djnz r7,i2c_1 ;等待5
9、0uS setb Res复位从机 CLR Res reti2c_next:* mov r5,#30d djnz r5 ,$有应答后等待从机初始化 mov r7,#DataNumber mov r0,#SendDataAdr clr ci2c_s1: mov r6,#08d mov a,r0i2c_s2: rlc a mov Sda,c clr Clk mov r5,#20d djnz r6,i2c_s2 inc r0 djnz r7,i2c_s1i2c_end:*在INTO中断中接收ReceByte:需接收的数据个数ReceBit:需接收的数据的位数ReceDataAdr:需接收的数据首地址R
10、eceF:接收启动标志ReceData: push a push b push psw push 00h push 01h jb ReceF ,i2c_ne1 setb ReceF clr Sda mov r1,#040d!2001.5.25 djnz r1 ,$ ;应答主机 mov ReceByte,#00h ;初始化 mov ReceBit ,#08h setb Sda sjmp int0_end i2c_ne1: mov a,#ReceDataAdr add a,ReceByte mov r0,a mov a ,r0 mov c,Sdaclr c mov r0,amov a,ReceBi
11、t djnz ReceBit,int0_end mov ReceBit,#08d inc ReceByte mov a,ReceByte cjne a,#DataNumber,int0_end mov ReceByte,#00h mov ReceBit,#08h clr ReceF*数据转移到使用区 MOV R0,#ReceDataAdr MOV R1,#USE_DATA ;使用区的首地址 push 07h MOV R7,#DataNumberMOV_1: MOV A,R0 MOV R1,A inc r1 DJNZ R7,MOV_1 pop 07hint0_end: pop 01h pop 0
12、0h pop psw pop b pop a reti附二:并口通讯程序*需发送数据的首地址需发送数据的个数SendOverF:=1发送完毕标志IntoF=p3.2:中断脚*SendOut: rd_d1: mov p0,a* send printer_s* clr IntoFsend data to printer_cpu mov r6,#03 rd_d2: mul ab djnz r6,rd_d2延时等待15uS setb IntoF djnz r7,rd_d1 setb SendOverF*接收子程序(在INT0中接收)需接收数据的个数地址ReceNumber:需接收数据的个数ReceOv
13、erF: push 00h mov r0,#ReceDataAdr mov a,DateNumber;count address add a,r0* mov a,p0 inc DataNumber mov a,DataNumber cjne a,#ReceNumber,int0_do_end mov DataNumber,#0 setb ReceOverF ;rece printer_m dataint0_do_end:附三:DS1302读写子程序*r6 数据位计数器r7 数据字节计数器a 命令*发送数据程序名称:Send_Byte描述:发送A 个字节给被控器DS1302命令字节地址在r0 中
14、,Use a,b,r7所发送数据的字节数在A 中,发送的数据在XmtDat 缓冲区中*SendByte:CLR CsDs1302 ;复位引脚为低电平所有数据传送终止NOP CLR ClkDs1302; 清时钟总线NOPSETB CsDs1302 ;复位引脚为高电平逻辑控制有效push 07h;mov r7,aS_b1:MOV A,R0 ;传送数据过程与传送命令相同MOV b,#08hS_Byte2:RRC AMOV SoDs1302,CSETB ClkDs1302nop CLR ClkDs1302DJNZ b,S_Byte2INC R0 ;发送数据的内存地址加1DJNZ r7,S_B1 pop
15、 07hCLR CsDs1302 RET接收数据程序;ReceByte从被控器DS1302 接收a个字节数据命令字节地址在r0中;use a,b,r7所接收数据的字节数在r0中接收的缓冲区中CLR ClkDs1302 ;清时钟总线noppush 07mov b,amov a,r0;Read OrderMOV r7,#08h ;传送位数为8R_Byte0:RRC A ;将最低位传送给进位位CMOV SoDs1302,C ;位传送至数据总线SETB ClkDs1302 ;时钟上升沿发送数据有效DJNZ r7,R_Byte0 ;位传送未完毕则继续*R_B1:CLR A CLR C 接收位数为8R_B
16、yte2:MOV C,SoDs1302 ;数据总线上的数据传送给C从最低位接收数据时钟总线置高时钟下降沿接收数据有效DJNZ r7,R_Byte2; 位接收未完毕则继续MOV R0 ,A; 接收到的完整数据字节放入接收内存缓冲区INC R0; 接收数据的内存地址加1DJNZ b,R_B1 *1 写保护寄存器操作当写保护寄存器的最高位为0 时允许数据写入寄存器写保护寄存器可以通过命令字节8E,8F来规定禁止写入/读出写保护位不能在多字节传送模式下写入Write_Enable:MOV a,#2;命令字节+命令=2 单字节传送模式MOV R0,#Temp ;数据地址覆给R0mov r0,#WrEnable;命令字节为8Einc r0MOV r0,#00h ;数据内容为0 写入允许ACALL SendByte ;调用写入数据子程序RET 当写保护寄存器的最高位为1 时禁止数据写入寄存器Write_Disable:MOV a,#2 ;MOV R0,#TempMOV r0,#80h; 数据内容为80h 禁止写入当把秒寄存器的第7 位时钟停止位设置为0 时起动时钟开始Osc_Enable: 单字节传送模式mov r0,#80h数据内容为0 振荡器工作允许/
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1