当前位置:   article > 正文

【安徽省机器人大赛单片机与嵌入式赛道竞赛】C平台作品_安徽省机器人单片机与嵌入式大赛c平台

安徽省机器人单片机与嵌入式大赛c平台

目录

一、比赛简介

二、赛题说明(详细题目已经收走,凭记忆复现)

1、设计目的:

(1)每公里价格(RATE):

(2)停车等待计时(TIME):

(3)行走里程(KM):

(4)行走耗费(FUEL):

(5)停车等待耗费(COST):

(6)到达目的地总耗费(Total):

2、设计要求:

三、作品实现详解

1、实现思路:

2、实现效果:

(1)IDLE状态

 (2)START状态

(3)PARK状态

 (4)STOP状态

 3、实现过程

四、演示视频

五、经验与教训

六、源码自取

一、比赛简介

安徽省机器人大赛单片机与嵌入式赛道竞赛分为多个赛道,笔者参加C赛道使用A7系列FPGA进行比赛。比赛分为两个部分,上午8:00-12:00,参赛队员需要根据现场收到的赛题进行Coding,下午1:00左右评委老师验收打分。

由于是现场根据题目比赛(有点像考试),所以要拿到好成绩的话需要做好充足的准备,且因为行程紧张(大学生特种兵式比赛),保持良好的精神状态是充分发挥的重要前提。

二、赛题说明(详细题目已经收走,凭记忆复现)

1、设计目的:

实现一个出租车计价系统,显示行走里程(KM)、行走耗费(FUEL)、停车等待耗费(COST)、停车等待计时(TIME)、到达目的地总耗费(Total)、每公里价格(RATE)。

(1)每公里价格(RATE):

前两公里每公里2元,两公里以后每公里1元,不足的公里向上取整按照整数公里计算,在RATE中计算。

(2)停车等待计时(TIME):

没有详细说明,本题我们仅使用了分钟和秒两组数值,没有加入小时计时(考虑到一个红绿灯不可能等待一个多小时)。

(3)行走里程(KM):

小轮转动一圈表示一米。

(4)行走耗费(FUEL):

按照行驶里程的总费用。根据要求分析,公里数在[0,1)km为2,在[1,2)为4,大于等于2为(公里数+2).

(5)停车等待耗费(COST):

按照等待时间的总费用。根据要求,每等待20s COST加一。

(6)到达目的地总耗费(Total):

为行走耗费(FUEL)与停车等待耗费(COST)的和。

2、设计要求:

整个系统需要有行驶、临时停车(模拟红灯)、结束(到达目的地)三种状态,使用两个按键S1和S2控制整个系统。按下S1,系统进入行驶状态,直流电机驱动小轮旋转;按下S2,系统进入暂时停车状态,LED灯亮起表示红灯,直流电机停止驱动,计时器开始计时;按下S2,系统恢复行驶状态;按下S1,系统进入结束状态,表示到达目的地,直流电机停止驱动。

赛题要求使用LCD12864进行显示。在行驶状态显示里程数(KM)、行走耗费(FUEL)、每公里价格(RATE);在临时停车状态显示停车等待耗费(COST)、计时器计时时间;在结束状态显示总费用(Total)和总里程数(KM)。

三、作品实现详解

1、实现思路:

采用两段式状态机实现控制器,完成对直流电机、矩阵键盘、光电测速、LED、LCD12864外设的驱动,以及计时器的使能和复位。状态机状态转移图如下所示:

自顶向下,逐步求精。先完成直流电机、矩阵键盘、光电测速、LED、LCD12864、计时器各个子模块,以及控制器模块,再在顶层模块中实例化连接。

2、实现效果:

(1)IDLE状态

 (2)START状态

(3)PARK状态

 (4)STOP状态

 3、实现过程

整个系统由以下六部分组成,共7个module,分别完成后在top中连接。

 

由于赛方提供实验平台例程,因此直流电机、矩阵键盘、光电测速、LED、LCD12864的驱动仅需要自行修改,不需要一行行输入(几千行代码不是闹着玩的,四小时肯定写不完)。其他的控制器和计数器则需要自己编写。

(1)clk_wiz_0:

将外部晶振20MHz时钟倍频为100MHz时钟。实例化IP即可。

 

(2)Speed_detect_module:

检测小轮的转数,小轮一圈为20个间隙,通过在固定时间间隔检测接收到的红外光上升沿数就可计算得出转速,同样可以修改为仅计转数。修改例程即可实现。

内部例化一个二进制计数器IP进行计数。

 此外需要计数器控制采样时间,起始和结束标志位如下:

根据100MHz时钟测算,每3秒采样一次。

二进制计数器由start_flag使能,输出为Q。

 在这里仅讲述我们对例程修改的部分。Pulse_cnt为3秒检测的小轮间隙红外光上升沿次数,由于一圈20个间隙,因此要得到累计的圈数,需要累加:

  1. module speed_detect_module(
  2.     input           clock,
  3.     input          reset,
  4.     input          pulse_from_motor,
  5.     output [19:0]  speed_value,
  6.     output reg [15:0] turns_num
  7. );
  8.     reg [32:0] cnt;
  9.     always @(posedge clock or posedge reset)
  10.     begin
  11.         if (reset)
  12.             cnt <= 0;
  13.     //  else if(cnt == 33'd6000000000)
  14.         else if(cnt == 33'd300000000)
  15.             cnt <= 0;
  16.         else
  17.             cnt <= cnt + 1'b1;
  18.     end
  19.     wire start_flag;
  20.     wire end_flag;
  21.     assign start_flag = (cnt <= 33'd5);
  22.     //assign end_flag = (cnt == 33'd6000000000);
  23.     assign end_flag = (cnt == 33'd300000000);
  24.     reg [1:0] pulse_from_motor_sync;
  25.     always @(posedge clock or posedge reset) begin
  26.         if (reset)
  27.             pulse_from_motor_sync <= 2'b00;
  28.         else
  29.             pulse_from_motor_sync <= {pulse_from_motor_sync[0],pulse_from_motor};
  30.     end
  31.     wire pulse_from_motor_pos;
  32.     assign pulse_from_motor_pos = (pulse_from_motor_sync == 2'b01);//������
  33.     wire [23 : 0] Q;
  34.     c_counter_binary_0 c_counter_binary_0_0(
  35.         .CLK(clock),    // input wire CLK
  36.         .CE(pulse_from_motor_pos),      // input wire CE
  37.         .SCLR(start_flag),  // input wire SCLR
  38.         .Q(Q)        // output wire [23 : 0] Q
  39.     );
  40.     reg [23:0] pulse_cnt;
  41.     always @(posedge clock or posedge reset)
  42.     begin
  43.         if (reset)begin
  44.         pulse_cnt <= 0;
  45.         turns_num <= 0;
  46.         end
  47.         else if(end_flag)begin
  48.             pulse_cnt <= Q;
  49.             turns_num <= turns_num + pulse_cnt / 20;
  50.         end
  51.         else begin
  52.             turns_num <= turns_num;
  53.             pulse_cnt <= pulse_cnt;
  54.         end
  55.     end
  56.     //assign turns_num = turns_num + pulse_cnt / 20;
  57.     //assign turns_num = pulse_cnt / 20;
  58.     //assign turns_num = pulse_cnt[15:0];
  59.     //assign turns_num = turns_num + pulse_cnt[15:0];
  60.     assign speed_value [3:0] = turns_num % 10;
  61.     assign speed_value [7:4] = turns_num % 100 / 10;
  62.     assign speed_value [11:8] = turns_num % 1000 / 100;
  63.     assign speed_value [15:12] = turns_num % 10000 / 1000;
  64.     assign speed_value [19:16] = turns_num % 100000 / 10000;
  65. endmodule

(3)Button4x4_drive:

矩阵键盘动态扫描与按键消抖。直接把例程拿过来用,由于clk_20ms_flag的使能,矩阵键盘模块自带了按键消抖功能,非常nice!

  1. module button4x4_drive(
  2.     input         clock,
  3.     input         reset,
  4.     input   [3:0] row,  //��
  5.     output  [3:0] col,  //��
  6.     output  [3:0] key_value,
  7.    
  8.     output        key_out_flag
  9. );
  10.     reg [3:0] col;
  11.     reg [3:0] key_value;
  12.     reg [31:0] count;
  13.     wire clk_20ms_flag;
  14.     reg [2:0] state;  //״̬��־
  15.     reg key_flag;   //������־λ
  16.     reg key_out_flag;
  17.     reg [3:0] col_reg;  //�Ĵ�ɨ����ֵ
  18.     reg [3:0] row_reg;  //�Ĵ�ɨ����ֵ
  19.     always @(posedge clock or posedge reset)
  20.     begin
  21.         if(reset)
  22.             count <= 0;
  23.         else
  24.             count <= count + 1;
  25.     end
  26.     assign clk_20ms_flag = (count[20:0] == 21'd2000000);
  27.     always @(posedge clock or posedge reset)
  28.     begin
  29.         if(reset)
  30.         begin
  31.             col <= 4'b0000;
  32.             state <= 0;
  33.         end
  34.         else if(clk_20ms_flag)
  35.         case (state)
  36.         0:
  37.             begin
  38.                 col[3:0] <= 4'b0000;
  39.                 key_flag <= 1'b0;
  40.                 if(row[3:0] != 4'b1111)
  41.                 begin
  42.                     state <= 1;
  43.                     col[3:0] <= 4'b1110;
  44.                 end //�м����£�ɨ���һ��
  45.                 else
  46.                     state <= 0;
  47.            
  48.             end
  49.         1:
  50.             begin
  51.                 if(row[3:0] != 4'b1111)
  52.                     state <= 5;//�ж��Ƿ��ǵ�һ��
  53.                 else
  54.                 begin
  55.                     state <= 2;
  56.                     col[3:0] <= 4'b1101;
  57.                 end  //ɨ��ڶ���
  58.             end
  59.         2:
  60.             begin
  61.                 if(row[3:0] != 4'b1111)
  62.                     state <= 5;//�ж��Ƿ��ǵڶ���
  63.                 else
  64.                 begin
  65.                     state <= 3;
  66.                     col[3:0] <= 4'b1011;
  67.                 end  //ɨ�������
  68.             end
  69.         3:
  70.             begin
  71.                 if(row[3:0] != 4'b1111)
  72.                     state <= 5; //�ж��Ƿ��ǵ���һ��
  73.                 else
  74.                 begin
  75.                     state <= 4;
  76.                     col[3:0] <= 4'b0111;
  77.                 end  //ɨ�������
  78.             end
  79.         4:
  80.             begin
  81.                 if(row[3:0] != 4'b1111)
  82.                     state <= 5;//�ж��Ƿ��ǵ�һ��
  83.                 else
  84.                     state <= 0;
  85.             end
  86.         5:
  87.             begin
  88.                 if(row[3:0] != 4'b1111)
  89.                 begin
  90.                     col_reg <= col;  //����ɨ����ֵ
  91.                     row_reg <= row;  //����ɨ����ֵ
  92.                     state <= 5;
  93.                     key_flag <= 1'b1;  //�м�����
  94.                 end
  95.                 else
  96.                     state <= 0;
  97.             end
  98.         endcase
  99.     end
  100.     always @(clock or col_reg or row_reg)
  101.     begin
  102.         if(key_flag == 1'b1)
  103.         begin
  104.             key_out_flag <= 1;
  105.             case ({col_reg,row_reg})
  106.                 8'b1110_1110:key_value <= 0;
  107.                 8'b1110_1101:key_value <= 4;
  108.                 8'b1110_1011:key_value <= 8;
  109.                 8'b1110_0111:key_value <= 12;
  110.                 8'b1101_1110:key_value <= 1;
  111.                 8'b1101_1101:key_value <= 5;
  112.                 8'b1101_1011:key_value <= 9;
  113.                 8'b1101_0111:key_value <= 13;
  114.                 8'b1011_1110:key_value <= 2;
  115.                 8'b1011_1101:key_value <= 6;
  116.                 8'b1011_1011:key_value <= 10;
  117.                 8'b1011_0111:key_value <= 14;
  118.                 8'b0111_1110:key_value <= 3;
  119.                 8'b0111_1101:key_value <= 7;
  120.                 8'b0111_1011:key_value <= 11;
  121.                 8'b0111_0111:key_value <= 15;
  122.         endcase
  123.         end
  124.         else
  125.             key_out_flag <= 0;
  126.     end
  127.  endmodule

(4)Timer:

实现秒、分钟的计时,这个例程没有,需要自行编写,比较基础容易实现。

先设计一个分频模块产生1Hz时钟。

  1. module clk_1Hz(
  2.     input clk,
  3.     output reg clk_1Hz
  4.     );
  5.      reg [26:0]cnt;
  6.     initial begin
  7.         clk_1Hz = 0;
  8.         cnt = 0;
  9.     end
  10.     always@(posedge clk)begin
  11.         if(cnt == 27'd99999999)begin
  12.             cnt <= 0;
  13.         end
  14.         else begin
  15.             cnt <= cnt + 1;
  16.         end
  17.     end
  18.     always@(posedge clk)begin
  19.         if(cnt < 27'd49999999)begin
  20.             clk_1Hz <= 1'b0;
  21.         end
  22.         else begin
  23.             clk_1Hz <= 1'b1;
  24.         end
  25.     end
  26.    
  27. endmodule

 然后使用1Hz时钟进行计数器的控制完成秒表:

  1. module Timer(
  2.     input clk,
  3.     input en,
  4.     input rst_n,
  5.     output clk_1Hz,
  6.     output reg[5:0]minute_cnt,
  7.     output reg[5:0]second_cnt
  8.     );
  9.     wire second_60_flag,minute_60_flag;
  10.     initial begin
  11.         minute_cnt = 0;
  12.         second_cnt = 0;
  13.     end
  14.    
  15.     clk_1Hz clk_1Hz_0(
  16.         .clk(clk),
  17.         .clk_1Hz(clk_1Hz)
  18.     );
  19.    
  20.     assign minute_60_flag = (minute_cnt == 6'd59)?1'b1:1'b0;
  21.     assign second_60_flag = (second_cnt == 6'd59)?1'b1:1'b0;
  22.    
  23.     always@(posedge clk_1Hz)begin
  24.         if(!rst_n)begin
  25.             second_cnt <= 6'd0;
  26.         end
  27.         else if(en)begin
  28.             if(second_60_flag)begin
  29.                 second_cnt <= 6'd0;
  30.             end
  31.             else begin
  32.                 second_cnt <= second_cnt + 6'd1;
  33.             end
  34.         end
  35.     end
  36.    
  37.     always@(posedge clk_1Hz)begin
  38.         if(!rst_n)begin
  39.             minute_cnt <= 6'd0;
  40.         end
  41.         else if(en)begin
  42.             if(minute_60_flag && second_60_flag)begin
  43.                 minute_cnt <= 6'd0;
  44.             end
  45.             else if(second_60_flag)begin
  46.                 minute_cnt <= minute_cnt + 6'd1;
  47.             end
  48.             else begin
  49.                 minute_cnt <= minute_cnt;
  50.             end
  51.         end
  52.     end
  53. endmodule

(5)LCD12864_drive:

实现LCD12864的SSD1306芯片的驱动。修改例程即可实现。由于例程中为静态显示,我们要实现动态显示的话需要接收外部数据。

  1. module lcd12864_drive(
  2.     input          clock,
  3.     input          reset,
  4.     input  [511:0] data,
  5.     output         lcd12864_rs,
  6.     output         lcd12864_rw,
  7.     output         lcd12864_en,
  8.     output   [7:0] lcd12864_data
  9. );
  10. wire [511:0] data_buf;
  11.      
  12. /**************************����lcd12864ʱ���ź�*************************/
  13. reg clk_lcd12864;
  14. reg [19:0]cnt;
  15. always @(posedge clock or posedge reset)
  16. begin
  17.     if (reset)
  18.     begin
  19.         cnt <= 20'b0;
  20.         clk_lcd12864 <= 0;
  21.     end  
  22.     else if(cnt == 20'd20000)               //ʱ��Ƶ�ʷdz���Ҫ��������3k����ʵ��5k���ڵ�0λ������
  23.     begin
  24.         cnt <= 20'd0;
  25.         clk_lcd12864 <= ~clk_lcd12864;
  26.     end  
  27.     else
  28.         cnt <= cnt +1'b1;
  29. end
  30. reg [1:0] clk_lcd12864_sync;
  31. always @(posedge clock or posedge reset)
  32. begin
  33.     if (reset)
  34.         clk_lcd12864_sync <= 2'b00;  
  35.     else
  36.         clk_lcd12864_sync <= {clk_lcd12864_sync[0],clk_lcd12864};
  37. end
  38. assign clk_lcd12864_pos = (clk_lcd12864_sync == 2'b01);
  39. //****************************lcd12864�����ź�*****************************************/                          
  40. reg [8:0] state; //State Machine code
  41. parameter IDLE          = 4'd0;            
  42. parameter CMD_WIDTH     = 4'd1;             //�������ݽӿ�����
  43. parameter CMD_SET       = 4'd2;             //ѡ��ָ�
  44. parameter CMD_CURSOR    = 4'd3;             //���ù��
  45. parameter CMD_CLEAR     = 4'd4;             //����
  46. parameter CMD_ACCESS   = 4'd5;              //���뷽ʽ���ã����ݶ�д�����
  47. parameter CMD_DDRAM    = 4'd6;              //DDRAM�е�ַ
  48. parameter DATA_WRITE    = 4'd7;             //����д��
  49. parameter STOP      = 4'd8;             //
  50. reg lcd12864_rs_r;
  51. reg [7:0] lcd12864_data_r;
  52. reg [7:0] data_buff;
  53. reg [5:0] cnt_time;
  54. //����ܽ�����
  55. assign lcd12864_rs = lcd12864_rs_r;
  56. assign lcd12864_rw = 1'b0;
  57. assign lcd12864_en = clk_lcd12864_sync[1];                                  //��lcd12864ʱ����ͬ
  58. assign lcd12864_data = lcd12864_data_r;
  59.    
  60. always @(posedge clock or posedge reset)
  61. begin
  62.     if(reset)
  63.     begin
  64.         lcd12864_rs_r <= 1'b0;
  65.         state <= IDLE;
  66. //      lcd12864_data_r <= 8'bzzzzzzzz;                         //����̬
  67.         lcd12864_data_r <= 8'b11111111;                         //����̬
  68.         cnt_time <= 6'd0;
  69.     end
  70.     else if(clk_lcd12864_pos)
  71.     begin
  72.         case(state)
  73.             IDLE:  
  74.             begin  
  75.                 lcd12864_rs_r <= 1'b0;
  76.                 cnt_time <= 6'd0;
  77.                 state <= CMD_WIDTH;
  78. //              lcd12864_data_r <= 8'bzzzzzzzz;  
  79.                 lcd12864_data_r <= 8'b11111111;  
  80.             end
  81.             CMD_WIDTH:
  82.             begin
  83.                 lcd12864_rs_r <= 1'b0;
  84.                 state <= CMD_SET;  
  85.                 lcd12864_data_r <= 8'h30;                           //8λ���ݿ�
  86.             end
  87.             CMD_SET:
  88.             begin
  89.                 lcd12864_rs_r <= 1'b0;
  90.                 state <= CMD_CURSOR;
  91.                 lcd12864_data_r <= 8'h30;                           //����ָ�
  92.             end
  93.             CMD_CURSOR:
  94.             begin
  95.                 lcd12864_rs_r <= 1'b0;
  96.                 state <= CMD_CLEAR;
  97.                 lcd12864_data_r <= 8'h0c;                           // �ع��
  98.             end
  99.             CMD_CLEAR:
  100.             begin
  101.                 lcd12864_rs_r <= 1'b0;
  102.                 state <= CMD_ACCESS;
  103.                 lcd12864_data_r <= 8'h01;                           //����
  104.             end
  105.             CMD_ACCESS:
  106.             begin
  107.                 lcd12864_rs_r <= 1'b0;
  108.                 state <= CMD_DDRAM;
  109.                 lcd12864_data_r <= 8'h06;                           //������趨
  110.             end
  111.             CMD_DDRAM:                                          //��������
  112.             begin
  113.                 lcd12864_rs_r <= 1'b0;
  114.                 state <= DATA_WRITE;
  115.                 case (cnt_time)
  116.                     6'd0:       lcd12864_data_r <= 8'h80;
  117.                     6'd16:  lcd12864_data_r <= 8'h90;
  118.                     6'd32:  lcd12864_data_r <= 8'h88;
  119.                     6'd48:  lcd12864_data_r <= 8'h98;
  120.                 endcase
  121.             end
  122.             DATA_WRITE:                                             //д����
  123.             begin
  124.                 lcd12864_rs_r <= 1'b1;
  125.                 cnt_time <= cnt_time + 1'b1;
  126.                 lcd12864_data_r <= data_buff;
  127.                 case (cnt_time)
  128.                     6'd15:  state <= CMD_DDRAM;
  129.                     6'd31:  state <= CMD_DDRAM;
  130.                     6'd47:  state <= CMD_DDRAM;
  131.                     6'd63:  state <= STOP;
  132.                     default:    state <= DATA_WRITE;
  133.                 endcase
  134.             end
  135.             STOP:
  136.             begin
  137.                 lcd12864_rs_r <= 1'b0;
  138.                 state <= CMD_DDRAM;
  139.                 lcd12864_data_r <= 8'h80;                               //�ӵڼ���ѭ��
  140.                 cnt_time <= 6'd0;
  141.             end
  142.             default:
  143.                 state <= IDLE;
  144.         endcase
  145.     end
  146. end
  147. always @(cnt_time)
  148. begin
  149.     case (cnt_time)
  150.         6'd0:data_buff <= data[7:0];
  151.         6'd1:data_buff <= data[15:8];
  152.         6'd2:data_buff <= data[23:16];
  153.         6'd3:data_buff <= data[31:24];
  154.         6'd4:data_buff <= data[39:32];
  155.         6'd5:data_buff <= data[47:40];
  156.         6'd6:data_buff <= data[55:48];
  157.         6'd7:data_buff <= data[63:56];
  158.         6'd8:data_buff <= data[71:64];
  159.         6'd9:data_buff <= data[79:72];
  160.         6'd10:data_buff <= data[87:80];
  161.         6'd11:data_buff <= data[95:88];
  162.         6'd12:data_buff <= data[103:96];
  163.         6'd13:data_buff <= data[111:104];
  164.         6'd14:data_buff <= data[119:112];
  165.         6'd15:data_buff <= data[127:120];
  166.         6'd16:data_buff <= data[135:128];
  167.         6'd17:data_buff <= data[143:136];
  168.         6'd18:data_buff <= data[151:144];
  169.         6'd19:data_buff <= data[159:152];
  170.         6'd20:data_buff <= data[167:160];
  171.         6'd21:data_buff <= data[175:168];
  172.         6'd22:data_buff <= data[183:176];
  173.         6'd23:data_buff <= data[191:184];
  174.         6'd24:data_buff <= data[199:192];
  175.         6'd25:data_buff <= data[207:200];
  176.         6'd26:data_buff <= data[215:208];
  177.         6'd27:data_buff <= data[223:216];
  178.         6'd28:data_buff <= data[231:224];
  179.         6'd29:data_buff <= data[239:232];
  180.         6'd30:data_buff <= data[247:240];
  181.         6'd31:data_buff <= data[255:248];
  182.         6'd32:data_buff <= data[263:256];
  183.         6'd33:data_buff <= data[271:264];
  184.         6'd34:data_buff <= data[279:272];
  185.         6'd35:data_buff <= data[287:280];
  186.         6'd36:data_buff <= data[295:288];
  187.         6'd37:data_buff <= data[303:296];
  188.         6'd38:data_buff <= data[311:304];
  189.         6'd39:data_buff <= data[319:312];
  190.         6'd40:data_buff <= data[327:320];
  191.         6'd41:data_buff <= data[335:328];
  192.         6'd42:data_buff <= data[343:336];
  193.         6'd43:data_buff <= data[351:344];
  194.         6'd44:data_buff <= data[359:352];
  195.         6'd45:data_buff <= data[367:360];
  196.         6'd46:data_buff <= data[375:368];
  197.         6'd47:data_buff <= data[383:376];
  198.         6'd48:data_buff <= data[391:384];
  199.         6'd49:data_buff <= data[399:392];
  200.         6'd50:data_buff <= data[407:400];
  201.         6'd51:data_buff <= data[415:408];
  202.         6'd52:data_buff <= data[423:416];
  203.         6'd53:data_buff <= data[431:424];
  204.         6'd54:data_buff <= data[439:432];
  205.         6'd55:data_buff <= data[447:440];
  206.         6'd56:data_buff <= data[455:448];
  207.         6'd57:data_buff <= data[463:456];
  208.         6'd58:data_buff <= data[471:464];
  209.         6'd59:data_buff <= data[479:472];
  210.         6'd60:data_buff <= data[487:480];
  211.         6'd61:data_buff <= data[495:488];
  212.         6'd62:data_buff <= data[503:496];
  213.         6'd63:data_buff <= data[511:504];
  214.         default :  data_buff <= 8'h20;
  215.     endcase
  216. end
  217. endmodule

(6)LCD_Decoder:

对来自时钟的秒、分钟计时、来自光电测速的圈数、以及要显示的FUEL、COST等数值进行数据的转换以用于LCD显示。由于例程中为静态显示,我们要实现动态显示的话需要实时向LCD12864_drive发送需要刷新的数据。

使用function来实现二进制数到LCD字库编码的转换,精简代码。

此外,我要实现界面切换的效果,需要根据控制器的state进行选择输出结果。

 

  1. module LCD_Decoder(
  2.     input clk,
  3.     input reset,
  4.     input [1:0]state,
  5.     input [19:0]speed_value,
  6.     input [15:0]turns_num,
  7.     input [5:0]minute_cnt,
  8.     input [5:0]second_cnt,
  9.     output reg [511:0]data
  10.     );
  11.     localparam n0 = 8'h30;
  12.     localparam n1 = 8'h31;
  13.     localparam n2 = 8'h32;
  14.     localparam n3 = 8'h33;
  15.     localparam n4 = 8'h34;
  16.     localparam n5 = 8'h35;
  17.     localparam n6 = 8'h36;
  18.     localparam n7 = 8'h37;
  19.     localparam n8 = 8'h38;
  20.     localparam n9 = 8'h39;
  21.     localparam nn = 8'h0f;
  22.    
  23.     //״̬��������
  24.     parameter IDLE = 2'b00;
  25.     parameter START= 2'b01;
  26.     parameter PARK = 2'b11;
  27.     parameter STOP = 2'b10;
  28.    
  29.     reg [7:0]speed_value_0,speed_value_1,speed_value_2,speed_value_3,speed_value_4;
  30.     reg [7:0]fuel_value_0,fuel_value_1,fuel_value_2,fuel_value_3;
  31.     reg [7:0]Total_cost_BCD_0,Total_cost_BCD_1,Total_cost_BCD_2,Total_cost_BCD_3;
  32.    
  33.     reg [7:0]cost_1,cost_0;
  34.     reg [7:0]minute_1,minute_0;
  35.     reg [7:0]second_1,second_0;
  36.     reg [15:0]fuel;//,KM
  37.     reg [7:0]rate;
  38.     reg [3:0]cost;
  39.     wire [15:0]fuel_BCD;
  40.     wire [15:0]Total_cost_BCD;
  41.     wire s_20_flag;
  42.     reg [4:0]s_20_cnt;
  43.     reg [15:0]Total_cost;
  44.     reg [26:0]clk_div_cnt;
  45.     reg clk_1Hz;
  46.    
  47.      initial begin
  48.         speed_value_0 = 0;
  49.         speed_value_1 = 0;
  50.         speed_value_2 = 0;
  51.         speed_value_3 = 0;
  52.         speed_value_4 = 0;
  53.         fuel_value_0 = 0;
  54.         fuel_value_1 = 0;
  55.         fuel_value_2 = 0;
  56.         fuel_value_3 = 0;
  57.         cost_1 = 0;
  58.         cost_0 = 0;
  59. //        KM = 0;
  60.         fuel = 0;
  61.         rate = n1;
  62.         cost = 1;
  63.         s_20_cnt = 0;
  64.         Total_cost = 0;
  65.         clk_1Hz = 0;
  66.         clk_div_cnt = 0;
  67.     end
  68.    
  69.     //ʼ�շ�Ƶ
  70.     wire div_1Hz_flag;
  71.     assign div_1Hz_flag = clk_div_cnt == 27'd99999999;
  72.     always@(posedge clk)begin
  73.         if(div_1Hz_flag)begin
  74.             clk_div_cnt <= 0;
  75.         end
  76.         else begin
  77.             clk_div_cnt <= clk_div_cnt + 1;
  78.         end
  79.     end
  80.     always@(posedge clk)begin
  81.         if(clk_div_cnt < 27'd49999999)begin
  82.             clk_1Hz <= 1'b0;
  83.         end
  84.         else begin
  85.             clk_1Hz <= 1'b1;
  86.         end
  87.     end
  88.     //ʼ�շ�Ƶ
  89.    
  90.     always@(posedge clk)begin
  91.         if(reset)begin
  92.             Total_cost <= 16'd0;
  93.         end
  94.         else begin
  95.             Total_cost <= fuel+{12'd0,cost};
  96.         end
  97.     end
  98.    
  99.     assign s_20_flag = (s_20_cnt == 5'd19)?1'b1:1'b0;
  100.     always@(posedge clk)begin
  101.         if(reset)begin
  102.             s_20_cnt <= 5'd0;
  103.         end
  104.         else begin
  105.             if(state != PARK)begin
  106.                s_20_cnt <= 5'd0;
  107.             end
  108.             else if(s_20_flag && div_1Hz_flag)begin
  109.                 s_20_cnt <= 5'd0;
  110.             end
  111.             else if(div_1Hz_flag)begin
  112.                 s_20_cnt <= s_20_cnt + 5'd1;
  113.             end
  114.             else begin
  115.                 s_20_cnt <= s_20_cnt;
  116.             end
  117.         end
  118.     end
  119.    
  120.     always@(posedge clk)begin
  121.         if(reset)begin
  122.             cost <= 4'd1;
  123.         end
  124.         else begin
  125.             if(state == IDLE)begin
  126.                 cost <= 4'd1;
  127.             end
  128.             else if(div_1Hz_flag && s_20_flag)begin
  129.                 cost <= cost + 4'd1;
  130.             end
  131.             else begin
  132.                 cost <= cost;
  133.             end
  134.         end
  135.     end
  136.    
  137.     assign fuel_BCD [3:0] = fuel % 10;
  138.     assign fuel_BCD [7:4] = fuel % 100 / 10;
  139.     assign fuel_BCD [11:8] = fuel % 1000 / 100;
  140.     assign fuel_BCD [15:12] = fuel % 10000 / 1000;
  141.    
  142.     assign Total_cost_BCD [3:0] = Total_cost % 10;
  143.     assign Total_cost_BCD [7:4] = Total_cost % 100 / 10;
  144.     assign Total_cost_BCD [11:8] = Total_cost % 1000 / 100;
  145.     assign Total_cost_BCD [15:12] = Total_cost % 10000 / 1000;
  146.    
  147.    
  148.    
  149.     //����ת�� ����
  150.     function [7:0]binary2code;
  151.         input [3:0]binary;
  152.         begin
  153.             case(binary)
  154.                 4'd0:binary2code = n0;
  155.                 4'd1:binary2code = n1;
  156.                 4'd2:binary2code = n2;
  157.                 4'd3:binary2code = n3;
  158.                 4'd4:binary2code = n4;
  159.                 4'd5:binary2code = n5;
  160.                 4'd6:binary2code = n6;
  161.                 4'd7:binary2code = n7;
  162.                 4'd8:binary2code = n8;
  163.                 4'd9:binary2code = n9;
  164.                 default:binary2code = nn;
  165.             endcase
  166.         end
  167.     endfunction
  168.    
  169.     //����ת�� ����
  170.     function [15:0]time2code;
  171.         input [5:0]binary;
  172.         begin
  173.             case(binary)
  174.                 6'd0:time2code = {n0,n0};
  175.                 6'd1:time2code ={ n0,n1};
  176.                 6'd2:time2code = {n0,n2};
  177.                 6'd3:time2code ={ n0,n3};
  178.                 6'd4:time2code ={ n0,n4};
  179.                 6'd5:time2code ={ n0,n5};
  180.                 6'd6:time2code = {n0,n6};
  181.                 6'd7:time2code = {n0,n7};
  182.                 6'd8:time2code = {n0,n8};
  183.                 6'd9:time2code = {n0,n9};
  184.                 6'd10:time2code ={ n1,n0};
  185.                 6'd11:time2code ={ n1,n1};
  186.                 6'd12:time2code ={ n1,n2};
  187.                 6'd13:time2code ={ n1,n3};
  188.                 6'd14:time2code = {n1,n4};
  189.                 6'd15:time2code = {n1,n5};
  190.                 6'd16:time2code = {n1,n6};
  191.                 6'd17:time2code = {n1,n7};
  192.                 6'd18:time2code = {n1,n8};
  193.                 6'd19:time2code = {n1,n9};
  194.                 6'd20:time2code = {n2,n0};
  195.                 6'd21:time2code = {n2,n1};
  196.                 6'd22:time2code = {n2,n2};
  197.                 6'd23:time2code = {n2,n3};
  198.                 6'd24:time2code = {n2,n4};
  199.                 6'd25:time2code = {n2,n5};
  200.                 6'd26:time2code = {n2,n6};
  201.                 6'd27:time2code = {n2,n7};
  202.                 6'd28:time2code = {n2,n8};
  203.                 6'd29:time2code = {n2,n9};
  204.                 6'd30:time2code = {n3,n0};
  205.                 6'd31:time2code = {n3,n1};
  206.                 6'd32:time2code = {n3,n2};
  207.                 6'd33:time2code = {n3,n3};
  208.                 6'd34:time2code = {n3,n4};
  209.                 6'd35:time2code = {n3,n5};
  210.                 6'd36:time2code = {n3,n6};
  211.                 6'd37:time2code = {n3,n7};
  212.                 6'd38:time2code = {n3,n8};
  213.                 6'd39:time2code = {n3,n9};
  214.                 6'd40:time2code = {n4,n0};
  215.                 6'd41:time2code = {n4,n1};
  216.                 6'd42:time2code = {n4,n2};
  217.                 6'd43:time2code = {n4,n3};
  218.                 6'd44:time2code = {n4,n4};
  219.                 6'd45:time2code = {n4,n5};
  220.                 6'd46:time2code = {n4,n6};
  221.                 6'd47:time2code = {n4,n7};
  222.                 6'd48:time2code = {n4,n8};
  223.                 6'd49:time2code = {n4,n9};
  224.                 6'd50:time2code = {n5,n0};
  225.                 6'd51:time2code = {n5,n1};
  226.                 6'd52:time2code = {n5,n2};
  227.                 6'd53:time2code = {n5,n3};
  228.                 6'd54:time2code = {n5,n4};
  229.                 6'd55:time2code = {n5,n5};
  230.                 6'd56:time2code = {n5,n6};
  231.                 6'd57:time2code = {n5,n7};
  232.                 6'd58:time2code = {n5,n8};
  233.                 6'd59:time2code = {n5,n9};
  234.                 default:time2code = {nn,nn};
  235.             endcase
  236.         end
  237.     endfunction
  238.        
  239.     always @(posedge clk) begin
  240.         speed_value_4 <= binary2code(speed_value[19:16]);
  241.         speed_value_3 <= binary2code(speed_value[15:12]);
  242.         speed_value_2 <= binary2code(speed_value[11:8]);
  243.         speed_value_1 <= binary2code(speed_value[7:4]);
  244.         speed_value_0 <= binary2code(speed_value[3:0]);
  245.         fuel_value_3 <= binary2code(fuel_BCD[15:12]);
  246.         fuel_value_2 <= binary2code(fuel_BCD[11:8]);
  247.         fuel_value_1 <= binary2code(fuel_BCD[7:4]);
  248.         fuel_value_0 <= binary2code(fuel_BCD[3:0]);
  249.         Total_cost_BCD_3 <= binary2code(Total_cost_BCD[15:12]);
  250.         Total_cost_BCD_2 <= binary2code(Total_cost_BCD[11:8]);
  251.         Total_cost_BCD_1 <= binary2code(Total_cost_BCD[7:4]);
  252.         Total_cost_BCD_0 <= binary2code(Total_cost_BCD[3:0]);
  253.         {minute_1,minute_0} <= time2code(minute_cnt);
  254.         {second_1,second_0} <= time2code(second_cnt);
  255.     end
  256.    
  257.     always@(posedge clk)begin
  258.         case(cost)
  259.             4'd0:{cost_1,cost_0} = {n0,n0};
  260.             4'd1:{cost_1,cost_0} = {n0,n1};
  261.             4'd2:{cost_1,cost_0} = {n0,n2};
  262.             4'd3:{cost_1,cost_0} = {n0,n3};
  263.             4'd4:{cost_1,cost_0} = {n0,n4};
  264.             4'd5:{cost_1,cost_0} = {n0,n5};
  265.             4'd6:{cost_1,cost_0} = {n0,n6};
  266.             4'd7:{cost_1,cost_0} = {n0,n7};
  267.             4'd8:{cost_1,cost_0} = {n0,n8};
  268.             4'd9:{cost_1,cost_0} = {n0,n9};
  269.             4'd10:{cost_1,cost_0} = {n1,n0};
  270.             4'd11:{cost_1,cost_0} = {n1,n1};
  271.             4'd12:{cost_1,cost_0} = {n1,n2};
  272.             4'd13:{cost_1,cost_0} = {n1,n3};
  273.             4'd14:{cost_1,cost_0} = {n1,n4};
  274.             4'd15:{cost_1,cost_0} = {n1,n5};
  275.             default:{cost_1,cost_0} ={nn, nn};
  276.         endcase
  277.     end
  278.    
  279.     always@(posedge clk)begin
  280. //        KM <= turns_num/1000;
  281.         if(reset)begin
  282.             fuel <= 32'd2;
  283.             rate <= n2;
  284.         end
  285.         else begin
  286.              if(!(|speed_value [15:12]))begin
  287.                 fuel <= 32'd2;
  288.                 rate <= n2;
  289.             end
  290.             else if((speed_value [15:12]==1))begin//||(speed_value [15:12] ==2)
  291.                 fuel <= 32'd4;
  292.                 rate <= n2;
  293.             end
  294.             else begin
  295.                 fuel <= speed_value [15:12] + 2;
  296.                 rate <= n1;
  297.             end
  298.         end
  299.     end
  300.    
  301.    
  302.    
  303.     always @(*) begin
  304.         if(state == START)begin
  305.             data = {
  306.                 "K","S","Z",8'h26,"Y","W","Z",8'h20,"y","b",8'h20,"e","d","a","M",8'h20,
  307.                 8'h20,8'h20,8'h20,8'h20,8'h20,"m","k",speed_value_0,speed_value_1,speed_value_2,".",speed_value_3,speed_value_4,8'h3a,"M","K",
  308.                 rate,8'h3a,"E","T","A","R",8'h20,fuel_value_0,fuel_value_1,fuel_value_2,fuel_value_3,8'h3a,"L","E","U","F",
  309.                 8'h20,8'h20,8'h20,8'h20
  310.                 ,8'h20,"T","R","A","T","S",8'h3a,"E","T","A","T","S"
  311.             };
  312.         end
  313.         else if(state == PARK)begin
  314.             data = {
  315.                 "K","S","Z",8'h26,"Y","W","Z",8'h20,"y","b",8'h20,"e","d","a","M",8'h20,
  316.                 8'h20,8'h20,8'h20,8'h20,8'h20,8'h20,second_0,second_1,":",minute_0,minute_1,8'h3a,"E","M","I","T",
  317.                 rate,8'h3a,"E","T","A","R",8'h20,8'h20,8'h20,cost_0,cost_1,8'h3a,"T","S","O","C",
  318.                 8'h20,8'h20,8'h20,8'h20,8'h20,8'h20,"K","R","A","P",8'h3a,"E","T","A","T","S"
  319.             };
  320.         end
  321.         else if(state == STOP)begin
  322.             data = {
  323.                 "K","S","Z",8'h26,"Y","W","Z",8'h20,"y","b",8'h20,"e","d","a","M",8'h20,
  324.                 8'h20,8'h20,8'h20,8'h20,8'h20,"m","k",speed_value_0,speed_value_1,speed_value_2,".",speed_value_3,speed_value_4,8'h3a,"M","K",
  325.                 8'h20,8'h20,8'h20,8'h20,8'h20,8'h20,Total_cost_BCD_0,Total_cost_BCD_1,Total_cost_BCD_2,Total_cost_BCD_3,8'h3a,"l","a","t","o","T",
  326.                 8'h20,8'h20,8'h20,8'h20,8'h20,8'h20,"P","O","T","S",8'h3a,"E","T","A","T","S"
  327.             };
  328.         end
  329.         else begin//IDLE
  330.             data = {
  331.                 "K","S","Z",8'h26,"Y","W","Z",8'h20,"y","b",8'h20,"e","d","a","M",8'h20,
  332.                 8'h20,8'h20,8'h20,8'h20,8'h20,"m","k",speed_value_0,speed_value_1,speed_value_2,".",speed_value_3,speed_value_4,8'h3a,"M","K",
  333.                 rate,8'h3a,"T","T","A","R",8'h20,fuel_value_0,fuel_value_1,fuel_value_2,fuel_value_3,8'h3a,"L","E","U","F",
  334.                 8'h20,8'h20,8'h20,8'h20,8'h20,8'h20,"E","L","D","I",8'h3a,"E","T","A","T","S"
  335.             };
  336.         end
  337.     end
  338. endmodule

特别声明,由于比赛时间有限,我这里使用了%和/等算数级描述来进行运算,会综合出及其复杂且性能低下的运算逻辑,这可能造成时序违例和面积的浪费,因此大家千万不要在流片的项目中使用!!!仅仅依赖综合器来对电路进行优化可不是一个合格的数字电路设计者。 

(7)CTRLOR:

由于使用到了按键复用,因此需要进行上升沿检测,否则仅使用键值进行条件转移的话会在两个状态反复跳转。

控制器是整个电路的灵魂所在,有了它就能控制各个模块的运转。根据我们之前的状态转移图进行编写。

  1. module CTRLOR(
  2.     input clk,
  3.     input reset,
  4.     input [3:0]key_value,
  5.     input key_out_flag,
  6.     output reg [1:0]cstate,
  7.     output reg Timer_en,
  8.     output reg Timer_rst_n,
  9.     output reg LED_en,
  10.     output reg motor_en
  11.     );
  12.     //״̬��������
  13.     parameter IDLE = 2'b00;
  14.     parameter START= 2'b01;
  15.     parameter PARK = 2'b11;
  16.     parameter STOP = 2'b10;
  17.    
  18.     //�����ڲ��ź�
  19.     wire s1_flag,s2_flag,s3_flag;
  20.     wire key_out_flag_pos;
  21.     reg key_out_flag_reg;
  22.     always@(posedge clk)begin
  23.         if(reset)begin
  24.             key_out_flag_reg <= 1'b0;
  25.         end
  26.         else begin
  27.             key_out_flag_reg <= key_out_flag;
  28.         end
  29.     end
  30.     assign key_out_flag_pos = (!key_out_flag_reg && key_out_flag);
  31.     assign s1_flag = (key_out_flag_pos && (key_value == 4'd1))?1'b1:1'b0;
  32.     assign s2_flag = (key_out_flag_pos && (key_value == 4'd2))?1'b1:1'b0;
  33.     assign s3_flag = (key_out_flag_pos && (key_value == 4'd3))?1'b1:1'b0;
  34.    
  35.     //״̬�Ĵ���
  36.     reg [1:0]nstate;
  37.    
  38.     initial begin
  39.         cstate = IDLE;
  40.         nstate = IDLE;
  41.         Timer_en = 0;
  42.         Timer_rst_n = 0;
  43.         LED_en = 1;
  44.         motor_en = 0;
  45.     end
  46.    
  47.     always@(posedge clk)begin
  48.         if(reset)begin
  49.             cstate <= IDLE;
  50.         end
  51.         else begin
  52.             cstate <= nstate;
  53.         end
  54.     end
  55.    
  56.     always@(*)begin
  57.         case(cstate)
  58.             IDLE:begin
  59.                 if(s1_flag)nstate = START;
  60.                 else nstate = IDLE;
  61.             end
  62.             START:begin
  63.                 if(s2_flag)nstate = PARK;
  64.                 else if(s1_flag)nstate = STOP;
  65.                 else nstate = START;
  66.             end
  67.             PARK:begin
  68.                 if(s2_flag)nstate = START;
  69.                 else nstate = PARK;
  70.             end
  71.             STOP:begin
  72.                 if(s3_flag)nstate = IDLE;
  73.                 else nstate = STOP;
  74.             end
  75.             default:nstate = IDLE;
  76.         endcase
  77.     end
  78.    
  79.     always@(*)begin
  80.         case(cstate)
  81.             IDLE:begin
  82.                 Timer_en = 0;
  83.                 Timer_rst_n = 0;
  84.                 LED_en = 1;
  85.                 motor_en = 0;
  86.             end
  87.             START:begin
  88.                 Timer_en = 0;
  89.                 Timer_rst_n = 0;
  90.                 LED_en = 1;
  91.                 motor_en = 1;//
  92.             end
  93.             PARK:begin
  94.                 Timer_en = 1;
  95.                 Timer_rst_n = 1;
  96.                 LED_en = 0;//
  97.                 motor_en = 0;//
  98.             end
  99.             STOP:begin
  100.                 Timer_en = 0;
  101.                 Timer_rst_n = 1;
  102.                 LED_en = 1;
  103.                 motor_en = 0;
  104.             end
  105.             default:begin
  106.                 Timer_en = 0;
  107.                 Timer_rst_n = 0;
  108.                 LED_en = 1;
  109.                 motor_en = 0;
  110.             end
  111.         endcase
  112.     end
  113. endmodule

(8)top:

完成模块的实例连接。

  1. module top(
  2.     //ϵͳ�ź�
  3.     input sysclkin,
  4.     input button,
  5.     //��������ź�
  6.     input   [3:0] row,  //��
  7.     output  [3:0] col,  //��
  8.     //LCD�ź�
  9.     output         lcd12864_rs,
  10.     output         lcd12864_rw,
  11.     output         lcd12864_en,
  12.     output   [7:0] lcd12864_data,
  13.     //�������ź�
  14.     input          pulse_from_motor,
  15.     //ֱ����������ź�
  16.     output motor_en,
  17.     //LED�ź�
  18.     output LED_en
  19.     );
  20.     //�����ź���
  21.     wire clk_100M,clk_100M_180;
  22.     wire [3:0] key_value;
  23.     wire key_out_flag;
  24.     wire [511:0] data;
  25.     wire [5:0]minute_cnt;
  26.     wire [5:0]second_cnt;
  27.     wire clk_1Hz,Timer_en,Timer_rst_n;
  28.     wire [19:0]  speed_value;
  29.     wire [15:0] turns_num;
  30.     wire [1:0]cstate;
  31.    
  32.     clk_wiz_0 clk_wiz_0_0(
  33.         // Clock out ports
  34.         .clk_out1(clk_100M),     // output clk_out1
  35.         .clk_out2(clk_100M_180),     // output clk_out2
  36.        // Clock in ports
  37.         .clk_in1(sysclkin)
  38.      );
  39.      speed_detect_module speed_detect_module_0(
  40.         .clock(clk_100M),
  41.         .reset(!button),
  42.         .pulse_from_motor(pulse_from_motor),
  43.         .speed_value(speed_value),
  44.         .turns_num(turns_num)
  45.     );
  46.      button4x4_drive button4x4_drive_0(
  47.         .clock(clk_100M),
  48.         .reset(!button),
  49.         .row(row),  //��
  50.         .col(col),  //��
  51.         .key_value(key_value),
  52.         .key_out_flag(key_out_flag)
  53.     );
  54.     CTRLOR CTRLOR_0(
  55.         .clk(clk_100M),
  56.         .reset(!button),
  57.         .key_value(key_value),
  58.         .key_out_flag(key_out_flag),
  59.         .cstate(cstate),
  60.         .Timer_en(Timer_en),
  61.         .Timer_rst_n(Timer_rst_n),
  62.         .LED_en(LED_en),
  63.         .motor_en(motor_en)
  64.     );
  65.     Timer Timer_0(
  66.         .clk(clk_100M),
  67.         .en(Timer_en),
  68.         .rst_n(Timer_rst_n),
  69.         .clk_1Hz(clk_1Hz),
  70.         .minute_cnt(minute_cnt),
  71.         .second_cnt(second_cnt)
  72.     );
  73.     LCD_Decoder LCD_Decoder_0(
  74.         .clk(clk_100M),
  75.         .reset(!button),
  76.         .state(cstate),
  77.         .speed_value(speed_value),
  78.         .turns_num(turns_num),
  79.         .minute_cnt(minute_cnt),
  80.         .second_cnt(second_cnt),
  81.         .data(data)
  82.     );
  83.     lcd12864_drive lcd12864_drive_0(
  84.         .clock(clk_100M),
  85.         .reset(!button),
  86.         .data(data),
  87.         .lcd12864_rs(lcd12864_rs),
  88.         .lcd12864_rw(lcd12864_rw),
  89.         .lcd12864_en(lcd12864_en),
  90.         .lcd12864_data(lcd12864_data)
  91.     );
  92. endmodule

四、演示视频

【2023安徽省机器人大赛】单片机与嵌入式竞赛C赛道作品_哔哩哔哩_bilibili评审95分,冲击省一等奖,正在等待评审结果源码:https://github.com/lionelZhaowy/Taxi_pricing, 视频播放量 2、弹幕量 0、点赞数 0、投硬币枚数 0、收藏人数 0、转发人数 0, 视频作者 lionel赵, 作者简介 今天也要快乐呀,相关视频:【 竞 赛 党 喜 欢 的 男 孩 子 / 女 孩 子 】,如果我在歌唱大赛掏出《雪distance》你该怎么应对,买单片机吗?,进大疆要什么学历?,【M J】多有趣送我上首页好吗?官方要求15秒视频舞蹈大赛!!!!,学妹拙作作为“粉丝作品”入选STM32峰会展出,铺胶赛道有多黏?为何国内一条没有……,这机器不太对劲,纽北赛道为什么考验车?,【选美比赛】清华大学理工科女生获世界小姐选美大赛中国区冠军https://www.bilibili.com/video/BV15c411A7et/?spm_id_from=333.999.0.0

五、经验与教训

  1. 平台例程源码要吃透。实验平台会给出相应的资料方便大家备赛,每个外设的驱动原理与模块的编写要做到心中有数,不能仅仅会使用,否则就会出现我们今年光电测速模块原理没有搞清楚,在赛场上现分析造成时间的浪费,导致最终技术文档没有写完而扣掉了5分。
  2. 技术文档要写好。前面说到我们所有功能都实现了,但是时间不够没有写完技术文档没能满分。可见技术文档的重要性,编写技术文档需要标明各个子模块的功能、数据的流向等,不能只有图片,文字描述非常重要!!!因为评委老师就是因为我们只有图片而没有文字而扣分的。
  3. 打字速度要快,推荐自带自己熟悉的鼠标和键盘。比赛节奏很快,要高效coding,但是要记得不要忘记带回来,笔者因为着急去打篮球,下午评审完成后匆匆收拾了一下把无线键鼠套装的USB接头落在了比赛的机房,回学校才发现,目前正在焦急的等待比赛场地那边老师的回应(QAQ)。

六、源码自取

https://github.com/lionelZhaowy/Taxi_pricinghttps://github.com/lionelZhaowy/Taxi_pricing

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

闽ICP备14008679号