5. module UART (
6. sys_clk,//系统时钟输入 7. reset_n,//异步复位输入 8. Rx,//数据输入引脚 9. NewRxData,//接收到新数据 10. RxDATA//RxDATA当前接收的数据 11. ); 12.
13. input sys_clk,reset_n,Rx; 14. output NewRxData; 15. output [7 : 0] RxDATA; 16. reg [7 : 0] RxDATA; 17.
18. parameter SYS_CLK = 20000000;//系统时钟 19. parameter Rx_CLK = 9600;//9600bps
20. parameter RxDATA_W = 12;//波特率时钟发生器分频寄存器位宽
21. parameter RXCLK_DATA = SYS_CLK / Rx_CLK - 1;//波特率分频器时钟分频
值 (2083) 22. 23.
24. //波特率时钟发生器
25. reg [RxDATA_W-1 : 0] clk_cnt; 26. reg EN_RXCLK;//使能接收时钟 27. wire RX_CLK;//接收波特率时钟
28. always @ (posedge sys_clk or negedge reset_n) 29. if(!reset_n)
30. clk_cnt <= 12'd0;
31. else if(!EN_RXCLK)//不需要使能时钟 32. clk_cnt <= 12'd0; 33. else if(clk_cnt == RXCLK_DATA) 34. clk_cnt <= 12'd0; 35. else
36. clk_cnt <= clk_cnt + 1'b1; 37.
38. assign RX_CLK = (clk_cnt == RXCLK_DATA/2);//产生接收时钟 39. 40.
41. //接收数据线下降沿检测,用来启动数据接收
42. //采用边沿检测法,因为数据线空闲位高,起始位位低,因此1帧数据开始有一个下降沿 43. reg RxThis,RxLast;
44. wire RxStart;
45. always @ (posedge sys_clk or negedge reset_n) 46. if(!reset_n) begin 47. RxThis = 1'b0; 48. RxLast = 1'b0; 49. end 50. else begin
51. RxLast <= RxThis; 52. RxThis <= Rx; 53. end .
55. assign RxStart = RxLast&&(!RxThis);//产生起始信号 56. 57.
58. //数据接收控制逻辑 59. reg [10 : 0] RxTemp; 60. reg [4 : 0] RxState; 61. reg NewRxData;
62. always @ (posedge sys_clk or negedge reset_n) 63. if(!reset_n) begin . RxDATA = 8'd0; 65. RxTemp = 11'd0; 66. RxState = 5'd0;
67. EN_RXCLK = 1'b0;//停止接收时钟 68. NewRxData = 1'b0;//去除新数据标志 69. end
70. else if((RxState==5'd0) && RxStart)begin//有起始信号,并且接收器空闲,则
再次检测起始信号
71. EN_RXCLK <= 1'd1;//启动接收时钟 72. RxState <= 5'b1; //进入接收状态机 73. end
74. else if(RX_CLK) begin //每个接收时钟启动一次 75. case (RxState) //synthesis full_case 76. 5'd1 : begin
77. RxTemp[0] = Rx;//接收起始位 78. RxState <= 5'd2; 79. end 80. 5'd2 : begin
81. RxTemp[1] = Rx;//bit0 82. RxState <= 5'd3; 83. end 84. 5'd3 : begin
85. RxTemp[2] = Rx;//bit1 86. RxState <= 5'd4;
87. end 88. 5'd4 : begin
. RxTemp[3] = Rx;//bit2 90. RxState <= 5'd5; 91. end 92. 5'd5 : begin
93. RxTemp[4] = Rx;//bit3 94. RxState <= 5'd6; 95. end 96. 5'd6 : begin
97. RxTemp[5] = Rx;//bit4 98. RxState <= 5'd7; 99. end 100. 5'd7 : begin
101. RxTemp[6] = Rx;//bit5 102. RxState <= 5'd8; 103. end 104. 5'd8 : begin
105. RxTemp[7] = Rx;//bit6 106. RxState <= 5'd9; 107. end 108. 5'd9 : begin
109. RxTemp[8] = Rx;//bit7 110. RxState <= 5'd10; 111. end 112. 5'd10 : begin
113. RxTemp[9] = Rx;//校验位 114. RxState <= 5'd11; 115. end 116. 5'd11 : begin
117. RxTemp[10] = Rx;//结束位,接收完成 118. EN_RXCLK <= 1'b0;//停止接收时钟 119. RxState <= 5'd0;//接收进入空闲状态
120. if(!RxTemp[0] && RxTemp[10]) begin//有正确的
起始和停止位
121. RxDATA <= RxTemp[8 : 1];//保存接收的数
据
122. NewRxData = 1'b1;//新数据标志置位 123. end 124. end 125. endcase 126. end //end else if 127. else
128. NewRxData = 1'b0;//去除新数据标志
129. 130. endmodule
131. UART发送模块,波特率9600 132. //陈鹏 133. //20120118 134.
135. module UART_TX (
136. sys_clk,//系统时钟输入 137. reset_n,//异步复位输入 138. Tx,//数据线
139. TxData,//发送数据的数据线 140. Tx_Start,//启动发送信号 141. TX_STATE//发送器的状态 142. ); 143. 144. 145.
146. input sys_clk,reset_n,Tx_Start; 147. input [7 : 0] TxData; 148. output Tx,TX_STATE; 149. reg Tx,TX_STATE; 150.
151. parameter SYS_CLK = 20000000;//系统时钟 152. parameter Tx_CLK = 9600;//9600bps
153. parameter TxDATA_W = 12;//波特率时钟发生器分频寄存器位宽
1. parameter TXCLK_DATA = SYS_CLK / Tx_CLK - 1;//波特率分频器时钟分频值 155.
156. //波特率时钟发生器
157. reg [TxDATA_W-1 : 0] clk_cnt; 158. reg EN_TXCLK;//使能发送时钟 159. wire TX_CLK;//发送波特率时钟
160. always @ (posedge sys_clk or negedge reset_n) 161. if(!reset_n)
162. clk_cnt <= 12'd0;
163. else if(!EN_TXCLK)//不需要使能时钟 1. clk_cnt <= 12'd0; 165. else if(clk_cnt == TXCLK_DATA) 166. clk_cnt <= 12'd0; 167. else
168. clk_cnt <= clk_cnt + 1'b1; 169.
170. assign TX_CLK = (clk_cnt == 0);//产生接收时钟 171. 172.
173. //发送控制状态机 174. reg [3 : 0] TxState;
175. reg [7 : 0] TxTemp;//存放需要发送的数据 176.
177. always @ (posedge sys_clk or negedge reset_n) 178. if(!reset_n) begin 179. TxState = 4'd0; 180. TxTemp = 8'd0; 181. TX_STATE = 1'b0; 182. EN_TXCLK = 1'b0; 183. end
184. else if ((TxState == 0) && (TX_STATE == 0) && Tx_Start) begin//总线
空闲,并且有开始信号,那么开始发送数据
185. EN_TXCLK <= 1'b1;//使能发送时钟 186. TxState <= 4'd1;//开始发送的第一个状态 187. TX_STATE <= 1'd1;//发送忙
188. TxTemp <= TxData;//载入需要发送的数据 1. end
190. else if(TX_CLK) begin
191. case (TxState) //synthesis full_case
192. 4'd1 : begin //发送起始位 193. Tx <= 1'b0; 194. TxState <= 4'd2; 195. end
196. 4'd2 : begin //发送bit0 197. Tx <= TxTemp[0]; 198. TxState <= 4'd3; 199. end
200. 4'd3 : begin //发送bit1 201. Tx <= TxTemp[1]; 202. TxState <= 4'd4; 203. end
204. 4'd4 : begin //发送bit2 205. Tx <= TxTemp[2]; 206. TxState <= 4'd5; 207. end
208. 4'd5 : begin //发送bit3 209. Tx <= TxTemp[3]; 210. TxState <= 4'd6; 211. end
212. 4'd6 : begin //发送bit4 213. Tx <= TxTemp[4]; 214. TxState <= 4'd7; 215. end
216. 4'd7 : begin //发送bit5 217. Tx <= TxTemp[5]; 218. TxState <= 4'd8; 219. end
220. 4'd8 : begin //发送bit6 221. Tx <= TxTemp[6]; 222. TxState <= 4'd9; 223. end
224. 4'd9 : begin //发送bit7 225. Tx <= TxTemp[7]; 226. TxState <= 4'd10; 227. end
228. 4'd10 : begin //发送奇偶校验位,随便发 229. Tx <= 1'b0; 230. TxState <= 4'd11; 231. end
232. 4'd11 : begin //发送停止位,高电平 233. Tx <= 1'b1;
234. TxState <= 4'd0;//进入空闲状态 235. EN_TXCLK <= 1'b0;//发送波特率时钟停在 236. TX_STATE <= 1'd0;//发送逻辑空闲 237. end 238. endcase 239. end //end else if 240. 241. 242. endmodule 243.
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- awee.cn 版权所有 湘ICP备2023022495号-5
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务