当前位置:   article > 正文

数字时钟 小脚丫 FPGA板_秒表小脚丫

秒表小脚丫

  首先明确试验任务, 利用小脚丫板子进行数字时钟的设计,实验要求:能够完整正常的走时功能,能够完成时钟的调节加或者减,并且能够设置闹钟和整点报时,指示分秒的变化。

首先是整体的设计思路clk时钟信号,rst清零信号,key四个按键,switch四个开关,利用不同的按键和开关进行时钟的控制。

使用说明如下:

优点,不需要按键消抖

缺点,在调节时分秒时是一秒调节一次,过一秒加一,或者过一秒减一。

关于实验结果是没问题的,三色闪烁灯闪烁分别指示秒针和分针,一列长的闪烁灯闪烁指示整点报时和闹钟。

下面是主文件的代码。管脚分配如图。

  1. module true5shuzishizhong(clk,rst,key,seg_led_1,seg_led_2,switch,led,rgb1,rgb2);
  2. input clk,rst; //时钟信号和清零信号
  3. input [2:0]key; //四个按键
  4. input [3:0]switch; //四个开关
  5. output reg [8:0] seg_led_1; //显示管1显示十位
  6. output reg [8:0] seg_led_2; //显示管2,显示个位
  7. output reg [7:0] led; //显示灯
  8. output reg [2:0] rgb1=3'b101; //三色灯
  9. output reg [2:0] rgb2=3'b010; //三色灯
  10. wire clk1;
  11. wire clk2;
  12. wire clk3;
  13. wire [2:0] key;
  14. reg [7:0] cntmiao;
  15. reg [7:0] cntfen;
  16. reg [7:0] cntxiaoshi;
  17. reg [8:0] seg [9:0];
  18. reg [7:0] setmiao;
  19. reg [7:0] setfen;
  20. reg [7:0] setxiaoshi;
  21. //此处产生秒分时的十位和个位
  22. //此处产生秒分时的调时闹钟
  23. divide1 #(.WIDTH(24),.N(12000000)) u1 ( //传递参数产生一秒钟
  24. .clk(clk), //例化的端口信号都连接到定义好的信号
  25. .rst(rst),
  26. .clkout(clk1)
  27. );
  28. divide1 #(.WIDTH(30),.N(720000000)) u2( //传递参数产生一分钟
  29. .clk(clk),//例化的端口信号都连接到定义好的信号
  30. .rst(rst),
  31. .clkout(clk2)
  32. );
  33. divide1 #(.WIDTH(6),.N(60)) u3 ( //传递参数产生一小时
  34. .clk(clk2), //例化的端口信号都
  35. .rst(rst),
  36. .clkout(clk3)
  37. );
  38. reg [7:0] cntmiao1;
  39. reg [7:0] cntfen1;
  40. reg [7:0] cntxiaoshi1;
  41. always @(posedge clk1 or negedge rst) //产生60进制计数器
  42. begin //数码管显示要按照十进制的方式显示
  43. if(!rst) begin
  44. cntmiao<=8'd0;
  45. setmiao<=8'd0;
  46. end
  47. else
  48. begin
  49. if(switch[0]==1)
  50. begin
  51. if(cntmiao[3:0] == 4'd9) //个位满九?
  52. begin
  53. cntmiao[3:0] <= 4'd0; //个位清零
  54. if(cntmiao[7:4] == 4'd5) //十位满五?
  55. cntmiao[7:4] <= 4'd0; //个位清零
  56. else
  57. cntmiao[7:4] <= cntmiao[7:4] + 1'b1; //十位加一
  58. end
  59. else cntmiao[3:0] <= cntmiao[3:0] + 1'b1; //个位加一
  60. end
  61. else if(switch[0]==0&&switch[1]==0&&switch[2]==0&&switch[3]==1 &&key[0]==0)//走时秒针加法
  62. begin
  63. if(cntmiao[3:0] == 4'd9) //个位满九?
  64. begin
  65. cntmiao[3:0] <= 4'd0; //个位清零
  66. if(cntmiao[7:4] == 4'd5 ) //十位满五?
  67. cntmiao[7:4] <= 4'd0; //个位清零
  68. else
  69. cntmiao[7:4] <= cntmiao[7:4] + 1'b1; //十位加一
  70. end
  71. else cntmiao[3:0] <= cntmiao[3:0] + 1'b1; //个位加一
  72. end
  73. else if(switch[0]==0&&switch[1]==1&&switch[2]==1&&switch[3]==1 &&key[0]==0)//闹钟秒针加法
  74. begin
  75. if(setmiao[3:0] == 4'd9) //个位满九?
  76. begin
  77. setmiao[3:0] <= 4'd0; //个位清零
  78. if(setmiao[7:4] == 4'd5 ) //十位满五?
  79. setmiao[7:4] <= 4'd0; //个位清零
  80. else
  81. setmiao[7:4] <= setmiao[7:4] + 1'b1; //十位加一
  82. end
  83. else setmiao[3:0] <= setmiao[3:0] + 1'b1; //个位加一
  84. end
  85. else if(switch[0]==0&&switch[1]==0&&switch[2]==1&&switch[3]==0 &&key[0]==0)//秒针减法
  86. begin
  87. if(cntmiao[3:0] == 4'd0) //个位满九?
  88. begin
  89. cntmiao[3:0] <= 4'd9; //个位清零
  90. if(cntmiao[7:4] == 4'd0 ) //十位满五?
  91. cntmiao[7:4] <= 4'd5; //个位清零
  92. else
  93. cntmiao[7:4] <= cntmiao[7:4] - 1'b1; //十位加一
  94. end
  95. else cntmiao[3:0] <= cntmiao[3:0] - 1'b1; //个位加一
  96. end
  97. else if(switch[0]==0&&switch[1]==1&&switch[2]==1&&switch[3]==0 &&key[0]==0)//闹钟秒针加法
  98. begin
  99. if(setmiao[3:0] == 4'd0) //个位满九?
  100. begin
  101. setmiao[3:0] <= 4'd9; //个位清零
  102. if(setmiao[7:4] == 4'd0 ) //十位满五?
  103. setmiao[7:4] <= 4'd5; //个位清零
  104. else
  105. setmiao[7:4] <= setmiao[7:4] - 1'b1; //十位加一
  106. end
  107. else setmiao[3:0] <= setmiao[3:0] - 1'b1; //个位加一
  108. end
  109. else begin
  110. cntmiao<=cntmiao;
  111. setmiao<=setmiao;
  112. end
  113. end
  114. end
  115. always @(posedge clk1 or negedge rst) //产生60进制计数器
  116. begin //数码管显示要按照十进制的方式显示
  117. if(!rst) begin
  118. cntfen<=8'd0;
  119. setfen<=8'd0;
  120. end
  121. else begin
  122. if(switch[0]==1&&cntmiao[3:0]==4'd9)
  123. begin
  124. if(cntmiao[7:4]==4'd5)
  125. if(cntfen[3:0] == 4'd9) //个位满九?
  126. begin
  127. cntfen[3:0] <= 4'd0; //个位清零
  128. if(cntfen[7:4] == 4'd5 ) //十位满五?
  129. cntfen[7:4] <= 4'd0; //个位清零
  130. else
  131. cntfen[7:4] <= cntfen[7:4] + 1'b1; //十位加一
  132. end
  133. else cntfen[3:0] <= cntfen[3:0] + 1'b1; //个位加一
  134. end
  135. else if(switch[0]==0&&switch[1]==0&&switch[2]==0&&switch[3]==1&&key[1]==0)//走时秒针加法
  136. begin
  137. if(cntfen[3:0] == 4'd9) //个位满九?
  138. begin
  139. cntfen[3:0] <= 4'd0; //个位清零
  140. if(cntfen[7:4] == 4'd5 ) //十位满五?
  141. cntfen[7:4] <= 4'd0; //个位清零
  142. else
  143. cntfen[7:4] <= cntfen[7:4] + 1'b1; //十位加一
  144. end
  145. else cntfen[3:0] <= cntfen[3:0] + 1'b1; //个位加一
  146. end
  147. else if(switch[0]==0&&switch[1]==1&&switch[2]==1&&switch[3]==1&&key[1]==0)//闹钟秒针加法
  148. begin
  149. if(setfen[3:0] == 4'd9) //个位满九?
  150. begin
  151. setfen[3:0] <= 4'd0; //个位清零
  152. if(setfen[7:4] == 4'd5 ) //十位满五?
  153. setfen[7:4] <= 4'd0; //个位清零
  154. else
  155. setfen[7:4] <= setfen[7:4] + 1'b1; //十位加一
  156. end
  157. else setfen[3:0] <= setfen[3:0] + 1'b1; //个位加一
  158. end
  159. else if(switch[0]==0&&switch[1]==0&&switch[2]==1&&switch[3]==0&&key[1]==0)//秒针减法
  160. begin
  161. if(cntfen[3:0] == 4'd0) //个位满九?
  162. begin
  163. cntfen[3:0] <= 4'd9; //个位清零
  164. if(cntfen[7:4] == 4'd0 ) //十位满五?
  165. cntfen[7:4] <= 4'd5; //个位清零
  166. else
  167. cntfen[7:4] <= cntfen[7:4] - 1'b1; //十位加一
  168. end
  169. else cntfen[3:0] <= cntfen[3:0] - 1'b1; //个位加一
  170. end
  171. else if(switch[0]==0&&switch[1]==1&&switch[2]==1&&switch[3]==0&&key[1]==0)//闹钟秒针加法
  172. begin
  173. if(setfen[3:0] == 4'd0) //个位满九?
  174. begin
  175. setfen[3:0] <= 4'd9; //个位清零
  176. if(setfen[7:4] == 4'd0 ) //十位满五?
  177. setfen[7:4] <= 4'd5; //个位清零
  178. else
  179. setfen[7:4] <= setfen[7:4] - 1'b1; //十位加一
  180. end
  181. else setfen[3:0] <= setfen[3:0] - 1'b1; //个位加一
  182. end
  183. else begin
  184. cntfen<=cntfen;
  185. setfen<=setfen;
  186. end
  187. end
  188. end
  189. always @(posedge clk1 or negedge rst) //产生60进制计数器
  190. begin //数码管显示要按照十进制的方式显示
  191. if(!rst) begin
  192. cntxiaoshi<=8'd0;
  193. setxiaoshi<=8'd0;
  194. end
  195. else begin
  196. if(switch[0]==1&& cntfen[3:0]==4'd9)
  197. begin
  198. if(cntfen[7:4]==4'd5 )
  199. if(cntmiao[7:4]==4'd5)
  200. if(cntmiao[3:0]==4'd9)
  201. if(cntxiaoshi[3:0] == 4'd9) //个位满九?
  202. begin
  203. cntxiaoshi[3:0] <= 4'd0; //个位清零
  204. if(cntxiaoshi[7:4] == 4'd5 ) //十位满五?
  205. cntxiaoshi[7:4] <= 4'd0; //个位清零
  206. else
  207. cntxiaoshi[7:4] <= cntxiaoshi[7:4] + 1'b1; //十位加一
  208. end
  209. else cntxiaoshi[3:0] <= cntxiaoshi[3:0] + 1'b1; //个位加一
  210. end
  211. else if(switch[0]==0&&switch[1]==0&&switch[2]==0&&switch[3]==1 && key[2]==0)//走时秒针加法
  212. begin
  213. if(cntxiaoshi[3:0] == 4'd9) //个位满九?
  214. begin
  215. cntxiaoshi[3:0] <= 4'd0; //个位清零
  216. if(cntxiaoshi[7:4] == 4'd5 ) //十位满五?
  217. cntxiaoshi[7:4] <= 4'd0; //个位清零
  218. else
  219. cntxiaoshi[7:4] <= cntxiaoshi[7:4] + 1'b1; //十位加一
  220. end
  221. else cntxiaoshi[3:0] <= cntxiaoshi[3:0] + 1'b1; //个位加一
  222. end
  223. else if(switch[0]==0&&switch[1]==1&&switch[2]==1&&switch[3]==1 && key[2]==0)//闹钟秒针加法
  224. begin
  225. if(setxiaoshi[3:0] == 4'd9) //个位满九?
  226. begin
  227. setxiaoshi[3:0] <= 4'd0; //个位清零
  228. if(setxiaoshi[7:4] == 4'd5 ) //十位满五?
  229. setxiaoshi[7:4] <= 4'd0; //个位清零
  230. else
  231. setxiaoshi[7:4] <= setxiaoshi[7:4] + 1'b1; //十位加一
  232. end
  233. else setxiaoshi[3:0] <= setxiaoshi[3:0] + 1'b1; //个位加一
  234. end
  235. else if(switch[0]==0&&switch[1]==0&&switch[2]==1&&switch[3]==0 && key[2]==0)//秒针减法
  236. begin
  237. if(cntxiaoshi[3:0] == 4'd0) //个位满九?
  238. begin
  239. cntxiaoshi[3:0] <= 4'd9; //个位清零
  240. if(cntxiaoshi[7:4] == 4'd0 ) //十位满五?
  241. cntxiaoshi[7:4] <= 4'd5; //个位清零
  242. else
  243. cntxiaoshi[7:4] <= cntxiaoshi[7:4] - 1'b1; //十位加一
  244. end
  245. else cntxiaoshi[3:0] <= cntxiaoshi[3:0] - 1'b1; //个位加一
  246. end
  247. else if(switch[0]==0&&switch[1]==1&&switch[2]==1&&switch[3]==0&&key[2]==0)//闹钟秒针加法
  248. begin
  249. if(setxiaoshi[3:0] == 4'd0) //个位满九?
  250. begin
  251. setxiaoshi[3:0] <= 4'd9; //个位清零
  252. if(setxiaoshi[7:4] == 4'd0 ) //十位满五?
  253. setxiaoshi[7:4] <= 4'd5; //个位清零
  254. else
  255. setxiaoshi[7:4] <= setxiaoshi[7:4] - 1'b1; //十位加一
  256. end
  257. else setxiaoshi[3:0] <= setxiaoshi[3:0] - 1'b1; //个位加一
  258. end
  259. else begin
  260. cntxiaoshi<=cntxiaoshi;
  261. setxiaoshi<=setxiaoshi;
  262. end
  263. end
  264. end
  265. initial //initial和always不同,其中语句只执行一次
  266. begin
  267. seg[0] = 9'h3f; //对存储器中第一个数赋值9'b00_0011_1111,相当于共阴极接地,DP点变低不亮,7段显示数字 0
  268. seg[1] = 9'h06; //7段显示数字 1
  269. seg[2] = 9'h5b; //7段显示数字 2
  270. seg[3] = 9'h4f; //7段显示数字 3
  271. seg[4] = 9'h66; //7段显示数字 4
  272. seg[5] = 9'h6d; //7段显示数字 5
  273. seg[6] = 9'h7d; //7段显示数字 6
  274. seg[7] = 9'h07; //7段显示数字 7
  275. seg[8] = 9'h7f; //7段显示数字 8
  276. seg[9] = 9'h6f; //7段显示数字 9
  277. end
  278. always @(posedge clk1)//显示模块分别对应着走时的秒分时和闹钟的秒分时
  279. begin
  280. if(switch[0]==1&&switch[1]==0&&switch[2]==1&&switch[3]==1)
  281. begin
  282. seg_led_1<=seg[cntmiao[7:4]];
  283. seg_led_2<=seg[cntmiao[3:0]];
  284. end
  285. else if(switch[0]==1&&switch[1]==1&&switch[2]==0&&switch[3]==0)
  286. begin
  287. seg_led_1<=seg[cntfen[7:4]];
  288. seg_led_2<=seg[cntfen[3:0]];
  289. end
  290. else if(switch[0]==1&&switch[1]==1&&switch[2]==0&&switch[3]==1)
  291. begin
  292. seg_led_1<=seg[cntxiaoshi[7:4]];
  293. seg_led_2<=seg[cntxiaoshi[3:0]];
  294. end
  295. else if(switch[0]==1&&switch[1]==0&&switch[2]==0&&switch[3]==0)
  296. begin
  297. seg_led_1<=seg[setmiao[7:4]];
  298. seg_led_2<=seg[setmiao[3:0]];
  299. end
  300. else if(switch[0]==1&&switch[1]==1&&switch[2]==1&&switch[3]==0)
  301. begin
  302. seg_led_1<=seg[setfen[7:4]];
  303. seg_led_2<=seg[setfen[3:0]];
  304. end
  305. else if(switch[0]==1&&switch[1]==1&&switch[2]==1&&switch[3]==1)
  306. begin
  307. seg_led_1<=seg[setxiaoshi[7:4]];
  308. seg_led_2<=seg[setxiaoshi[3:0]];
  309. end
  310. end
  311. always @(posedge clk1)//闹钟闪烁
  312. begin
  313. if(setfen == cntfen && setxiaoshi==cntxiaoshi)
  314. begin
  315. led<=~led;
  316. end
  317. else if(cntfen==8'd0)
  318. led<=~led;
  319. else
  320. begin
  321. led<=8'b 11111111;
  322. end
  323. end
  324. always @(posedge clk1)//三色灯闪烁显示秒的频率
  325. begin
  326. rgb1<=~rgb1;
  327. end
  328. always @(posedge clk2)//三色灯闪烁显示分的频率
  329. begin
  330. rgb2<=~rgb2;
  331. end
  332. endmodule

在主函数中提到的函数名如下,懒得自己写了用的小脚丫官网的代码。

  1. module divide1 #
  2. (
  3. parameter WIDTH = 24, //计数器的位数,计数的最大值为 2**(WIDTH-1)
  4. parameter N = 12_000_000 //分频系数,确保 N<2**(WIDTH-1)
  5. )
  6. (
  7. input clk,
  8. input rst,
  9. output clkout
  10. );
  11. reg [WIDTH-1:0] cnt_p,cnt_n; //cnt_p为上升沿触发时的计数器,cnt_n为下降沿触发时的计数器
  12. reg clk_p,clk_n; //clk_p为上升沿触发时分频时钟,clk_n为下降沿触发时分频时钟
  13. /**********上升沿触发部分**************************************/
  14. //上升沿触发时计数器的控制
  15. always @(posedge clk or negedge rst) begin
  16. if(!rst)
  17. cnt_p <= 1'b0;
  18. else if(cnt_p == (N-1))
  19. cnt_p <= 1'b0;
  20. else
  21. cnt_p <= cnt_p + 1'b1;
  22. end
  23. //上升沿触发的分频时钟输出
  24. always @(posedge clk or negedge rst)
  25. begin
  26. if(!rst)
  27. clk_p <= 1'b0;
  28. else if(cnt_p < (N>>1))
  29. clk_p <= 1'b0;
  30. else
  31. clk_p <= 1'b1;
  32. end
  33. /*****************下降沿触发部分**************************************/
  34. //下降沿触发时计数器的控制
  35. always @(negedge clk or negedge rst)
  36. begin
  37. if(!rst)
  38. cnt_n <= 1'b0;
  39. else if(cnt_n == (N-1))
  40. cnt_n <= 1'b0;
  41. else
  42. cnt_n <= cnt_n + 1'b1;
  43. end
  44. //下降沿触发的分频时钟输出,和clk_p相差半个clk时钟
  45. always @(negedge clk or negedge rst)
  46. begin
  47. if(!rst)
  48. clk_n <= 1'b0;
  49. else if(cnt_n < (N>>1))
  50. clk_n <= 1'b0;
  51. else
  52. clk_n <= 1'b1; //得到的分频时钟正周期比负周期多一个clk时钟
  53. end
  54. /*************************************************************************/
  55. wire clk1 = clk; //当N=1时,直接输出clk
  56. wire clk2 = clk_p; //当N为偶数也就是N的最低位为0,N[0]=0,输出clk_p
  57. wire clk3 = clk_p & clk_n; //当N为奇数也就是N最低位为1,N[0]=1,输出clk_p&clk_n。
  58. assign clkout = (N==1)? clk1:(N[0]? clk3:clk2);
  59. endmodule

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/709714
推荐阅读
相关标签
  

闽ICP备14008679号