在异步串行通信中,接受方是如何知道发送方开始发送数据的?

在异步串行通信中,接受方是如何知道发送方开始发送数据的?,第1张

一位一位地接受。

通信双方以一个字符(包括特定附加位)作为数据传输单蚂散谨位且发送方传送字符的间闷基隔时间不一定,具有不规则数据段传送特性的串行数据传输。

在异步通信中,字符数据掘衫以图所示的格式一个一个地传送。在发送间隙,即空闲时,通信线路总是处于逻辑“1”状态,每个字符数据的传送均以逻辑“0”开始。

扩展资料

编制串行通信的数据发送程序,发送片内RAM50H~5FH的16个字节的数据,串行接口设定为方式2,采用奇偶校验方式。设晶振频率为6MHz。

ORG 0000H

LJMP START

ORG 0030H

START:

MOV SP, #30H

MOV PCON, #80H

MOV SCON, #80H

MOV R0, #50H

MOV R7, #16

LOOP:

MOV A, R0

MOV C, P    ;红色部分为奇偶校验方式

MOV TB8, C

MOV SBUF, A

JNB TI, $

CLR TI

INC R0

DJNZ R7, LOOP

SJMP $

END

module asyn(clk,rst,wr,wr_bit,addr,bit_in,data_in,t1_ow,rxd,txd,intr,data_out,pcon,scon,rx_sbuf)

input clk

input rst

input wr

input wr_bit

input [7:0] addr

input bit_in

input [7:0] data_in

input t1_ow

input rxd

output txd

output intr

output [7:0] data_out

output [7:0] scon

output [7:0] pcon

output [7:0] rx_sbuf

reg txd

reg [7:0] scon

reg [7:0] pcon

assign intr=scon[1]|scon[0]

//

wire t1_ow_final

reg div2_flag

reg t1_ow_buf

reg t1_ow_final_buf

// signals with transmit part

reg [7:0] tx_sbuf

reg send_n //active low,indicate that it is transmiting datas

wire wr_sbuf_en

assign wr_sbuf_en=(wr==1'b1&&addr==8'h99)

reg wr_sbuf_en_mem

wire shift_en

reg [3:0] tx_next_state

reg [3:0] tx_current_state

parameter IDLE=11,START=0,D0=1,D1=2,D2=3,D3=4,D4=5,D5=6,D6=7,D7=8,TB8_BIT=9,STOP_BIT=10//states define

reg [3:0] osc_cnt

reg [3:0] tx_sample_cnt

reg tx_clk

//signals with receive part

reg [3:0] rx_next_state

reg [3:0] rx_current_state

reg [3:0] rx_sample_cnt

wire one_bit

reg rxd_buf

reg [10:0] sbuf_rxd_tmp

reg [7:0] rx_sbuf

reg sample_7,sample_8,sample_9

reg receive

//signals with both transmiting and receiving parts

//always @(*)

//begin

//SM0=scon[7]

//SM1=scon[6]

//SM2=scon[5]

//REN=scon[4]

//TB8=scon[3]

//RB8=scon[2]

//TI=scon[1]

//RI=scon[0]

//end

always @(posedge clk or posedge rst) //register scon

begin

if (rst)

scon <=8'b0100_0000

else if ((wr) &!(wr_bit) &(addr==8'h98))

scon <=data_in

else if ((wr) &(wr_bit) &(addr[7:3]==5'b10011))

scon[addr[2:0]]<=bit_in

else if (tx_next_state==STOP_BIT)

scon[1] <=1'b1

else

case(rx_next_state)

START:scon[0]<=1'b0

IDLE:if(rx_current_state==STOP_BIT)

begin

case (scon[7:6])

2'b00: scon[0] <= 1'b1

2'b01: if(scon[5])

if(one_bit)

scon[0] <= 1'b1

else

scon[0] <= 1'b0

else

scon[0] <= 1'b1

2'b10,2'b11: if(scon[5])

scon[0]<=sbuf_rxd_tmp[9]

else

scon[0]=1'b1

endcase

end

endcase

end

//

//power control register

//

wire smod

assign smod = pcon[7]

always @(posedge clk or posedge rst)

begin

if (rst)

pcon <= 8'b0000_0000

else if ((addr==8'h87) &(wr) &!(wr_bit))

pcon <= data_in

end

always @(posedge clk or posedge rst) //osc_cnt

if(rst)

osc_cnt<=4'b0000

else if(osc_cnt==4'b1011)

osc_cnt<=4'b0000

else

osc_cnt<=osc_cnt+1'b1

always @(posedge clk or posedge rst) //t1_ow_buf

if(rst)

t1_ow_buf<=1'b0

else if(t1_ow)

t1_ow_buf<=~t1_ow

always @(posedge clk or posedge rst) //div2_flag

if(rst)

div2_flag<=1'b0

else if(~t1_ow_buf&t1_ow)

div2_flag<=~div2_flag

assign t1_ow_final=(pcon[7]==1'b1)?t1_ow:t1_ow&div2_flag

//transmit part

always @(posedge clk or posedge rst) //t1_ow_final_buf

if(rst) t1_ow_final_buf<=1'b0

elset1_ow_final_buf<=t1_ow_final

always @(posedge clk or posedge rst) //tx_sample_cnt

if(rst)

begin

tx_sample_cnt<=4'b0000

end

else if(t1_ow_final_buf==1'b0&&t1_ow_final==1'b1)

tx_sample_cnt<=tx_sample_cnt+1'b1

always @(posedge clk or posedge rst)

if(rst)

wr_sbuf_en_mem<=1'b0

else if (wr_sbuf_en&&wr_sbuf_en_mem<=1'b0)

wr_sbuf_en_mem<=1'b1//represent that the tx_sbuf has been loaded

else if(tx_current_state==STOP_BIT)

wr_sbuf_en_mem<=1'b0

assign shift_en=wr_sbuf_en_mem==1'b1&&tx_sample_cnt==4'b1111&&osc_cnt==4'b1011&&t1_ow_final_buf==1'b0&&t1_ow_final==1'b1

always @(posedge clk or posedge rst)

if(rst)

tx_sbuf<=8'b0000_0000

else if (wr_sbuf_en&&wr_sbuf_en_mem<=1'b0)

tx_sbuf<=data_in

else if(send_n==1'b0&&shift_en)

tx_sbuf<=tx_sbuf>>1'b1

//the three always phrase below is the 3 parts discription of state machine

always @(*)//(tx_current_state or wr_sbuf_en_mem or tx_sample_cnt or osc_cnt or TH1 or TL1 or shift_en)

begin

case(tx_current_state)

IDLE: if(shift_en) //

tx_next_state=START

else

tx_next_state= IDLE

START:if(shift_en)

tx_next_state=D0

else

tx_next_state=START

D0: if(shift_en)

tx_next_state=D1

else

tx_next_state=D0

D1: if(shift_en)

tx_next_state=D2

else

tx_next_state=D1

D2: if(shift_en)

tx_next_state=D3

else

tx_next_state=D2

D3: if(shift_en)

tx_next_state=D4

else

tx_next_state=D3

D4: if(shift_en)

tx_next_state=D5

else

tx_next_state=D4

D5: if(shift_en)

tx_next_state=D6

else

tx_next_state=D5

D6: if(shift_en)

tx_next_state=D7

else

tx_next_state=D6

D7: if(shift_en)

if(scon[7:6]==2'b00||scon[7:6]==2'b01)

tx_next_state=STOP_BIT

else

tx_next_state=TB8_BIT

else

tx_next_state=D7

TB8_BIT: tx_next_state=STOP_BIT

STOP_BIT: if(tx_sample_cnt==4'b1111&&osc_cnt==4'b1011&&t1_ow_final==1'b1)

tx_next_state=IDLE

else

tx_next_state=STOP_BIT

default:tx_next_state=IDLE

endcase

end

always @(posedge clk or posedge rst)

if(rst)

tx_current_state<=IDLE

else

tx_current_state<=tx_next_state

always @(posedge clk or posedge rst)

if(rst)

begin

txd<=1'b1

send_n<=1'b1

end

else

case(tx_next_state)

IDLE:

begin

send_n<=1'b1

txd<=1'b1

end

START:begin

send_n<=1'b0

txd<=1'b0

end

D0: txd<=tx_sbuf[0]

D1: txd<=tx_sbuf[0]

D2: txd<=tx_sbuf[0]

D3: txd<=tx_sbuf[0]

D4: txd<=tx_sbuf[0]

D5: txd<=tx_sbuf[0]

D6: txd<=tx_sbuf[0]

D7: txd<=tx_sbuf[0]

TB8_BIT: txd<=scon[3]

STOP_BIT:

begin

txd<=1'b1

end

endcase

//receiving part

assign rx_shift_en=rx_sample_cnt==4'b1111&&t1_ow_final_buf==1'b0&&t1_ow_final==1'b1

always @(posedge clk or posedge rst) //describe the rxd_buf

if(rst)

rxd_buf<=1'b0

else

rxd_buf<=rxd

always @(posedge clk or posedge rst) //describe the rx_sample_cnt

if(rst)

rx_sample_cnt<=4'b0000

else if(rxd_buf==1'b1&&rxd==1'b0)//此条件启动接收过程

rx_sample_cnt<=4'b0000

else if(t1_ow_final)

rx_sample_cnt<=rx_sample_cnt+1'b1

always @(posedge clk)

if(rx_sample_cnt==4'b0110&&t1_ow_final)

sample_7<=rxd

always @(posedge clk)

if(rx_sample_cnt==4'b0111&&t1_ow_final)

sample_8<=rxd

always @(posedge clk)

if(rx_sample_cnt==4'b1000&&t1_ow_final)

sample_9<=rxd

assign one_bit=sample_7&&sample_8||sample_7&&sample_9||sample_8&&sample_9

//the three always phrase below is the 3 parts discription of state machine

always @(*)

begin

case(rx_current_state)

IDLE: if(rxd_buf==1'b1&&rxd==1'b0&&scon[4]==1'b1) //检测到了rxd从1到0的跳变

rx_next_state=START

else

rx_next_state= IDLE

START: if(rx_shift_en)

if(~one_bit)

rx_next_state=D0

else

rx_next_state=IDLE

else

rx_next_state=START

D0: if(rx_shift_en)

rx_next_state=D1

else

rx_next_state=D0

D1: if(rx_shift_en)

rx_next_state=D2

else

rx_next_state=D1

D2: if(rx_shift_en)

rx_next_state=D3

else

rx_next_state=D2

D3: if(rx_shift_en)

rx_next_state=D4

else

rx_next_state=D3

D4: if(rx_shift_en)

rx_next_state=D5

else

rx_next_state=D4

D5: if(rx_shift_en)

rx_next_state=D6

else

rx_next_state=D5

D6: if(rx_shift_en)

rx_next_state=D7

else

rx_next_state=D6

D7: if(rx_shift_en)

if(scon[7:6]==2'b00||scon[7:6]==2'b01)

rx_next_state=STOP_BIT

else

rx_next_state=TB8_BIT

else rx_next_state=D7

TB8_BIT: if(rx_shift_en)

rx_next_state=STOP_BIT

else

rx_next_state=TB8_BIT

STOP_BIT: if(rx_shift_en)

rx_next_state=IDLE

else

rx_next_state=STOP_BIT

endcase

end

always @(posedge clk or posedge rst)

if(rst)

rx_current_state<=IDLE

else

rx_current_state<=rx_next_state

always @(posedge clk or posedge rst)

if(rst)

receive<=1'b0

else

case(rx_next_state)

IDLE:

receive<=1'b0

START:begin

receive<=1'b1

sbuf_rxd_tmp<=10'b11_1111_1111

end

D0,D1,D2,D3,D4,D5,D6,D7: if(rx_shift_en) sbuf_rxd_tmp<={sbuf_rxd_tmp[10:0],one_bit}

STOP_BIT:

receive<=1'b1 // end of receiving

endcase

//

//serial port buffer (receive)

//

always @(posedge clk or posedge rst)

begin

if (rst)

rx_sbuf<=8'h00

else if (rx_next_state==STOP_BIT)

case (scon[7:6])

2'b00,2'b01:rx_sbuf<=sbuf_rxd_tmp[7:0]

2'b10,2'b11:rx_sbuf<=sbuf_rxd_tmp[8:1]

endcase

end

endmodule

因为你是用查询方式进行通信的,而程序没有中没有设置两机通信的联络信号,即接受机接收到的第一位数据不一定是发送机发送的第一位数据,而有可能是第二、第三位数据,这样接受到的八位数据就可能是发送机发送多次数据中截取的八册答位数据,又因两机延时时间不同,因此接受到丛大的第一位数据不可能固定不变的。

所以就会出现你州郑慧说的现象。如果采用的是查询方式进行串行通信,两机之间需要建立握手信号,告知接受机发送机开始发送地位数据,接受机才开始接受数据。

#include <reg51.h>

#define uchar unsigned char

#define uint unsigned int

void uart_init()

{

TMOD=0x20

TH1=0xFD

TL1=0xFD

PCON=0x00

TR1=1

SCON=0x50

}

void delay(uint z)

{

uint x,y

for(x=zx>0x--)

for(y=125y>0y--)

}

void main()

{

uart_init()

do

{

SBUF=0x01

while(TI==0)

TI=0

while(RI==0)

REN=0

}

while(SBUF!=0x02)

while(1)

{

SBUF=0x07

while(TI==0)

TI=0

delay(500)

SBUF=0x00

while(TI==0)

TI=0

delay(500)

}

}

#include <reg51.h>

#define uchar unsigned char

#define uint unsigned int

void uart_init()

{

TMOD=0x20

TH1=0xFD

TL1=0xFD

PCON=0x00

TR1=1

SM0=0 //串口方式1

SM1=1

REN=1

}

void main()

{

uart_init()

do

{

SBUF=0x02

while(TI==0)

TI=0

while(RI==0)

RI=0

P2=SBUF

}

while(P2!=0x01)

while(1)

{

while(RI==0)

P1=SBUF

RI=0

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/12379104.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存