• 状态机练习基于MCP3313110 与 LCD12864 (SPI串口)的 ADC电压显示


    LCD12864用 的是SPI串口形式,接口信号简单,好久之前用过LCD12864做过实验,“LCD12864 液晶显示-汉字及自定义显示(串口)”,但现在拿之前的代码下载进去,压根就不正常,没法显示,现在看之前写的代码,真的是没法入眼,很不规范。

    LCD 的SPI硬件 原理图接法:

    (1)、VDD接的是3.3V,这是IO逻辑电平,需跟FPGA的IO电平相匹配。

    (2)、V0是接的电位器,电位器接的是5V,用来调节对比度,电压越大,其对比度更明显,最好是调节到4V以上。

    (3)、PSB接地,选中SPI 串口模式

    时序:

     (1)、在时钟的低电平中间发送数据

    (2)、sck的时钟需确认,看下表,SCLK的最小周期是400ns ,本实验sclk设置的600ns

     LCD初始化过程参考网上传的流程

     等待上电复位时间40ms,这个不变,发送指令之间的延时都不一样,为了方便点,就挑一个时间最长的延时就可以满足

    查看指令表,最长的也就是下面两个指令,需要4.6ms的等待,本实验用5ms就可以,没用上面的流程图中的>10ms

     看下LCD12864的时序是否正确,仿真波形如下,和上面的时序是对的,先发 5个1 

     LCD12664完整代码:

      1 module lcd12864_spi(
      2                     clk,
      3                     rst_n,
      4                     data,
      5                     lcd_cs,
      6                     lcd_sid,
      7                     lcd_sck
      8 );
      9 parameter         T5MS               = 18'd250_000    ;
     10 parameter         T40MS              = 21'd2_000_000    ;
     11 parameter         SCK_CLK          =  5'd30        ; //1.7M
     12                                 
     13 parameter         START              =  4'd0            ;
     14 parameter         SET_FUN1         =  4'd1            ;
     15 parameter         DLY_5MS             =  4'd2            ;
     16 parameter         SET_FUN2         =  4'd3            ;
     17 parameter         SET_DISPLAY         =  4'd4            ;
     18 parameter         SET_CLEAR         =  4'd5            ;
     19 parameter         SET_ADDR         =  4'd6            ;
     20 parameter         WRITE_DAT1xxx     =  4'd7            ;
     21 parameter         WRITE_DATx1xx     =  4'd8            ;
     22 parameter         WRITE_DATxx1x     =  4'd9            ;
     23 parameter         WRITE_DATxxx1     =  4'd10        ;
     24 parameter         STOP             =  4'd11        ;
     25 
     26 parameter         CMD_FUNCTION =  8'h30            ;    //功能设置
     27 parameter         CMD_DISPLAY  =  8'h0C            ;    //显示设置
     28 parameter         CMD_CLEAR    =  8'h01            ;    //清屏设置
     29 parameter         CMD_ADDR      =  8'h81            ;    //设置显示地址
     30 
     31 
     32 input            clk        ;
     33 input            rst_n    ;
     34 input[32-1:0]    data    ;
     35 
     36 output            lcd_cs    ;
     37 output            lcd_sid    ;
     38 output            lcd_sck    ;
     39 
     40 wire             add_cnt0            ;
     41 wire             end_cnt0            ;
     42 wire             add_cnt1            ;
     43 wire             end_cnt1            ;
     44 wire             START2SET_FUN1         ;
     45 wire             SET_FUN12DLY_5MS     ;
     46 wire             DLY_5MS2SET_FUN2     ;
     47 wire             DLY_5MS2SET_DISPLAY    ;
     48 wire             DLY_5MS2SET_CLEAR     ;
     49 wire             DLY_5MS2SET_ADDR     ;
     50 //wire             DLY_5MS2WRITE_DAT     ;
     51 wire            DLY_5MS2WRITE_DAT1xxx;
     52 wire            DLY_5MS2WRITE_DATx1xx;
     53 wire            DLY_5MS2WRITE_DATxx1x;
     54 wire            DLY_5MS2WRITE_DATxxx1;
     55 wire             SET_FUN22DLY_5MS     ;
     56 wire             SET_DISPLAY2DLY_5MS    ;
     57 wire             SET_CLEAR2DLY_5MS     ;
     58 wire             SET_ADDR2DLY_5MS     ;
     59 
     60 
     61 wire            WRITE_DAT1xxx2DLY_5MS;
     62 wire            WRITE_DATx1xx2DLY_5MS;
     63 wire            WRITE_DATxx1x2DLY_5MS;
     64 wire            WRITE_DATxxx12DLY_5MS;
     65 wire             WRITE_DAT2STOP         ;
     66 wire            lcd_cs                ;
     67 
     68 reg             lcd_sck    ;
     69 reg             lcd_sel    ;
     70 
     71 reg             lcd_sid    ;
     72 reg                add_flag;
     73 reg[21-1:0]        cnt0    ;
     74 reg[5 -1:0]        cnt1    ;
     75 reg[4 -1:0]        state_c    ;
     76 reg[4 -1:0]        state_n    ;
     77 reg[3 -1:0]     dly_flag;
     78 reg[24-1:0]     data_buf;
     79 reg[21-1:0]        x        ;
     80 
     81 always @(posedge clk or negedge rst_n)begin
     82     if(!rst_n)begin
     83         cnt0 <= 0;
     84     end
     85     else if(add_cnt0)begin
     86         if(end_cnt0)begin
     87             cnt0 <= 0;
     88         end
     89         else begin
     90             cnt0 <= cnt0 + 1;
     91         end
     92     end
     93 end
     94 
     95 assign add_cnt0 = add_flag;
     96 assign end_cnt0 = add_cnt0 && cnt0 == x - 1;
     97 
     98 always @(posedge clk or negedge rst_n)begin
     99     if(!rst_n)begin
    100         add_flag <= 0;
    101     end
    102     else if(state_c == START)begin
    103         add_flag <= 1;
    104     end
    105     else if(state_c == STOP)begin
    106         add_flag <= 0;
    107     end
    108 end
    109 
    110 always @(*)begin
    111     if(state_c == START)begin
    112         x =  T40MS;
    113     end
    114     else if(state_c == DLY_5MS)begin
    115         x =  T5MS;
    116     end
    117     else begin
    118         x = SCK_CLK; 
    119     end
    120 end
    121 
    122 always @(posedge clk or negedge rst_n)begin
    123     if(!rst_n)begin
    124         cnt1 <= 0;
    125     end
    126     else if(add_cnt1)begin
    127         if(end_cnt1)begin
    128             cnt1 <= 0;
    129         end
    130         else begin
    131             cnt1 <= cnt1 + 1;
    132         end
    133     end
    134 end
    135 
    136 assign add_cnt1 = end_cnt0 && state_c != START && state_c != DLY_5MS && state_c != STOP;
    137 assign end_cnt1 = add_cnt1 && cnt1 == 25 - 1;
    138 
    139 always @(posedge clk or negedge rst_n)begin
    140     if(!rst_n)begin
    141         lcd_sck <= 0;
    142     end
    143     else if(lcd_sel==1)begin
    144         if(end_cnt0 && cnt1 != 25-1)begin
    145             lcd_sck <= 1;
    146         end
    147         else if(add_cnt0 && cnt0 == ((x>>1) -1))begin
    148             lcd_sck <= 0;
    149         end
    150     end
    151 end
    152 
    153 assign sck_low_middle = add_cnt0 && cnt0 == ((x>>1)+((x>>1)>>1)) - 1;
    154 
    155 always @(posedge clk or negedge rst_n)begin
    156     if(!rst_n)begin
    157         lcd_sid <= 0;
    158     end
    159     else if(lcd_sel && sck_low_middle && cnt1 >= 0 && cnt1 < 24)begin //在低电平中间发送数据
    160         lcd_sid <= data_buf[23-cnt1];
    161     end
    162 end
    163 
    164 always @(*)begin
    165     if(state_c == SET_FUN1 || state_c == SET_FUN2)begin
    166         data_buf = {5'b11111, 1'b0, 1'b0, 1'b0, CMD_FUNCTION[7:4], 4'b0000, CMD_FUNCTION[3:0], 4'b0000};
    167     end
    168     else if(state_c == SET_DISPLAY)begin
    169         data_buf = {5'b11111, 1'b0, 1'b0, 1'b0, CMD_DISPLAY[7:4], 4'b0000, CMD_DISPLAY[3:0], 4'b0000};
    170     end
    171     else if(state_c == SET_CLEAR)begin
    172         data_buf = {5'b11111, 1'b0, 1'b0, 1'b0, CMD_CLEAR[7:4], 4'b0000, CMD_CLEAR[3:0], 4'b0000};
    173     end
    174     else if(state_c == SET_ADDR)begin
    175         data_buf = {5'b11111, 1'b0, 1'b0, 1'b0, CMD_ADDR[7:4], 4'b0000, CMD_ADDR[3:0], 4'b0000};
    176     end
    177     else if(state_c == WRITE_DAT1xxx)begin
    178         data_buf = {5'b11111, 1'b0, 1'b1, 1'b0, data[31:28], 4'b0000, data[27:24], 4'b0000};
    179     end
    180     else if(state_c == WRITE_DATx1xx)begin
    181         data_buf = {5'b11111, 1'b0, 1'b1, 1'b0, data[23:20], 4'b0000, data[19:16], 4'b0000};
    182     end
    183     else if(state_c == WRITE_DATxx1x)begin
    184         data_buf = {5'b11111, 1'b0, 1'b1, 1'b0, data[15:12], 4'b0000, data[11:8], 4'b0000};
    185     end
    186     else if(state_c == WRITE_DATxxx1)begin
    187         data_buf = {5'b11111, 1'b0, 1'b1, 1'b0, data[7:4], 4'b0000, data[3:0], 4'b0000};
    188     end
    189 end
    190 
    191 always @(*)begin
    192     if(state_c == START || state_c == DLY_5MS || state_c == STOP)begin
    193         lcd_sel = 0;
    194     end
    195     else begin
    196         lcd_sel = 1;
    197     end
    198 end
    199 
    200 assign lcd_cs = lcd_sel;
    201 
    202 
    203 always @(posedge clk or negedge rst_n)begin
    204     if(!rst_n)begin
    205         state_c <= START;
    206     end
    207     else begin
    208         state_c <= state_n;
    209     end
    210 end
    211 
    212 always @(*)begin
    213     case(state_c)
    214     
    215     START:begin
    216         if(START2SET_FUN1)begin //延时40ms
    217             state_n = SET_FUN1;
    218         end
    219         else begin
    220             state_n = state_c;
    221         end
    222     end
    223     
    224     SET_FUN1:begin  //功能设定
    225         if(SET_FUN12DLY_5MS)begin
    226             state_n = DLY_5MS;
    227         end
    228         else begin
    229             state_n = state_c;
    230         end
    231     end
    232     
    233     DLY_5MS:begin  //延时5MS
    234         if(DLY_5MS2SET_FUN2)begin
    235             state_n = SET_FUN2;
    236         end
    237         else if(DLY_5MS2SET_DISPLAY)begin
    238             state_n = SET_DISPLAY;
    239         end
    240         else if(DLY_5MS2SET_CLEAR)begin
    241             state_n = SET_CLEAR;
    242         end
    243         else if(DLY_5MS2SET_ADDR)begin
    244             state_n = SET_ADDR;
    245         end
    246         else if(DLY_5MS2WRITE_DAT1xxx)begin
    247             state_n = WRITE_DAT1xxx;
    248         end
    249         else if(DLY_5MS2WRITE_DATx1xx)begin
    250             state_n = WRITE_DATx1xx;
    251         end
    252         else if(DLY_5MS2WRITE_DATxx1x)begin
    253             state_n = WRITE_DATxx1x;
    254         end
    255         else if(DLY_5MS2WRITE_DATxxx1)begin
    256             state_n = WRITE_DATxxx1;
    257         end
    258         else begin
    259             state_n = state_c;
    260         end
    261     end
    262     
    263     SET_FUN2:begin  //功能设定
    264         if(SET_FUN22DLY_5MS)begin
    265             state_n = DLY_5MS;
    266         end
    267         else begin
    268             state_n = state_c;
    269         end
    270     end
    271     
    272     SET_DISPLAY:begin  //设置显示
    273         if(SET_DISPLAY2DLY_5MS)begin
    274             state_n = DLY_5MS;
    275         end
    276         else begin
    277             state_n = state_c;
    278         end
    279     end
    280     
    281     SET_CLEAR:begin  //设置清除
    282         if(SET_CLEAR2DLY_5MS)begin
    283             state_n = DLY_5MS;
    284         end
    285         else begin
    286             state_n = state_c;
    287         end
    288     end
    289     
    290     SET_ADDR:begin  //设置地址
    291         if(SET_ADDR2DLY_5MS)begin
    292             state_n = DLY_5MS;
    293         end
    294         else begin
    295             state_n = state_c;
    296         end
    297     end
    298     
    299     WRITE_DAT1xxx:begin
    300         if(WRITE_DAT1xxx2DLY_5MS)begin
    301             state_n = DLY_5MS;
    302         end
    303         else begin
    304             state_n = state_c;
    305         end
    306     end
    307     
    308     WRITE_DATx1xx:begin
    309         if(WRITE_DATx1xx2DLY_5MS)begin
    310             state_n = DLY_5MS;
    311         end
    312         else begin
    313             state_n = state_c;
    314         end
    315     end
    316     
    317     WRITE_DATxx1x:begin
    318         if(WRITE_DATxx1x2DLY_5MS)begin
    319             state_n = DLY_5MS;
    320         end
    321         else begin
    322             state_n = state_c;
    323         end
    324     end
    325     
    326     WRITE_DATxxx1:begin
    327         if(WRITE_DATxxx12DLY_5MS)begin
    328             state_n = DLY_5MS;
    329         end
    330         else begin
    331             state_n = state_c;
    332         end
    333     end
    334 /*    
    335     WRITE_DAT:begin  //写数据
    336         if(WRITE_DAT2STOP)begin
    337             state_n = STOP;
    338         end
    339         else begin
    340             state_n = state_c;
    341         end
    342     end
    343     
    344     STOP:begin  //设置地址
    345             state_n = state_c;
    346     end
    347 */
    348     default:begin
    349             state_n = START;
    350     end
    351     endcase
    352 end
    353 
    354 
    355 
    356 assign START2SET_FUN1             = state_c == START             && end_cnt0; //延时40ms,即可跳转
    357 assign SET_FUN12DLY_5MS         = state_c == SET_FUN1        && end_cnt1;
    358 assign DLY_5MS2SET_FUN2         = state_c == DLY_5MS        && end_cnt0 && dly_flag == 0;
    359 assign DLY_5MS2SET_DISPLAY         = state_c == DLY_5MS        && end_cnt0 && dly_flag == 1;
    360 assign DLY_5MS2SET_CLEAR         = state_c == DLY_5MS        && end_cnt0 && dly_flag == 2;
    361 assign DLY_5MS2SET_ADDR         = state_c == DLY_5MS        && end_cnt0 && dly_flag == 3;
    362 assign DLY_5MS2WRITE_DAT1xxx     = state_c == DLY_5MS        && end_cnt0 && dly_flag == 4;
    363 assign DLY_5MS2WRITE_DATx1xx     = state_c == DLY_5MS        && end_cnt0 && dly_flag == 5;
    364 assign DLY_5MS2WRITE_DATxx1x     = state_c == DLY_5MS        && end_cnt0 && dly_flag == 6;
    365 assign DLY_5MS2WRITE_DATxxx1     = state_c == DLY_5MS        && end_cnt0 && dly_flag == 7;
    366 assign SET_FUN22DLY_5MS         = state_c == SET_FUN2        && end_cnt1;
    367 assign SET_DISPLAY2DLY_5MS         = state_c == SET_DISPLAY    && end_cnt1;
    368 assign SET_CLEAR2DLY_5MS         = state_c == SET_CLEAR        && end_cnt1;
    369 assign SET_ADDR2DLY_5MS         = state_c == SET_ADDR        && end_cnt1;
    370 assign WRITE_DAT1xxx2DLY_5MS     = state_c == WRITE_DAT1xxx    && end_cnt1;
    371 assign WRITE_DATx1xx2DLY_5MS     = state_c == WRITE_DATx1xx    && end_cnt1;
    372 assign WRITE_DATxx1x2DLY_5MS     = state_c == WRITE_DATxx1x    && end_cnt1;
    373 assign WRITE_DATxxx12DLY_5MS     = state_c == WRITE_DATxxx1    && end_cnt1;
    374 
    375 //assign WRITE_DAT2STOP             = state_c == WRITE_DAT        && end_cnt1;
    376 
    377 always @(posedge clk or negedge rst_n)begin
    378     if(!rst_n)begin
    379         dly_flag <= 0;
    380     end
    381     else if(state_c == START || state_c == STOP)begin
    382         dly_flag <= 0;
    383     end
    384     else if(state_c == SET_FUN2)begin
    385         dly_flag <= 1;
    386     end
    387     else if(state_c == SET_DISPLAY)begin
    388         dly_flag <= 2;
    389     end
    390     else if(state_c == SET_CLEAR || state_c == WRITE_DATxxx1)begin
    391         dly_flag <= 3;
    392     end
    393     else if(state_c == SET_ADDR)begin
    394         dly_flag <= 4;
    395     end
    396     else if(state_c == WRITE_DAT1xxx)begin
    397         dly_flag <= 5;
    398     end
    399     else if(state_c == WRITE_DATx1xx)begin
    400         dly_flag <= 6;
    401     end
    402     else if(state_c == WRITE_DATxx1x)begin
    403         dly_flag <= 7;
    404     end
    405 end
    406 
    407 endmodule
    View Code

    MCP33131代码有所改动,之前实验中写的代码看的比较累,状态机一锅端,阅读起来费劲,改用四段式状态机,就比较清晰好理解,简化代码

    MCP33131-10完整代码:

      1 module adc(
      2                     clk,
      3                     rst_n,
      4                     adc_sdo,
      5                     din_vld,
      6                     
      7                     adc_cs,    
      8                     adc_sclk,
      9                     dout,
     10                     dout_vld
     11                     
     12 );
     13 
     14 parameter            S0 = 2'd0;
     15 parameter            S1 = 2'd1;
     16 parameter            S2 = 2'd2;
     17 
     18 input                   clk;
     19 input                   rst_n;
     20 input                   adc_sdo;
     21 input                din_vld;    
     22 
     23 output                adc_cs;
     24 output                adc_sclk;
     25 output[16-1 : 0]      dout;
     26 output                dout_vld;
     27     
     28 reg[16-1 : 0]         dout_temp;
     29 reg[16-1 : 0]         dout;
     30 reg[3 -1 : 0]         cnt0/* synthesis keep*/;
     31 reg[5 -1 : 0]         cnt1/* synthesis keep*/;
     32 reg[5 -1 : 0]         x/* synthesis keep*/;
     33 reg[2 -1 : 0]         state_c;
     34 reg[2 -1 : 0]         state_n;
     35 reg                   flag_add;
     36 reg                   dout_vld;
     37 reg                   adc_cs;
     38 reg                   adc_sclk;
     39     
     40 wire                  add_cnt0;
     41 wire                  end_cnt0;
     42 wire                  add_cnt1;
     43 wire                  end_cnt1;
     44 
     45 
     46 always @(posedge clk or negedge rst_n)begin
     47     if(!rst_n)begin
     48         flag_add <= 0;
     49     end
     50     else if(din_vld)begin
     51         flag_add <= 1;
     52     end
     53     else if(state_c == S2 && end_cnt1)begin
     54         flag_add <= 0;
     55     end
     56 end
     57 
     58 always @(posedge clk or negedge rst_n)begin
     59     if(!rst_n)begin
     60         cnt0 <= 0;
     61     end
     62     else if(add_cnt0)begin
     63         if(end_cnt0)begin
     64             cnt0 <= 0;
     65         end
     66         else begin
     67             cnt0 <= cnt0 + 1;
     68         end
     69     end
     70 end
     71 
     72 assign add_cnt0 = flag_add;
     73 assign end_cnt0 = add_cnt0 && cnt0 == 4 - 1; //输入时钟50M,4分屏,sclk = 50/4 = 12.5M
     74 
     75 always @(posedge clk or negedge rst_n)begin
     76     if(!rst_n)begin
     77         cnt1 <= 0;
     78     end
     79     else if(add_cnt1)begin
     80         if(end_cnt1)begin
     81             cnt1 <= 0;
     82         end
     83         else begin
     84             cnt1 <= cnt1 + 1;
     85         end
     86     end
     87 end
     88 
     89 assign add_cnt1 = end_cnt0;
     90 assign end_cnt1 = add_cnt1 && cnt1 == x - 1;
     91 
     92 always @(*)begin
     93 /*
     94     if(state_c == S0)begin
     95         x = 16;         //tACQ:等待16 * 80 = 1280 ns
     96     end
     97     else 
     98 */
     99     if(state_c == S1)begin
    100         x = 24;        //tCNV:等待24 * 80 = 1920 ns ,
    101     end
    102     else begin
    103         x = 16;       //tACQ:等待16 * 80 = 1280 ns
    104     end
    105 end
    106 
    107 always @(posedge clk or negedge rst_n)begin
    108     if(!rst_n)begin
    109         state_c <= S0;
    110     end
    111     else begin
    112         state_c <= state_n;
    113     end
    114 end
    115 
    116 always @(*)begin
    117     case(state_c)
    118     
    119     S0:begin
    120         if(S02S1)begin
    121             state_n = S1;
    122         end
    123         else begin
    124             state_n = state_c;
    125         end
    126     end
    127     
    128     S1:begin
    129         if(S12S2)begin
    130             state_n = S2;
    131         end
    132         else begin
    133             state_n = state_c;
    134         end
    135     end
    136     
    137     S2:begin
    138         if(S22S0)begin
    139             state_n = S0;
    140         end
    141         else begin
    142             state_n = state_c;
    143         end
    144     end
    145     
    146     default:begin
    147         state_n = S0;
    148     end
    149     
    150     endcase
    151 end
    152 
    153 assign S02S1 = state_c == S0 && din_vld;
    154 assign S12S2 = state_c == S1 && end_cnt1;
    155 assign S22S0 = state_c == S2 && end_cnt1;
    156 
    157 always @(posedge clk or negedge rst_n)begin
    158     if(!rst_n)begin
    159         dout_vld <= 0;
    160     end
    161     else if(state_c == S2 && end_cnt1)begin
    162         dout_vld <= 1;
    163     end
    164     else begin
    165         dout_vld <= 0;
    166     end
    167 end
    168 
    169 always @(posedge clk or negedge rst_n)begin
    170     if(!rst_n)begin
    171         adc_cs <= 1;
    172     end
    173     else if(state_c == S2)begin
    174         adc_cs <= 0;
    175     end 
    176     else begin
    177         adc_cs <= 1;
    178     end
    179 end
    180 
    181 always @(posedge clk or negedge rst_n)begin
    182     if(!rst_n)begin
    183         dout_temp <= 0;
    184     end
    185     else if(state_c == S2 && add_cnt0 && cnt0 == 2-1)begin //在sclk的下降沿采数据,同时在flag_sel有效期间
    186             dout_temp[15-cnt1] <= adc_sdo;
    187     end
    188 end
    189 
    190 always @(posedge clk or negedge rst_n)begin
    191     if(!rst_n)begin
    192         dout <= 0;
    193     end
    194     else if(dout_vld)begin //一个完整的16bit数据采集完
    195         dout <= dout_temp;
    196     end
    197 end
    198 
    199 always @(posedge clk or negedge rst_n)begin
    200     if(!rst_n)begin
    201         adc_sclk <= 1;
    202     end
    203     else if(add_cnt0 && cnt0 == 2-1)begin
    204         adc_sclk <= 0;
    205     end
    206     else if(end_cnt0)begin
    207         adc_sclk <= 1;
    208     end
    209 end
    210 
    211 endmodule
    View Code

    顶层代码: 就ADC的数值进行转化,并拆分,便于LCD显示

      1 module flash_top(
      2                     clk,
      3                     rst_n,
      4                     
      5                     adc_sdo,
      6                     adc_cs1,
      7                     adc_cs2,
      8                     adc_sclk,
      9                     
     10                     lcd_cs,
     11                     lcd_sid,
     12                     lcd_sck
     13                     
     14 );
     15 parameter     T400MS = 25'd20_000_000;
     16     
     17 input        clk;
     18 input        rst_n;
     19 input        adc_sdo;
     20 output        adc_cs1;
     21 output        adc_cs2;
     22 output        adc_sclk;
     23 output        lcd_cs;
     24 output        lcd_sid;
     25 output        lcd_sck;
     26 wire        adc_cs2;
     27 assign        adc_cs2 = 1;
     28 reg            din_vld;
     29 wire[16-1:0]dout;
     30 wire        dout_vld;
     31 reg[32-1:0] data;
     32 wire        add_cnt0;
     33 wire        end_cnt0;    
     34 
     35 reg[25-1:0] cnt0;
     36 always @(posedge clk or negedge rst_n)begin
     37     if(!rst_n)begin
     38         cnt0 <= 0;
     39     end
     40     else if(add_cnt0)begin
     41         if(end_cnt0)begin
     42             cnt0 <= 0;
     43         end
     44         else begin
     45             cnt0 <= cnt0 + 1;
     46         end
     47     end
     48 end
     49 assign add_cnt0 = 1;
     50 assign end_cnt0 = add_cnt0 && cnt0 == T400MS -1;  
     51 
     52 always @(posedge clk or negedge rst_n)begin
     53     if(!rst_n)begin
     54         din_vld <= 0;
     55     end
     56     else begin
     57         din_vld <= end_cnt0; //隔400ms就取一次ADC的值
     58     end
     59 end
     60 
     61 wire[32-1:0]     mV;
     62 wire[3-1:0]     V;             //千位
     63 wire[4-1:0]        v_temp1;    //百位
     64 wire[4-1:0]        v_temp2;    //十位
     65 wire[4-1:0]        v_temp3;    //个位
     66 
     67 assign mV         = ((dout-1600) <<2) * 1000 / 65536;  //-1600 是用于校准 ,参考电压是4.096V,所以左移2
     68 assign V          = mV /1000;
     69 assign v_temp1     = (mV - V*1000) / 100;
     70 assign v_temp2     = ((mV - V*1000) -100) / 10;
     71 assign v_temp3     = ((mV - V*1000) -100) - (v_temp2*10);
     72 
     73 always @(*)begin
     74     case(V)
     75     0:            data[31:24] = "0";
     76     1:            data[31:24] = "1";
     77     2:            data[31:24] = "2";
     78     3:            data[31:24] = "3";
     79     4:            data[31:24] = "4";
     80     default:    data[31:24] = "0";
     81     endcase
     82 end
     83 
     84 always @(*)begin
     85     case(v_temp1)
     86     0:            data[23:16] = "0";
     87     1:            data[23:16] = "1";
     88     2:            data[23:16] = "2";
     89     3:            data[23:16] = "3";
     90     4:            data[23:16] = "4";
     91     5:            data[23:16] = "5";
     92     6:            data[23:16] = "6";
     93     7:            data[23:16] = "7";
     94     8:            data[23:16] = "8";
     95     9:            data[23:16] = "9";
     96     default:    data[23:16] = "0";
     97     endcase
     98 end
     99 
    100 always @(*)begin
    101     case(v_temp2)
    102     0:            data[15:8] = "0";
    103     1:            data[15:8] = "1";
    104     2:            data[15:8] = "2";
    105     3:            data[15:8] = "3";
    106     4:            data[15:8] = "4";
    107     5:            data[15:8] = "5";
    108     6:            data[15:8] = "6";
    109     7:            data[15:8] = "7";
    110     8:            data[15:8] = "8";
    111     9:            data[15:8] = "9";
    112     default:    data[15:8] = "0";
    113     endcase
    114 end
    115 
    116 always @(*)begin
    117     case(v_temp3)
    118     0:            data[7:0] = "0";
    119     1:            data[7:0] = "1";
    120     2:            data[7:0] = "2";
    121     3:            data[7:0] = "3";
    122     4:            data[7:0] = "4";
    123     5:            data[7:0] = "5";
    124     6:            data[7:0] = "6";
    125     7:            data[7:0] = "7";
    126     8:            data[7:0] = "8";
    127     9:            data[7:0] = "9";
    128     default:    data[7:0] = "0";
    129     endcase
    130 end
    131 
    132 adc                adc_u1(    
    133                         .clk        (clk),
    134                         .rst_n        (rst_n),
    135                         .adc_sdo    (adc_sdo),
    136                         .din_vld    (din_vld),
    137                                     
    138                         .adc_cs        (adc_cs1),    
    139                         .adc_sclk    (adc_sclk),
    140                         .dout        (dout),
    141                         .dout_vld   (dout_vld)
    142                     
    143 );
    144 
    145 
    146 lcd12864_spi    lcd_u2(
    147                         .clk    (clk),
    148                         .rst_n    (rst_n),
    149                         .data    (data),
    150                         .lcd_cs    (lcd_cs),
    151                         .lcd_sid(lcd_sid),
    152                         .lcd_sck(lcd_sck)
    153 );
    154 endmodule
    View Code

    ADC 和 LCD之间的关系, 就是数据流的方式,没有相互交互打招呼的关系, ADC固定间隔采集,LCD不停的刷新显示, 类似 “生产者 + 消费者 模式” 。

    显示效果比较简单,如下图:3304 = 3.304V ,后续有时间将显示的更加好看点。

  • 相关阅读:
    STP-5-STP配置及分析
    PostgreSQL-10-数据运算与函数
    PostgreSQL-9-别名与动态表复制
    PostgreSQL-8-数据合并
    PostgreSQL-7-数据连接
    PostgreSQL-6-数据分组
    STP-4-每VLAN生成树和Trunk上的STP
    VLAN-6-VLAN Trunk协议(VTP)
    STP-3-收敛到新的STP拓扑
    STP-2-三个选择
  • 原文地址:https://www.cnblogs.com/wen2376/p/16209216.html
Copyright © 2020-2023  润新知