一位一位地接受。
通信双方以一个字符(包括特定附加位)作为数据传输单蚂散谨位且发送方传送字符的间闷基隔时间不一定,具有不规则数据段传送特性的串行数据传输。
在异步通信中,字符数据掘衫以图所示的格式一个一个地传送。在发送间隙,即空闲时,通信线路总是处于逻辑“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
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)