C/C++教程

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

本文主要是介绍状态机练习-基于MCP33131-10 与 LCD12864 (SPI串口)的 ADC电压显示,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

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

时序:

 

 在时钟的低电平中间发送数据

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 ,后续有时间将显示的更加好看点。

 

这篇关于状态机练习-基于MCP33131-10 与 LCD12864 (SPI串口)的 ADC电压显示的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!