Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16601 Discussions

I have the problem that my RS232 always is sending data to the PC

Altera_Forum
Honored Contributor II
1,684 Views

Dear readers - I have been programming following code: 

 

//******************************************************* 

//****** PAVLE DUKANOVIC ******* 

//****** www.dukelanovic.com ******* 

//****** dukelanovic@yahoo.de ******* 

//******************************************************* 

 

 

// Serial port demo program 

// http://www.techques.com/question/4-13718/implement-serial-port-on-fpga-(verilog)  

// Assumptions: 50Mhz clock rate 

 

 

module serial(input clk,input key_in, output ser, input rxd); 

 

 

 

 

// Start signal tells it to start sending bits 

 

 

reg[24:0]count; 

reg [3:0] ones; 

reg [3:0] tens; 

//The bits of data to send 

reg [7:0] data; 

reg sec; 

reg [14:0] clockdiv; 

reg [14:0] clockdivrx; 

// Output register to pin 

assign ser = outbit; 

 

 

// Count from 0..5207 then reset back to zero (9600 Baud for TX) 

always @(posedge clk)  

begin 

if (clockdiv == 5207)  

clockdiv <= 0; 

else 

clockdiv <= clockdiv + 1; 

end 

 

 

// Count from 0..5207 then reset back to zero (9600 Baud for TX) 

always @(posedge clk)  

begin 

if (clockdivrx == 1302)  

clockdivrx <= 0; 

else 

clockdivrx <= clockdivrx + 1; 

end 

 

 

 

 

// The serclock is a short pulse each time we are reset 

wire serclock = (clockdiv == 0); 

wire start = (clockdiv == 0); 

wire serclockrx = (clockdivrx == 0); 

 

 

///////////////////////////////////////////////////////////////////////////// 

// Serial port state machine 

// Only start the state machine when "start" is set. Only advance to the 

// next state when serclock is set. 

 

 

reg [3:0] state; 

 

 

always @(posedge clk) 

begin 

case (state) 

4'b0000: if (start) state <= 4'b0001; 

4'b0001: if (serclock) state <= 4'b0010; // Start bit 

4'b0010: if (serclock) state <= 4'b0011; // Bit 0 

4'b0011: if (serclock) state <= 4'b0100; // Bit 1 

4'b0100: if (serclock) state <= 4'b0101; // Bit 2 

4'b0101: if (serclock) state <= 4'b0110; // Bit 3 

4'b0110: if (serclock) state <= 4'b0111; // Bit 4 

4'b0111: if (serclock) state <= 4'b1000; // Bit 5 

4'b1000: if (serclock) state <= 4'b1001; // Bit 6 

4'b1001: if (serclock) state <= 4'b1010; // Bit 7 

4'b1010: if (serclock) state <= 4'b0000; // Stop bit 

default: state <= 4'b0000; // Undefined, skip to stop 

endcase 

end 

 

 

/////////////////////////////////////////////////////////////////////////////// 

// Serial port data 

// Ensure that the serial port has the correct data on it in each state 

 

 

reg outbit; 

 

 

always @(posedge clk) 

begin 

case (state) 

4'b0000: outbit <= 1; // idle 

4'b0001: outbit <= 0; // Start bit 

4'b0010: outbit <= data[0]; // Bit 0 

4'b0011: outbit <= data[1]; // Bit 1 

4'b0100: outbit <= data[2]; // Bit 2 

4'b0101: outbit <= data[3]; // Bit 3 

4'b0110: outbit <= data[4]; // Bit 4 

4'b0111: outbit <= data[5]; // Bit 5 

4'b1000: outbit <= data[6]; // Bit 6 

4'b1001: outbit <= data[7]; // Bit 7 

4'b1010: outbit <= 0; // Stop bit 

default: outbit <= 1;df // Bad state output idle 

endcase 

end 

 

 

reg [7:0] charstate; 

 

 

reg [5:0] rxstate; 

 

 

always @(posedge clk) 

begin 

case (rxstate) 

6'b000000: if (!rxd) rxstate <= 4'b000001; 

6'b000001: if (serclockrx) rxstate <= 6'b000010;  

6'b000010: if (serclockrx) rxstate <= 6'b000011;  

6'b000011: if (serclockrx) rxstate <= 6'b000100;  

 

6'b000100: if (serclockrx) rxstate <= 6'b000101;  

6'b000101: if (serclockrx) rxstate <= 6'b000110;  

6'b000110: if (serclockrx) begin rxstate <= 6'b000111; data[0] <= rxd; end // The sixth tact LSB reg [7:0] data; 

6'b000111: if (serclockrx) rxstate <= 6'b001000;  

 

6'b001000: if (serclockrx) rxstate <= 6'b001001;  

6'b001001: if (serclockrx) rxstate <= 6'b001010;  

6'b001010: if (serclockrx) begin rxstate <= 6'b001011; data[1] <= rxd; end // The 10'th tact  

6'b001011: if (serclockrx) rxstate <= 6'b001100; 

 

6'b001100: if (serclockrx) rxstate <= 6'b001101;  

6'b001101: if (serclockrx) rxstate <= 6'b001110;  

6'b001110: if (serclockrx) begin rxstate <= 6'b001111; data[2] <= rxd; end // The 14'th tact  

6'b001111: if (serclockrx) rxstate <= 6'b010000;  

 

6'b010000: if (serclockrx) rxstate <= 6'b010001;  

6'b010001: if (serclockrx) rxstate <= 6'b010010;  

6'b010010: if (serclockrx) begin rxstate <= 6'b010011; data[3] <= rxd; end // The 18'th tact  

6'b010011: if (serclockrx) rxstate <= 6'b010100;  

 

6'b010100: if (serclockrx) rxstate <= 6'b010101;  

6'b010101: if (serclockrx) rxstate <= 6'b010110;  

6'b010110: if (serclockrx) begin rxstate <= 6'b010111; data[4] <= rxd; end // The 22'nd tact  

6'b010111: if (serclockrx) rxstate <= 6'b011000;  

 

6'b011000: if (serclockrx) rxstate <= 6'b011001;  

6'b011001: if (serclockrx) rxstate <= 6'b011010;  

6'b011010: if (serclockrx) begin rxstate <= 6'b011011; data[5] <= rxd; end // The 26'th tact  

6'b011011: if (serclockrx) rxstate <= 6'b011100;  

 

6'b011100: if (serclockrx) rxstate <= 6'b011101;  

6'b011101: if (serclockrx) rxstate <= 6'b011110;  

6'b011110: if (serclockrx) begin rxstate <= 6'b011111; data[6] <= rxd; end // The 30'th tact  

6'b011111: if (serclockrx) rxstate <= 6'b100000;  

 

6'b100000: if (serclockrx) rxstate <= 6'b100001;  

6'b100001: if (serclockrx) rxstate <= 6'b100010;  

6'b100010: if (serclockrx) begin rxstate <= 6'b100011; data[7] <= rxd; end // The 34'th tact  

6'b100011: if (serclockrx) rxstate <= 6'b100100; 

 

6'b100100: if (serclockrx) rxstate <= 6'b100101;  

6'b100101: if (serclockrx) rxstate <= 6'b100110;  

 

default: rxstate <= 6'b000000;  

endcase 

end 

 

 

endmodule 

 

 

 

the rs232 transmitter is always sending if i type in a character into my pc 

please help me to fix taht problem.
0 Kudos
9 Replies
Altera_Forum
Honored Contributor II
577 Views

 

--- Quote Start ---  

 

The RS232 transmitter is always sending if I type in a character into my PC 

 

--- Quote End ---  

 

This is correct, according to your code. Infact you assert 'start' periodically when clockdiv==0.
0 Kudos
Altera_Forum
Honored Contributor II
577 Views

 

--- Quote Start ---  

This is correct, according to your code. Infact you assert 'start' periodically when clockdiv==0. 

--- Quote End ---  

 

 

Thank you Cris72 I also was born in 72. For now my plan is to write a book about the Chinese module A-C8V4 that uses a Cyclone II chip. 

I am going through all examples and for now I do not have an idea what I could program here. Surely start is always called when clockdiv==0.
0 Kudos
Altera_Forum
Honored Contributor II
577 Views

 

--- Quote Start ---  

Thank you Cris72 I also was born in 72. For now my plan is to write a book about the Chinese module A-C8V4 that uses a Cyclone II chip. 

I am going through all examples and for now I do not have an idea what I could program here. Surely start is always called when clockdiv==0. 

--- Quote End ---  

 

 

 

Please help me because I do not know how to start that.
0 Kudos
Altera_Forum
Honored Contributor II
577 Views

 

--- Quote Start ---  

Please help me because I do not know how to start that. 

--- Quote End ---  

 

I can't help you if you don't specify what your design is supposed to do. 

You should assert 'start' only when you really want your fpga to transmit something.  

You can use the rising edge of an input signal (for example, what's the purpose of key_in signal? you could possibly use this). 

Otherwise, if you may want your board to transmit back when it receives data: in this case you could assert start when rxstate=6'b100110 

 

Advice: 

That rxstate case statement is very cumbersome and somewhat unreadable. You could replace it with a simple increment of rxstate and a test on the two LSB 

for the data[n] <= rxd assignement. 

 

This is an example: 

(please note I wrote this code by heart; I give you no assurance it works, not even it compiles without errors) 

 

always @(posedge clk) 

begin 

if (rxstate >= 6'b100110) 

begin 

if (!rxd) 

rxstate <= 6'b000000;  

end 

else 

begin 

rxstate <= rxstate + 6'b1; 

if (rxstate[1:0] == 2'b10) 

data[rxstate[5:2]-1] <= rxd; 

end 

end
0 Kudos
Altera_Forum
Honored Contributor II
577 Views

your main problem is that start is being asserted roughly 9600 times a second and is NEVER stopping. Therefore, your device will forever continue transmitting. You have made no provision to stop the device after some condition or other has been fulfilled.

0 Kudos
Altera_Forum
Honored Contributor II
577 Views

you should only assert start when clockdiv == 0 AND [some signal which indicates you have something to transmit and want to transmit it]. Else, the cycle pasted below will keep looping forever. 

always @(posedge clk) 

begin 

case (state) 

4'b0000: if (start) state <= 4'b0001; 

4'b0001: if (serclock) state <= 4'b0010; // Start bit 

4'b0010: if (serclock) state <= 4'b0011; // Bit 0 

4'b0011: if (serclock) state <= 4'b0100; // Bit 1 

4'b0100: if (serclock) state <= 4'b0101; // Bit 2 

4'b0101: if (serclock) state <= 4'b0110; // Bit 3 

4'b0110: if (serclock) state <= 4'b0111; // Bit 4 

4'b0111: if (serclock) state <= 4'b1000; // Bit 5 

4'b1000: if (serclock) state <= 4'b1001; // Bit 6 

4'b1001: if (serclock) state <= 4'b1010; // Bit 7 

4'b1010: if (serclock) state <= 4'b0000; // Stop bit 

default: state <= 4'b0000; // Undefined, skip to stop 

endcase 

end
0 Kudos
Altera_Forum
Honored Contributor II
577 Views

0also serclock and start will carry equivalent values so one of them is redundant

0 Kudos
Altera_Forum
Honored Contributor II
577 Views

here is a functioning receiver. 

 

greeting 

 

----------------------------------------------- 

module rs232_rx ( 

input clock, 

input rxd, 

output reg [7:0] led_g 

); 

 

parameter idle = 2'b01; 

parameter ready = 2'b10; 

parameter busy = 2'b11; 

 

reg [1:0] state=idle; 

reg [3:0] rxd_sr=4'b1111; 

reg [7:0] rxsr=8'b00000000; 

reg [3:0] rxbitcnt; 

reg [11:0] rxcnt; 

reg [7:0] rx_data; 

 

reg rx_en = 0; 

 

parameter rcv_bit_per = 2604; //19200 Baud 

 

always @(posedge clock ) begin  

if(rx_en==1) 

led_g =rx_data; 

end  

 

always @(posedge clock ) begin  

 

rxd_sr = {rxd_sr[2:0], rxd};  

rx_en = 0; 

 

case (state)  

idle:  

begin 

if(rxd_sr[3:2] == 2'b10)  

begin 

rxcnt =1302; 

rxbitcnt =0; 

state =busy; 

end  

end 

 

busy:  

begin 

if(rxbitcnt<9) 

begin 

if(rxcnt < rcv_bit_per) 

rxcnt =rxcnt+1; 

else 

begin 

rxcnt =0; 

rxbitcnt <=rxbitcnt+1; 

rxsr ={rxd_sr[2], rxsr[7:1]};  

end  

end 

else 

state=ready; 

end 

 

ready: 

begin 

rx_data =rxsr; 

state =idle; 

rx_en =1;  

end  

endcase 

 

end  

endmodule 

 

------------------------------------------------------------------
0 Kudos
Altera_Forum
Honored Contributor II
577 Views

WooW thank you - now it functions :)

0 Kudos
Reply