-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom.xml
865 lines (449 loc) · 389 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>kelecn</title>
<link href="https://kelecn.top/atom.xml" rel="self"/>
<link href="https://kelecn.top/"/>
<updated>2021-08-24T15:25:09.781Z</updated>
<id>https://kelecn.top/</id>
<author>
<name>kelecn</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>深圳文和友</title>
<link href="https://kelecn.top/posts/2042/"/>
<id>https://kelecn.top/posts/2042/</id>
<published>2021-08-15T15:49:14.000Z</published>
<updated>2021-08-24T15:25:09.781Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:深圳文和友在<a href="https://map.baidu.com/poi/%E8%8C%B6%E9%A2%9C%E6%82%A6%E8%89%B2(%E6%B7%B1%E5%9C%B3%E6%96%87%E5%92%8C%E5%8F%8B%E5%BA%97)/@12704034.005,2561377.52,19z?uid=5211749389a9ed5b2ce67bef&ugc_type=3&ugc_ver=1&device_ratio=2&compat=1&querytype=detailConInfo&da_src=shareurl">深圳(东门)附近</a>,介于广深铁路和布吉河之间,往返的和谐号动车与绿皮火车、“科技之城”与“市井文化”,过去与未来、生活与艺术在此交织,颇有赛博朋克、怀旧复古之感。</p><a id="more"></a><div class="video"><video controls preload><source src='https://cdn.jsdelivr.net/gh/kelecn/images@master/Shenzhen-and-friends.mp4' type='video/mp4'>Your browser does not support the video tag.</video></div><h2 id="一、游玩建议"><a href="#一、游玩建议" class="headerlink" title="一、游玩建议"></a>一、游玩建议</h2><p><strong><em>1、节假日人超级多,去了基本就是人挤人,建议错峰出行。</em></strong></p><p><strong><em>2、打卡圣地茶颜悦色需要到现场扫码抢票(整点抢),一个人只能买两杯,周三有第二杯半价优惠。</em></strong></p><p><strong><em>3、茶颜悦色我去的是三楼那家,其实一楼还有一家,一楼的人可能会少一点。</em></strong></p><p><strong><em>4、建议下午去,太阳还没下山之前去到那里,可以看到比较震撼的3D显示外墙。</em></strong></p><p><strong><em>5、离开时,可以去地铁的马路对面,那里位置特别好。</em></strong></p><h2 id="二、打卡"><a href="#二、打卡" class="headerlink" title="二、打卡"></a>二、打卡</h2> <div class="note quote"><p>读万卷书,行万里路。</p></div><div class="gallery stretch" col='2'> <p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-1.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-1.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-2.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-2.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-3.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-3.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-4.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-4.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-5.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-5.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-6.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-6.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-7.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-7.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-8.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-8.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-9.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-9.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-10.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-10.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-11.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-11.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-12.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-12.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-13.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-13.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-14.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-14.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-15.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-15.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-16.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-16.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-17.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/31-17.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p> </div>]]></content>
<summary type="html">kelecn's Blog,一个记录个人成长的地方。</summary>
<category term="生活" scheme="https://kelecn.top/categories/%E7%94%9F%E6%B4%BB/"/>
<category term="旅行" scheme="https://kelecn.top/tags/%E6%97%85%E8%A1%8C/"/>
<category term="打卡" scheme="https://kelecn.top/tags/%E6%89%93%E5%8D%A1/"/>
<category term="深圳" scheme="https://kelecn.top/tags/%E6%B7%B1%E5%9C%B3/"/>
<category term="深圳文和友" scheme="https://kelecn.top/tags/%E6%B7%B1%E5%9C%B3%E6%96%87%E5%92%8C%E5%8F%8B/"/>
</entry>
<entry>
<title>给博客添加一个聊天机器人—Botui.js</title>
<link href="https://kelecn.top/posts/32834/"/>
<id>https://kelecn.top/posts/32834/</id>
<published>2021-08-12T15:13:14.000Z</published>
<updated>2021-08-20T16:37:03.195Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:<a href="https://github.com/botui/botui">Botui.js</a> 是一个用于创建对话 UI 的开源 JavaScript 框架,可以用于我们的博客美化。</p><a id="more"></a><div class="note quote"><p>聊天机器人效果 ^-^</p></div><p>具体效果看:<a href="https://kelecn.top/about/">关于 - kelecn</a></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/kele.gif" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/kele.gif" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><strong>开源项目:</strong><div class="tag link"><a class="link-card" title="Botui" href="https://github.com/botui/botui"><div class="left"><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/post301.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/post301.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="right"><p class="text">Botui</p><p class="url">https://github.com/botui/botui</p></div></a></div></p><h3 id="一、Botui-简介"><a href="#一、Botui-简介" class="headerlink" title="一、Botui 简介"></a>一、Botui 简介</h3><p><a href="https://github.com/botui/botui">Botui</a> 是一个有趣的聊天 JS 框架,界面样式像是一个对话聊天界面,使用者可以创建一个对话内容与访客进行互动,互动起来很有趣😋😋😋😋,可自定义程度高,使用难度也不高。下面我就针对 <a href="https://volantis.js.org/">Volantis</a> hexo博客主题进行部署演示。</p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/post301.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/post301.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><h3 id="二、部署-Botui-聊天机器人"><a href="#二、部署-Botui-聊天机器人" class="headerlink" title="二、部署 Botui 聊天机器人"></a>二、部署 Botui 聊天机器人</h3><p>首先,你可以参考 <a href="https://github.com/botui/botui">Botui</a> 进行其他博客系统、主题、网站进行部署,我这边仅提供 <a href="https://volantis.js.org/">Volantis</a> hexo博客主题的部署演示,其实都大差不差,可以参考一下。</p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/post302.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/post302.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><ol><li><p>下载 <a href="https://cdn.jsdelivr.net/gh/kelecn/images@master/botui.js">botui.js</a> ,我这边提供我使用的,各位直接修改即可;</p></li><li><p>将下载好的 botui.js 复制到…\themes\volantis\source\js 路径下;</p></li><li><p>在你想调用 botui 聊天机器人的文章(index.md)里对应的位置添加以下代码,即可。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><!-- https:<span class="comment">//www.bootcdn.cn/botui/ --></span></span><br><span class="line"><link href=<span class="string">"https://cdn.bootcss.com/botui/0.3.9/botui-theme-default.css"</span> rel=<span class="string">"stylesheet"</span>></span><br><span class="line"><link href=<span class="string">"https://cdn.bootcss.com/botui/0.3.9/botui.min.css"</span> rel=<span class="string">"stylesheet"</span>></span><br><span class="line"> </span><br><span class="line"><bot-ui></botui></span><br><span class="line"><script src=<span class="string">"/js/botui.js"</span>></script></span><br><span class="line"><script></span><br><span class="line">bot_ui_ini()</span><br><span class="line"></script></span><br></pre></td></tr></table></figure><p>我的-<a href="https://kelecn.top/about/">关于页</a> markdown文档全文配置如下:有需要朋友的可以参考一下。</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="xml"><span class="comment"><!-- 我的-关于markdown文档配置 --></span></span></span><br><span class="line">---</span><br><span class="line">layout: docs</span><br><span class="line">seo<span class="emphasis">_title: 关于</span></span><br><span class="line"><span class="emphasis">bottom_</span>meta: false</span><br><span class="line">sidebar: []</span><br><span class="line">valine:</span><br><span class="line"> placeholder: 有什么想对我说的呢?</span><br><span class="line">---</span><br><span class="line">{% p center logo large red, 关 %}{% p center logo large blue, 于 %}</span><br><span class="line"><span class="xml"><span class="comment"><!-- https://www.bootcdn.cn/botui/ --></span></span></span><br><span class="line"><span class="xml"><span class="tag"><<span class="name">link</span> <span class="attr">href</span>=<span class="string">"https://cdn.bootcss.com/botui/0.3.9/botui-theme-default.css"</span> <span class="attr">rel</span>=<span class="string">"stylesheet"</span>></span></span></span><br><span class="line"><span class="xml"><span class="tag"><<span class="name">link</span> <span class="attr">href</span>=<span class="string">"https://cdn.bootcss.com/botui/0.3.9/botui.min.css"</span> <span class="attr">rel</span>=<span class="string">"stylesheet"</span>></span></span></span><br><span class="line">{% raw %}</span><br><span class="line"><span class="xml"><span class="comment"><!-- 因为vue和botui更新导至bug,现将对话移至js下的botui中配置 --></span></span></span><br><span class="line"><span class="xml"><span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"entry-content"</span>></span></span></span><br><span class="line"> <span class="xml"><span class="tag"><<span class="name">div</span> <span class="attr">id</span>=<span class="string">"kelecnbot"</span> <span class="attr">class</span>=<span class="string">"popcontainer"</span> <span class="attr">style</span>=<span class="string">"min-height: 0px; padding: 2px 6px 4px; background-color: rgba(255, 255, 255, 0.5); border-radius: 10px;"</span>></span></span></span><br><span class="line"> <span class="xml"><span class="tag"><<span class="name">center</span>></span></span>您正在与&nbsp;kelecn&nbsp;对话中...<span class="xml"><span class="tag"></<span class="name">center</span>></span></span> </span><br><span class="line"><span class="xml"><span class="tag"><<span class="name">bot-ui</span>></span></span><span class="xml"><span class="tag"></<span class="name">botui</span>></span></span></span><br><span class="line"> <span class="xml"><span class="tag"></<span class="name">div</span>></span></span></span><br><span class="line"><span class="xml"><span class="tag"><<span class="name">iframe</span> <span class="attr">src</span>=<span class="string">"https://kelecn.top/donate/simple/"</span> <span class="attr">style</span>=<span class="string">"overflow-x:hidden;overflow-y:hidden; border:0xp none #fff; min-height:240px; width:100%;"</span> <span class="attr">frameborder</span>=<span class="string">"0"</span> <span class="attr">scrolling</span>=<span class="string">"no"</span>></span></span><span class="xml"><span class="tag"></<span class="name">iframe</span>></span></span></span><br><span class="line"><span class="xml"><span class="tag"></<span class="name">div</span>></span></span></span><br><span class="line"><span class="xml"><span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"/js/botui.js"</span>></span></span><span class="xml"><span class="tag"></<span class="name">script</span>></span></span></span><br><span class="line"><span class="xml"><span class="tag"><<span class="name">script</span>></span></span></span><br><span class="line">bot<span class="emphasis">_ui_</span>ini()</span><br><span class="line"><span class="xml"><span class="tag"></<span class="name">script</span>></span></span></span><br><span class="line">{% endraw %}</span><br><span class="line"></span><br></pre></td></tr></table></figure></li></ol><h3 id="三、修改-Botui-聊天机器人配置"><a href="#三、修改-Botui-聊天机器人配置" class="headerlink" title="三、修改 Botui 聊天机器人配置"></a>三、修改 Botui 聊天机器人配置</h3><p>Botui 聊天机器人的预设配置在…\themes\volantis\source\js\botui.js,也就是刚才下载的botui.js文件。</p><div class="note quote"><p>这个一看就懂,我就不详细解释了,要注意一下中文支持需要使用UTF-8编码格式,否则可能会乱码。</p></div><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//略部分配置代码</span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * botui 0.3.4</span></span><br><span class="line"><span class="comment"> * A JS library to build the UI for your bot</span></span><br><span class="line"><span class="comment"> * https://botui.org</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * Copyright 2017, Moin Uddin</span></span><br><span class="line"><span class="comment"> * Released under the MIT license.</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="comment">//略部分配置代码</span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * BotUI回复配置,这个一看就懂,我就不详细解释了,要注意一下中文支持需要使用UTF-8编码格式,否则可能会乱码。</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> botui = <span class="keyword">new</span> BotUI(<span class="string">"kelecnbot"</span>);</span><br><span class="line">botui.message.bot({</span><br><span class="line"> delay: <span class="number">200</span>,</span><br><span class="line"> content: <span class="string">"Hi, 陌生人👋👋👋"</span></span><br><span class="line">}).then(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> botui.message.bot({</span><br><span class="line"> delay: <span class="number">1000</span>,</span><br><span class="line"> content: <span class="string">"这里是 kelecn 😋😋😋"</span></span><br><span class="line"> })</span><br><span class="line">}).then(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> botui.message.bot({</span><br><span class="line"> delay: <span class="number">1000</span>,</span><br><span class="line"> content: <span class="string">"一个热爱技术的蓝孩子~😉😉😉"</span></span><br><span class="line"> })</span><br><span class="line">}).then(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> botui.action.button({</span><br><span class="line"> delay: <span class="number">1500</span>,</span><br><span class="line"> action: [{</span><br><span class="line"> text: <span class="string">"然后呢? 😃😃😃"</span>,</span><br><span class="line"> value: <span class="string">"and"</span></span><br><span class="line"> },</span><br><span class="line"> {</span><br><span class="line"> text: <span class="string">"少废话! 🙄🙄🙄"</span>,</span><br><span class="line"> value: <span class="string">"gg"</span></span><br><span class="line"> }]</span><br><span class="line"> })</span><br><span class="line">}).then(<span class="function"><span class="keyword">function</span>(<span class="params">res</span>) </span>{</span><br><span class="line"> <span class="keyword">if</span> (res.value == <span class="string">"and"</span>) {</span><br><span class="line"> other()</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (res.value == <span class="string">"gg"</span>) {</span><br><span class="line"> <span class="keyword">return</span> botui.message.bot({</span><br><span class="line"> delay: <span class="number">1500</span>,</span><br><span class="line"> content: <span class="string">" ![告辞](https://cdn.jsdelivr.net/gh/kelecn/images@master/gaoci%20.jpg) "</span></span><br><span class="line"> })</span><br><span class="line"> }</span><br><span class="line">});</span><br><span class="line"> </span><br><span class="line"><span class="keyword">var</span> other = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> botui.message.bot({</span><br><span class="line"> delay: <span class="number">1500</span>,</span><br><span class="line"> content: <span class="string">"😘😘😘"</span></span><br><span class="line"> }).then(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> botui.message.bot({</span><br><span class="line"> delay: <span class="number">1500</span>,</span><br><span class="line"> content: <span class="string">"目前在从事嵌入式、物联网、硬件方面的工作🐧🐧🐧"</span></span><br><span class="line"> })</span><br><span class="line"> }).then(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> botui.message.bot({</span><br><span class="line"> delay: <span class="number">1500</span>,</span><br><span class="line"> content: <span class="string">"略懂HTML/CSS/JavaScript/Java,专攻C/C++/Python"</span></span><br><span class="line"> })</span><br><span class="line"> }).then(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> botui.message.bot({</span><br><span class="line"> delay: <span class="number">1500</span>,</span><br><span class="line"> content: <span class="string">"日常兴趣:旅行、爬山、美食"</span></span><br><span class="line"> })</span><br><span class="line"> }).then(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> botui.message.bot({</span><br><span class="line"> delay: <span class="number">1500</span>,</span><br><span class="line"> content: <span class="string">"喜欢动手,热爱学习新知识,热爱开源文化,目前正在嵌入式的道路上探索中💪💪💪"</span></span><br><span class="line"> })</span><br><span class="line"> }).then(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> botui.action.button({</span><br><span class="line"> delay: <span class="number">1500</span>,</span><br><span class="line"> action: [{</span><br><span class="line"> text: <span class="string">"为什么叫 kelecn 呢?🤔🤔🤔"</span>,</span><br><span class="line"> value: <span class="string">"next"</span></span><br><span class="line"> }]</span><br><span class="line"> })</span><br><span class="line"> }).then(<span class="function"><span class="keyword">function</span>(<span class="params">res</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> botui.message.bot({</span><br><span class="line"> delay: <span class="number">1500</span>,</span><br><span class="line"> content: <span class="string">"因为很喜欢《刺客伍六七》里可乐这个角色,于是我就沿用了kele下来,嗯!"</span></span><br><span class="line"> })</span><br><span class="line"> }).then(<span class="function"><span class="keyword">function</span> (<span class="params">res</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> botui.message.add({</span><br><span class="line"> delay: <span class="number">1500</span>,</span><br><span class="line"> type: <span class="string">'embed'</span>,</span><br><span class="line"> content: <span class="string">'https://cdn.jsdelivr.net/gh/kelecn/images@master/kele.gif'</span></span><br><span class="line"> });</span><br><span class="line"> }).then(<span class="function"><span class="keyword">function</span>(<span class="params">res</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> botui.message.bot({</span><br><span class="line"> delay: <span class="number">1500</span>,</span><br><span class="line"> content: <span class="string">"emmmmm,至于cn嘛,中国国家顶级域名2333"</span></span><br><span class="line"> })</span><br><span class="line"> }).then(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> botui.action.button({</span><br><span class="line"> delay: <span class="number">1500</span>,</span><br><span class="line"> action: [{</span><br><span class="line"> text: <span class="string">"怎样可以联系你呢?(ง •_•)ง"</span>,</span><br><span class="line"> value: <span class="string">"next"</span></span><br><span class="line"> }]</span><br><span class="line"> })</span><br><span class="line"> }).then(<span class="function"><span class="keyword">function</span>(<span class="params">res</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> botui.message.bot({</span><br><span class="line"> delay: <span class="number">1500</span>,</span><br><span class="line"> content: <span class="string">"博客评论区留言或者是左下角的对话窗口留言都可以联系我哦~"</span></span><br><span class="line"> })</span><br><span class="line"> }).then(<span class="function"><span class="keyword">function</span>(<span class="params">res</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> botui.message.bot({</span><br><span class="line"> delay: <span class="number">1500</span>,</span><br><span class="line"> content: <span class="string">"欢迎联系我交流哦~🤗🤗🤗"</span></span><br><span class="line"> })</span><br><span class="line"> }).then(<span class="function"><span class="keyword">function</span>(<span class="params">res</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> botui.message.bot({</span><br><span class="line"> delay: <span class="number">1500</span>,</span><br><span class="line"> content: <span class="string">"有需要交换友链的朋友,欢迎点击友链页提交哦~😋😋😋"</span></span><br><span class="line"> })</span><br><span class="line"> }).then(<span class="function"><span class="keyword">function</span>(<span class="params">res</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> botui.message.bot({</span><br><span class="line"> delay: <span class="number">1500</span>,</span><br><span class="line"> content: <span class="string">"那么,仔细看看我的博客吧? ^_^"</span></span><br><span class="line"> })</span><br><span class="line"> }).then(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> botui.message.bot({</span><br><span class="line"> delay: <span class="number">3000</span>,</span><br><span class="line"> content: <span class="string">"还有,欢迎关注我的 [GitHub](https://github.com/kelecn)哦 !🤗🤗🤗"</span></span><br><span class="line"> })</span><br><span class="line"> }).then(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> botui.message.bot({</span><br><span class="line"> delay: <span class="number">1500</span>,</span><br><span class="line"> content: <span class="string">" [![GitHub](https://cdn.jsdelivr.net/gh/kelecn/images@master/%E6%82%9F%E7%A9%BA.jpg)](https://github.com/kelecn) "</span></span><br><span class="line"> })</span><br><span class="line"> });</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="四、特别感谢"><a href="#四、特别感谢" class="headerlink" title="四、特别感谢"></a>四、特别感谢</h3><p>特别感谢 <a href="https://github.com/botui/botui">Botui</a> 项目的大力支持,喜欢的朋友,欢迎去其Github点点小星星~</p><div class="tag link"><a class="link-card" title="Botui" href="https://github.com/botui/botui"><div class="left"><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/post301.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/post301.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="right"><p class="text">Botui</p><p class="url">https://github.com/botui/botui</p></div></a></div>]]></content>
<summary type="html">kelecn's Blog,一个记录个人成长的地方。</summary>
<category term="美化" scheme="https://kelecn.top/categories/%E7%BE%8E%E5%8C%96/"/>
<category term="Hexo" scheme="https://kelecn.top/tags/Hexo/"/>
<category term="Volantis" scheme="https://kelecn.top/tags/Volantis/"/>
<category term="Botui" scheme="https://kelecn.top/tags/Botui/"/>
<category term="聊天机器人" scheme="https://kelecn.top/tags/%E8%81%8A%E5%A4%A9%E6%9C%BA%E5%99%A8%E4%BA%BA/"/>
<category term="JavaScript" scheme="https://kelecn.top/tags/JavaScript/"/>
</entry>
<entry>
<title>基于OpenMV的无人驾驶智能小车模拟系统</title>
<link href="https://kelecn.top/posts/51495/"/>
<id>https://kelecn.top/posts/51495/</id>
<published>2021-07-29T09:47:47.000Z</published>
<updated>2021-07-31T08:00:44.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:基于机器视觉模块OpenMV采集车道、红绿灯、交通标志等模拟路况信息,实现一辆能车道保持、红绿灯识别、交通标志识别、安全避障以及远程WiFi控制的多功能无人驾驶小车。</p><a id="more"></a><h2 id="一、项目简介"><a href="#一、项目简介" class="headerlink" title="一、项目简介"></a>一、项目简介</h2><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/post291.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/post291.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><strong>项目地址:</strong><div class="tag link"><a class="link-card" title="OpenMV-autodrive" href="https://github.com/kelecn/OpenMV-autodrive"><div class="left"><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/post291.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/post291.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="right"><p class="text">OpenMV-autodrive</p><p class="url">https://github.com/kelecn/OpenMV-autodrive</p></div></a></div></p><p><strong>编程软件:</strong></p><table><thead><tr><th align="center">硬件模块</th><th align="left">编程软件</th></tr></thead><tbody><tr><td align="center">OpenMV</td><td align="left">使用OpenMV官方的<a href="https://singtown.com/openmv-download/">OpenMV IDE</a></td></tr><tr><td align="center">ESP8266</td><td align="left">使用Arduino官方的<a href="https://www.arduino.cc/en/software">Arduino IDE</a></td></tr><tr><td align="center">STM32</td><td align="left">使用ARM官方的<a href="https://www2.keil.com/mdk5">Keil uVision5</a>(ARM版)</td></tr></tbody></table><p><strong>功能介绍:</strong></p><table><thead><tr><th align="center">硬件模块</th><th align="left">功能实现</th></tr></thead><tbody><tr><td align="center">OpenMV</td><td align="left">主要是利用OpenMV进行路况信息(红绿灯、交通标志、车道)的采取,以及和STM32的通信,具体看OpenMV文件夹。</td></tr><tr><td align="center">ESP8266</td><td align="left">主要是利用ESP8266与手机端进行远程的指令接收和数据交互,以及和STM32的通讯,具体看ESP8266文件夹。</td></tr><tr><td align="center">STM32</td><td align="left">主要是通过ESP8266接收远程控制指令和处理路况信息,并根据这些指令数据进行实时的PID控制小车运动。具体看STM32文件夹。</td></tr></tbody></table> <div class="note quote"><p>欢迎各位去点点小星星哦~</p></div><h2 id="二、硬件系统"><a href="#二、硬件系统" class="headerlink" title="二、硬件系统"></a>二、硬件系统</h2><p>本项目《基于OpenMV的无人驾驶智能小车模拟系统》,主要依靠机器视觉模块OpenMV通过图像处理的方式获取实时的路况信息,以及超声波传感器获取障碍物距离信息,得到的路况数据再通过串口传输到主控器STM32上面,STM32会将实时的路况信息处理成智能小车的运动控制指令,让智能小车实现红绿灯识别、交通标志识别以及车道实时保持的功能,还有STM32也会通过WiFi模块ESP8266与手机端进行路况数据和控制指令的远程交互。硬件系统框图如下:</p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/post292.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/post292.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p>下面简单介绍一下,整个系统用到的硬件模块。</p><table><thead><tr><th align="center">硬件模块</th><th>型号</th></tr></thead><tbody><tr><td align="center">主控器</td><td>STM32F103ZET6(正点原子精英板F103)</td></tr><tr><td align="center">视觉模块</td><td>OpenMV4 H7 PLUS(STM32H750VBT6 +OV7725)</td></tr><tr><td align="center">超声波传感器</td><td>HC-SR04</td></tr><tr><td align="center">WiFi模块</td><td>ESP8266</td></tr><tr><td align="center">执行器</td><td>双路 H 桥电机驱动、直流电机、开发板自带的LED和蜂鸣器</td></tr><tr><td align="center">控制平台</td><td>安装Blinker APP的安卓/苹果手机</td></tr><tr><td align="center">其他</td><td>电源、模型车、导线若干等</td></tr></tbody></table><p>具体的硬件电路连接框图如下:</p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/post293.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/post293.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><h2 id="三、软件系统"><a href="#三、软件系统" class="headerlink" title="三、软件系统"></a>三、软件系统</h2><h4 id="1、OpenMV中的路况识别算法实现"><a href="#1、OpenMV中的路况识别算法实现" class="headerlink" title="1、OpenMV中的路况识别算法实现"></a>1、OpenMV中的路况识别算法实现</h4><p>本项目的主要路况数据信息都是基于OpenMV摄像头获取的图像进行图像处理得到的。要实现智能小车的自动驾驶行为,最起码要让小车识别到红绿灯、交通标志以及车道,后续主控器才能根据这些路况数据信息控制小车的运动。关于机器视觉模块OpenMV,之前我在《<a href="https://kelecn.top/posts/9237/">初探机器视觉模块OpenMV</a>》里面已经介绍过了,这里不再赘述。</p><h5 id="①红绿灯识别"><a href="#①红绿灯识别" class="headerlink" title="①红绿灯识别"></a>①红绿灯识别</h5><p>主要是对摄像头每帧拍摄到的图像进行图像进行阈值处理,再进行判断出现的究竟是哪种红绿灯(红灯、绿灯、黄灯),然后再将这个判定结果和其他两个数据一起打包通过串口发送出去。</p><p><strong>【程序流程图】</strong></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/post294.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/post294.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><strong>【主要程序】</strong></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">###################################开始####################################</span></span><br><span class="line">...</span><br><span class="line">sensor.set_pixformat(sensor.RGB565) <span class="comment"># 图片格式设为 RGB565彩色图</span></span><br><span class="line">light_threshold = [(<span class="number">59</span>, <span class="number">100</span>, <span class="number">26</span>, <span class="number">127</span>, <span class="number">-128</span>, <span class="number">127</span>),(<span class="number">59</span>, <span class="number">100</span>, <span class="number">-128</span>, <span class="number">-40</span>, <span class="number">-128</span>, <span class="number">127</span>)]; <span class="comment">#设置红绿灯阈值,默认为0无红绿灯 1红灯 2绿灯 4黄灯</span></span><br><span class="line">...</span><br><span class="line"><span class="comment">#定义寻找色块面积最大的函数</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">find_max</span>(<span class="params">blobs</span>):</span> </span><br><span class="line"> max_size=<span class="number">0</span></span><br><span class="line"> <span class="keyword">for</span> blob <span class="keyword">in</span> blobs:</span><br><span class="line"> <span class="keyword">if</span> blob.pixels() > max_size:</span><br><span class="line"> max_blob=blob</span><br><span class="line"> max_size = blob.pixels()</span><br><span class="line"><span class="keyword">return</span> max_blob</span><br><span class="line"><span class="comment">#主循环</span></span><br><span class="line"><span class="keyword">while</span>(<span class="literal">True</span>):</span><br><span class="line"> clock.tick() <span class="comment">#追踪两个snapshots()之间经过的毫秒数</span></span><br><span class="line"> img = sensor.snapshot() <span class="comment">#拍一张照片,返回图像</span></span><br><span class="line"> blobs = img.find_blobs(light_threshold,area_threshold=<span class="number">150</span>); <span class="comment">#找到红绿灯</span></span><br><span class="line"> cx=<span class="number">0</span>;cy=<span class="number">0</span>;LED_color=<span class="number">0</span>; <span class="comment">#变量定义</span></span><br><span class="line"> <span class="keyword">if</span> blobs:</span><br><span class="line"> max_b = find_max(blobs); <span class="comment">#如果找到了目标颜色</span></span><br><span class="line"> img.draw_rectangle(max_b[<span class="number">0</span>:<span class="number">4</span>]) <span class="comment">#在Blob周围绘制一个矩形</span></span><br><span class="line"> <span class="comment">#用矩形标记出目标颜色区域</span></span><br><span class="line"> img.draw_cross(max_b[<span class="number">5</span>], max_b[<span class="number">6</span>]) <span class="comment"># cx, cy</span></span><br><span class="line"> img.draw_cross(<span class="number">160</span>, <span class="number">120</span>) <span class="comment"># 在中心点画标记</span></span><br><span class="line"> <span class="comment">#在目标颜色区域的中心画十字形标记</span></span><br><span class="line"> cx=max_b[<span class="number">5</span>];</span><br><span class="line"> cy=max_b[<span class="number">8</span>];</span><br><span class="line"> img.draw_line((<span class="number">160</span>,<span class="number">120</span>,cx,cy), color=(<span class="number">127</span>));</span><br><span class="line"> img.draw_string(cx, cy, <span class="string">"(%d, %d)"</span>%(cx,cy), color=(<span class="number">127</span>));</span><br><span class="line">LED_color=cy; <span class="comment">#红绿灯的阈值是数组里的cy(二进制)个</span></span><br><span class="line">print(LED_color); <span class="comment">#串行终端打印出 红绿灯序号数据</span></span><br><span class="line"><span class="comment">###################################结束####################################</span></span><br></pre></td></tr></table></figure><h5 id="②交通标志识别"><a href="#②交通标志识别" class="headerlink" title="②交通标志识别"></a>②交通标志识别</h5><p>主要是利用NCC(Normalized Cross Correlation)归一化互相关算法来进行交通标志的图像识别与匹配。</p><p><strong>【NCC算法】</strong></p><p>NCC算法的基本实现原理:主要是通过求两幅大小相近的图像的相关系数矩阵来判别两幅图像是否相关。假设需要识别的初始图片$g$的大小为$m×n$,摄像头拍摄到的图片S的大小为$M×N$,其中的以$(x,y)$为左上角点与$g$大小相同的子图像为$S_{(x,y)}$。具体的利用NCC算法实现计算图像相似度的方法如下:</p><p>$\rho{(x,y)}$的定义为:随机变量$X$、$Y$的相关系数</p><p>$$<br>\rho{(x,y)}=\frac{\sigma(S_{x,y},g)}{\sqrt[]{D_{x,y}D}}<br>$$<br> 式中:$\sigma(S_{x,y},g)$是$S_{x,y}$和$g$的协方差;</p><p>$D_{x,y}=\frac {1}{mn}\sum_{i=1}^{m} \sum_{j=1}^{n}{(S_{x,y}(i,j)-\overline S_{x,y})^2}$为$S_{x,y}$的方差;</p><p>$D=\frac {1}{mn}\sum_{i=1}^{m} \sum_{j=1}^{n}{(g(i,j)-\overline g)^2}$为$g$的方差;</p><p>$\overline g$为$g$的灰度均值;</p><p>$\overline S_{x,y}$为$S_{x,y}$的灰度均值;</p><p>将$D_{x,y}$和D代入$\rho{(x,y)}$,会有:</p><p>$$<br>\rho{(x,y)=\frac{ \frac {1}{mn}\sum_{i=1}^{m} \sum_{j=1}^{n}{(S_{x,y}(i,j)-\overline S_{x,y})(g(i,j)-\overline g)}}{\sqrt[]{\frac {1}{mn}\sum_{i=1}^{m} \sum_{j=1}^{n}{(S_{x,y}(i,j)-\overline S_{x,y})^2}}\sqrt[]{\frac {1}{mn}\sum_{i=1}^{m} \sum_{j=1}^{n}{(g(i,j)-\overline g)^2}}}}<br>$$<br>其中,相关系数$\rho{(x,y)}$满足:$\rho{(x,y)\le1}$。</p><p>$\rho{(x,y)}$越接近1,说明两幅图像越接近,也就是大图像的子集中越有可能包含有小图像。通过选取恰当的相关系数,我们就可以认为,相关系数大于该设定值的图像为所需识别的图像,也就是可以实现交通标识的识别。</p><p><strong>【程序流程图】</strong></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/post295.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/post295.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><strong>【主要程序】</strong></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">###################################开始####################################</span></span><br><span class="line">...</span><br><span class="line">sensor.set_pixformat(sensor.GRAYSCALE) <span class="comment">#设置图片格式为灰度图</span></span><br><span class="line"><span class="comment">#导入图片模板</span></span><br><span class="line">template1 = image.Image(<span class="string">"/1.pgm"</span>) <span class="comment">#直行</span></span><br><span class="line">template2 = image.Image(<span class="string">"/2.pgm"</span>) <span class="comment">#向右转弯</span></span><br><span class="line">template3 = image.Image(<span class="string">"/3.pgm"</span>) <span class="comment">#向左转弯</span></span><br><span class="line">template4 = image.Image(<span class="string">"/4.pgm"</span>) <span class="comment">#停车让行</span></span><br><span class="line">template5 = image.Image(<span class="string">"/5.pgm"</span>) <span class="comment">#鸣喇叭</span></span><br><span class="line"><span class="comment">#主循环</span></span><br><span class="line"><span class="keyword">while</span> (<span class="literal">True</span>):</span><br><span class="line"> clock.tick()</span><br><span class="line"> img = sensor.snapshot()</span><br><span class="line"> flag=<span class="number">0</span></span><br><span class="line">ratio=<span class="number">0</span></span><br><span class="line"><span class="comment">#匹配1.pgm(直行)串行终端打印go,flag=1</span></span><br><span class="line"> r1 = img.find_template(template1, <span class="number">0.70</span>, step=<span class="number">4</span>, search=SEARCH_EX)</span><br><span class="line"> <span class="keyword">if</span> r1:</span><br><span class="line"> img.draw_rectangle(r1,color=(<span class="number">255</span>,<span class="number">0</span>,<span class="number">0</span>))</span><br><span class="line"> print(<span class="string">"go"</span>)</span><br><span class="line"> flag=<span class="number">1</span></span><br><span class="line"> img.draw_string(<span class="number">10</span>, <span class="number">10</span>, <span class="string">"%.d"</span>%flag)</span><br><span class="line"><span class="comment">#匹配2.pgm(向右转弯)串行终端打印right,flag=2</span></span><br><span class="line"> r2 = img.find_template(template2, <span class="number">0.70</span>, step=<span class="number">4</span>, search=SEARCH_EX) </span><br><span class="line"> <span class="keyword">if</span> r2:</span><br><span class="line"> img.draw_rectangle(r2,color=(<span class="number">0</span>,<span class="number">255</span>,<span class="number">0</span>))</span><br><span class="line"> print(<span class="string">"right"</span>)</span><br><span class="line"> flag=<span class="number">2</span></span><br><span class="line"> img.draw_string(<span class="number">10</span>, <span class="number">10</span>, <span class="string">"%.d"</span>%flag)</span><br><span class="line"><span class="comment">#匹配3.pgm(向左转弯)串行终端打印left,flag=3</span></span><br><span class="line"> r3 = img.find_template(template3, <span class="number">0.70</span>, step=<span class="number">4</span>, search=SEARCH_EX)</span><br><span class="line"> <span class="keyword">if</span> r3:</span><br><span class="line"> img.draw_rectangle(r3,color=(<span class="number">255</span>,<span class="number">0</span>,<span class="number">0</span>))</span><br><span class="line"> print(<span class="string">"left"</span>)</span><br><span class="line"> flag=<span class="number">3</span></span><br><span class="line"> img.draw_string(<span class="number">10</span>, <span class="number">10</span>, <span class="string">"%.d"</span>%flag)</span><br><span class="line"><span class="comment">#匹配4.pgm(停车让行)串行终端打印stop,flag=4</span></span><br><span class="line"> r4 = img.find_template(template4, <span class="number">0.70</span>, step=<span class="number">4</span>, search=SEARCH_EX) </span><br><span class="line"> <span class="keyword">if</span> r4:</span><br><span class="line"> img.draw_rectangle(r4,color=(<span class="number">255</span>,<span class="number">255</span>,<span class="number">0</span>))</span><br><span class="line"> print(<span class="string">"stop"</span>)</span><br><span class="line"> flag=<span class="number">4</span></span><br><span class="line"> img.draw_string(<span class="number">10</span>, <span class="number">10</span>, <span class="string">"%.d"</span>%flag)</span><br><span class="line"><span class="comment">#匹配5.pgm(鸣喇叭)串行终端打印beep,flag=5</span></span><br><span class="line"> r5 = img.find_template(template5, <span class="number">0.70</span>, step=<span class="number">4</span>, search=SEARCH_EX)</span><br><span class="line"> <span class="keyword">if</span> r5:</span><br><span class="line"> img.draw_rectangle(r5,color=(<span class="number">255</span>,<span class="number">255</span>,<span class="number">0</span>))</span><br><span class="line"> print(<span class="string">"beep"</span>)</span><br><span class="line"> flag=<span class="number">5</span></span><br><span class="line"> img.draw_string(<span class="number">10</span>, <span class="number">10</span>, <span class="string">"%.d"</span>%flag)</span><br><span class="line"><span class="comment">###################################结束####################################</span></span><br></pre></td></tr></table></figure><h5 id="③车道识别"><a href="#③车道识别" class="headerlink" title="③车道识别"></a>③车道识别</h5><p> 主要通过OpenMV模块,识别并跟踪车道阈值,通过几何运算出小车与车道中线的角度(偏左为正、偏右为负),反馈出小车与车道的真实偏离情况(可量化),后续用于PID控制。</p><p><strong>【程序流程图】</strong></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/post296.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/post296.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><strong>【主要程序】</strong></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">###################################开始####################################</span></span><br><span class="line">...</span><br><span class="line">sensor.set_pixformat(sensor.RGB565) <span class="comment"># 图片格式设为 RGB565彩色图</span></span><br><span class="line">road_threshold = [(<span class="number">23</span>, <span class="number">0</span>, <span class="number">-45</span>, <span class="number">19</span>, <span class="number">-31</span>, <span class="number">28</span>)]; <span class="comment">#黑线道路</span></span><br><span class="line">ROI = (<span class="number">0</span>, <span class="number">100</span>, <span class="number">320</span>, <span class="number">40</span>)</span><br><span class="line">...</span><br><span class="line"><span class="comment">#省略了识别车道边框函数</span></span><br><span class="line"><span class="comment">#偏移角度计算算法</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_direction</span>(<span class="params">left_blob, right_blob</span>):</span></span><br><span class="line"> <span class="comment"># 根据图像中的三块左中右的白色部分,计算出摄像头偏转角度</span></span><br><span class="line"> <span class="comment"># ratio < 0 左拐,小车在车道偏右位置</span></span><br><span class="line"> <span class="comment"># ratio > 0 右拐,小车在车道偏左位置</span></span><br><span class="line"></span><br><span class="line"> MAX_WIDTH = <span class="number">320</span></span><br><span class="line"> <span class="comment"># 调节theta来设置中间宽度的比重, theta越高ratio越靠近0</span></span><br><span class="line"> <span class="comment"># 需要根据赛道宽度与摄像头高度重新设定到合适大小</span></span><br><span class="line"> theta = <span class="number">0.01</span></span><br><span class="line"> <span class="comment"># 这里的b是为了防止除数是0的情况发生, 设定一个小一点的值</span></span><br><span class="line"> b = <span class="number">3</span></span><br><span class="line"> x1 = left_blob.x() - int(<span class="number">0.5</span> * left_blob.w()) <span class="comment">#左边黑线中心x值</span></span><br><span class="line"> x2 = right_blob.x() + int(<span class="number">0.5</span> * right_blob.w()) <span class="comment">#右边黑线中心x值</span></span><br><span class="line"><span class="comment">#车道信息计算</span></span><br><span class="line"> w_left = x1 <span class="comment">#左边车道外宽度</span></span><br><span class="line"> w_center = math.fabs(x2 - x1) <span class="comment">#车道中心x值</span></span><br><span class="line"> w_right = math.fabs(MAX_WIDTH - x2) <span class="comment">#右边车道外宽度</span></span><br><span class="line"><span class="comment">#计算摄像头偏移角度</span></span><br><span class="line"> direct_ratio = (w_left + b + theta * w_center) / (w_left + w_right + <span class="number">2</span> * b + <span class="number">2</span> * theta * w_center) - <span class="number">0.5</span></span><br><span class="line"><span class="comment">#返回摄像头偏移角度</span></span><br><span class="line"><span class="keyword">return</span> direct_ratio</span><br><span class="line"><span class="comment">#省略了可视化绘图函数</span></span><br><span class="line">...</span><br><span class="line"><span class="keyword">while</span>(<span class="literal">True</span>): <span class="comment">#主循环</span></span><br><span class="line">clock.tick() <span class="comment">#追踪两个snapshots()之间经过的毫秒数</span></span><br><span class="line"> img = sensor.snapshot() <span class="comment">#拍一张照片,返回图像</span></span><br><span class="line"> blobs = img.find_blobs(road_threshold, roi=ROI, merge=<span class="literal">True</span>);</span><br><span class="line"> a=<span class="number">0</span>;ratio=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">if</span> blobs:</span><br><span class="line"> left_blob, right_blob = get_top2_blobs(blobs)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span>(left_blob == <span class="literal">None</span> <span class="keyword">or</span> right_blob == <span class="literal">None</span>):</span><br><span class="line"> print(<span class="string">"Out Of Range"</span>)</span><br><span class="line"> <span class="keyword">continue</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"><span class="comment">#画出车道左边线</span></span><br><span class="line"> img.draw_rectangle(left_blob.rect())</span><br><span class="line"> img.draw_cross(left_blob.cx(), left_blob.cy())</span><br><span class="line"><span class="comment">#画出车道右边线</span></span><br><span class="line"> img.draw_rectangle(right_blob.rect())</span><br><span class="line"> img.draw_cross(right_blob.cx(), right_blob.cy())</span><br><span class="line"><span class="comment">#可视化显示偏转角度</span></span><br><span class="line"> direct_ratio = get_direction(left_blob, right_blob)</span><br><span class="line"> draw_direct(img,direct_ratio)</span><br><span class="line"> ratio=int(math.degrees(direct_ratio)) <span class="comment">#偏转角度转成弧度值</span></span><br><span class="line"> img.draw_string(<span class="number">10</span>, <span class="number">10</span>, <span class="string">"%.d"</span>%ratio) <span class="comment">#帧缓冲区实时画出偏转角度</span></span><br><span class="line"> print(ratio) <span class="comment">#串行终端打印偏转角度</span></span><br><span class="line"> img.draw_rectangle(ROI,color=(<span class="number">255</span>, <span class="number">0</span>, <span class="number">0</span>)) <span class="comment">#画出感兴趣区域</span></span><br><span class="line"><span class="comment">###################################结束####################################</span></span><br></pre></td></tr></table></figure><h4 id="2、基于ESP8266的远程控制平台实现"><a href="#2、基于ESP8266的远程控制平台实现" class="headerlink" title="2、基于ESP8266的远程控制平台实现"></a>2、基于ESP8266的远程控制平台实现</h4><p>主要是利用点灯科技-<a href="https://diandeng.tech/home">Blinker</a>物联网平台搭建控制APP的UI界面,以及调用Blinker的控制代码,实现智能小车控制指令的下发与路况数据的上传。</p><p><strong>【远程控制平台UI界面】</strong></p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/post297.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/post297.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII=" style="zoom: 25%;" /><p><strong>【UI配置代码】</strong></p><p>直接使用 <a href="https://www.diandeng.tech/home">点灯.blinker</a> APP导入配置代码即可获得和我一样的UI布局。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">{¨config¨{¨headerColor¨¨transparent¨¨headerStyle¨¨dark¨¨background¨{¨img¨¨assets/img/headerbg.jpg¨¨isFull¨«}}¨dashboard¨|{¨type¨¨btn¨¨ico¨¨fad fa-arrow-alt-up¨¨mode¨É¨t0¨¨前进¨¨t1¨¨文本2¨¨bg¨Ì¨cols¨Ë¨rows¨Ë¨key¨¨btn-go¨´x´Ì´y´Ï¨speech¨|÷¨clr¨¨#076EEF¨}{ßAßBßC¨fad fa-arrow-alt-down¨ßEÉßF¨后退¨ßHßIßJÌßKËßLËßM¨btn-back¨´x´Ì´y´¤CßO|÷ßPßQ¨lstyle¨É}{ßAßBßC¨fad fa-arrow-alt-right¨ßEÉßF¨右转¨ßHßIßJÌßKËßLËßM¨btn-right¨´x´Ï´y´ÒßO|÷ßPßQßUÉ}{ßAßBßC¨fad fa-arrow-alt-left¨ßEÉßF¨左转¨ßHßIßJÌßKËßLËßM¨btn-left¨´x´É´y´ÒßO|÷ßPßQßUÉ}{ßAßBßC¨fad fa-power-off¨ßEÉßF¨停车¨ßHßIßJÌßKËßLËßM¨btn-stoping¨´x´Ï´y´ÏßO|÷ßPßQßUÉ}{ßA¨tex¨ßF¨😋小车远程监控系统😋¨ßH´´ßJËßC´´ßKÍßLÊßM´´´x´Ë´y´ËßO|÷ßPßQßUÊ}{ßA¨num¨ßF¨障碍物距离¨ßC¨fad fa-route¨ßPßQ¨min¨É¨max¨¢1c¨uni¨¨cm¨ßJÉßKÍßLËßM¨num-distance¨´x´É´y´¤EßO|÷ßUÊ}{ßAßgßF¨小车偏移角度¨ßC¨fad fa-tachometer-alt-fast¨ßPßQßjÉßkº0ßl´º´ßJÉßKÍßLËßM¨num-angle¨´x´Í´y´¤EßO|÷ßUÊ}{ßAßgßF¨红绿灯(红1绿2)¨ßC¨fad fa-siren-on¨ßPßQßjÉßkËßl´´ßJÉßKËßLËßM¨num-led¨´x´É´y´ÏßO|÷ßUÉ}{ßA¨deb¨ßEÉßJÉßKÑßLÌßM¨debug¨´x´É´y´ÌßO|÷ßUÉ}{ßAßgßF¨WIFI信号¨ßC¨fad fa-signal-4¨ßP¨#389BEE¨ßjÉßkº0ßl¨dbm¨ßJÉßKËßLËßM¨num-wifi¨´x´Ï´y´ÉßO|÷ßUÉ}{ßAßBßC¨fad fa-repeat-alt¨ßEÊßF¨自动驾驶模式¨ßHßIßJËßKËßLËßM¨btn-auto¨´x´Ì´y´ÒßO|÷ßPßQßUÉ}÷¨actions¨|¦¨cmd¨¦¨switch¨‡¨text¨‡´on´¨打开?name¨¨off¨¨关闭?name¨—÷¨triggers¨|{¨source¨ß16¨source_zh¨¨开关状态¨¨state¨|´on´ß19÷¨state_zh¨|´打开´´关闭´÷}÷}</span><br></pre></td></tr></table></figure><p><strong>【控制指令与监控数据】</strong></p><table><thead><tr><th>名称</th><th>功能按钮/数据接收框的功能</th><th>数据键名</th><th>指令</th></tr></thead><tbody><tr><td>WiFi信号</td><td>接收WiFi信号数据</td><td>num-wifi</td><td>—</td></tr><tr><td>红绿灯数据</td><td>接收红绿灯数据(无0,红1,绿2)</td><td>num-led</td><td>—</td></tr><tr><td>小车偏移角度</td><td>接收小车偏移角度</td><td>num-angle</td><td>—</td></tr><tr><td>障碍物距离</td><td>接收障碍物距离数据</td><td>num-distance</td><td>—</td></tr><tr><td>停车</td><td>发出停车指令</td><td>btn-stoping</td><td>0</td></tr><tr><td>前进</td><td>发出前进指令</td><td>btn-go</td><td>1</td></tr><tr><td>右转</td><td>发出右转指令</td><td>btn-right</td><td>2</td></tr><tr><td>左转</td><td>发出左转指令</td><td>btn-left</td><td>3</td></tr><tr><td>后退</td><td>发出后退指令</td><td>btn-back</td><td>4</td></tr><tr><td>自动驾驶</td><td>发出自动驾驶指令</td><td>btn-auto</td><td>5</td></tr><tr><td>Debug</td><td>显示收发数据的原始数据格式</td><td>—</td><td>—</td></tr></tbody></table><p><strong>【程序流程图】</strong></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/post298.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/post298.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><strong>【主要程序】</strong></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/***********************************开始***********************************/</span></span><br><span class="line">...</span><br><span class="line"><span class="keyword">int</span> flag= <span class="number">0</span>; <span class="comment">//按键标志位</span></span><br><span class="line"><span class="keyword">int</span> l= <span class="number">0</span>; <span class="comment">//红绿灯数据</span></span><br><span class="line"><span class="keyword">int</span> a= <span class="number">0</span>; <span class="comment">//角度数据</span></span><br><span class="line"><span class="keyword">int</span> d= <span class="number">0</span>; <span class="comment">//距离数据</span></span><br><span class="line"><span class="keyword">int</span> z= <span class="number">0</span>; <span class="comment">//json解析出来的数据</span></span><br><span class="line"><span class="function">BlinkerNumber <span class="title">Number0</span><span class="params">(<span class="string">"num-wifi"</span>)</span></span>;<span class="comment">//WIFI信号</span></span><br><span class="line"><span class="function">BlinkerNumber <span class="title">Number1</span><span class="params">(<span class="string">"num-led"</span>)</span></span>;<span class="comment">//红绿灯信号</span></span><br><span class="line"><span class="function">BlinkerNumber <span class="title">Number2</span><span class="params">(<span class="string">"num-angle"</span>)</span></span>;<span class="comment">//角度信号</span></span><br><span class="line"><span class="function">BlinkerNumber <span class="title">Number3</span><span class="params">(<span class="string">"num-distance"</span>)</span></span>;<span class="comment">//距离信号</span></span><br><span class="line"><span class="function">BlinkerButton <span class="title">Button0</span><span class="params">(<span class="string">"btn-stoping"</span>)</span></span>;<span class="comment">//停止状态按键</span></span><br><span class="line"><span class="function">BlinkerButton <span class="title">Button1</span><span class="params">(<span class="string">"btn-go"</span>)</span></span>;<span class="comment">//前进状态按键</span></span><br><span class="line"><span class="function">BlinkerButton <span class="title">Button2</span><span class="params">(<span class="string">"btn-right"</span>)</span></span>;<span class="comment">//右转状态按键</span></span><br><span class="line"><span class="function">BlinkerButton <span class="title">Button3</span><span class="params">(<span class="string">"btn-left"</span>)</span></span>;<span class="comment">//左转状态按键</span></span><br><span class="line"><span class="function">BlinkerButton <span class="title">Button4</span><span class="params">(<span class="string">"btn-back"</span>)</span></span>;<span class="comment">//后退状态按键</span></span><br><span class="line"><span class="function">BlinkerButton <span class="title">Button5</span><span class="params">(<span class="string">"btn-auto"</span>)</span></span>;<span class="comment">//自动驾驶状态按键</span></span><br><span class="line">...</span><br><span class="line"><span class="comment">/*主循环*/</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">loop</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> Blinker.run();</span><br><span class="line"> Number0.print(WiFi.RSSI()); <span class="comment">//发送信号强度</span></span><br><span class="line"> usartEvent();<span class="comment">//串口中断</span></span><br><span class="line"> l=<span class="keyword">int</span>(z/<span class="number">10000</span>); <span class="comment">//解析红绿灯数据</span></span><br><span class="line"> a=<span class="keyword">int</span>((z<span class="number">-10000</span>*l)/<span class="number">100</span>); <span class="comment">//解析偏移角度数据</span></span><br><span class="line">d=<span class="keyword">int</span>(z<span class="number">-10000</span>*l<span class="number">-100</span>*a); <span class="comment">//解析距离数据</span></span><br><span class="line"> Number1.print(l); <span class="comment">//发送红绿灯信号</span></span><br><span class="line"> Number2.print(a); <span class="comment">//发送角度信号</span></span><br><span class="line"> Number3.print(d); <span class="comment">//发送距离信号</span></span><br><span class="line"><span class="comment">//发送控制指令,灯的亮灭,主要是检查WiFi模块是否接收到数据</span></span><br><span class="line"> <span class="keyword">if</span>(oState == <span class="literal">false</span> && digitalRead(LED_BUILTIN)== LOW)<span class="comment">//灯灭</span></span><br><span class="line"> {</span><br><span class="line"> digitalWrite(LED_BUILTIN,HIGH);<span class="comment">//灯灭</span></span><br><span class="line"> Serial.print(flag); <span class="comment">//发送指令</span></span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span>(oState == <span class="literal">true</span> && digitalRead(LED_BUILTIN)== HIGH)<span class="comment">//灯亮</span></span><br><span class="line"> {</span><br><span class="line"> digitalWrite(LED_BUILTIN,LOW);<span class="comment">//灯亮</span></span><br><span class="line"> Serial.print(flag); <span class="comment">//发送指令</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="comment">//Blinker初始化略</span></span><br><span class="line"><span class="comment">//WiFi连接信号检测略</span></span><br><span class="line"><span class="comment">//STM32数据上传解析略</span></span><br><span class="line">...</span><br><span class="line"><span class="comment">/***********************************结束***********************************/</span></span><br></pre></td></tr></table></figure><h4 id="3、智能小车的无人控制方案实现"><a href="#3、智能小车的无人控制方案实现" class="headerlink" title="3、智能小车的无人控制方案实现"></a>3、智能小车的无人控制方案实现</h4><p>智能小车在接收到ESP8266的控制指令和OpenMV路况数据,会根据这些指令数据进行小车运动的控制。</p><p><strong>【程序流程图】</strong></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/post299.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/post299.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><strong>【PID控制算法】</strong></p><p>关于直流电机的PID调节,主要用来实现车道保持功能。通过OpenMV返回的偏转角度,进行实时调节电机PWM输出,使得偏转角度$Y=50$(也就是小车与中线的偏转角为0,由于之前为了传输方便整体加上了50)。故将设定值定为50,通过实时返回的$Y$值与50做差值运算,得到PID的输入偏差,通过位置式PID返回实时的PWM值。关于<a href="https://kelecn.top/posts/16358/">PID控制算法</a>,之前也有介绍到,这里不再深入赘述。<br>$$<br>PWM=K_P\theta(t)+K_i\sum_{t=0}\theta(t)+K_d[\theta(t)-\theta(t-1)]<br>$$<br>其中为$\theta(t)$是本次OpenMV返回的偏移角度数据$Y$与50的差值,$\theta(t-1)$为上一个$Y$与50的差值。</p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/post299-1.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/post299-1.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p> <strong>【模拟环境】</strong></p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/post299-2.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/post299-2.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII=" style="zoom: 33%;" /><p><strong>【主要程序】</strong></p><div class="tag link"><a class="link-card" title="OpenMV-autodrive" href="https://github.com/kelecn/OpenMV-autodrive"><div class="left"><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/post291.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/post291.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="right"><p class="text">OpenMV-autodrive</p><p class="url">https://github.com/kelecn/OpenMV-autodrive</p></div></a></div>]]></content>
<summary type="html">kelecn's Blog,一个记录个人成长的地方。</summary>
<category term="技术" scheme="https://kelecn.top/categories/%E6%8A%80%E6%9C%AF/"/>
<category term="嵌入式" scheme="https://kelecn.top/tags/%E5%B5%8C%E5%85%A5%E5%BC%8F/"/>
<category term="OpenMV" scheme="https://kelecn.top/tags/OpenMV/"/>
<category term="机器视觉" scheme="https://kelecn.top/tags/%E6%9C%BA%E5%99%A8%E8%A7%86%E8%A7%89/"/>
<category term="ESP8266" scheme="https://kelecn.top/tags/ESP8266/"/>
<category term="STM32" scheme="https://kelecn.top/tags/STM32/"/>
</entry>
<entry>
<title>基于ESP8266的局域网图片刷新显示系统</title>
<link href="https://kelecn.top/posts/44882/"/>
<id>https://kelecn.top/posts/44882/</id>
<published>2021-04-29T09:47:47.000Z</published>
<updated>2021-05-03T11:39:50.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:简单的说就是通过网页将图片上传至NodeMCU(ESP8266)的flash闪存,再将图片数据通过SPI更新至TFT-LCD显示屏进行显示。</p><a id="more"></a><p><strong>项目地址:</strong><div class="tag link"><a class="link-card" title="ESP8266-refresh-image-display" href="https://github.com/kelecn/ESP8266-refresh-image-display"><div class="left"><img src="https://7.dusays.com/2021/04/30/623386b314664.png" class="lazyload" data-srcset="https://7.dusays.com/2021/04/30/623386b314664.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="right"><p class="text">ESP8266-refresh-image-display</p><p class="url">https://github.com/kelecn/ESP8266-refresh-image-display</p></div></a></div><br> <div class="note quote"><p>欢迎各位去点点小星星哦~</p></div></p><h3 id="一、硬件系统"><a href="#一、硬件系统" class="headerlink" title="一、硬件系统"></a>一、硬件系统</h3><hr><p>硬件主要用到NodeMCU(ESP8266)和1.44寸TFT彩色液晶屏,<a href="https://item.taobao.com/item.htm?spm=a230r.1.14.1.4909234fdyizrn&id=531755241333&ns=1&abbucket=0#detail">淘宝</a>都有得卖,也不贵。</p><table><thead><tr><th align="center">硬件</th><th align="center">型号</th><th align="center">价格</th></tr></thead><tbody><tr><td align="center">WiFi模块</td><td align="center">NodeMCU(ESP8266)</td><td align="center">十几到二十不等</td></tr><tr><td align="center">显示屏</td><td align="center">1.44寸TFT-LCD液晶屏(SKU:MAR1442)</td><td align="center">十几到二十不等</td></tr><tr><td align="center">排线</td><td align="center">母对母</td><td align="center">一两块</td></tr></tbody></table><ul><li>NodeMCU(ESP8266)IO口介绍:</li></ul><p><img src="https://7.dusays.com/2021/05/03/6fc70dbf34c98.png" class="lazyload" data-srcset="https://7.dusays.com/2021/05/03/6fc70dbf34c98.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><ul><li>1.44寸TFT-LCD液晶屏IO口介绍:</li></ul><table><thead><tr><th align="center">标号</th><th align="center">PIN</th><th align="center">ESP8266开发板对应的接线引脚</th><th align="center">引脚说明</th></tr></thead><tbody><tr><td align="center">1</td><td align="center">VCC</td><td align="center">3V</td><td align="center">电源正</td></tr><tr><td align="center">2</td><td align="center">GND</td><td align="center">G</td><td align="center">电源地</td></tr><tr><td align="center">3</td><td align="center">GND</td><td align="center">-</td><td align="center">电源地</td></tr><tr><td align="center">4</td><td align="center">NC</td><td align="center">-</td><td align="center">无定义,保留,不需要接线</td></tr><tr><td align="center">5</td><td align="center">NC</td><td align="center">-</td><td align="center">无定义,保留,不需要接线</td></tr><tr><td align="center">6</td><td align="center">LED</td><td align="center">3V</td><td align="center">LCD背光控制信号(如不需要控制,请接3.3V)</td></tr><tr><td align="center">7</td><td align="center">CLK</td><td align="center">D5</td><td align="center">LCD SPI总线时钟引脚</td></tr><tr><td align="center">8</td><td align="center">SDI</td><td align="center">D7</td><td align="center">LCD SPI总线数据引脚</td></tr><tr><td align="center">9</td><td align="center">RS</td><td align="center">D1</td><td align="center">LCD寄存器/数据选择控制引脚</td></tr><tr><td align="center">10</td><td align="center">RST</td><td align="center">D2</td><td align="center">LCD复位控制引脚</td></tr><tr><td align="center">11</td><td align="center">CS</td><td align="center">D8</td><td align="center">LCD片选控制引脚</td></tr></tbody></table><ul><li>NodeMCU(ESP8266)与1.44TFT-LCD显示屏接线图:</li></ul><p><img src="https://7.dusays.com/2021/05/01/0150e73282eec.png" class="lazyload" data-srcset="https://7.dusays.com/2021/05/01/0150e73282eec.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><h3 id="二、软件系统"><a href="#二、软件系统" class="headerlink" title="二、软件系统"></a>二、软件系统</h3><hr><p><strong>1、开发环境搭建</strong></p><ol><li><p>NodeMCU硬件通过USB连接电脑,需提前安装好CH340USB<a href="http://www.wch.cn/downloads/CH341SER_EXE.html">串口驱动</a>。</p></li><li><p>电脑端提前安装好<a href="https://www.arduino.cc/en/software">Arduino</a>开发平台。</p></li><li><p>安装ESP8266开发板:打开Arduino IDE点击菜单栏的【文件】-【首选项】,添加【附加开发板管理器】网站:<a href="https://arduino.esp8266.com/stable/package_esp8266com_index.json">https://arduino.esp8266.com/stable/package_esp8266com_index.json</a> 。</p><p><img src="https://7.dusays.com/2021/05/01/1ab6a2dc11779.png" class="lazyload" data-srcset="https://7.dusays.com/2021/05/01/1ab6a2dc11779.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p>然后点击【工具】->【开发板】->【开发板管理器】,搜索 <code>esp8266</code> 后安装。</p><p><img src="https://7.dusays.com/2021/05/01/bfdbdb8c8e2b3.png" class="lazyload" data-srcset="https://7.dusays.com/2021/05/01/bfdbdb8c8e2b3.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p></li><li><p>安装第三方显示屏支持库:将文件夹(Adafruit_ST7735_Library、Adafruit-GFX-Library)移动到Arduino安装目录下的libraries文件夹中,重启Arduino IDE,即可,也就是编程环境搭建完毕。</p></li><li><p>可选择性安装mDNS服务,安装后,可在浏览器输入域名(host.local)实现访问ESP8266的Web页面,若不安装mDNS服务则通过访问ESP8266实际分配的IP地址实现Web访问。</p><ul><li>Mac OS:默认自带mDNS</li><li>Windows:需安装<a href="https://support.apple.com/kb/DL999?viewlocale=en_US&locale=en_US">Bonjour</a></li><li>Linux:需安装<a href="http://avahi.org/">avahi</a></li></ul></li></ol><p><strong>2、软件程序</strong></p><p>软件实现通过网页将图片上传至NodeMCU(ESP8266),并将图片更新至TFT-LCD显示屏。主要的程序流程图如下:</p><img src="https://7.dusays.com/2021/05/01/73e40087635a5.png" class="lazyload" data-srcset="https://7.dusays.com/2021/05/01/73e40087635a5.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII=" style="zoom: 33%;" width="auto" height="auto" align="middle" /><h3 id="三、效果演示"><a href="#三、效果演示" class="headerlink" title="三、效果演示"></a>三、效果演示</h3><hr><p><strong>1、配网</strong></p><p>配置WiFi或热点的名称和密码、设定mDNS地址。</p><img src="https://7.dusays.com/2021/05/01/a9bc9ef1671d8.png" class="lazyload" data-srcset="https://7.dusays.com/2021/05/01/a9bc9ef1671d8.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII=" style="zoom: 33%;" /><p><strong>2、程序下载</strong></p><p>将下载程序到开发版,待ESP8266与电脑连接上同一个WiFi(或者是电脑开的热点),就可以从串口监视器看到IP地址。</p><img src="https://7.dusays.com/2021/05/01/89ac6760a38fe.png" class="lazyload" data-srcset="https://7.dusays.com/2021/05/01/89ac6760a38fe.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII=" style="zoom:;" /><p>若是使用手机热点,也可以通过<a href="https://cdn.jsdelivr.net/gh/kelecn/ESP8266-refresh-image-display@master/IP%E6%9F%A5%E8%AF%A2%E8%BD%AF%E4%BB%B6/%E7%BB%88%E7%AB%AF%E6%A8%A1%E6%8B%9F%E5%99%A8_1.0.70.apk">终端模拟器</a>应用终端输入<code>ip neigh</code>进行查看连接到手机热点的设备IP地址。</p><p><strong>3、图片上传</strong></p><p>访问该IP地址即可,访问图片上传Web页面,选择图片上传即可。</p><p><img src="https://7.dusays.com/2021/05/01/deb2e1cbaed96.png" class="lazyload" data-srcset="https://7.dusays.com/2021/05/01/deb2e1cbaed96.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><strong>4、显示效果</strong></p><table><thead><tr><th align="center"><img src="https://7.dusays.com/2021/05/01/67b682e9ada8f.jpg" class="lazyload" data-srcset="https://7.dusays.com/2021/05/01/67b682e9ada8f.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII=" style="zoom: 25%;" /></th><th align="center"><img src="https://7.dusays.com/2021/05/01/79a3e8fbcbb4c.jpg" class="lazyload" data-srcset="https://7.dusays.com/2021/05/01/79a3e8fbcbb4c.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII=" style="zoom:25%;" /></th></tr></thead><tbody><tr><td align="center"><img src="https://7.dusays.com/2021/05/01/035c4c302e6b3.jpg" class="lazyload" data-srcset="https://7.dusays.com/2021/05/01/035c4c302e6b3.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII=" style="zoom:25%;" /></td><td align="center"><img src="https://7.dusays.com/2021/05/01/6c451a1e4ae45.jpg" class="lazyload" data-srcset="https://7.dusays.com/2021/05/01/6c451a1e4ae45.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII=" style="zoom:25%;" /></td></tr></tbody></table><h3 id="四、参考资料"><a href="#四、参考资料" class="headerlink" title="四、参考资料"></a>四、参考资料</h3><hr><p>1、<a href="https://www.arduino.cn/thread-42247-1-1.html">ESP8266 TFT(ST7735)彩屏-web刷图</a> </p><p>2、<a href="https://www.bilibili.com/video/BV1Jc411h767">ESP8266网络应用5 - 设置mdns</a></p>]]></content>
<summary type="html">kelecn's Blog,一个记录个人成长的地方。</summary>
<category term="技术" scheme="https://kelecn.top/categories/%E6%8A%80%E6%9C%AF/"/>
<category term="嵌入式" scheme="https://kelecn.top/tags/%E5%B5%8C%E5%85%A5%E5%BC%8F/"/>
<category term="ESP8266" scheme="https://kelecn.top/tags/ESP8266/"/>
<category term="NodeMCU" scheme="https://kelecn.top/tags/NodeMCU/"/>
<category term="Web" scheme="https://kelecn.top/tags/Web/"/>
</entry>
<entry>
<title>内置壁纸系列:持续更新中...</title>
<link href="https://kelecn.top/posts/21388/"/>
<id>https://kelecn.top/posts/21388/</id>
<published>2021-02-25T09:43:43.000Z</published>
<updated>2021-04-27T08:57:18.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:本系列主要分享各种内置壁纸,包括但不限于:苹果(Apple)、安卓(Android)、谷歌(Google)、三星(Samsung)、华为(Huawei)、小米(Xiaomi)、OPPO、VIVO、一加(OnePlus)、魅族(Meizu)、联想(Lenovo)、中兴(ZTE)、摩托罗拉(Motorola)、索尼(Sony)、诺基亚(Nokia)、美图(Meitu)、LG、HTC、Elephone等等……</p><a id="more"></a><p><svg t="1616338619486" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1636" width="256" height="256"><path d="M170.24 138.24l538.88 227.84c15.36 6.4 24.32 20.48 24.32 37.12v453.12c0 21.76-17.92 39.68-39.68 39.68-5.12 0-10.24-1.28-15.36-2.56L139.52 665.6c-14.08-6.4-24.32-21.76-24.32-37.12V175.36c0-21.76 17.92-39.68 39.68-39.68 5.12 0 11.52 1.28 15.36 2.56z" fill="#2453EF" p-id="1637"></path><path d="M282.88 128l576 25.6c21.76 1.28 38.4 17.92 38.4 39.68v441.6c0 33.28-26.88 60.16-60.16 60.16h-39.68c-11.52 0-20.48-8.96-20.48-20.48V349.44l-458.24-192-38.4-15.36c-3.84-1.28-5.12-5.12-3.84-8.96 0-2.56 2.56-5.12 6.4-5.12z" fill="#C7EDFE" p-id="1638"></path><path d="M734.72 665.6v192c0 21.76-16.64 38.4-38.4 38.4-5.12 0-10.24-1.28-15.36-2.56L140.8 665.6h593.92z" fill="#57B4FD" p-id="1639"></path></svg></p><div class="note quote"><p>愿你美化半生,归来仍是内置壁纸!</p></div><p><strong>项目地址:</strong><div class="tag link"><a class="link-card" title="Built-in-wallpaper" href="https://github.com/kelecn/Built-in-wallpaper"><div class="left"><img src="https://7.dusays.com/2021/03/21/1fe39a1e95054.png" class="lazyload" data-srcset="https://7.dusays.com/2021/03/21/1fe39a1e95054.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="right"><p class="text">Built-in-wallpaper</p><p class="url">https://github.com/kelecn/Built-in-wallpaper</p></div></a></div><br> <div class="note quote"><p>喜欢内置壁纸的小伙伴,欢迎去点点小星星哦~</p></div></p><h3 id="DONE"><a href="#DONE" class="headerlink" title="DONE"></a>DONE</h3><hr><div class="site-card-group"><a class="site-card" href="/wallpaper/Apple/"><div class="img"><img src="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/Apple/Apple123.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/Apple/Apple123.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="info"><img src="https://7.dusays.com/2021/04/02/f4a2c8407570d.png" class="lazyload" data-srcset="https://7.dusays.com/2021/04/02/f4a2c8407570d.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/><span class="title">苹果</span></div></a><a class="site-card" href="/wallpaper/Google/"><div class="img"><img src="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/Google/Google27.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/Google/Google27.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="info"><img src="https://7.dusays.com/2021/04/02/b3277cca03839.png" class="lazyload" data-srcset="https://7.dusays.com/2021/04/02/b3277cca03839.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/><span class="title">谷歌</span></div></a><a class="site-card" href="/wallpaper/Android/"><div class="img"><img src="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/Android/Android16.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/Android/Android16.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="info"><img src="https://7.dusays.com/2021/04/02/1fa7e399ca16f.png" class="lazyload" data-srcset="https://7.dusays.com/2021/04/02/1fa7e399ca16f.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/><span class="title">安卓</span></div></a><a class="site-card" href="/wallpaper/Huawei/"><div class="img"><img src="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/Huawei/Huawei603.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/Huawei/Huawei603.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="info"><img src="https://7.dusays.com/2021/04/02/dedc8d769a16c.png" class="lazyload" data-srcset="https://7.dusays.com/2021/04/02/dedc8d769a16c.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/><span class="title">华为</span></div></a><a class="site-card" href="/wallpaper/Xiaomi/"><div class="img"><img src="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/Xiaomi/Xiaomi88.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/Xiaomi/Xiaomi88.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="info"><img src="https://7.dusays.com/2021/04/02/24bcf2960549e.png" class="lazyload" data-srcset="https://7.dusays.com/2021/04/02/24bcf2960549e.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/><span class="title">小米</span></div></a><a class="site-card" href="/wallpaper/Samsung/"><div class="img"><img src="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/Samsung/Samsung174.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/Samsung/Samsung174.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="info"><img src="https://7.dusays.com/2021/04/05/1fbff16e30ae9.png" class="lazyload" data-srcset="https://7.dusays.com/2021/04/05/1fbff16e30ae9.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/><span class="title">Samsung</span></div></a><a class="site-card" href="/wallpaper/OPPO/"><div class="img"><img src="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/OPPO/OPPO7.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/OPPO/OPPO7.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="info"><img src="https://7.dusays.com/2021/04/05/6f012d93fc1b8.png" class="lazyload" data-srcset="https://7.dusays.com/2021/04/05/6f012d93fc1b8.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/><span class="title">OPPO</span></div></a><a class="site-card" href="/wallpaper/VIVO/"><div class="img"><img src="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/VIVO/VIVO127.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/VIVO/VIVO127.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="info"><img src="https://7.dusays.com/2021/04/05/03db9077118da.png" class="lazyload" data-srcset="https://7.dusays.com/2021/04/05/03db9077118da.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/><span class="title">VIVO</span></div></a><a class="site-card" href="/wallpaper/OnePlus/"><div class="img"><img src="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/OnePlus/OnePlus14.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/OnePlus/OnePlus14.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="info"><img src="https://7.dusays.com/2021/04/05/4a7db488d970b.png" class="lazyload" data-srcset="https://7.dusays.com/2021/04/05/4a7db488d970b.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/><span class="title">一加</span></div></a><a class="site-card" href="/wallpaper/Meizu/"><div class="img"><img src="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/Meizu/Meizu40.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/Meizu/Meizu40.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="info"><img src="https://7.dusays.com/2021/04/03/297503263fa90.png" class="lazyload" data-srcset="https://7.dusays.com/2021/04/03/297503263fa90.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/><span class="title">魅族</span></div></a><a class="site-card" href="/wallpaper/Sony/"><div class="img"><img src="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/Sony/Sony47.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/Sony/Sony47.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="info"><img src="https://7.dusays.com/2021/04/27/1c64a002c6627.png" class="lazyload" data-srcset="https://7.dusays.com/2021/04/27/1c64a002c6627.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/><span class="title">索尼</span></div></a><a class="site-card" href="/wallpaper/LG/"><div class="img"><img src="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/LG/LG2.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/LG/LG2.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="info"><img src="https://7.dusays.com/2021/04/27/5486554199307.png" class="lazyload" data-srcset="https://7.dusays.com/2021/04/27/5486554199307.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/><span class="title">LG</span></div></a><a class="site-card" href="/wallpaper/HTC/"><div class="img"><img src="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/HTC/HTC1.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/HTC/HTC1.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="info"><img src="https://7.dusays.com/2021/04/06/43eb8648566c2.png" class="lazyload" data-srcset="https://7.dusays.com/2021/04/06/43eb8648566c2.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/><span class="title">HTC</span></div></a><a class="site-card" href="/wallpaper/Lenovo/"><div class="img"><img src="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/Lenovo/Lenovo131.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/Lenovo/Lenovo131.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="info"><img src="https://7.dusays.com/2021/04/27/2f0d4b3aab8e9.png" class="lazyload" data-srcset="https://7.dusays.com/2021/04/27/2f0d4b3aab8e9.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/><span class="title">Lenovo</span></div></a><a class="site-card" href="/wallpaper/ZTE/"><div class="img"><img src="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/ZTE/ZTE82.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/ZTE/ZTE82.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="info"><img src="https://7.dusays.com/2021/04/27/05431d8a4103b.png" class="lazyload" data-srcset="https://7.dusays.com/2021/04/27/05431d8a4103b.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/><span class="title">ZTE</span></div></a><a class="site-card" href="/wallpaper/Motorola/"><div class="img"><img src="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/Motorola/Motorola78.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/Motorola/Motorola78.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="info"><img src="https://7.dusays.com/2021/04/27/59fa6c35246e3.png" class="lazyload" data-srcset="https://7.dusays.com/2021/04/27/59fa6c35246e3.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/><span class="title">Motorola</span></div></a><a class="site-card" href="/wallpaper/Nokia/"><div class="img"><img src="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/Nokia/Nokia7.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/Nokia/Nokia7.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="info"><img src="https://7.dusays.com/2021/04/27/3652be288b4a3.png" class="lazyload" data-srcset="https://7.dusays.com/2021/04/27/3652be288b4a3.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/><span class="title">Nokia</span></div></a><a class="site-card" href="/wallpaper/Meitu/"><div class="img"><img src="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/Meitu/Meitu6.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/Built-in-wallpaper@master/Meitu/Meitu6.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="info"><img src="https://7.dusays.com/2021/04/27/1f763da7327ac.png" class="lazyload" data-srcset="https://7.dusays.com/2021/04/27/1f763da7327ac.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/><span class="title">Meitu</span></div></a></div><h3 id="TODO"><a href="#TODO" class="headerlink" title="TODO"></a>TODO</h3><hr><ul><li><input disabled="" type="checkbox"> 其他(Other)</li></ul><div class="note quote"><p>现在基本所有品牌的内置壁纸均已更新到本博客,后续其他新产品发布后,就会同步发布到Github和本博客上,敬请期待。^_^</p></div>]]></content>
<summary type="html">kelecn's Blog,一个记录个人成长的地方。</summary>
<category term="美化" scheme="https://kelecn.top/categories/%E7%BE%8E%E5%8C%96/"/>
<category term="内置壁纸" scheme="https://kelecn.top/tags/%E5%86%85%E7%BD%AE%E5%A3%81%E7%BA%B8/"/>
<category term="Wallpaper" scheme="https://kelecn.top/tags/Wallpaper/"/>
<category term="Google" scheme="https://kelecn.top/tags/Google/"/>
<category term="数码" scheme="https://kelecn.top/tags/%E6%95%B0%E7%A0%81/"/>
</entry>
<entry>
<title>给博客添加捐赠小部件—sponsor-page</title>
<link href="https://kelecn.top/posts/34795/"/>
<id>https://kelecn.top/posts/34795/</id>
<published>2021-01-20T09:43:43.000Z</published>
<updated>2021-08-12T14:55:38.514Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:<a href="https://github.com/Kaiyuan/sponsor-page">sponsor-page</a>是一个开源的捐赠按钮样式,可以用于美化我们的博客。</p><a id="more"></a><div class="note quote"><p>说在前面,捐赠是不可能捐赠的</p></div><p>只有<del>白嫖</del>才能维持得了生活,捐赠按钮主要还是起一个美化的效果。</p><p><strong>参考项目:</strong><div class="tag link"><a class="link-card" title="sponsor-page" href="https://github.com/Kaiyuan/sponsor-page"><div class="left"><img src="https://7.dusays.com/2021/01/23/e93738a83403c.png" class="lazyload" data-srcset="https://7.dusays.com/2021/01/23/e93738a83403c.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="right"><p class="text">sponsor-page</p><p class="url">https://github.com/Kaiyuan/sponsor-page</p></div></a></div></p><p>该项目主要主要有四种捐赠渠道:</p><ul><li><p>PayPal</p></li><li><p>比特币</p></li><li><p>支付宝</p></li><li><p>微信支付</p><div class="note up"><p>我考虑到,比特币在国内使用有限,就把比特币换成了QQ支付,有需要的朋友也可以直接用我的。</p></div><div class="tag link"><a class="link-card" title="sponsor-page" href="https://github.com/kelecn/sponsor-page"><div class="left"><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/%E6%82%9F%E7%A9%BA.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/%E6%82%9F%E7%A9%BA.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="right"><p class="text">sponsor-page</p><p class="url">https://github.com/kelecn/sponsor-page</p></div></a></div></li></ul><h3 id="一、捐赠按钮的修改"><a href="#一、捐赠按钮的修改" class="headerlink" title="一、捐赠按钮的修改"></a>一、捐赠按钮的修改</h3><hr><ol><li><p>首先,直接把对应项目fork到自己的Github,需要比特币按钮可以选择原版的<a href="https://github.com/Kaiyuan/sponsor-page">sponsor-page</a>,需要QQ支付按钮可以选择我修改后的<a href="https://github.com/kelecn/sponsor-page">sponsor-page</a>,如果有其他支付方式需求,自己按需修改即可。</p></li><li><p>第二步,二维码美化,相信大家的路子肯定很多,欢迎在评论区推荐一下,我这边就给大家推荐一个常用的:<div class="tag link"><a class="link-card" title="草料二维码" href="https://cli.im/"><div class="left"><img src="https://static.clewm.net/static/images/favicon.ico" class="lazyload" data-srcset="https://static.clewm.net/static/images/favicon.ico" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="right"><p class="text">草料二维码</p><p class="url">https://cli.im/</p></div></a></div></p><p>还有PayPal链接、支付宝链接,各位去对应平台获取即可。</p></li><li><p>第三步,当然就是修改自己对应的支付二维码图片(sponsor-page\simple\images)、<a href="https://www.paypal.com/paypalme/kelecn">PayPal</a>(sponsor-page\simple\index.html和sponsor-page\drinks\index.html)链接和<a href="https://qr.alipay.com/fkx05422rnstyh9yihg7u78">支付宝</a>(sponsor-page\drinks\script.js)链接啦,你可以直接在Github上传和修改相应文件即可,也可以克隆到本地,修改后再一起推送到Github。</p></li></ol><h3 id="二、捐赠按钮的使用(部署到Github)"><a href="#二、捐赠按钮的使用(部署到Github)" class="headerlink" title="二、捐赠按钮的使用(部署到Github)"></a>二、捐赠按钮的使用(部署到Github)</h3><hr><ul><li>直接开启对应项目的GitHub Pages即可,访问。(博客要是Github+Coding双线部署可能会出现套娃现象,国内线路访问捐赠页面,不会去访问Github Pages,会访问国内的404页面)</li><li>下面会介绍对应的解决方法——将捐赠按钮页面部署到博客本地(无论是国内还是国外访问都会正常)</li></ul><p><img src="https://7.dusays.com/2021/01/23/cb1ac313b3a8c.png" class="lazyload" data-srcset="https://7.dusays.com/2021/01/23/cb1ac313b3a8c.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><h3 id="三、捐赠按钮的使用(部署到博客)"><a href="#三、捐赠按钮的使用(部署到博客)" class="headerlink" title="三、捐赠按钮的使用(部署到博客)"></a>三、捐赠按钮的使用(部署到博客)</h3><hr><ol><li><p>首先,定位Volantis主题的捐赠布局。(themes\volantis\layout\_partial\article.ejs)</p></li><li><p>修改article.ejs文件。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"></blockquote></span><br><span class="line"></div></span><br><span class="line">//上面用于定位,下面为新添加的,对应修改src即可,要是已经部署到Github Pages,直接使用对应链接即可,要是想放在博客项目中,可往下看</span><br><span class="line"><div class='donate'></span><br><span class="line"><iframe src="https://kelecn.top/donate/drinks" style="overflow-x:hidden;overflow-y:hidden; border:0xp none #fff; min-height:240px; width:100%;" frameborder="0" scrolling="no"></iframe></span><br><span class="line"></div></span><br></pre></td></tr></table></figure></li><li><p>部署到博客项目中(本地)</p><ul><li><p>直接将刚才修改好的Github项目克隆到本地,放到博客项目的source中,文件夹命名随意(一般为donate,不要改成sponsor-page以防与前面的开启Github Pages后发生冲突)</p></li><li><p>在_config.yml中修改</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"># Directory</span><br><span class="line">...</span><br><span class="line">skip_render: "donate/**" #hexo会跳过donate文件夹编译,直接把donate文件夹搬移到public</span><br></pre></td></tr></table></figure></li><li><p>则对应的捐赠按钮访问链接为</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//1、域名/donate/drinks</span></span><br><span class="line">https:<span class="comment">//kelecn.top/donate/drinks</span></span><br><span class="line"><span class="comment">//2、域名/donate/simple</span></span><br><span class="line">https:<span class="comment">//kelecn.top/donate/simple</span></span><br></pre></td></tr></table></figure></li></ul></li><li><p>捐赠按钮展示(可以用任意Html页面展示)</p></li></ol><ul><li>simple页面</li></ul> <iframe src="https://kelecn.top/donate/simple/" style="overflow-x:hidden;overflow-y:hidden; border:0xp none #fff; min-height:240px; width:100%;" frameborder="0" scrolling="no"></iframe><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">//simple对应引用代码</span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">iframe</span> <span class="attr">src</span>=<span class="string">"https://kelecn.top/donate/simple/"</span> <span class="attr">style</span>=<span class="string">"overflow-x:hidden;overflow-y:hidden; border:0xp none #fff; min-height:240px; width:100%;"</span> <span class="attr">frameborder</span>=<span class="string">"0"</span> <span class="attr">scrolling</span>=<span class="string">"no"</span>></span><span class="tag"></<span class="name">iframe</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br></pre></td></tr></table></figure><ul><li>drinks页面</li></ul> <iframe src="https://kelecn.top/donate/drinks/" style="overflow-x:hidden;overflow-y:hidden; border:0xp none #fff; min-height:240px; width:100%;" frameborder="0" scrolling="no"></iframe><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">//drinks对应引用代码</span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">iframe</span> <span class="attr">src</span>=<span class="string">"https://kelecn.top/donate/drinks/"</span> <span class="attr">style</span>=<span class="string">"overflow-x:hidden;overflow-y:hidden; border:0xp none #fff; min-height:240px; width:100%;"</span> <span class="attr">frameborder</span>=<span class="string">"0"</span> <span class="attr">scrolling</span>=<span class="string">"no"</span>></span><span class="tag"></<span class="name">iframe</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br></pre></td></tr></table></figure><h3 id="四、特别感谢"><a href="#四、特别感谢" class="headerlink" title="四、特别感谢"></a>四、特别感谢</h3><hr><p>特别感谢<a href="https://github.com/Kaiyuan/sponsor-page">sponsor-page</a>项目的大力支持,喜欢的朋友,欢迎去其Github点点小星星~</p><div class="tag link"><a class="link-card" title="sponsor-page" href="https://github.com/Kaiyuan/sponsor-page"><div class="left"><img src="https://7.dusays.com/2021/01/23/e93738a83403c.png" class="lazyload" data-srcset="https://7.dusays.com/2021/01/23/e93738a83403c.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="right"><p class="text">sponsor-page</p><p class="url">https://github.com/Kaiyuan/sponsor-page</p></div></a></div>]]></content>
<summary type="html">kelecn's Blog,一个记录个人成长的地方。</summary>
<category term="美化" scheme="https://kelecn.top/categories/%E7%BE%8E%E5%8C%96/"/>
<category term="Hexo" scheme="https://kelecn.top/tags/Hexo/"/>
<category term="Github" scheme="https://kelecn.top/tags/Github/"/>
<category term="Volantis" scheme="https://kelecn.top/tags/Volantis/"/>
<category term="捐赠" scheme="https://kelecn.top/tags/%E6%8D%90%E8%B5%A0/"/>
</entry>
<entry>
<title>jsDelivr CDN的使用及缓存刷新</title>
<link href="https://kelecn.top/posts/22877/"/>
<id>https://kelecn.top/posts/22877/</id>
<published>2021-01-08T09:43:43.000Z</published>
<updated>2021-04-03T06:55:24.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:jsDelivr 是一个免费、开源的加速CDN公共服务。</p><a id="more"></a><p> 之前搭建的基于PicGo的GitHub图床,自动生成的链接由于没有经过CDN加速,相当于直接访问Github,常常会出现无法访问的现象,使用体验很一般,现在结合免费的jsDelivr CDN使用效果真不错!</p><p><strong>参考项目:</strong><div class="tag link"><a class="link-card" title="基于PicGo的GitHub图床" href="https://kelecn.top/posts/10250/"><div class="left"><img src="https://molunerfinn.com/PicGo/imgs/256x256--icons.png" class="lazyload" data-srcset="https://molunerfinn.com/PicGo/imgs/256x256--icons.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="right"><p class="text">基于PicGo的GitHub图床</p><p class="url">https://kelecn.top/posts/10250/</p></div></a></div></p><h3 id="一、jsDelivr的使用"><a href="#一、jsDelivr的使用" class="headerlink" title="一、jsDelivr的使用"></a>一、jsDelivr的使用</h3><hr> 首先,jsDelivr的使用[官网](https://www.jsdelivr.com/features)有很详细的介绍,包括npm、Github、Wordpress,下面主要介绍,我通常使用的Github。<p>也就是说,你要引用一个Github文件,它的链接可以是:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://cdn.jsdelivr.net/gh/user/repo@version/file</span><br></pre></td></tr></table></figure><p>换成中文也就是:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://cdn.jsdelivr.net/gh/您的Github用户名/项目仓库名@项目版本/文件路径</span><br></pre></td></tr></table></figure><p>当然了,有些朋友的项目可能没有设置版本,那么可以写成:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://cdn.jsdelivr.net/gh/您的Github用户名/项目仓库名@master/文件路径</span><br></pre></td></tr></table></figure><p>值得注意的是,文件命名请尽量不要用中文,也不要有空格,这样可以解决大部分无法访问的问题。</p><h3 id="二、jsDelivr的缓存刷新"><a href="#二、jsDelivr的缓存刷新" class="headerlink" title="二、jsDelivr的缓存刷新"></a>二、jsDelivr的缓存刷新</h3><hr><p> jsDelivr对于我们这些<del>白嫖怪</del>来说,当然是体验很好啦,可惜还是存在一点点小毛病,比如说,CDN缓存刷新不及时,Github那边我已经修改文件好久了,通过CDN访问还是上一个版本,这就很难受。下面介绍一下如何正确刷新jsDelivr的缓存:</p><ol><li><p>官方工具</p><p>jsDelivr官方说,不久的将来将会推出用于清除CDN缓存的工具,各位可以期待一下。QAQ</p></li><li><p>简单方法</p><p>对于 jsDelivr,缓存刷新的方式其实很简单,只需将想刷新的链接的开头的<strong>cdn</strong> 更改为 <strong>purge</strong>,访问这个接口,返回<strong>status: ok</strong>,就代表缓存刷新了。</p></li><li><p>一个例子</p></li></ol><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">//刷新前</span><br><span class="line">https://cdn.jsdelivr.net/gh/kelecn/images@master/myblog.png</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">//仅用于刷新返回status: ok,即可</span><br><span class="line">https://purge.jsdelivr.net/gh/kelecn/images@master/myblog.png</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">//重新访问即可</span><br><span class="line">https://cdn.jsdelivr.net/gh/kelecn/images@master/myblog.png</span><br></pre></td></tr></table></figure><h3 id="三、特别感谢"><a href="#三、特别感谢" class="headerlink" title="三、特别感谢"></a>三、特别感谢</h3><hr><p> 特别感谢jsDelivr项目的大力支持,喜欢的朋友,欢迎去其Github点点小星星~</p><div class="tag link"><a class="link-card" title="jsDelivr" href="https://github.com/jsdelivr/jsdelivr"><div class="left"><img src="https://www.jsdelivr.com/favicon.ico" class="lazyload" data-srcset="https://www.jsdelivr.com/favicon.ico" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="right"><p class="text">jsDelivr</p><p class="url">https://github.com/jsdelivr/jsdelivr</p></div></a></div>]]></content>
<summary type="html">kelecn's Blog,一个记录个人成长的地方。</summary>
<category term="技术" scheme="https://kelecn.top/categories/%E6%8A%80%E6%9C%AF/"/>
<category term="Github" scheme="https://kelecn.top/tags/Github/"/>
<category term="jsDelivr" scheme="https://kelecn.top/tags/jsDelivr/"/>
<category term="CDN" scheme="https://kelecn.top/tags/CDN/"/>
<category term="缓存" scheme="https://kelecn.top/tags/%E7%BC%93%E5%AD%98/"/>
</entry>
<entry>
<title>初探机器视觉模块OpenMV</title>
<link href="https://kelecn.top/posts/9237/"/>
<id>https://kelecn.top/posts/9237/</id>
<published>2020-12-24T16:50:41.000Z</published>
<updated>2021-04-03T06:55:12.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:OpenMV是一款开源,低成本,可扩展,支持Python的机器视觉模块,可媲美机器视觉世界的Arduino。</p><a id="more"></a><p><strong>OpenMV官方教程:</strong></p><div class="tag link"><a class="link-card" title="OpenMV中文教程" href="https://book.openmv.cc/"><div class="left"><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/openmvbook.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/openmvbook.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="right"><p class="text">OpenMV中文教程</p><p class="url">https://book.openmv.cc/</p></div></a></div><p><strong>开源项目GitHub链接:</strong></p><div class="tag link"><a class="link-card" title="OpenMV" href="https://github.com/openmv"><div class="left"><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/OpenMV.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/OpenMV.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="right"><p class="text">OpenMV</p><p class="url">https://github.com/openmv</p></div></a></div><h3 id="一、OpenMV简介"><a href="#一、OpenMV简介" class="headerlink" title="一、OpenMV简介"></a>一、OpenMV简介</h3><hr><p> OpenMV是一个开源,低成本,功能强大的机器视觉模块。以STM32F427CPU为核心,集成了OV7725摄像头芯片,在小巧的硬件模块上,用C语言高效地实现了核心机器视觉算法,并提供Python编程接口。</p><p><img src="https://cdn.shopifycdn.net/s/files/1/0803/9211/products/new-cam-v4-angle-web_grande.jpg?v=1536445279" class="lazyload" data-srcset="https://cdn.shopifycdn.net/s/files/1/0803/9211/products/new-cam-v4-angle-web_grande.jpg?v=1536445279" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p> OpenMV采用的STM32F427拥有丰富的硬件资源,引出UART,I2C,SPI,PWM,ADC,DAC以及GPIO等接口方便扩展外围功能。USB接口用于连接电脑上的集成开发环境OpenMVIDE,协助完成编程、调试和更新固件等工作。TF卡槽支持大容量的TF卡(最大32GB),可以用于存放程序和保存照片等。</p><div class="video"><video controls preload><source src='https://cdn.jsdelivr.net/gh/kelecn/images@master/OpenMV4_Cam_H7.mp4' type='video/mp4'>Your browser does not support the video tag.</video></div><h3 id="二、OpenMV功能"><a href="#二、OpenMV功能" class="headerlink" title="二、OpenMV功能"></a>二、OpenMV功能</h3><hr><p> OpenMV上的机器视觉算法包括寻找色块、人脸检测、眼球跟踪、边缘检测、标志跟踪等。可以用来实现非法入侵检测、产品的残次品筛选、跟踪固定的标记物等。使用者仅需要写一些简单的Python代码,即可轻松的完成各种机器视觉相关的任务。小巧的设计,使得OpenMV可以用到很多创意的产品上。比如,可以给自己的机器人提供周边环境感知能力;给智能车增加视觉巡线功能;给智能玩具增加识别人脸功能,提高产品趣味性等;甚至,可以给工厂产品线增加残次品筛选功能等。</p><p> OpenMV的定位是“带机器视觉功能的“Arduino”。它可以通过UART,I2C,SPI,AsyncSerial以及GPIO等控制其他的硬件,甚至是单片机模块,如Arduino、RaspberryPi(树莓派)等。它也可以被其他的单片机模块控制。这个特点使得它可以很灵活的和其他流行的模块配合,实现复杂的产品功能。</p><h3 id="三、OpenMV项目"><a href="#三、OpenMV项目" class="headerlink" title="三、OpenMV项目"></a>三、OpenMV项目</h3><hr><ul><li><input checked="" disabled="" type="checkbox"> 追球小车</li><li><input checked="" disabled="" type="checkbox"> 巡线小车</li><li><input checked="" disabled="" type="checkbox"> 口罩检测</li><li><input checked="" disabled="" type="checkbox"> 人脸识别</li><li><input checked="" disabled="" type="checkbox"> 垃圾分类</li></ul>]]></content>
<summary type="html">kelecn's Blog,一个记录个人成长的地方。</summary>
<category term="技术" scheme="https://kelecn.top/categories/%E6%8A%80%E6%9C%AF/"/>
<category term="嵌入式" scheme="https://kelecn.top/tags/%E5%B5%8C%E5%85%A5%E5%BC%8F/"/>
<category term="硬件" scheme="https://kelecn.top/tags/%E7%A1%AC%E4%BB%B6/"/>
<category term="OpenMV" scheme="https://kelecn.top/tags/OpenMV/"/>
<category term="机器视觉" scheme="https://kelecn.top/tags/%E6%9C%BA%E5%99%A8%E8%A7%86%E8%A7%89/"/>
<category term="Python" scheme="https://kelecn.top/tags/Python/"/>
</entry>
<entry>
<title>基于QT开发的局域网聊天室</title>
<link href="https://kelecn.top/posts/29647/"/>
<id>https://kelecn.top/posts/29647/</id>
<published>2020-11-11T12:00:01.000Z</published>
<updated>2021-04-03T06:55:02.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:基于QT开发的一个简易的局域网聊天室。</p><a id="more"></a><p><strong>注意事项:</strong></p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">开发工具:QT</span><br><span class="line">开发语言:C++</span><br><span class="line">测试软件:LAN-Chat-Room-Test文件夹</span><br><span class="line">程序源码:LAN-Chat-Room-Code文件夹</span><br><span class="line">注意:Windows环境下请在全英文路径下打开工程,否则会因为编码出错。</span><br></pre></td></tr></table></figure><p><strong>GitHub链接:</strong></p><div class="tag link"><a class="link-card" title="LAN-Chat-Room" href="https://github.com/kelecn/LAN-Chat-Room"><div class="left"><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/LAN.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/LAN.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="/></div><div class="right"><p class="text">LAN-Chat-Room</p><p class="url">https://github.com/kelecn/LAN-Chat-Room</p></div></a></div><h3 id="一、功能简介"><a href="#一、功能简介" class="headerlink" title="一、功能简介"></a>一、功能简介</h3><hr><p>本次设计是一个简易的局域网聊天室,功能设计主要分为群聊和私聊两部分,每部分都支持基础聊天以及文件传输功能。参考了<a href="https://raw.githubusercontent.com/kelecn/images/master/Qt%E5%8F%8AQt%20Quick%E5%BC%80%E5%8F%91%E5%AE%9E%E6%88%98%E7%B2%BE%E8%A7%A3.pdf">《Qt及Qt Quick开发实战精解》</a>中的群聊实例,并在群聊的基础设计了私聊这部分内容以及其他一些功能,其中消息传递使用UDP来实现,而文件传输使用TCP来实现。</p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/%E5%8A%9F%E8%83%BD%E7%AE%80%E4%BB%8B1.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/%E5%8A%9F%E8%83%BD%E7%AE%80%E4%BB%8B1.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><h3 id="二、UDP群聊部分"><a href="#二、UDP群聊部分" class="headerlink" title="二、UDP群聊部分"></a>二、UDP群聊部分</h3><hr><p>本程序实现的功能是:局域网内,每个用户登录到聊天软件,则软件界面的右端可以显示在线用户列表,分别显示的是用户名,主机名,ip地址。软件左边那大块是聊天内容显示界面,这里局域网相当于qq中的qq群,即群聊。每个人可以在聊天输入界面中输入文字(还可修改文字格式&颜色)并发送。其聊天界面如下:</p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/%E4%B8%BB%E7%95%8C%E9%9D%A2.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/%E4%B8%BB%E7%95%8C%E9%9D%A2.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><strong>注:此处的客户端,同时也是服务器。</strong></p><p>下面分服务器端和客户端两部分来介绍:</p><p><strong>服务器:</strong> 建立一个UDP Socket并绑定在固定端口后,用信号与槽的方式进行监听是否有数据来临。如果用,接收其数据并分析数据的消息类型,如果消息是新用户登录则更新用户列表并在聊天显示窗口中添加新用户上线通知;同理,如果是用户下线,则在用户列表中删除该用户且在聊天显示窗口中显示下线通知;如果是聊天消息,则接收该消息并且在窗口中显示。其流程图如下:</p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/%E6%9C%8D%E5%8A%A1%E5%99%A8.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/%E6%9C%8D%E5%8A%A1%E5%99%A8.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><strong>客户端:</strong> 首先当客户端登录时,获取本机的用户名,计算机名和ip地址,并广播给局域网的服务器更新用户列表。然后当客户端需要发送信息时,则在聊天输入栏中输入信息并按发送键发送聊天内容,当然于此同时也广播本地系统的各种信息。其流程图如下:</p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/%E5%AE%A2%E6%88%B7%E7%AB%AF.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/%E5%AE%A2%E6%88%B7%E7%AB%AF.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><h3 id="三、TCP文件传输部分"><a href="#三、TCP文件传输部分" class="headerlink" title="三、TCP文件传输部分"></a>三、TCP文件传输部分</h3><hr><p><strong>发送端界面:</strong></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/%E4%BC%A0%E6%96%87%E4%BB%B61.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/%E4%BC%A0%E6%96%87%E4%BB%B61.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><strong>接收端界面:</strong></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/%E6%8E%A5%E6%94%B6%E6%96%87%E4%BB%B61.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/%E6%8E%A5%E6%94%B6%E6%96%87%E4%BB%B61.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p> <strong>发送端,也即承担服务器角色的操作:</strong></p><p>在主界面程序右侧选择一个需要发送文件的用户,弹出发送端界面后,点击打开按钮,在本地计算机中选择需要发送的文件,点击发送按钮,则进度条上会显示当前文件传送的信息,有已传送文件大小信息,传送速度等信息。如果想关闭发送过程,则单击关闭按钮。其流程图如下:</p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/%E5%8F%91%E9%80%81%E7%AB%AF%E6%B5%81%E7%A8%8B%E5%9B%BE.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/%E5%8F%91%E9%80%81%E7%AB%AF%E6%B5%81%E7%A8%8B%E5%9B%BE.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p> <strong>接收端,也即承担客户端角色的操作:</strong></p><p>当在主界面中突然弹出一个对话框,问是否接自某个用户名和IP地址的文件传送信息,如果接受则单击yes按钮,否则就单击no按钮。当接收文件时,选择好接收文件所存目录和文件名后就开始接收文件了,其过程也会显示已接收文件的大小,接收速度和剩余时间的大小等信息。其流程图如下:</p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/%E6%8E%A5%E6%94%B6%E7%AB%AF%E6%B5%81%E7%A8%8B%E5%9B%BE.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/%E6%8E%A5%E6%94%B6%E7%AB%AF%E6%B5%81%E7%A8%8B%E5%9B%BE.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><h3 id="四、私聊部分"><a href="#四、私聊部分" class="headerlink" title="四、私聊部分"></a>四、私聊部分</h3><hr><p><strong>私聊界面:</strong></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/%E7%A7%81%E8%81%8A.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/%E7%A7%81%E8%81%8A.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><strong>私聊发送端流程图:</strong></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/%E7%A7%81%E8%81%8A%E5%8F%91%E9%80%81%E7%AB%AF%E6%B5%81%E7%A8%8B%E5%9B%BE.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/%E7%A7%81%E8%81%8A%E5%8F%91%E9%80%81%E7%AB%AF%E6%B5%81%E7%A8%8B%E5%9B%BE.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><strong>私聊接收端流程图:</strong></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/%E7%A7%81%E8%81%8A%E6%8E%A5%E6%94%B6%E7%AB%AF%E6%B5%81%E7%A8%8B%E5%9B%BE.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/%E7%A7%81%E8%81%8A%E6%8E%A5%E6%94%B6%E7%AB%AF%E6%B5%81%E7%A8%8B%E5%9B%BE.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><strong>下面来介绍下2者实现的具体过程:</strong></p><p><strong>A方(主动开始首次发送的一方):</strong></p><ol><li>在主窗口右侧双击自己想与之聊天的B方,此时A方实际上完成的工作有:用B方的主机名和ip地址新建了私聊的类privatechat,在新建该类的过程中,已经设置了显示顶端为:xxx与聊天中,对方IP:xxx,且绑定了本地ip和私聊的专用端口,同时设置了信号与槽的联系,即该端口如果有数据输入,则触发槽函数processPendingDatagrams().该函数是char.cpp中的。</li><li>当上面的新建私聊类完成后,用通讯对方ip地址和其群聊专用的端口(但用的是主udp群聊的socket进行的)将以下内容分别发送出去:消息类型(Xchat),用户名,主机名,本地ip地址。完成后,在屏幕中显示私聊窗口。</li><li>在私聊窗口中输入需要聊天的内容,单击发送键。该过程玩成的内容有:分别将消息类型(Message)+用户名+本地名+本地IP+消息内容本身通过私聊专用端口发送出去。在私聊窗口中显示主机名+聊天时间,换行后显示消息内容本身。</li></ol><p><strong>B方(第一次信息是他人发送过来的):</strong></p><ol><li>当A在2步骤中用群聊的方法发送其消息类型(Xchat),其用户名,其主机名,其ip地址后,由于程序运行时已经初始化了widget.cpp中的构造函数,所以每个程序都绑定了本地地址+群聊专用的端口,一旦有数据传入,就触发widget.cpp中的槽函数processPendingDatagrams().</li><li>在processPendingDatagrams()函数中,判断消息类型为Xchat后,接收缓存区内接收对方用户名,对方主机名和对方ip地址。并用接收到的主机名和ip地址新建一个私聊类。新建该私聊的过程与A中的步骤1一样。完后在程序中显示私聊窗口。</li><li>当对方A按完发送按钮后,通过私聊专用端口绑定槽函数来触发chart.cpp中的processPendingDatagrams()函数,该函数中先读取消息类型(Message),然后依次读取用户名,主机名,ip地址,消息内容本身,并将对方信息和消息内容显示在聊天窗口中。</li></ol><h3 id="五、参考资料及资源下载"><a href="#五、参考资料及资源下载" class="headerlink" title="五、参考资料及资源下载"></a>五、参考资料及资源下载</h3><hr><p><a href="https://raw.githubusercontent.com/kelecn/images/master/Qt%E5%8F%8AQt%20Quick%E5%BC%80%E5%8F%91%E5%AE%9E%E6%88%98%E7%B2%BE%E8%A7%A3.pdf">《Qt及Qt Quick开发实战精解》</a></p>]]></content>
<summary type="html">kelecn's Blog,一个记录个人成长的地方。</summary>
<category term="技术" scheme="https://kelecn.top/categories/%E6%8A%80%E6%9C%AF/"/>
<category term="C++" scheme="https://kelecn.top/tags/C/"/>
<category term="TCP" scheme="https://kelecn.top/tags/TCP/"/>
<category term="UDP" scheme="https://kelecn.top/tags/UDP/"/>
<category term="QT" scheme="https://kelecn.top/tags/QT/"/>
</entry>
<entry>
<title>PID控制算法</title>
<link href="https://kelecn.top/posts/16358/"/>
<id>https://kelecn.top/posts/16358/</id>
<published>2020-09-09T12:00:00.000Z</published>
<updated>2021-04-03T06:54:52.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:PID控制算法是结合比例、积分和微分三种环节于一体的控制算法,它是连续系统中技术最为成熟、应用最为广泛的一种控制算法。</p><a id="more"></a><h3 id="一、什么是PID算法"><a href="#一、什么是PID算法" class="headerlink" title="一、什么是PID算法"></a>一、什么是PID算法</h3><hr><p>PID,就是“比例(proportional)、积分(integral)、微分(derivative)”,是一种很常见的控制算法。常用于需要将某一个物理量“保持稳定”的场合(比如维持平衡,稳定温度、转速等)。</p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images/pid.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/pid.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p>总的来说,当得到系统的输出后,将输出经过比例,积分,微分3种运算方式,叠加到输入中,从而控制系统的行为。</p><div class="note quote"><p>在工业应用中PID及其衍生算法是应用最广泛的算法之一,是当之无愧的万能算法,如果能够熟练掌握PID算法的设计与实现过程,对于一般的研发人员来讲,应该是足够应对一般研发问题了,而难能可贵的是,在我所接触的控制算法当中,PID控制算法又是最简单,最能体现反馈思想的控制算法,可谓经典中的经典。经典的未必是复杂的,经典的东西常常是简单的,而且是最简单的,想想牛顿的力学三大定律吧,想想爱因斯坦的质能方程吧,何等的简单!简单的不是原始的,简单的也不是落后的,简单到了美的程度。</p></div><div class="video"><video controls preload><source src='https://cdn.jsdelivr.net/gh/kelecn/images@master/PID%E6%BC%94%E7%A4%BA.mp4' type='video/mp4'>Your browser does not support the video tag.</video></div><h3 id="二、PID算法原理"><a href="#二、PID算法原理" class="headerlink" title="二、PID算法原理"></a>二、PID算法原理</h3><hr><p>$$<br>U(t)=K_P[e(t)+\frac{1}{T_I}\int{e(t)}dt+\frac{T_De(t)}{dt}]<br>$$</p><span class='p red'>三个重要的参数:</span><br><span class='p red'>Kp:</span>控制器的比例系数。<br><span class='p red'>Ti:</span>控制器的积分时间,也称积分系数。<br><span class='p red'>Td:</span>控制器的微分时间,也称微分系数。<br><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images/PID.gif" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/PID.gif" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><strong>1、P - 比例部分</strong></p><p>比例环节的作用是对偏差瞬间作出反应。偏差一旦产生控制器立即产生控制作用, 使控制量向减少偏差的方向变化。 控制作用的强弱取决于比例系数Kp, 比例系数Kp越大,控制作用越强, 则过渡过程越快, 控制过程的静态偏差也就越小; 但是Kp越大,也越容易产生振荡, 破坏系统的稳定性。 故而,<span class='p green'>比例系数Kp选择必须恰当, 才能过渡时间少, 静差小而又稳定的效果</span>。</p><p><strong>2、I - 积分部分</strong></p><p>从积分部分的数学表达式可以知道, 只要存在偏差, 则它的控制作用就不断的增加; 只有在偏差e(t)=0时, 它的积分才能是一个常数,控制作用才是一个不会增加的常数。 可见,<span class='p blue'>积分部分可以消除系统的偏差</span>。<br></p><span class='p red'>我们需要设置一个积分量。只要偏差存在,就不断地对偏差进行积分(累加),并反应在调节力度上。</span><br><span class='p blue'>积分环节的调节作用虽然会消除静态误差,但也会降低系统的响应速度,增加系统的超调量。</span>积分常数Ti越大,积分的积累作用越弱,这时系统在过渡时不会产生振荡; 但是增大积分常数Ti会减慢静态误差的消除过程,消除偏差所需的时间也较长, 但可以减少超调量,提高系统的稳定性。<p>当 Ti 较小时, 则积分的作用较强,这时系统过渡时间中有可能产生振荡,不过消除偏差所需的时间较短。所以必须根据实际控制的具体要求来确定Ti 。</p><p><strong>3、D - 微分部分</strong></p><span class='p cyan'>实际的控制系统除了希望消除静态误差外,还要求加快调节过程。在偏差出现的瞬间,或在偏差变化的瞬间, 不但要对偏差量做出立即响应(比例环节的作用), 而且要根据偏差的变化趋势预先给出适当的纠正。</span>为了实现这一作用,可在 PI 控制器的基础上加入微分环节,形成 PID 控制器。<br><span class='p red'>我们需要一个控制作用,让被控制的物理量的“变化速度”趋于0,即类似于“阻尼”的作用。</span><br><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/KD.gif" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/KD.gif" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><span class='p cyan'>微分环节的作用使阻止偏差的变化。</span>它是根据偏差的变化趋势(变化速度)进行控制。偏差变化的越快,微分控制器的输出就越大,并能在偏差值变大之前进行修正。微分作用的引入, 将有助于减小超调量, 克服振荡, 使系统趋于稳定, 特别对髙阶系统非常有利, 它加快了系统的跟踪速度。但微分的作用对输入信号的噪声很敏感,对那些噪声较大的系统一般不用微分, 或在微分起作用之前先对输入信号进行滤波。<h3 id="三、PID算法应用实例"><a href="#三、PID算法应用实例" class="headerlink" title="三、PID算法应用实例"></a>三、PID算法应用实例</h3><hr><p>PID 控制算法可以分为<strong>位置式 PID</strong> 和<strong>增量式 PID</strong> 控制算法。</p><p>两者的区别:</p><p>(1)位置式PID控制的输出与整个过去的状态有关,用到了误差的累加值;而增量式PID的输出只与当前拍和前两拍的误差有关,因此位置式PID控制的累积误差相对更大;</p><p>(2)增量式PID控制输出的是控制量增量,并无积分作用,因此该方法适用于执行机构带积分部件的对象,如步进电机等,而位置式PID适用于执行机构不带积分部件的对象,如电液伺服阀。</p><p>(3)由于增量式PID输出的是控制量增量,如果计算机出现故障,误动作影响较小,而执行机构本身有记忆功能,可仍保持原位,不会严重影响系统的工作,而位置式的输出直接对应对象的输出,因此对系统影响较大。</p><p>下面给出公式直接体现的C语言源代码(请结合项目修改源代码):</p><p><strong>1.位置式PID</strong></p><p>$$<br>u(k)=K_Pe(k)+K_I\sum_{i=0}{e(i)}+K_D[e(k)-e(k-1)]<br>$$</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span></span></span><br><span class="line"><span class="class">{</span></span><br><span class="line"> <span class="keyword">float</span> Kp; <span class="comment">//比例系数Proportional</span></span><br><span class="line"> <span class="keyword">float</span> Ki; <span class="comment">//积分系数Integral</span></span><br><span class="line"> <span class="keyword">float</span> Kd; <span class="comment">//微分系数Derivative</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">float</span> Ek; <span class="comment">//当前误差</span></span><br><span class="line"> <span class="keyword">float</span> Ek1; <span class="comment">//前一次误差 e(k-1)</span></span><br><span class="line"> <span class="keyword">float</span> Ek2; <span class="comment">//再前一次误差 e(k-2)</span></span><br><span class="line"> <span class="keyword">float</span> LocSum; <span class="comment">//累计积分位置</span></span><br><span class="line">}PID_LocTypeDef;</span><br><span class="line"></span><br><span class="line"><span class="comment">/************************************************</span></span><br><span class="line"><span class="comment">函数名称 : PID_Loc</span></span><br><span class="line"><span class="comment">功 能 : PID位置(Location)计算</span></span><br><span class="line"><span class="comment">参 数 : SetValue ------ 设置值(期望值)</span></span><br><span class="line"><span class="comment"> ActualValue --- 实际值(反馈值)</span></span><br><span class="line"><span class="comment"> PID ----------- PID数据结构</span></span><br><span class="line"><span class="comment">返 回 值 : PIDLoc -------- PID位置</span></span><br><span class="line"><span class="comment">作 者 : strongerHuang</span></span><br><span class="line"><span class="comment">*************************************************/</span></span><br><span class="line"><span class="function"><span class="keyword">float</span> <span class="title">PID_Loc</span><span class="params">(<span class="keyword">float</span> SetValue, <span class="keyword">float</span> ActualValue, PID_LocTypeDef *PID)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">float</span> PIDLoc; <span class="comment">//位置</span></span><br><span class="line"></span><br><span class="line"> PID->Ek = SetValue - ActualValue;</span><br><span class="line"> PID->LocSum += PID->Ek; <span class="comment">//累计误差</span></span><br><span class="line"></span><br><span class="line"> PIDLoc = PID->Kp * PID->Ek + (PID->Ki * PID->LocSum) + PID->Kd * (PID->Ek1 - PID->Ek);</span><br><span class="line"></span><br><span class="line"> PID->Ek1 = PID->Ek; <span class="keyword">return</span> PIDLoc;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><strong>2.增量式PID</strong></p><p>$$<br>\Delta u(k)=u(k)-u(k-1)=K_P[e(k)-e(k-1)]+K_Ie(k)+K_D[e(k)-2e(k-1)-e(k-2)]<br>$$</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span></span></span><br><span class="line"><span class="class">{</span></span><br><span class="line"> <span class="keyword">float</span> Kp; <span class="comment">//比例系数Proportional</span></span><br><span class="line"> <span class="keyword">float</span> Ki; <span class="comment">//积分系数Integral</span></span><br><span class="line"> <span class="keyword">float</span> Kd; <span class="comment">//微分系数Derivative</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">float</span> Ek; <span class="comment">//当前误差</span></span><br><span class="line"> <span class="keyword">float</span> Ek1; <span class="comment">//前一次误差 e(k-1)</span></span><br><span class="line"> <span class="keyword">float</span> Ek2; <span class="comment">//再前一次误差 e(k-2)</span></span><br><span class="line">}PID_IncTypeDef;</span><br><span class="line"></span><br><span class="line"><span class="comment">/************************************************</span></span><br><span class="line"><span class="comment">函数名称 : PID_Inc</span></span><br><span class="line"><span class="comment">功 能 : PID增量(Increment)计算</span></span><br><span class="line"><span class="comment">参 数 : SetValue ------ 设置值(期望值)</span></span><br><span class="line"><span class="comment"> ActualValue --- 实际值(反馈值)</span></span><br><span class="line"><span class="comment"> PID ----------- PID数据结构</span></span><br><span class="line"><span class="comment">返 回 值 : PIDInc -------- 本次PID增量(+/-)</span></span><br><span class="line"><span class="comment">作 者 : strongerHuang</span></span><br><span class="line"><span class="comment">*************************************************/</span></span><br><span class="line"><span class="function"><span class="keyword">float</span> <span class="title">PID_Inc</span><span class="params">(<span class="keyword">float</span> SetValue, <span class="keyword">float</span> ActualValue, PID_IncTypeDef *PID)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">float</span> PIDInc; <span class="comment">//增量</span></span><br><span class="line"></span><br><span class="line"> PID->Ek = SetValue - ActualValue;</span><br><span class="line"> PIDInc = (PID->Kp * PID->Ek) - (PID->Ki * PID->Ek1) + (PID->Kd * PID->Ek2);</span><br><span class="line"></span><br><span class="line"> PID->Ek2 = PID->Ek1;</span><br><span class="line"> PID->Ek1 = PID->Ek; <span class="keyword">return</span> PIDInc;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="四、参考文章"><a href="#四、参考文章" class="headerlink" title="四、参考文章"></a>四、参考文章</h3><hr><p><a href="https://mp.weixin.qq.com/s?__biz=MjM5MzUxMTAwMg==&mid=2649734802&idx=2&sn=b8a896404ebaf1dbe275ba4a281c3dcd&chksm=be8efda789f974b115ec328f16c2d662e4d9e233877480d7e81d66b7caba8f9fd6189ca47720&mpshare=1&scene=1&srcid=1020km89Ecfz59MNwMVFcu7B&sharer_sharetime=1603170032106&sharer_shareid=95275518834f500dd6086e94b808c654&key=0acde1ff6de13ef4bd822c98cf17d2a9a436801111978df77638151040810ed28bf179899e499e2024bccaf8fb940755486b0ba6a1fc3598002febd1df0b31c19686a785e2fc8e40d66f0444db303a6a4ccf2ab44e9865d47af8587e91df231a8c2b5f2472f4792f93fa6f88dc8b7efa36c8a80cd5cd40bdb1e8815ae3caa849&ascene=1&uin=MzU3ODk4Mzk4&devicetype=Windows+10+x64&version=6300002f&lang=zh_CN&exportkey=A3CADoujGIx6OAsqHKnBpkA=&pass_ticket=zsGkzwY1nGXg6FPLvRx5z1hbA2UsYgsHzLUjdFhGUIqu5dE53McbwBW+wqG7JJYb&wx_header=0">一文读懂PID控制算法(抛弃公式,从原理上真正理解PID控制)</a></p><p><a href="https://mp.weixin.qq.com/s?__biz=MzI4MDI4MDE5Ng==&mid=2247485678&idx=1&sn=130d5e51d07035a00061c308de3cbbcd&chksm=ebbba505dccc2c13ba2557d807755c41aa096b2f11bc4086bd2d464f529855db7791a7e6ab2c&scene=21#wechat_redirect">重温经典PID算法</a></p><p><a href="https://mp.weixin.qq.com/s?__biz=MzI4MDI4MDE5Ng==&mid=2247488157&idx=2&sn=3b214c5ee27da1a0075b51d886b9f580&chksm=ebbbbf76dccc36603e441e89aca2f61ad22858c49756e51c601d213acd4778c1ff5b2b56fb0f&scene=21#wechat_redirect">PID原理和参数调试</a></p><p><a href="https://mp.weixin.qq.com/s?__biz=MzI4MDI4MDE5Ng==&mid=2247493113&idx=1&sn=4ce0422a394a614475d27d38b7169823&chksm=ebb84812dccfc10491c0f6627752016b0d8efa0b8abf90730fe13c111c4de198c44cb322c86a&mpshare=1&scene=1&srcid=1030z19rmwZnutSYKw0OJjlw&sharer_sharetime=1604024742543&sharer_shareid=95275518834f500dd6086e94b808c654&key=0acde1ff6de13ef4044e4878ea27ecfba6b6c92b95886d3343c34f36e674ef71f51ea5410737542feed9583f29a9b8f4c7e9dddcee554082f248cbfa568e04ecd7b9c2ae1ee0a618ec9eae8f14d78ab5dfbc535ab0025dbf08966c3ec760dd87cd8c0737aa5e02655434bb9217f44076123696db01177ae5b438ecfc49ecad4a&ascene=1&uin=MzU3ODk4Mzk4&devicetype=Windows+10+x64&version=6300002f&lang=zh_CN&exportkey=A/C1gLRDXw+/ILG5Wc/VFrw=&pass_ticket=zsGkzwY1nGXg6FPLvRx5z1hbA2UsYgsHzLUjdFhGUIqu5dE53McbwBW+wqG7JJYb&wx_header=0">结合案例轻松理解PID到底是个啥?</a></p><p><strong>视频来源:</strong><a href="https://www.bilibili.com/video/BV1et4y1i7Gm/">【编程三分钟】通俗易懂的PID控制算法讲解</a></p><p><strong>特别鸣谢:</strong>微信公众号:<a href="https://mp.weixin.qq.com/s?__biz=MzI4MDI4MDE5Ng==&mid=100001463&idx=1&sn=066b2b7a82aa4d5c8272182ddb3812a6&chksm=6bbbab5c5ccc224a30071793f5fa6377422b119d2268eb047906c81f0475dcf146290a7b0d9d&scene=18#wechat_redirect"><strong><em>strongerHuang</em></strong></a>的知识整理</p>]]></content>
<summary type="html">kelecn's Blog,一个记录个人成长的地方。</summary>
<category term="知识" scheme="https://kelecn.top/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="嵌入式" scheme="https://kelecn.top/tags/%E5%B5%8C%E5%85%A5%E5%BC%8F/"/>
<category term="C语言" scheme="https://kelecn.top/tags/C%E8%AF%AD%E8%A8%80/"/>
<category term="PID" scheme="https://kelecn.top/tags/PID/"/>
<category term="算法" scheme="https://kelecn.top/tags/%E7%AE%97%E6%B3%95/"/>
</entry>
<entry>
<title>C语言内存管理</title>
<link href="https://kelecn.top/posts/24097/"/>
<id>https://kelecn.top/posts/24097/</id>
<published>2020-09-07T12:00:00.000Z</published>
<updated>2021-04-03T06:54:44.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:嵌入式系统的内存资源很稀缺,其内存页会更小,在嵌入式开发当中需要特别注意内存管理。</p><a id="more"></a><h3 id="一、内存分配方式"><a href="#一、内存分配方式" class="headerlink" title="一、内存分配方式"></a>一、内存分配方式</h3><hr><p> 内存分配方式有三种:<br> [1]从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。<br> [2]在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。<br> [3]从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释 放内存。动态内存的生存期由程序员决定,使用非常灵活,但如果在堆上分配了空间,就有责任回收它,否则运行的程序会出现内存泄漏,频繁地分配和释放不同大 小的堆空间将会产生堆内碎块。</p><h3 id="二、程序的内存空间"><a href="#二、程序的内存空间" class="headerlink" title="二、程序的内存空间"></a>二、程序的内存空间</h3><hr><p> 在C语言程序中,代码是放在内存中执行的,我们大致将程序所占用的内存分为四个区域:栈区 堆区 数据区 代码区。<br> 一个由C/C++编译的程序占用的内存分为以下几个部分,</p><p><strong>1、栈区(stack)</strong></p><p>由编译器自动分配释放 ,存放为运行函数而分配的局部变量、函数参数、返回数据、返回地址等。其操作方式类似于数据结构中的栈。 例如:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">recive</span><span class="params">(<span class="keyword">int</span> a,<span class="keyword">int</span> b)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> c;</span><br><span class="line">}<span class="comment">//其中,参数a,参数b和变量c都是存放在栈区,当函数执行完毕的时候,它们占有的空间自动释放。</span></span><br></pre></td></tr></table></figure><p><strong>2、堆区(heap)</strong></p><p>一般由程序员分配释放(malloc&free), 若程序员不释放,程序结束时可能由OS(operating system)回收 。分配方式类似于链表。例如:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">char</span> *src;</span><br><span class="line">src = (<span class="keyword">char</span>*)<span class="built_in">malloc</span>(<span class="number">4</span> *<span class="keyword">sizeof</span>(<span class="keyword">char</span>));</span><br><span class="line"><span class="comment">//动态分配内存,表示查找可用的连续4个字节内存的空间,并将该内存首地址强制转换为指向字符数据的指针赋给scr,为src这个指针变量分配4个char类型的空间。</span></span><br></pre></td></tr></table></figure><p><strong>3、数据区(全局区)</strong></p><p>1、(文字)常量区:存放常量,一般是字符串常量。<br>2、静态区(static):存放全局变量和静态变量。<br>该区域是在程序结束后由操作系统释放。</p><p><strong>4、程序代码区</strong></p><p>存放函数体(类成员函数和全局函数)的二进制代码,也是由操作系统进行管理。</p><h3 id="三、一个例子"><a href="#三、一个例子" class="headerlink" title="三、一个例子"></a>三、一个例子</h3><hr><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdlib.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">int</span> i;</span><br><span class="line"> <span class="keyword">char</span>* p1[<span class="number">3</span>]= {<span class="string">"abc"</span>,<span class="string">"def"</span>,<span class="string">"ghi"</span>};</span><br><span class="line"> <span class="keyword">char</span> p2[<span class="number">3</span>][<span class="number">4</span>]= {<span class="string">"123"</span>,<span class="string">"456"</span>,<span class="string">"789"</span>};</span><br><span class="line"> <span class="keyword">char</span>** p3= (<span class="keyword">char</span>**)<span class="built_in">malloc</span>( <span class="number">3</span> * <span class="keyword">sizeof</span>(<span class="keyword">char</span>*));</span><br><span class="line"> <span class="keyword">for</span>(i=<span class="number">0</span>;i < <span class="number">3</span>;i++)</span><br><span class="line"> {</span><br><span class="line"> p3[i]= (<span class="keyword">char</span> *)<span class="built_in">malloc</span> ( <span class="number">5</span> * <span class="keyword">sizeof</span>(<span class="keyword">char</span>));</span><br><span class="line"> <span class="built_in">sprintf</span>(p3[i],<span class="string">"%d%d%d"</span>,i,i,i); </span><br><span class="line"> <span class="comment">/*</span></span><br><span class="line"><span class="comment"> sprintf()函数:最常见的应用之一是把整数打印到字符串中</span></span><br><span class="line"><span class="comment"> 例如:</span></span><br><span class="line"><span class="comment"> srpintf(s,"%d",123);</span></span><br><span class="line"><span class="comment"> 输出为:"123"</span></span><br><span class="line"><span class="comment"> 输出结果不会打印在屏幕上,而是写入字符串中</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%s\n"</span>,p3[i]);</span><br><span class="line"> <span class="comment">/*</span></span><br><span class="line"><span class="comment"> printf()函数才将结果输出到屏幕上</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">free</span>(p3);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images/%E4%B8%80%E4%B8%AA%E4%BE%8B%E5%AD%90.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/%E4%B8%80%E4%B8%AA%E4%BE%8B%E5%AD%90.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><h3 id="四、参考资料"><a href="#四、参考资料" class="headerlink" title="四、参考资料"></a>四、参考资料</h3><hr><p><a href="https://www.cnblogs.com/yif1991/p/5049638.html">C语言知识整理(3):内存管理(详细版)</a></p><p><a href="https://www.jianshu.com/p/98cb5f584a31">C语言中一些关于内存四区的归纳</a></p>]]></content>
<summary type="html"><p>简介:嵌入式系统的内存资源很稀缺,其内存页会更小,在嵌入式开发当中需要特别注意内存管理。</p></summary>
<category term="知识" scheme="https://kelecn.top/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="嵌入式" scheme="https://kelecn.top/tags/%E5%B5%8C%E5%85%A5%E5%BC%8F/"/>
<category term="C语言" scheme="https://kelecn.top/tags/C%E8%AF%AD%E8%A8%80/"/>
<category term="内存" scheme="https://kelecn.top/tags/%E5%86%85%E5%AD%98/"/>
</entry>
<entry>
<title>常见总线通讯协议:SPI、I2C、UART、USART、CAN、USB等</title>
<link href="https://kelecn.top/posts/55976/"/>
<id>https://kelecn.top/posts/55976/</id>
<published>2020-09-05T13:50:00.000Z</published>
<updated>2021-10-22T11:54:29.030Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:介绍常见总线通讯协议:SPI、I2C、UART、USART、CAN、USB等。</p><a id="more"></a><h3 id="一、SPI:串行外设接口"><a href="#一、SPI:串行外设接口" class="headerlink" title="一、SPI:串行外设接口"></a>一、SPI:串行外设接口</h3><hr><p>SPI(Serial Peripheral Interface)是一种由Motorola公司提出的串行同步通讯协议,由一个主设备和一个或多个从设备组成。其拥有四根(类)硬脚引线,分别为 SDI(串行数据输入),SDO(串行数据输出),SCK(串行移位时钟),CS(片选)。因为一个主设备可以挂多个从设备,则通过片选引脚对从设备进行选择。从设备的工作时钟则是来自于主设备的SCK线。</p><p><strong>1.1 电路示意图</strong></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/spi1.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/spi1.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><strong>1.2 数据的传输</strong></p><p>SPI在数据传输的时候,需要确定两件事情:其一,数据是在时钟的上升沿采集还是下降沿采集;其二,时钟的初始(空闲)状态是为高电平还是低电平。而I2C的空闲状态,时钟线为高电平;数据采集的时候,时钟线也为高电平。但SPI给出了更自由的方式。</p><p>CPOL:时钟极性, 表示 SPI 在空闲时, 时钟信号是高电平还是低电平。</p><p>CPHA:时钟相位, 表示 SPI 设备是在 SCK 管脚上的时钟信号变为上升沿时触发数据采样, 还是在时钟信号变为下降沿时触发数据采样。</p><p>那么,SPI CPOL有两种可能,CPHA有两种可能,则SPI数据传输就有四种可能—按照标准的说法,SPI数据传输就有四种模式。</p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/spi2.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/spi2.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/spi3.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/spi3.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/spi4.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/spi4.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/spi5.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/spi5.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/spi6.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/spi6.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><strong>1.3 SPI读写</strong></p><p>SPI在硬件设计上采用的双数据线制,根据设计,在SPI通信过程中,主从设备之间会形成一个数据环形链路—也即是,主设备向从设备写一次数据,从设备就会回一次数据(至于该从设备回复的数据是否有效,则另当别论—如果有效,主设备就把它读入;如果无效,则丢弃即可)。</p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/spi7.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/spi7.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/spi8.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/spi8.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><h3 id="二、I2C:意为IC之间总线"><a href="#二、I2C:意为IC之间总线" class="headerlink" title="二、I2C:意为IC之间总线"></a>二、I2C:意为IC之间总线</h3><hr><p><strong>I²C</strong> (<strong>Inter-Integrated Circuit</strong>)。其拥有一根数据线SDA和一根时钟线SCL。其总线通过上拉电阻与电源相连接。每个接到I2C总线上的器件都有唯一的地址。其中,主动发起操作的一方为主机,另外一方为从机。</p><p><strong>1.1 电路示意图</strong></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/I2C1.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/I2C1.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><strong>1.2 数据传输</strong></p><p>当没有数据传输的时候,两根总线都为高电平;当采集IIC上的数据时,其时钟线SCL必须是高电平且SDA的数据必须保持稳定不变—将SDA的电平与SCL的高电平进行“与”操作后,以便确定SDA上是1还是0;在SCL为低电平的时候,SDA上的数据可以进行跳变。</p><p>数据传输开始时,需要发送一个起始信号;数据传输结束后,需要发送一个终止信号;每8bit数据传输结束,都需要一个ACK。起止信号都有Master发出,而ACK则可能由Master或者SLAVE来发出。数据的传输采用大端传输。</p><p>开始信号:SCL为高电平,SDA的电平由高跳到低表示开始信号。</p><p>终止信号:SCL为高电平,SDA的电平由低跳到高表示终止信号。</p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/I2C2.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/I2C2.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><strong>1.3 数据协议</strong></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/I2C3.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/I2C3.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><strong>1.4 I2C读写流程</strong></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/I2C4.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/I2C4.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/I2C5.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/I2C5.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/I2C6.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/I2C6.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/I2C7.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/I2C7.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><h3 id="三、UART:通用异步收发器"><a href="#三、UART:通用异步收发器" class="headerlink" title="三、UART:通用异步收发器"></a>三、UART:通用异步收发器</h3><hr><p><strong>1.1 电路示意图</strong></p><p>UART是一个大家族,其包括了RS232、RS499、RS423、RS422和RS485等接口标准规范和总线标准规范。它们的主要区别在于其各自的电平范围不相同。</p><p>嵌入式设备中常常使用到的是TTL、TTL转RS232的这种方式。常用的就三根引线:发送线TX、接收线RX、电平参考地线GND。</p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/UART1.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/UART1.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><strong>1.2 通信协议</strong></p><p>将传输数据的每个字符一位接一位地传输。</p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/UART2.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/UART2.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p>起始位:先发出一个逻辑”0”的信号,表示传输字符的开始。</p><p>数据位:紧接着起始位之后。数据位的个数可以是4、5、6、7、8等,构成一个字符。通常采用ASCII码。</p><p>奇偶校验位:数据位加上这一位后,使得“1”的位数应为偶数(偶校验)或奇数(奇校验),以此来校验资料传送的正确性。</p><p>停止位:它是一个字符数据的结束标志。可以是1位、1.5位、2位的高电平。</p><p>空闲位:处于逻辑“1”状态,表示当前线路上没有资料传送。</p><p>波特率:数据传输的速率。有以下几个档位:300、600、1200、2400、4800、9600、19200、38400、43000、56000、57600、115200.当然也可以自定义。在数据传输和接收双方,需要预先统一波特率,以便正确的传输数据。</p><h3 id="四、USART:通用同步异步收发器"><a href="#四、USART:通用同步异步收发器" class="headerlink" title="四、USART:通用同步异步收发器"></a>四、USART:通用同步异步收发器</h3><hr><p>USART是一个全双工通用同步/异步串行收发模块,该接口是一个高度灵活的串行通信设备。</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">1. 全双工操作(相互独立的接收数据和发送数据);</span><br><span class="line">2. 同步操作时,可主机时钟同步,也可从机时钟同步;</span><br><span class="line">3. 独立的高精度波特率发生器,不占用定时/计数器;</span><br><span class="line">4. 支持5、6、7、8和9位数据位,1或2位停止位的串行数据桢结构;</span><br><span class="line">5. 由硬件支持的奇偶校验位发生和检验;</span><br><span class="line">6. 数据溢出检测;</span><br><span class="line">7. 帧错误检测;</span><br><span class="line">8. 包括错误起始位的检测噪声滤波器和数字低通滤波器;</span><br><span class="line">9. 三个完全独立的中断,TX发送完成、TX发送数据寄存器空、RX接收完成;</span><br><span class="line">10.支持多机通信模式;</span><br><span class="line">11.支持倍速异步通信模式。</span><br></pre></td></tr></table></figure><h3 id="五、CAN:现场总线"><a href="#五、CAN:现场总线" class="headerlink" title="五、CAN:现场总线"></a>五、CAN:现场总线</h3><hr><p>CAN是控制器局域网络(Controller Area Network, CAN)的简称,是由以研发和生产汽车电子产品著称的德国BOSCH公司开发的,并最终成为国际标准(ISO 11898),是国际上应用最广泛的现场总线之一。 在北美和西欧,CAN总线协议已经成为汽车计算机控制系统和嵌入式工业控制局域网的标准总线,并且拥有以CAN为底层协议专为大型货车和重工机械车辆设计的J1939协议。</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">CAN属于现场总线的范畴,它是一种有效支持分布式控制或实时控制的串行通信网络。较之许多RS-485基于R线构建的分布式控制系统而言,基于CAN总线的分布式控制系统在以下方面具有明显的优越性:</span><br><span class="line">1、网络各节点之间的数据通信实时性强</span><br><span class="line">2、开发周期短</span><br><span class="line">3、已形成国际标准的现场总线</span><br><span class="line">4、最有前途的现场总线之一</span><br></pre></td></tr></table></figure><h3 id="六、LIN:局域互联网络"><a href="#六、LIN:局域互联网络" class="headerlink" title="六、LIN:局域互联网络"></a>六、LIN:局域互联网络</h3><hr><p>LIN总线是针对汽车分布式电子系统而定义的一种低成本的串行通讯网络,是对控制器区域网络(CAN)等其它汽车多路网络的一种补充,适用于对网络的带宽、性能或容错功能没有过高要求的应用。LIN总线是基于SCI(UART)数据格式,采用单主控制器/多从设备的模式,是UART中的一种特殊情况。</p><h3 id="七、USB:通用串行总线"><a href="#七、USB:通用串行总线" class="headerlink" title="七、USB:通用串行总线"></a>七、USB:通用串行总线</h3><hr><p>USB是英文Universal Serial BUS(通用串行总线)的缩写,是一个外部总线标准,用于规范电脑与外部设备的连接和通讯,是应用在PC 领域的接口技术。USB 接口支持设备的即 即用和热插拔功能。USB 是在1994 年底由尔、康柏.IBM、Microsoft 等多家公司联合提出的.USB的电气特性还有传输特性</p><h3 id="八、GPIO:通用输入-输出"><a href="#八、GPIO:通用输入-输出" class="headerlink" title="八、GPIO:通用输入/输出"></a>八、GPIO:通用输入/输出</h3><hr><p> <strong>GPIO</strong>(General Purpose Input Output )为通用输入/输出,通用端口,总线扩展器, 利用工业标准I2C、SMBus™或SPI™接口简化了I/O口的扩展。当微控制器或芯片组没有足够的I/O端口,或当系统需要采用远端串行通信或控制时,GPIO产品能够提供额外的控制和监视功能。</p><p>由于LIN网络在汽车中一般不独立存在,通常会与上层CAN网络相连,形成CAN-LIN网关节点。</p><h3 id="九、SPI、I2C、UART、CAN、LIN对比"><a href="#九、SPI、I2C、UART、CAN、LIN对比" class="headerlink" title="九、SPI、I2C、UART、CAN、LIN对比"></a>九、SPI、I2C、UART、CAN、LIN对比</h3><hr><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images/%E6%80%BB%E7%BA%BF%E5%8D%8F%E8%AE%AE%E5%AF%B9%E6%AF%94.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/%E6%80%BB%E7%BA%BF%E5%8D%8F%E8%AE%AE%E5%AF%B9%E6%AF%94.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><h3 id="十、参考文献"><a href="#十、参考文献" class="headerlink" title="十、参考文献"></a>十、参考文献</h3><hr><p><a href="https://blog.csdn.net/weixin_43046653/article/details/84998083?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param">通信方式梳理:GPIO,I2C,SPI,UART,USART,USB的区别</a></p><p><a href="https://blog.csdn.net/qq_32693119/article/details/81263446">通信总线协议学习整理</a></p><p><a href="https://blog.csdn.net/weixin_43046653/article/details/84998083?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param">通信方式梳理:GPIO,I2C,SPI,UART,USART,USB的区别</a></p><p><a href="https://blog.csdn.net/u010183728/article/details/81984433">SPI、I2C、UART、CAN</a></p>]]></content>
<summary type="html"><p>简介:介绍常见总线通讯协议:SPI、I2C、UART、USART、CAN、USB等。</p></summary>
<category term="知识" scheme="https://kelecn.top/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="SPI" scheme="https://kelecn.top/tags/SPI/"/>
<category term="I2C" scheme="https://kelecn.top/tags/I2C/"/>
<category term="USB" scheme="https://kelecn.top/tags/USB/"/>
<category term="总线" scheme="https://kelecn.top/tags/%E6%80%BB%E7%BA%BF/"/>
</entry>
<entry>
<title>精简指令集计算机(RISC)和复杂指令集计算机(CISC)的区别</title>
<link href="https://kelecn.top/posts/38602/"/>
<id>https://kelecn.top/posts/38602/</id>
<published>2020-09-01T13:50:00.000Z</published>
<updated>2021-04-03T06:54:24.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:精简指令集计算机(RISC)和复杂指令集计算机(CISC)的区别</p><a id="more"></a><h3 id="一、RISC(精简指令集计算机)"><a href="#一、RISC(精简指令集计算机)" class="headerlink" title="一、RISC(精简指令集计算机)"></a>一、RISC(精简指令集计算机)</h3><hr><p>RISC(reduced instruction set computer,精简指令集计算机)是一种执行较少类型计算机指令的微处理器。这样一来,它能够以更快的速度执行操作。因为计算机执行每个指令类型都需要额外的晶体管和电路元件,计算机指令集越大就会使微处理器更复杂,执行操作也会更慢。</p><h3 id="二、-CISC-复杂指令集计算机)"><a href="#二、-CISC-复杂指令集计算机)" class="headerlink" title="二、 CISC(复杂指令集计算机)"></a>二、 CISC(复杂指令集计算机)</h3><hr><p>除了RISC,任何全指令集计算机都使用的是CISC(complexinstruction set computer,复杂指令集计算机)。</p><p>目前常见使用RISC的处理器包括DEC Alpha、ARC、ARM、MIPS、PowerPC、SPARC和SuperH等。</p><p>常见使用CISC的处理器主要有X86.</p><h3 id="三、RISC和CISC的区别"><a href="#三、RISC和CISC的区别" class="headerlink" title="三、RISC和CISC的区别"></a>三、RISC和CISC的区别</h3><hr><p><strong>(1) 指令系统:</strong>RISC 设计者把主要精力放在那些经常使用的指令上,尽量使它们具有简单高效的特色。对不常用的功能,常通过组合指令来完成。因此,在RISC 机器上实现特殊功能时,效率可能较低。但可以利用流水技术和超标量技术加以改进和弥补。而CISC 计算机的指令系统比较丰富,有专用指令来完成特定的功能。因此,处理特殊任务效率较高。</p><p><strong>(2) 存储器操作:</strong>RISC 对存储器操作有限制,使控制简单化;而CISC 机器的存储器操作指令多,操作直接。</p><p><strong>(3) 程序:</strong>RISC 汇编语言程序一般需要较大的内存空间,实现特殊功能时程序复杂,不易设计;而CISC 汇编语言程序编程相对简单,科学计算及复杂操作的程序设计相对容易,效率较高。</p><p><strong>(4) 中断:</strong>RISC 机器在一条指令执行的适当地方可以响应中断;而CISC 机器是在一条指令执行结束后响应中断。</p><p><strong>(5) CPU芯片电路:</strong>RISC CPU 包含有较少的单元电路,因而面积小、功耗低;而CISC CPU 包含有丰富的电路单元,因而功能强、面积大、功耗大。</p><p><strong>(6) 设计周期:</strong>RISC 微处理器结构简单,布局紧凑,设计周期短,且易于采用最新技术;CISC 微处理器结构复杂,设计周期长。</p><p><strong>(7) 用户使用:</strong>RISC 微处理器结构简单,指令规整,性能容易把握,易学易用;CISC微处理器结构复杂,功能强大,实现特殊功能容易。</p><p><strong>(8) 应用范围:</strong>由于RISC 指令系统的确定与特定的应用领域有关,故RISC 机器更适合于专用机;而CISC 机器则更适合于通用机。</p><h3 id="四、参考文章"><a href="#四、参考文章" class="headerlink" title="四、参考文章"></a>四、参考文章</h3><hr><p><a href="https://blog.csdn.net/WHEgqing/article/details/101300822">RISC和CISC的区别</a></p>]]></content>
<summary type="html"><p>简介:精简指令集计算机(RISC)和复杂指令集计算机(CISC)的区别</p></summary>
<category term="知识" scheme="https://kelecn.top/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="CISC" scheme="https://kelecn.top/tags/CISC/"/>
<category term="RISC" scheme="https://kelecn.top/tags/RISC/"/>
<category term="指令集" scheme="https://kelecn.top/tags/%E6%8C%87%E4%BB%A4%E9%9B%86/"/>
</entry>
<entry>
<title>几种常见的DC-DC拓扑</title>
<link href="https://kelecn.top/posts/50067/"/>
<id>https://kelecn.top/posts/50067/</id>
<published>2020-08-28T13:50:00.000Z</published>
<updated>2021-04-03T06:54:14.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:开关电源三大基础拓扑解析:BUCK/BOOST/BUCK-BOOST</p><a id="more"></a><h3 id="一、Buck-拓扑电路"><a href="#一、Buck-拓扑电路" class="headerlink" title="一、Buck 拓扑电路"></a>一、Buck 拓扑电路</h3><hr><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/Buck%E9%99%8D%E5%8E%8B.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/Buck%E9%99%8D%E5%8E%8B.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br>Buck电路是一个降压电路,Uin=Ul+Uo。因Uin>Uo,故具有降压作用。</p><h3 id="二、Boost拓扑电路"><a href="#二、Boost拓扑电路" class="headerlink" title="二、Boost拓扑电路"></a>二、Boost拓扑电路</h3><hr><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/Boost%E5%8D%87%E5%8E%8B.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/Boost%E5%8D%87%E5%8E%8B.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br>Boost电路是一个升压电路,Uo=Uin+Ul-Ud ,由于Ud值较小,忽略不计,Uin+Ul>Uo,故具有升压作用。</p><h3 id="三、Buck-Boost拓扑电路"><a href="#三、Buck-Boost拓扑电路" class="headerlink" title="三、Buck-Boost拓扑电路"></a>三、Buck-Boost拓扑电路</h3><hr><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/Buck-Boost.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/Buck-Boost.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><ul><li>其中的器件和Buck电路完全一致,只是开关SW,二极管和电感的位置发生了改变</li><li>Buck-Boost变换器输出的是相对地的负压<h3 id="四、参考文献"><a href="#四、参考文献" class="headerlink" title="四、参考文献"></a>四、参考文献</h3></li></ul><hr><p><a href="https://blog.csdn.net/ima_xu/article/details/88393304">开关电源学习笔记1 — Buck变换器的基本原理</a><br><a href="https://blog.csdn.net/ima_xu/article/details/88382812">开关电源学习笔记2 — Boost变换器的基本原理</a><br><a href="https://blog.csdn.net/ima_xu/article/details/88536926">开关电源学习笔记3 — Buck-Boost变换器的基本原理</a><br><a href="https://zhuanlan.zhihu.com/p/52887325">开关电源三大基础拓扑解析:BUCK/BOOST/BUCK-BOOST</a></p>]]></content>
<summary type="html"><p>简介:开关电源三大基础拓扑解析:BUCK/BOOST/BUCK-BOOST</p></summary>
<category term="知识" scheme="https://kelecn.top/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="Boost" scheme="https://kelecn.top/tags/Boost/"/>
<category term="Buck" scheme="https://kelecn.top/tags/Buck/"/>
<category term="DCDC" scheme="https://kelecn.top/tags/DCDC/"/>
</entry>
<entry>
<title>一文搞懂TCP与UDP的区别</title>
<link href="https://kelecn.top/posts/22814/"/>
<id>https://kelecn.top/posts/22814/</id>
<published>2020-08-26T13:57:00.000Z</published>
<updated>2021-04-03T06:54:04.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:网络协议是每个IT工程师都必须要掌握的知识,TCP/IP 中有两个具有代表性的传输层协议,分别是 TCP 和 UDP,本文将介绍下这两者以及它们之间的区别。</p><a id="more"></a><h3 id="一、TCP-IP网络模型"><a href="#一、TCP-IP网络模型" class="headerlink" title="一、TCP/IP网络模型"></a>一、TCP/IP网络模型</h3><hr><p>计算机与网络设备要相互通信,双方就必须基于相同的方法。比如,如何探测到通信目标、由哪一边先发起通信、使用哪种语言进行通信、怎样结束通信等规则都需要事先确定。不同的硬件、操作系统之间的通信,所有的这一切都需要一种规则。而我们就把这种规则称为协议(protocol)。</p><p>TCP/IP 是互联网相关的各类协议族的总称,比如:TCP,UDP,IP,FTP,HTTP,ICMP,SMTP 等都属于 TCP/IP 族内的协议。</p><p>TCP/IP模型是互联网的基础,它是一系列网络协议的总称。这些协议可以划分为四层,分别为链路层、网络层、传输层和应用层。</p><ul><li>链路层:负责封装和解封装IP报文,发送和接受ARP/RARP报文等。</li><li>网络层:负责路由以及把分组报文发送给目标网络或主机。</li><li>传输层:负责对报文进行分组和重组,并以TCP或UDP协议格式封装报文。</li><li>应用层:负责向用户提供应用程序,比如HTTP、FTP、Telnet、DNS、SMTP等。</li></ul><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/2019-03-21-01.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/2019-03-21-01.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p>在网络体系结构中网络通信的建立必须是在通信双方的对等层进行,不能交错。 在整个数据传输过程中,数据在发送端时经过各层时都要附加上相应层的协议头和协议尾(仅数据链路层需要封装协议尾)部分,也就是要对数据进行协议封装,以标识对应层所用的通信协议。接下去介绍TCP/IP 中有两个具有代表性的传输层协议—-TCP 和 UDP。</p><h3 id="二、UDP"><a href="#二、UDP" class="headerlink" title="二、UDP"></a>二、UDP</h3><hr><p>UDP协议全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。在OSI模型中,在第四层——传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。</p><p>它有以下几个特点:</p><p><strong>1. 面向无连接</strong></p><p>首先 UDP 是不需要和 TCP一样在发送数据前进行三次握手建立连接的,想发数据就可以开始发送了。并且也只是数据报文的搬运工,不会对数据报文进行任何拆分和拼接操作。</p><p>具体来说就是:</p><ul><li>在发送端,应用层将数据传递给传输层的 UDP 协议,UDP 只会给数据增加一个 UDP 头标识下是 UDP 协议,然后就传递给网络层了</li><li>在接收端,网络层将数据传递给传输层,UDP 只去除 IP 报文头就传递给应用层,不会任何拼接操作</li></ul><p><strong>2. 有单播,多播,广播的功能</strong></p><p>UDP 不止支持一对一的传输方式,同样支持一对多,多对多,多对一的方式,也就是说 UDP 提供了单播,多播,广播的功能。</p><p><strong>3. UDP是面向报文的</strong></p><p>发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付IP层。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。因此,应用程序必须选择合适大小的报文</p><p><strong>4. 不可靠性</strong></p><p>首先不可靠性体现在无连接上,通信都不需要建立连接,想发就发,这样的情况肯定不可靠。</p><p>并且收到什么数据就传递什么数据,并且也不会备份数据,发送数据也不会关心对方是否已经正确接收到数据了。</p><p>再者网络环境时好时坏,但是 UDP 因为没有拥塞控制,一直会以恒定的速度发送数据。即使网络条件不好,也不会对发送速率进行调整。这样实现的弊端就是在网络条件不好的情况下可能会导致丢包,但是优点也很明显,在某些实时性要求高的场景(比如电话会议)就需要使用 UDP 而不是 TCP。</p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/2019-03-21-02.gif" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/2019-03-21-02.gif" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p>从上面的动态图可以得知,UDP只会把想发的数据报文一股脑的丢给对方,并不在意数据有无安全完整到达。</p><p><strong>5. 头部开销小,传输数据报文时是很高效的。</strong></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/2019-03-21-03.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/2019-03-21-03.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p>UDP 头部包含了以下几个数据:</p><ul><li>两个十六位的端口号,分别为源端口(可选字段)和目标端口</li><li>整个数据报文的长度</li><li>整个数据报文的检验和(IPv4 可选 字段),该字段用于发现头部信息和数据中的错误</li></ul><p>因此 UDP 的头部开销小,只有八字节,相比 TCP 的至少二十字节要少得多,在传输数据报文时是很高效的</p><h3 id="三、TCP"><a href="#三、TCP" class="headerlink" title="三、TCP"></a>三、TCP</h3><hr><p>当一台计算机想要与另一台计算机通讯时,两台计算机之间的通信需要畅通且可靠,这样才能保证正确收发数据。例如,当你想查看网页或查看电子邮件时,希望完整且按顺序查看网页,而不丢失任何内容。当你下载文件时,希望获得的是完整的文件,而不仅仅是文件的一部分,因为如果数据丢失或乱序,都不是你希望得到的结果,于是就用到了TCP。</p><p>TCP协议全称是传输控制协议是一种面向连接的、可靠的、基于字节流的传输层通信协议,由 IETF 的RFC 793定义。TCP 是面向连接的、可靠的流协议。流就是指不间断的数据结构,你可以把它想象成排水管中的水流。</p><p><strong>1. TCP连接过程</strong></p><p>如下图所示,可以看到建立一个TCP连接的过程为(三次握手的过程):</p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/2019-03-21-04.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/2019-03-21-04.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><strong>第一次握手</strong></p><p>客户端向服务端发送连接请求报文段。该报文段中包含自身的数据通讯初始序号。请求发送后,客户端便进入 SYN-SENT 状态。</p><p><strong>第二次握手</strong></p><p>服务端收到连接请求报文段后,如果同意连接,则会发送一个应答,该应答中也会包含自身的数据通讯初始序号,发送完成后便进入 SYN-RECEIVED 状态。</p><p><strong>第三次握手</strong></p><p>当客户端收到连接同意的应答后,还要向服务端发送一个确认报文。客户端发完这个报文段后便进入 ESTABLISHED 状态,服务端收到这个应答后也进入 ESTABLISHED 状态,此时连接建立成功。</p><p>这里可能大家会有个疑惑:为什么 TCP 建立连接需要三次握手,而不是两次?这是因为这是为了防止出现失效的连接请求报文段被服务端接收的情况,从而产生错误。</p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/2019-03-21-05.gif" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/2019-03-21-05.gif" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><strong>2. TCP断开链接</strong></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/2019-03-21-06.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/2019-03-21-06.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p>TCP 是全双工的,在断开连接时两端都需要发送 FIN 和 ACK。</p><p><strong>第一次握手</strong></p><p>若客户端 A 认为数据发送完成,则它需要向服务端 B 发送连接释放请求。</p><p><strong>第二次握手</strong></p><p>B 收到连接释放请求后,会告诉应用层要释放 TCP 链接。然后会发送 ACK 包,并进入 CLOSE_WAIT 状态,此时表明 A 到 B 的连接已经释放,不再接收 A 发的数据了。但是因为 TCP 连接是双向的,所以 B 仍旧可以发送数据给 A。</p><p><strong>第三次握手</strong></p><p>B 如果此时还有没发完的数据会继续发送,完毕后会向 A 发送连接释放请求,然后 B 便进入 LAST-ACK 状态。</p><p><strong>第四次握手</strong></p><p>A 收到释放请求后,向 B 发送确认应答,此时 A 进入 TIME-WAIT 状态。该状态会持续 2MSL(最大段生存期,指报文段在网络中生存的时间,超时会被抛弃) 时间,若该时间段内没有 B 的重发请求的话,就进入 CLOSED 状态。当 B 收到确认应答后,也便进入 CLOSED 状态。</p><p><strong>3. TCP协议的特点</strong></p><ul><li><p>面向连接</p><p>面向连接,是指发送数据之前必须在两端建立连接。建立连接的方法是“三次握手”,这样能建立可靠的连接。建立连接,是为数据的可靠传输打下了基础。</p></li><li><p>仅支持单播传输</p></li></ul><p>每条TCP传输连接只能有两个端点,只能进行点对点的数据传输,不支持多播和广播传输方式。</p><ul><li>面向字节流</li></ul><p>TCP不像UDP一样那样一个个报文独立地传输,而是在不保留报文边界的情况下以字节流方式进行传输。</p><ul><li><p>可靠传输</p><p>对于可靠传输,判断丢包,误码靠的是TCP的段编号以及确认号。TCP为了保证报文传输的可靠,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的字节发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据(假设丢失了)将会被重传。</p></li><li><p>提供拥塞控制</p></li></ul><p>当网络出现拥塞的时候,TCP能够减小向网络注入数据的速率和数量,缓解拥塞</p><ul><li>TCP提供全双工通信</li></ul><p>TCP允许通信双方的应用程序在任何时候都能发送数据,因为TCP连接的两端都设有缓存,用来临时存放双向通信的数据。当然,TCP可以立即发送一个数据段,也可以缓存一段时间以便一次发送更多的数据段(最大的数据段大小取决于MSS)</p><h3 id="四、TCP和UDP的比较"><a href="#四、TCP和UDP的比较" class="headerlink" title="四、TCP和UDP的比较"></a>四、TCP和UDP的比较</h3><hr><p><strong>1. 对比</strong></p><table><thead><tr><th align="left"></th><th align="left">UDP</th><th>TCP</th></tr></thead><tbody><tr><td align="left">是否连接</td><td align="left">无连接</td><td>面向连接</td></tr><tr><td align="left">是否可靠</td><td align="left">不可靠传输,不使用流量控制和拥塞控制</td><td>可靠传输,使用流量控制和拥塞控制</td></tr><tr><td align="left">连接对象个数</td><td align="left">支持一对一,一对多,多对一和多对多交互通信</td><td>只能是一对一通信</td></tr><tr><td align="left">传输方式</td><td align="left">面向报文</td><td>面向字节流</td></tr><tr><td align="left">首部开销</td><td align="left">首部开销小,仅8字节</td><td>首部最小20字节,最大60字节</td></tr><tr><td align="left">适用场景</td><td align="left">适用于实时应用(IP电话、视频会议、直播等)</td><td>适用于要求可靠传输的应用,例如文件传输</td></tr></tbody></table><p><strong>2. 总结</strong></p><ul><li>TCP向上层提供面向连接的可靠服务 ,UDP向上层提供无连接不可靠服务。</li><li>虽然 UDP 并没有 TCP 传输来的准确,但是也能在很多实时性要求高的地方有所作为</li><li>对数据准确性要求高,速度可以相对较慢的,可以选用TCP</li></ul><h3 id="五、参考文章"><a href="#五、参考文章" class="headerlink" title="五、参考文章"></a><strong>五、参考文章</strong></h3><hr><p><strong><a href="https://www.cnblogs.com/fundebug/p/differences-of-tcp-and-udp.html">一文搞懂TCP与UDP的区别</a></strong> </p><p><strong><a href="https://blog.csdn.net/qq_38950316/article/details/81087809">TCP的三次握手与四次挥手理解及面试题(很全面)</a></strong></p>]]></content>
<summary type="html"><p>简介:网络协议是每个IT工程师都必须要掌握的知识,TCP/IP 中有两个具有代表性的传输层协议,分别是 TCP 和 UDP,本文将介绍下这两者以及它们之间的区别。</p></summary>
<category term="知识" scheme="https://kelecn.top/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="TCP" scheme="https://kelecn.top/tags/TCP/"/>
<category term="UDP" scheme="https://kelecn.top/tags/UDP/"/>
<category term="计算机网络" scheme="https://kelecn.top/tags/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/"/>
</entry>
<entry>
<title>C语言基础知识(复习)</title>
<link href="https://kelecn.top/posts/57201/"/>
<id>https://kelecn.top/posts/57201/</id>
<published>2020-08-25T13:57:00.000Z</published>
<updated>2021-04-03T06:53:56.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介: 嵌入式笔试相关题目、考点。</p><a id="more"></a><h3 id="一、static关键词"><a href="#一、static关键词" class="headerlink" title="一、static关键词"></a>一、static关键词</h3><hr><p>1)、用于声明函数体内的变量为静态局部变量,存储在静态数据存储区,在函数被调用过程中维持其值保持不变。<br>2)、在文件内(函数体外)被声明为静态的变量,可以被文件内的所有函数访问,但不能被其他文件的函数访问,是一个本地的局部变量。<br>3)、在文件内,被声明为静态的函数只可被文件内的其他函数调用,但不能被其他文件的函数调用。</p><h3 id="二、const关键词"><a href="#二、const关键词" class="headerlink" title="二、const关键词"></a>二、const关键词</h3><hr><p>常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的。不管出现在任何上下文都是为这个目的而服务的。<br>注意:非const变量默认为extern。要使const变量能够在其他文件中访问,必须在文件中显式地指定它为extern。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> a;</span><br><span class="line"><span class="comment">//同上面的代码行是等价的,都表示一个常整形数。</span></span><br><span class="line"><span class="keyword">int</span> <span class="keyword">const</span> a;</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* const具有"左结合"性,即const修饰*,那么,不难理解,该句表示一个指向整数的常指针,</span></span><br><span class="line"><span class="comment"> a指向的整数可以修改,但指针a不能修改。</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">int</span> *<span class="keyword">const</span> a;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 同理,下面的这两行,根据"左结合"性,const修饰的是(*a),也即是一个整数,</span></span><br><span class="line"><span class="comment"> 所以,这两句表示指针指向一个常整数。</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> *a;</span><br><span class="line"><span class="keyword">int</span> <span class="keyword">const</span> *a;</span><br><span class="line"></span><br><span class="line"><span class="comment">//根据"左结合"性质,第一个const修饰(*),第二个const修饰(a),因此,这句话表示一个指向常整数的常指针。</span></span><br><span class="line"><span class="keyword">int</span> <span class="keyword">const</span> *a <span class="keyword">const</span>;</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="keyword">char</span> *p; <span class="comment">//*p是const,p可变</span></span><br><span class="line"><span class="keyword">const</span> (<span class="keyword">char</span> *) p;<span class="comment">//p是const,*p可变</span></span><br><span class="line"><span class="keyword">char</span>* <span class="keyword">const</span> p; <span class="comment">//p是const,*p可变</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">char</span>* <span class="keyword">const</span> p; <span class="comment">//p和*p都是const</span></span><br><span class="line"><span class="keyword">char</span> <span class="keyword">const</span> * p;<span class="comment">// *p是const,p可变</span></span><br><span class="line">(<span class="keyword">char</span>*) <span class="keyword">const</span> p;<span class="comment">//p是const,*p可变</span></span><br><span class="line"><span class="keyword">char</span>* <span class="keyword">const</span> p;<span class="comment">// p是const,*p可变</span></span><br><span class="line"><span class="keyword">char</span> <span class="keyword">const</span>* <span class="keyword">const</span> p;<span class="comment">// p和*p都是const</span></span><br><span class="line"><span class="comment">//例如</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdlib.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><string.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="comment">//const修饰一个变量为只读</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> a = <span class="number">10</span>;</span><br><span class="line"><span class="comment">//a = 100; //err</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//指针变量, 指针指向的内存, 2个不同概念</span></span><br><span class="line"><span class="keyword">char</span> buf[] = <span class="string">"aklgjdlsgjlkds"</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//从左往右看,跳过类型,看修饰哪个字符</span></span><br><span class="line"><span class="comment">//如果是*, 说明指针指向的内存不能改变</span></span><br><span class="line"><span class="comment">//如果是指针变量,说明指针的指向不能改变,指针的值不能修改</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">char</span> *p = buf;</span><br><span class="line"><span class="comment">// 等价于上面 char const *p1 = buf;</span></span><br><span class="line"><span class="comment">//p[1] = '2'; //err</span></span><br><span class="line">p = <span class="string">"agdlsjaglkdsajgl"</span>; <span class="comment">//ok</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">char</span> * <span class="keyword">const</span> p2 = buf;</span><br><span class="line">p2[<span class="number">1</span>] = <span class="string">'3'</span>;</span><br><span class="line"><span class="comment">//p2 = "salkjgldsjaglk"; //err</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//p3为只读,指向不能变,指向的内存也不能变</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">char</span> * <span class="keyword">const</span> p3 = buf;</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="三、数组越界问题"><a href="#三、数组越界问题" class="headerlink" title="三、数组越界问题"></a>三、数组越界问题</h3><hr><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">test</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="keyword">char</span> <span class="built_in">string</span>[<span class="number">10</span>];<span class="comment">//应该是char string[11];//字符串数组最后一位是\0</span></span><br><span class="line"><span class="keyword">char</span>*str=<span class="string">"0123456789"</span>;</span><br><span class="line"><span class="built_in">strcpy</span>(<span class="built_in">string</span>,str);<span class="comment">//err</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="四、C语言中宏定义的使用"><a href="#四、C语言中宏定义的使用" class="headerlink" title="四、C语言中宏定义的使用"></a>四、C语言中宏定义的使用</h3><hr><p>==预处理==命令可以改变程序设计环境,提高编程效率,它们并不是 C 语言本身的组成部分,不能直接对 它们进行编译,必须在对程序进行编译之前,先对程序中这些特殊的命令进行“预处理” 。经过预处理后,程序就不再包括预处理命令了,最后再由编译程序对==预处理==之后的源程序进行==编译==处理,得到可供执行的目标代码。C 语言提供的预处理功能有三种,分别为==宏定义==、文件包含和条件编译。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 不带参数的宏定义</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> MAX 10</span></span><br><span class="line"><span class="comment">/*带参宏定义*/</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> M(y) y*y+3*y</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/*宏调用*/</span></span><br><span class="line">k=M(<span class="number">5</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//宏定义最大值</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> max(a,b) (((a)>(b))?(a):(b))</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line"><span class="built_in">cout</span> << max(<span class="number">1</span>+<span class="number">1</span>,<span class="number">2</span>+<span class="number">2</span>) << <span class="built_in">endl</span>;</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"><span class="comment">//这个面试题主要考查面试者对宏定义的使用,宏定义可以实现类似于函数的功能,但是它终归不是函数,而宏定义中括弧中的“参数”也不是真的参数,在宏展开的时候对“参数”进行的是一对一的替换。</span></span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">#define MAX( x, y ) ( ((x) > (y)) ? (x) : (y) )//输入a++,a=a+2 调用两次</span></span><br><span class="line"><span class="comment">#define MIN( x, y ) ( ((x) < (y)) ? (x) : (y) )</span></span><br><span class="line"><span class="comment">#define MAX( a, b ) ({int _a = a;int _b = b;(_a) > (_b)? (_a) :(_b); })</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="comment">/*程序员对宏定义的使用要非常小心,特别要注意两个问题:</span></span><br><span class="line"><span class="comment"> (1)谨慎地将宏定义中的“参数”和整个宏用用括弧括起来。所以,严格地讲,下述解答:</span></span><br><span class="line"><span class="comment">#define MIN(A,B) (A) <= (B) ? (A) : (B)</span></span><br><span class="line"><span class="comment">#define MIN(A,B) (A <= B ? A : B )</span></span><br><span class="line"><span class="comment"> 都应判0分;</span></span><br><span class="line"><span class="comment"> (2)防止宏的副作用。</span></span><br><span class="line"><span class="comment"> 宏定义#define MIN(A,B) ((A) <= (B) ? (A) : (B))对MIN(*p++, b)的作用结果是:</span></span><br><span class="line"><span class="comment">((*p++) <= (b) ? (*p++) : (*p++))</span></span><br><span class="line"><span class="comment"> 这个表达式会产生副作用,指针p会作三次++自增操作。</span></span><br><span class="line"><span class="comment"> 除此之外,另一个应该判0分的解答是:</span></span><br><span class="line"><span class="comment">#define MIN(A,B) ((A) <= (B) ? (A) : (B)); 不能在后面加冒号。</span></span><br></pre></td></tr></table></figure><p>参考文章:<a href="https://www.cnblogs.com/emptyYPen/p/7872604.html">宏定义正确处理a++</a></p><h3 id="五、递归算N!"><a href="#五、递归算N!" class="headerlink" title="五、递归算N!"></a>五、递归算N!</h3><hr><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"> <span class="function"><span class="keyword">long</span> <span class="title">fac</span><span class="params">(<span class="keyword">int</span> n)</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">long</span> f;</span><br><span class="line"> <span class="keyword">if</span>(n<<span class="number">0</span>)</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"n<0,data error!"</span>);</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span>(n==<span class="number">0</span>,n==<span class="number">1</span>)</span><br><span class="line"> f=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">else</span> f = fac(n<span class="number">-1</span>)*n;</span><br><span class="line"> <span class="keyword">return</span> (f);</span><br><span class="line"> }</span><br><span class="line"> <span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="function"><span class="keyword">long</span> <span class="title">fac</span><span class="params">(<span class="keyword">int</span> n)</span></span>;</span><br><span class="line"><span class="keyword">int</span> n,y;</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"input an integer number:"</span>);</span><br><span class="line"><span class="built_in">scanf</span>(<span class="string">"%d"</span>,&n);</span><br><span class="line">y= fac(n);</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"%d!=%ld\n"</span>,n,y);</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> } </span><br></pre></td></tr></table></figure><h3 id="六、中断服务子程序-ISR"><a href="#六、中断服务子程序-ISR" class="headerlink" title="六、中断服务子程序(ISR)"></a>六、中断服务子程序(ISR)</h3><hr><p>中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展-让标准C支持中断。其代表事实是,产生了一个新的关键字 interrupt(51即如此)。下面的代码就使用了interrupt关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">__interrupt <span class="keyword">double</span> <span class="title">compute_area</span> <span class="params">(<span class="keyword">double</span> radius)</span> </span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"></span><br><span class="line"><span class="keyword">double</span> area = PI * radius * radius;</span><br><span class="line"></span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"/nArea = %f"</span>, area);</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> area;</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">中断服务程序需要满足如下要求: </span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">(1)不能返回值; </span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">(2)不能向ISR传递参数; (嵌入式中的ISR指的是中断服务处理)</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">(3) ISR应该尽可能的短小精悍; </span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">(4) printf(char * lpFormatString,…)函数会带来重入和性能问题,不能在ISR中采用。</span></span><br><span class="line"><span class="comment">这个函数有太多的错误了,以至让人不知从何说起了(前提是**非操作系统**下的中断服务函数):</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">**1)ISR 不能返回一个值(都应该为void类型)。如果你不懂这个,那么你不会被雇用的。**</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">**2)ISR 不能传递参数。如果你没有看到这一点,你被雇用的机会等同第一项。**</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">3)在许多的处理器/编译器中,浮点一般都是不可重入的。有些处理器/编译器需要让额外的寄存器入栈,有些处理器/编译器就是不允许在ISR中做浮点运算。此外,ISR应该是**短而有效率**的,在ISR中做浮点运算是不明智的。另外中断服务程序是运行在内核态的(linux),**内核通常是不支持浮点运算的**。</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure><h3 id="七、位运算符"><a href="#七、位运算符" class="headerlink" title="七、位运算符"></a>七、位运算符</h3><hr><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//5=>0101,7=>0111</span></span><br><span class="line"><span class="number">1</span>)& 按位与<span class="comment">//5&7==>0101,也就是5</span></span><br><span class="line"></span><br><span class="line"><span class="number">2</span>)| 按位或<span class="comment">//5|7==>0111,也就是7</span></span><br><span class="line"></span><br><span class="line"><span class="number">3</span>)^ 按位异或<span class="comment">//5^7==>0010,也就是2</span></span><br><span class="line"></span><br><span class="line"><span class="number">4</span>)~ 按位取反</span><br><span class="line"></span><br><span class="line"><span class="number">5</span>)<< 左移</span><br><span class="line"></span><br><span class="line"><span class="number">6</span>)>> 右移 </span><br></pre></td></tr></table></figure><h3 id="八、register-关键词"><a href="#八、register-关键词" class="headerlink" title="八、register 关键词"></a>八、register 关键词</h3><hr><p><strong>寄存器存在于CPU内部,运算速度非常快, 因为内存中的数据必须载入寄存器才能计算。如果直接定义一个变量为寄存器变量,则少了载入等过程自然会快。对于频繁使用的变量可以把它放在寄存器中来提速度。</strong><br>1.寄存器变量可以用来优化加速c语言程序<br>2.声名只需在类型前多加register 即可,eg register int quick; (quick 就是一个整形的寄存器变量)<br>3.register只是一个建议型关键字,能不能声名成功还取决于编译器(建议型的关键字还有c++中的 inline),若不幸没有请求成功,则变量变成一个普通的自动变量。<br>4.是无法对一个register变量取地址的(因为寄存器变量多放在寄存器而非内存中,内存有地址,而寄存器是无地址的)</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//全局变量最好不要占用寄存器,会影响程序的速度</span></span><br><span class="line"><span class="keyword">register</span> <span class="keyword">int</span> num = <span class="number">1000</span>;<span class="comment">//err</span></span><br><span class="line"><span class="comment">//只有局部自动变量和形参才可以定义为寄存器变量。因为寄存器变量属于动态存储方式,凡需要采用静态存储方式的量都不能定义为寄存器变量,包括:模块间全局变量、模块内全局变量、局部static变量。 </span></span><br><span class="line"><span class="comment">//静态变量无法定义为寄存器变量,静态变量存在静态区</span></span><br><span class="line"><span class="keyword">register</span> <span class="keyword">static</span> <span class="keyword">double</span> res = <span class="number">0.0</span>;<span class="comment">//err</span></span><br></pre></td></tr></table></figure><h3 id="九、volatile-关键词"><a href="#九、volatile-关键词" class="headerlink" title="九、volatile 关键词"></a>九、volatile 关键词</h3><hr><p>volatile的作用是告知编译器,它修饰的变量随时都可能被改变,因此,编译后的程序每次在使用该变量的值时,都会从变量的地址中读取数据,而不是从寄存器中获取。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*volatile的本意是“易变的”</span></span><br><span class="line"><span class="comment">由于访问寄存器的速度要快过RAM,所以编译器一般都会作减少存取外部RAM的优化。比如:</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">static</span> <span class="keyword">int</span> i=<span class="number">0</span>;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line">...</span><br><span class="line"><span class="keyword">while</span> (<span class="number">1</span>)</span><br><span class="line">{</span><br><span class="line"><span class="keyword">if</span> (i) do_something();</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"><span class="comment">/* Interrupt service routine. */</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">ISR_2</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line">i=<span class="number">1</span>;</span><br><span class="line">}</span><br><span class="line"><span class="comment">/*程序的本意是希望ISR_2中断产生时,在main当中调用do_something函数,但是,由于编译器判断在main函数里面没有修改过i,因此可能只执行一次对从i到某寄存器的读操作,然后每次if判断都只使用这个寄存器里面的“i副本”,导致do_something永远也不会被调用。如果变量加上volatile修饰,则编译器保证对此变量的读写操作都不会被优化(肯定执行)。此例中i也应该如此说明。</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure><p> <strong>一般说来,volatile用在如下的几个地方:</strong><br><strong>1、中断服务程序中修改的供其它程序检测的变量需要加volatile;</strong><br><strong>2、多任务环境下各任务间共享的标志应该加volatile;</strong><br><strong>3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义;</strong><br><strong>另外,以上这几种情况经常还要同时考虑数据的完整性(相互关联的几个标志读了一半被打断了重写),在1中可以通过关中断来实现,2中可以禁止任务调度,3中则只能依靠硬件的良好设计了。</strong></p><h3 id="十、C-库函数-memset"><a href="#十、C-库函数-memset" class="headerlink" title="十、C 库函数 - memset()"></a>十、C 库函数 - memset()</h3><hr><p>C 库函数 void *memset(void *str, int c, size_t n) 复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> *<span class="title">memset</span><span class="params">(<span class="keyword">void</span> *str, <span class="keyword">int</span> c, <span class="keyword">size_t</span> n)</span></span></span><br><span class="line"><span class="function"><span class="comment">//str -- 指向要填充的内存块。</span></span></span><br><span class="line"><span class="function"><span class="comment">//c -- 要被设置的值。该值以 int 形式传递,但是函数在填充内存块时是使用该值的无符号字符形式。</span></span></span><br><span class="line"><span class="function"><span class="comment">//n -- 要被设置为该值的字符数。</span></span></span><br><span class="line"><span class="function"><span class="comment">//该值返回一个指向存储区 str 的指针。</span></span></span><br></pre></td></tr></table></figure><h3 id="十一、printf函数从右到左压栈"><a href="#十一、printf函数从右到左压栈" class="headerlink" title="十一、printf函数从右到左压栈"></a>十一、printf函数从右到左压栈</h3><hr><p>注意:函数printf从<strong>右到左压栈</strong>,然后将<strong>先读取放到栈底</strong>,<strong>最后读取的放在栈顶</strong>,处理时候是从栈顶开始的,所以我们看见的结果是,从右边开始处理的。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line"><span class="keyword">int</span> i=<span class="number">10</span>;</span><br><span class="line"><span class="keyword">int</span> a=i;</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"%d %d"</span>,(a+i),(a=<span class="number">2</span>*a));</span><br><span class="line">}<span class="comment">//30,20</span></span><br></pre></td></tr></table></figure><h3 id="十二、排序算法"><a href="#十二、排序算法" class="headerlink" title="十二、排序算法"></a>十二、排序算法</h3><hr><p>冒泡排序:基本思想:比较相邻的两个数,如果前者比后者大,则进行交换。每一轮排序结束,选出一个未排序中最大的数放到数组后面。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="comment">//冒泡排序算法</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">bubbleSort</span><span class="params">(<span class="keyword">int</span> *arr, <span class="keyword">int</span> n)</span> </span>{</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i<n - <span class="number">1</span>; i++)</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j < n - i - <span class="number">1</span>; j++)</span><br><span class="line"> {</span><br><span class="line"> <span class="comment">//如果前面的数比后面大,进行交换</span></span><br><span class="line"> <span class="keyword">if</span> (arr[j] > arr[j + <span class="number">1</span>]) {</span><br><span class="line"> <span class="keyword">int</span> temp = arr[j]; arr[j] = arr[j + <span class="number">1</span>]; arr[j + <span class="number">1</span>] = temp;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> arr[] = { <span class="number">10</span>,<span class="number">6</span>,<span class="number">5</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">8</span>,<span class="number">7</span>,<span class="number">4</span>,<span class="number">9</span>,<span class="number">1</span> };</span><br><span class="line"> <span class="keyword">int</span> n = <span class="keyword">sizeof</span>(arr) / <span class="keyword">sizeof</span>(<span class="keyword">int</span>);</span><br><span class="line"> bubbleSort(arr, n);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"排序后的数组为:\n"</span>);</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j<n; j++)</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d "</span>, arr[j]);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"\n"</span>); </span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br></pre></td></tr></table></figure><hr><p>参考文章:<a href="https://www.cnblogs.com/maluning/p/7944809.html">七大经典排序算法总结(C语言描述)</a></p>]]></content>
<summary type="html"><p>简介: 嵌入式笔试相关题目、考点。</p></summary>
<category term="知识" scheme="https://kelecn.top/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="C++" scheme="https://kelecn.top/tags/C/"/>
<category term="编程" scheme="https://kelecn.top/tags/%E7%BC%96%E7%A8%8B/"/>
<category term="嵌入式" scheme="https://kelecn.top/tags/%E5%B5%8C%E5%85%A5%E5%BC%8F/"/>
<category term="C" scheme="https://kelecn.top/tags/C/"/>
</entry>
<entry>
<title>精简代码:改换运算符</title>
<link href="https://kelecn.top/posts/38646/"/>
<id>https://kelecn.top/posts/38646/</id>
<published>2020-08-22T13:57:00.000Z</published>
<updated>2021-04-03T06:53:46.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介: 精简代码:改换运算符</p><a id="more"></a><h5 id="1、位运算(-amp-)替换取余(-)运算"><a href="#1、位运算(-amp-)替换取余(-)运算" class="headerlink" title="1、位运算(&)替换取余(%)运算"></a>1、位运算(&)替换取余(%)运算</h5><p><strong>即:如果Y =<img src="https://private.codecogs.com/gif.latex?2%5E%7Bn%7D" class="lazyload" data-srcset="https://private.codecogs.com/gif.latex?2%5E%7Bn%7D" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII=" alt="2^{n}">,则X%Y可以变化为X&(Y-1)</strong><br>由于我们知道位运算比较高效,在某些情况下,当b为2的n次方时,有如下替换公式:<br>a % b = a & (b-1)(b=2^n)<br>即:a % 2^n = a & (2^n-1)<br>例如:14%8,取余数,相当于取出低位,而余数最大为7,14二进制为1110,8的二进制1000,8-1 = 7的二进制为0111,由于现在低位全为1,让其跟14做&运算,正好取出的是其低位上的余数。1110&0111=110即6=14%8;(此公式只适用b=2^n,是因为可以保证b始终只有最高位为1,其他二进制位全部为0,减去1,之后,可以把高位1消除,其他位都为1,而与1做&运算,会保留原来的数。)</p><h5 id="2、左移运算(-lt-lt-)替换乘法(-)运算"><a href="#2、左移运算(-lt-lt-)替换乘法(-)运算" class="headerlink" title="2、左移运算(<<)替换乘法(*)运算"></a>2、左移运算(<<)替换乘法(*)运算</h5><p>a=a8;<br>b=b/8;<br><strong>可以改为:</strong><br>a=a<<3;<br>b=b>>3;<br><strong>说明:</strong><br>除2 = 右移1位; 乘2 = 左移1位<br>除4 = 右移2位; 乘4 = 左移2位<br>除8 = 右移3位; 乘8 = 左移3位<br><strong>通常如果需要乘以或除以2的n次方,都可以用移位的方法代替,大部分的C编译器,用移位的方法得到代码比调用乘除法子程序生成的代码效率高。</strong><br><strong>实际上,只要是乘以或除以一个整数才可以用移位的方法得到结果。</strong><br>如:<br>a=a9 =a(8+1)=a8+a1<br><strong>可以改为:</strong><br>a=(a<<3)+a<br>如:<br>a=a7 =a(8-1)=a8-a1<br><strong>可以改为:</strong><br>a=(a<<3)-a</p><p><strong>总结:a=an; n分解成(2^m + s),则a=an可以改为a=(a<<m)+as;as再同理分解替换。</strong></p><p>例:a=a10 => a=a(8+2) => a=a8 + a2 => a=(a<<3)+(a<<1)</p><h5 id="3、右移运算(-gt-gt-)替换除法(-)运算"><a href="#3、右移运算(-gt-gt-)替换除法(-)运算" class="headerlink" title="3、右移运算(>>)替换除法(/)运算"></a>3、右移运算(>>)替换除法(/)运算</h5><p>a=a*8;<br>b=b/8;<br><strong>可以改为:</strong><br>a=a<<3;<br>b=b>>3;<br><strong>说明:</strong><br>除2 = 右移1位; 乘2 = 左移1位<br>除4 = 右移2位; 乘4 = 左移2位<br>除8 = 右移3位; 乘8 = 左移3位<br><strong>通常如果需要乘以或除以2的n次方,都可以用移位的方法代替,大部分的C编译器,用移位的方法得到代码比调用乘除法子程序生成的代码效率高。</strong><br><strong>实际上,只要是乘以或除以一个整数才可以用移位的方法得到结果。</strong><br>如:<br>a=a/9 =a/(8+1)=a/8+a/1<br><strong>可以改为:</strong><br>a=(a>>3)+a<br>如:<br>a=a/7 =a/(8-1)=a/8-a/1<br><strong>可以改为:</strong><br>a=(a>>3)-a<br><strong>总结:a=a/n; n分解成(2^m + s),则a=a/n可以改为a=(a>>m)+a/s;a/s再同理分解替换。</strong><br>例:a=a/10 => a=a/(8+2) => a=a/8 + a/2 => a=(a>>3)+(a>>1)</p><h5 id="4、C-C-中的移位操作容易出错的情况:"><a href="#4、C-C-中的移位操作容易出错的情况:" class="headerlink" title="4、C/C++中的移位操作容易出错的情况:"></a>4、C/C++中的移位操作容易出错的情况:</h5><ul><li><strong>什么样的数据类型可以直接移位</strong><br> 只有整型数据才能用移位替代乘除法,如:char、short、int、long、unsigned char、unsigned short、unsigned int、unsigned long。(double、float、bool、long double则不可以进行移位操作。)</li><li><strong>有符号数据类型移位需要注意符号位</strong><br>对于char、short、int、long这些有符号的数据类型:<br>对负数进行左移:符号位始终为1,其他位左移。<br>对正数进行左移:所有位左移,即 <<,可能会变成负数<br>对负数进行右移:取绝对值,然后右移,再取相反数<br>对正数进行右移:所有位右移,即 >></li><li><strong>无符号数据类型的移位操作</strong><br>对于unsigned char、unsigned short、unsigned int、unsigned long这些无符号数据类型:<br>没有特殊要说明的,使用<< 和 >> 操作符就OK了。<h5 id="5、参考资料:"><a href="#5、参考资料:" class="headerlink" title="5、参考资料:"></a>5、参考资料:</h5></li><li><a href="https://blog.csdn.net/LZAlgorithm/article/details/101348934">使用位运算替换取余操作</a></li><li><a href="https://blog.csdn.net/qq_34473360/article/details/90547684">移位操作与乘除法的关系</a></li></ul>]]></content>
<summary type="html"><p>简介: 精简代码:改换运算符</p></summary>
<category term="知识" scheme="https://kelecn.top/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="C++" scheme="https://kelecn.top/tags/C/"/>
<category term="ARM" scheme="https://kelecn.top/tags/ARM/"/>
<category term="嵌入式" scheme="https://kelecn.top/tags/%E5%B5%8C%E5%85%A5%E5%BC%8F/"/>
<category term="C" scheme="https://kelecn.top/tags/C/"/>
<category term="单片机" scheme="https://kelecn.top/tags/%E5%8D%95%E7%89%87%E6%9C%BA/"/>
</entry>
<entry>
<title>基于PicGo的GitHub图床</title>
<link href="https://kelecn.top/posts/10250/"/>
<id>https://kelecn.top/posts/10250/</id>
<published>2020-08-18T13:57:00.000Z</published>
<updated>2021-08-24T15:31:09.100Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:GitHub图床(基于PicGo)</p><a id="more"></a><h2 id="GitHub图床(基于PicGo)"><a href="#GitHub图床(基于PicGo)" class="headerlink" title="GitHub图床(基于PicGo)"></a>GitHub图床(基于PicGo)</h2><h5 id="1-首先你得有一个GitHub账号。注册GitHub就不用我多言。"><a href="#1-首先你得有一个GitHub账号。注册GitHub就不用我多言。" class="headerlink" title="1. 首先你得有一个GitHub账号。注册GitHub就不用我多言。"></a><strong>1.</strong> 首先你得有一个GitHub账号。注册GitHub就不用我多言。</h5><h5 id="2-新建一个仓库"><a href="#2-新建一个仓库" class="headerlink" title="2. 新建一个仓库"></a><strong>2.</strong> 新建一个仓库</h5><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/PicGo1.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/PicGo1.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p>记下你取的仓库名。</p><h5 id="3-生成一个token用于PicGo操作你的仓库:"><a href="#3-生成一个token用于PicGo操作你的仓库:" class="headerlink" title="3. 生成一个token用于PicGo操作你的仓库:"></a><strong>3.</strong> 生成一个token用于PicGo操作你的仓库:</h5><p>访问:<a href="https://github.com/settings/tokens">https://github.com/settings/tokens</a></p><p>然后点击<code>Generate new token</code>。</p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/PicGo2.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/PicGo2.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p>把repo的勾打上即可。然后翻到页面最底部,点击<code>Generate token</code>的绿色按钮生成token。</p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/PicGo3.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/PicGo3.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p><strong>注意:</strong>这个token生成后只会显示一次!你要把这个token复制一下存到其他地方以备以后要用。</p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/PicGo4.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/PicGo4.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><h5 id="4-配置PicGo"><a href="#4-配置PicGo" class="headerlink" title="4. 配置PicGo"></a><strong>4.</strong> 配置PicGo</h5><p><strong>注意:</strong>仓库名的格式是<code>用户名/仓库</code>,比如我创建了一个叫做<code>test</code>的仓库,在PicGo里我要设定的仓库名就是<code>kelecn/images</code>。一般我们选择<code>master</code>分支即可。然后记得点击确定以生效,然后可以点击<code>设为默认图床</code>来确保上传的图床是GitHub。</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//PicGo配置</span></span><br><span class="line">{</span><br><span class="line"> <span class="attr">"repo"</span>: <span class="string">""</span>, <span class="comment">// 仓库名,格式是username/reponame</span></span><br><span class="line"> <span class="attr">"token"</span>: <span class="string">""</span>, <span class="comment">// github token</span></span><br><span class="line"> <span class="attr">"path"</span>: <span class="string">""</span>, <span class="comment">// 自定义存储路径,比如img/</span></span><br><span class="line"> <span class="attr">"customUrl"</span>: <span class="string">""</span>, <span class="comment">// 自定义域名,注意要加http://或者https://</span></span><br><span class="line"> <span class="attr">"branch"</span>: <span class="string">""</span> <span class="comment">// 分支名,默认是master</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/PicGo5.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/PicGo5.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p>至此配置完毕,已经可以使用了。当你上传的时候,你会发现你的仓库里也会增加新的图片了:</p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/PicGo6.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/PicGo6.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p><p>更多图床设计:请参考<a href="https://picgo.github.io/PicGo-Doc/zh/guide/">PicGo官方手册</a></p>]]></content>
<summary type="html"><p>简介:GitHub图床(基于PicGo)</p></summary>
<category term="技术" scheme="https://kelecn.top/categories/%E6%8A%80%E6%9C%AF/"/>
<category term="Hexo" scheme="https://kelecn.top/tags/Hexo/"/>
<category term="相册" scheme="https://kelecn.top/tags/%E7%9B%B8%E5%86%8C/"/>
<category term="图床" scheme="https://kelecn.top/tags/%E5%9B%BE%E5%BA%8A/"/>
<category term="Github" scheme="https://kelecn.top/tags/Github/"/>
<category term="PicGo" scheme="https://kelecn.top/tags/PicGo/"/>
</entry>
<entry>
<title>ARM处理器7种工作模式</title>
<link href="https://kelecn.top/posts/4235/"/>
<id>https://kelecn.top/posts/4235/</id>
<published>2020-06-11T13:47:00.000Z</published>
<updated>2021-04-03T06:53:18.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:ARM处理器7种工作模式(特权模式,异常模式,用户模式)。</p><a id="more"></a><h3 id="ARM处理器7种工作模式(特权模式,异常模式,用户模式)"><a href="#ARM处理器7种工作模式(特权模式,异常模式,用户模式)" class="headerlink" title="ARM处理器7种工作模式(特权模式,异常模式,用户模式)"></a>ARM处理器7种工作模式(特权模式,异常模式,用户模式)</h3><p><strong>用户模式(USR):</strong>正常程序执行模式,不能直接切换到其他模式<br><strong>系统模式(SYS):</strong>运行操作系统的特权任务,与用户模式类似,但具有可以直接切换到其他模式等特权<br><strong>快中断模式(FIQ):</strong>支持高速数据传输及通道处理,FIQ异常响应时进入此模式<br><strong>中断模式(IRQ):</strong>用于通用中断处理,IRQ异常响应时进入此模式<br><strong>管理模式(SVC):</strong>操作系统保护模式,系统复位和软件中断响应时进入此模式(由系统调用执行软中断SWI命令触发)<br><strong>中止模式(ABT):</strong>用于支持虚拟内存和/或存储器保护,在ARM7TDMI没有大用处<br><strong>未定义模式(UND):</strong>支持硬件协处理器的软件仿真,未定义指令异常响应时进入此模式 </p><p><strong>7种工作模式分类:</strong></p><ul><li><p>除用户模式外,其余6种工作模式都属于特权模式</p></li><li><p>特权模式中除了系统模式以外的其余5种模式称为异常模式</p></li><li><p>大多数程序运行于用户模式</p></li><li><p>进入特权模式是为了处理中断、异常、或者访问被保护的系统资源</p></li></ul><p><strong>硬件权限级别:</strong>系统模式 > 异常模式 > 用户模式<br><strong>快中断与慢中断区别:</strong>快中断处理时禁止中断</p>]]></content>
<summary type="html"><p>简介:ARM处理器7种工作模式(特权模式,异常模式,用户模式)。</p></summary>
<category term="知识" scheme="https://kelecn.top/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="ARM" scheme="https://kelecn.top/tags/ARM/"/>
<category term="嵌入式" scheme="https://kelecn.top/tags/%E5%B5%8C%E5%85%A5%E5%BC%8F/"/>
<category term="处理器" scheme="https://kelecn.top/tags/%E5%A4%84%E7%90%86%E5%99%A8/"/>
<category term="硬件" scheme="https://kelecn.top/tags/%E7%A1%AC%E4%BB%B6/"/>
</entry>
<entry>
<title>测试相册功能</title>
<link href="https://kelecn.top/posts/39047/"/>
<id>https://kelecn.top/posts/39047/</id>
<published>2020-06-09T13:57:00.000Z</published>
<updated>2021-08-15T15:46:30.656Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p class='p center logo large red'>相</p><p class='p center logo large blue'>册</p><div class="tabs" id="tab-id"><ul class="nav-tabs"><li class="tab active"><a class="#tab-id-1">壁纸</a></li><li class="tab"><a class="#tab-id-2">二次元</a></li><li class="tab"><a class="#tab-id-3">日常</a></li><li class="tab"><a class="#tab-id-4">旅游</a></li></ul><div class="tab-content"><div class="tab-pane active" id="tab-id-1"><div class="gallery stretch" col='4'> <p><img src="https://cdn.jsdelivr.net/gh/kelecn/images/001.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/001.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/002.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/002.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/003.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/003.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/004.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/004.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/005.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/005.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/006.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/006.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/007.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/007.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/008.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/008.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/009.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/009.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/010.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/010.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/011.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/011.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/012.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/012.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/013.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/013.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/014.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/014.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/015.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/015.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/016.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/016.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/017.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/017.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/018.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/018.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/019.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/019.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/020.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/020.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/021.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/021.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/022.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/022.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/023.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/023.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/024.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/024.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/025.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/025.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/026.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/026.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/027.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/027.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/028.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/028.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/029.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/029.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/030.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/030.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/031.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/031.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/032.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/032.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/033.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/033.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/034.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/034.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/035.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/035.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/036.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/036.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/037.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/037.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/038.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/038.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/039.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/039.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/040.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/040.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/041.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/041.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/042.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/042.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/043.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/043.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/044.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/044.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/045.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/045.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/046.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/046.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/047.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/047.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/048.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/048.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/049.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/049.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/050.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/050.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/051.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/051.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/052.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/052.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/053.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/053.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/054.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/054.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/055.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/055.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://cdn.jsdelivr.net/gh/kelecn/images/056.jpg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images/056.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p> </div></div><div class="tab-pane" id="tab-id-2"><div class="gallery stretch" col='4'> <p><img src="https://w.wallhaven.cc/full/4g/wallhaven-4g789d.png" class="lazyload" data-srcset="https://w.wallhaven.cc/full/4g/wallhaven-4g789d.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://w.wallhaven.cc/full/70/wallhaven-70pz34.jpg" class="lazyload" data-srcset="https://w.wallhaven.cc/full/70/wallhaven-70pz34.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://w.wallhaven.cc/full/0q/wallhaven-0q2637.jpg" class="lazyload" data-srcset="https://w.wallhaven.cc/full/0q/wallhaven-0q2637.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://w.wallhaven.cc/full/5w/wallhaven-5wr6y9.jpg" class="lazyload" data-srcset="https://w.wallhaven.cc/full/5w/wallhaven-5wr6y9.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://w.wallhaven.cc/full/nz/wallhaven-nz8mqw.png" class="lazyload" data-srcset="https://w.wallhaven.cc/full/nz/wallhaven-nz8mqw.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://w.wallhaven.cc/full/1j/wallhaven-1j292g.png" class="lazyload" data-srcset="https://w.wallhaven.cc/full/1j/wallhaven-1j292g.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://w.wallhaven.cc/full/43/wallhaven-43zow3.jpg" class="lazyload" data-srcset="https://w.wallhaven.cc/full/43/wallhaven-43zow3.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="><br><img src="https://w.wallhaven.cc/full/8x/wallhaven-8x67go.jpg" class="lazyload" data-srcset="https://w.wallhaven.cc/full/8x/wallhaven-8x67go.jpg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="></p> </div></div><div class="tab-pane" id="tab-id-3"><div class="gallery "> <p><img src="https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper/abstract/B18FCBB3-67FD-48CC-B4F3-457BA145F17A.jpeg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper/abstract/B18FCBB3-67FD-48CC-B4F3-457BA145F17A.jpeg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII=" alt="图片描述"><br><img src="https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper/abstract/67239FBB-E15D-4F4F-8EE8-0F1C9F3C4E7C.jpeg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper/abstract/67239FBB-E15D-4F4F-8EE8-0F1C9F3C4E7C.jpeg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII=" alt="图片描述"><br><img src="https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper/abstract/00E0F0ED-9F1C-407A-9AA6-545649D919F4.jpeg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper/abstract/00E0F0ED-9F1C-407A-9AA6-545649D919F4.jpeg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII=" alt="图片描述"></p> </div></div><div class="tab-pane" id="tab-id-4"><div class="gallery "> <p><img src="https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper/abstract/41F215B9-261F-48B4-80B5-4E86E165259E.jpeg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper/abstract/41F215B9-261F-48B4-80B5-4E86E165259E.jpeg" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII=" alt="图片描述"></p> </div></div></div></div>]]></content>
<summary type="html"><link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" cla</summary>
<category term="生活" scheme="https://kelecn.top/categories/%E7%94%9F%E6%B4%BB/"/>
<category term="Hexo" scheme="https://kelecn.top/tags/Hexo/"/>
<category term="相册" scheme="https://kelecn.top/tags/%E7%9B%B8%E5%86%8C/"/>
<category term="Kelecn" scheme="https://kelecn.top/tags/Kelecn/"/>
</entry>
<entry>
<title>C++与Java多态的区别</title>
<link href="https://kelecn.top/posts/33552/"/>
<id>https://kelecn.top/posts/33552/</id>
<published>2020-06-06T13:40:00.000Z</published>
<updated>2021-04-03T06:53:06.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:C++与Java多态的区别。</p><a id="more"></a><h3 id="多态是指用父指针指向不同子类对象时,调用其共有的函数,不同的子类会有不同的行为。虽然C-和Java都具有多态机制,但是他们的实现不同,使用时的效果也会略有不同。"><a href="#多态是指用父指针指向不同子类对象时,调用其共有的函数,不同的子类会有不同的行为。虽然C-和Java都具有多态机制,但是他们的实现不同,使用时的效果也会略有不同。" class="headerlink" title="多态是指用父指针指向不同子类对象时,调用其共有的函数,不同的子类会有不同的行为。虽然C++和Java都具有多态机制,但是他们的实现不同,使用时的效果也会略有不同。"></a>多态是指用父指针指向不同子类对象时,调用其共有的函数,不同的子类会有不同的行为。虽然C++和Java都具有多态机制,但是他们的实现不同,使用时的效果也会略有不同。</h3><h4 id="在C-中"><a href="#在C-中" class="headerlink" title="在C++中"></a>在C++中</h4><ul><li>普通函数调用:具体调用哪个方法在编译时就可以决定(通过查找编译器的符号表),同时在使用标准过程调用机制基础上增加一个表示对象身份的指针(this指针)。</li><li>虚函数调用:函数调用依赖于对象的实际类型,一般地说,对象的实际类型只能在运行时间才能确定。实现机制是使用virtual table(vtbls)和virtual table pointers(vptrs)。<ol><li>vtbl 是由函数指针构成的数组或链表,程序中每一个class凡声明(或继承)虚函数者,都有一个自己的vtbl,其中的条目就是该class的各个虚函数实现的指针。因此必须为每一个class消耗一个vtbl空间,其大小视虚函数的个数确定。</li><li>凡声明有虚函数的class,其对象都有一个隐藏的data member,用来指向class的vtbl。</li><li>当多态发生时,编译器首先根据对象vptr找出其vtbl,然后找出vtbl内对应的函数指针,最后调用函数指针指向的函数。从而实现多态。</li></ol></li></ul><h4 id="在Java中"><a href="#在Java中" class="headerlink" title="在Java中"></a>在Java中</h4><p>1.C++中VTable和vptr是在编译阶段由编译器自动生成的,也就是说,在C++程序载入内存以前,在.obj(.o)文件中已经有这些结构的信 息;Java中的方法表是由JVM生成的,因此,使用javac命令编译后生成的.class文件中并没有方法表的信息。只有等JVM把.class文件 载入到内存中时,才会为该.class文件动态生成一个与之关联的方法表,放置在JVM的方法区中。</p><p>2.C++中某个方法在VTable的索引号是在编译阶段已经明确知道的,并不需要在运行过程中动态获知;Java中的方法初始时都只是一个符号,并不是 一个明确的地址,只有等到该方法被第一次调用时,才会被解析成一个方法表中的偏移量,也就是说,只有在这个时候,实例方法才明确知道自己在方发表中的偏移 量了,在这之前必须经历一个解析的过程。</p><p>因此在构造函数是Java会发生多态,即使子类此时还没有构造完全(一个极难发现的bug)。而C++则不会发生多态,待父类构造完全,在构造子类。<br><strong>Java代码如下:</strong></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">A</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">fun</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> System.out.println(<span class="string">"A"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">A</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">this</span>.fun();</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">B</span> <span class="keyword">extends</span> <span class="title">A</span></span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">fun</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> System.out.println(<span class="string">"B"</span>);</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">B</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> fun();</span><br><span class="line"> }</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String [] argv)</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> B b = <span class="keyword">new</span> B();</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="comment">//B</span></span><br><span class="line"><span class="comment">//B</span></span><br></pre></td></tr></table></figure><p><strong>C++代码如下:</strong></p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><string></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstring></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstdlib></span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">A</span></span></span><br><span class="line"><span class="class">{</span></span><br><span class="line"> <span class="keyword">public</span>:</span><br><span class="line"> <span class="function"><span class="keyword">virtual</span> <span class="keyword">void</span> <span class="title">fun</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="built_in">cout</span><<<span class="string">"A"</span><<<span class="built_in">endl</span>;</span><br><span class="line"> }</span><br><span class="line"> A()</span><br><span class="line"> {</span><br><span class="line"> fun();</span><br><span class="line"> }</span><br><span class="line">};</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">B</span> :</span> A</span><br><span class="line">{</span><br><span class="line"> <span class="keyword">public</span>:</span><br><span class="line"> <span class="function"><span class="keyword">virtual</span> <span class="keyword">void</span> <span class="title">fun</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="built_in">cout</span><<<span class="string">"B"</span><<<span class="built_in">endl</span>;</span><br><span class="line"> }</span><br><span class="line"> B()</span><br><span class="line"> {</span><br><span class="line"> fun();</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line">};</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span> *argv[])</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> B b;</span><br><span class="line">}</span><br><span class="line"><span class="comment">//A</span></span><br><span class="line"><span class="comment">//B</span></span><br></pre></td></tr></table></figure><p>可以发现,C++构造子类时,先构造父类,输出A,然后在构造自身,输出B。而Java在构造子类时,父类并未构造完成,但已经可以发生多态输出B,然后再构造自身,输出B。Java一般为了避免这种情况,会把fun等init()函数声明为private或者finial。</p>]]></content>
<summary type="html"><p>简介:C++与Java多态的区别。</p></summary>
<category term="知识" scheme="https://kelecn.top/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="面向对象" scheme="https://kelecn.top/tags/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/"/>
<category term="C++" scheme="https://kelecn.top/tags/C/"/>
<category term="代码" scheme="https://kelecn.top/tags/%E4%BB%A3%E7%A0%81/"/>
<category term="编程" scheme="https://kelecn.top/tags/%E7%BC%96%E7%A8%8B/"/>
<category term="Java" scheme="https://kelecn.top/tags/Java/"/>
</entry>
<entry>
<title>C++重载注意点</title>
<link href="https://kelecn.top/posts/18002/"/>
<id>https://kelecn.top/posts/18002/</id>
<published>2020-05-20T13:30:00.000Z</published>
<updated>2021-04-03T06:52:22.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:C++重载注意点。</p><a id="more"></a><h4 id="1-调用函数在前,定义函数在后,进行原型声明"><a href="#1-调用函数在前,定义函数在后,进行原型声明" class="headerlink" title="1.调用函数在前,定义函数在后,进行原型声明"></a>1.调用函数在前,定义函数在后,进行原型声明</h4><h4 id="2-函数重载注意:参数类型和个数相同,参数顺序不同,也可以重载"><a href="#2-函数重载注意:参数类型和个数相同,参数顺序不同,也可以重载" class="headerlink" title="2.函数重载注意:参数类型和个数相同,参数顺序不同,也可以重载"></a>2.函数重载注意:参数类型和个数相同,参数顺序不同,也可以重载</h4><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iomanip></span></span></span><br><span class="line"> </span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">print</span><span class="params">(<span class="keyword">int</span> a,<span class="keyword">double</span> b)</span></span>;<span class="comment">//调用函数在前,定义函数在后,进行原型声明</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">print</span> <span class="params">(<span class="keyword">double</span> b,<span class="keyword">int</span> a)</span></span>;<span class="comment">//调用函数在前,定义函数在后,进行原型声明</span></span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="keyword">int</span> x=<span class="number">8</span>;</span><br><span class="line"> <span class="keyword">double</span> y=<span class="number">8</span>;</span><br><span class="line"> print(x,y);</span><br><span class="line"> print(y,x);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">print</span><span class="params">(<span class="keyword">int</span> a,<span class="keyword">double</span> b)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="built_in">cout</span><<showpoint<<<span class="string">"1"</span><<a<<b<<<span class="built_in">endl</span>;</span><br><span class="line">}</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">print</span> <span class="params">(<span class="keyword">double</span> b,<span class="keyword">int</span> a)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="built_in">cout</span><<showpoint<<<span class="string">"2"</span><< a<<b <<<span class="built_in">endl</span>;</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><h4 id="3-C-中cout输出字符型指针地址值的方法"><a href="#3-C-中cout输出字符型指针地址值的方法" class="headerlink" title="3.C++中cout输出字符型指针地址值的方法"></a>3.C++中cout输出字符型指针地址值的方法</h4><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//C++中cout输出字符型指针地址值的方法</span></span><br><span class="line"><span class="comment">//若要打印地址请用void*,否则 p会被认为是字符串。原因:运算符重载的匹配规则</span></span><br><span class="line"> <span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><iostream></span></span></span><br><span class="line"> <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">char</span> a;</span><br><span class="line"> <span class="keyword">char</span> *p=&a;</span><br><span class="line"> <span class="built_in">cout</span><<(<span class="keyword">void</span>*)p<<<span class="built_in">endl</span><<a<<<span class="built_in">endl</span>;</span><br><span class="line"> } </span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><p>简介:C++重载注意点。</p></summary>
<category term="知识" scheme="https://kelecn.top/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="面向对象" scheme="https://kelecn.top/tags/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/"/>
<category term="C++" scheme="https://kelecn.top/tags/C/"/>
<category term="代码" scheme="https://kelecn.top/tags/%E4%BB%A3%E7%A0%81/"/>
<category term="编程" scheme="https://kelecn.top/tags/%E7%BC%96%E7%A8%8B/"/>
</entry>
<entry>
<title>C++返回对象和返回引用</title>
<link href="https://kelecn.top/posts/10995/"/>
<id>https://kelecn.top/posts/10995/</id>
<published>2020-04-19T13:20:07.000Z</published>
<updated>2021-04-03T06:52:08.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:C++返回对象和返回引用。</p><a id="more"></a><p>我们发现,在C++中,有些成员函数返回的是对象,而有些函数返回的又是引用。</p><p>返回对象和返回引用的最主要的区别就是函数原型和函数头。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">Car <span class="title">run</span><span class="params">(<span class="keyword">const</span> Car &)</span> <span class="comment">//返回对象</span></span></span><br><span class="line"><span class="function"></span></span><br><span class="line"><span class="function">Car & <span class="title">run</span><span class="params">(<span class="keyword">const</span> Car &)</span> <span class="comment">//返回引用</span></span></span><br></pre></td></tr></table></figure><p> 返回对象会涉及到生成返回对象的副本。因此,返回对象的时间成本包括了调用复制构造函数来生成副本所需的时间和调用析构函数删除副本所需的时间。返回引用可以节省时间和内存。直接返回对象与按值传递对象类似,他们都生成临时副本。同样,返回引用与按引用传递对象类似,调用和被调用的函数对同一个对象进行操作。</p><p> 并不是总是可以返回引用的。比如函数不能返回在函数中创建的临时对象的引用。因为当函数结束调用时,临时对象将消失,因此这种引用是非法的。在这种情况下,应返回对象,以生成一个调用程序可以使用的副本。</p>]]></content>
<summary type="html"><p>简介:C++返回对象和返回引用。</p></summary>
<category term="知识" scheme="https://kelecn.top/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="面向对象" scheme="https://kelecn.top/tags/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/"/>
<category term="C++" scheme="https://kelecn.top/tags/C/"/>
<category term="代码" scheme="https://kelecn.top/tags/%E4%BB%A3%E7%A0%81/"/>
<category term="编程" scheme="https://kelecn.top/tags/%E7%BC%96%E7%A8%8B/"/>
<category term="嵌入式" scheme="https://kelecn.top/tags/%E5%B5%8C%E5%85%A5%E5%BC%8F/"/>
</entry>
<entry>
<title>关于free和delete的使用</title>
<link href="https://kelecn.top/posts/26216/"/>
<id>https://kelecn.top/posts/26216/</id>
<published>2020-03-29T13:10:00.000Z</published>
<updated>2021-04-03T06:51:54.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:关于free和delete的使用</p><a id="more"></a><p>两个同时存在是有它的原因的,free是函数,它只释放内存,但不会调用析构函数,如果用free去释放new申请的空间,会因为无法调用析构函数而出现不必要的错误。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">char</span> *point = (<span class="keyword">char</span> *) <span class="built_in">malloc</span>(<span class="number">100</span>); </span><br><span class="line"><span class="built_in">strcpy</span>(point, “hello”); </span><br><span class="line"><span class="built_in">free</span>(point); <span class="comment">// Be careful here,point 所指的内存被释放,but point 所指的地址仍然不变 </span></span><br><span class="line">… </span><br><span class="line"><span class="keyword">if</span>(point != <span class="literal">NULL</span>) <span class="comment">// 没有起到防错作用 </span></span><br><span class="line">{ </span><br><span class="line"><span class="built_in">strcpy</span>(point, “jackery”); <span class="comment">// error </span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>这段程序中,原来free和delete只是把指针所指的内存给释放掉,<strong>但并没有把指针本身干掉</strong>。指针point被free以后其地址仍然不变(非NULL),只是该地址对应的内存是垃圾,point成了“野指针”。如果此时不把point设置为NULL,会让人误以为point是个合法的指针。如果程序比较长,我们有时记不住 point 所指的内存是否已经被释放,在继续使用point 之前,通常会用语句if (p != NULL)进行防错处理。很遗憾,此时if语句起不到防错作用,因为即便point不是NULL指针,它也不指向合法的内存块。<strong>为了避免失误,最好在free之后或者之前,将指针指向NULL</strong></p><h4 id="new-delete-与-malloc-free-区别"><a href="#new-delete-与-malloc-free-区别" class="headerlink" title="new()/delete()与 malloc()/free() 区别"></a>new()/delete()与 malloc()/free() 区别</h4><p>1.malloc()/free() 是标准库函数, 使用前需调用库头文件 <stdlib.h> 方可使用;而 new/delete 是运算 符,执行效率更高。</p><p>2.malloc() 需要手工计算字节数;而 new 能够自动计算需要分配的内存空间。</p><p>3.malloc() 返回的指针是 void 类型;而 new*返回的指针是它分配空间的类型。</p><p>4.new 时调用构造函数,而 malloc() 不能;delete 时调用析构函数,而 free() 不能。</p><p>5.new 在申请单个类型变量时可以赋初值,而 malloc() 不具备。</p>]]></content>
<summary type="html"><p>简介:关于free和delete的使用</p></summary>
<category term="知识" scheme="https://kelecn.top/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="面向对象" scheme="https://kelecn.top/tags/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/"/>
<category term="C++" scheme="https://kelecn.top/tags/C/"/>
<category term="代码" scheme="https://kelecn.top/tags/%E4%BB%A3%E7%A0%81/"/>
<category term="编程" scheme="https://kelecn.top/tags/%E7%BC%96%E7%A8%8B/"/>
<category term="嵌入式" scheme="https://kelecn.top/tags/%E5%B5%8C%E5%85%A5%E5%BC%8F/"/>
</entry>
<entry>
<title>常量指针与指针常量</title>
<link href="https://kelecn.top/posts/8326/"/>
<id>https://kelecn.top/posts/8326/</id>
<published>2020-03-11T13:07:00.000Z</published>
<updated>2021-04-03T06:51:44.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:常量指针与指针常量的区别。</p><a id="more"></a><h3 id="常量指针-被指向的对象是常量"><a href="#常量指针-被指向的对象是常量" class="headerlink" title="常量指针(被指向的对象是常量)"></a>常量指针(被指向的对象是常量)</h3><h4 id="定义:"><a href="#定义:" class="headerlink" title="定义:"></a>定义:</h4><p>又叫常指针,可以理解为<strong>常量的指针</strong>,指向的是个常量</p><h4 id="关键点:"><a href="#关键点:" class="headerlink" title="关键点:"></a>关键点:</h4><ol><li>常量指针指向的对象不能通过这个指针来修改,可是仍然可以通过原来的声明修改;</li><li>常量指针可以被赋值为变量的地址,之所以叫常量指针,是限制了通过这个指针修改变量的值;</li><li>指针还可以指向别处,因为指针本身只是个变量,可以指向任意地址; </li></ol><h4 id="代码形式:"><a href="#代码形式:" class="headerlink" title="代码形式:"></a>代码形式:</h4><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> <span class="keyword">const</span>* p; <span class="keyword">const</span> <span class="keyword">int</span>* p;</span><br></pre></td></tr></table></figure><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 常量指针(被指向的对象是常量)</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> i = <span class="number">10</span>;</span><br><span class="line"> <span class="keyword">int</span> i2 = <span class="number">11</span>;</span><br><span class="line"> <span class="keyword">const</span> <span class="keyword">int</span> *p = &i;</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\n"</span>, *p);<span class="comment">//10</span></span><br><span class="line"> i = <span class="number">9</span>; <span class="comment">//OK,仍然可以通过原来的声明修改值,</span></span><br><span class="line"> <span class="comment">//Error,*p是const int的,不可修改,即常量指针不可修改其指向地址</span></span><br><span class="line"> <span class="comment">//*p = 11; //error: assignment of read-only location ‘*p’</span></span><br><span class="line"> p = &i2;<span class="comment">//OK,指针还可以指向别处,因为指针只是个变量,可以随意指向;</span></span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\n"</span>, *p);<span class="comment">//11</span></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><h3 id="指针常量-指针本身是常量"><a href="#指针常量-指针本身是常量" class="headerlink" title="指针常量(指针本身是常量)"></a>指针常量(指针本身是常量)</h3><h4 id="定义:-1"><a href="#定义:-1" class="headerlink" title="定义:"></a>定义:</h4><p>本质是一个常量,而用指针修饰它。指针常量的值是指针,这个值因为是常量,所以不能被赋值。</p><h4 id="关键点:-1"><a href="#关键点:-1" class="headerlink" title="关键点:"></a>关键点:</h4><ol><li>它是个常量!</li><li>指针所保存的地址可以改变,然而指针所指向的值却不可以改变;</li><li>指针本身是常量,指向的地址不可以变化,但是指向的地址所对应的内容可以变化;</li></ol><h4 id="代码形式:-1"><a href="#代码形式:-1" class="headerlink" title="代码形式:"></a>代码形式:</h4><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span>* <span class="keyword">const</span> p;</span><br></pre></td></tr></table></figure><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//指针常量(指针本身是常量)</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> i = <span class="number">10</span>;</span><br><span class="line"> <span class="keyword">int</span> *<span class="keyword">const</span> p = &i;</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\n"</span>, *p);<span class="comment">//10</span></span><br><span class="line"> <span class="comment">//Error,因为p是const 指针,因此不能改变p指向的内容</span></span><br><span class="line"> <span class="comment">//p++;//error: increment of read-only variable ‘p’</span></span><br><span class="line"> (*p)++; <span class="comment">//OK,指针是常量,指向的地址不可以变化,但是指向的地址所对应的内容可以变化</span></span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\n"</span>, *p);<span class="comment">//11</span></span><br><span class="line"> i = <span class="number">9</span>;<span class="comment">//OK,仍然可以通过原来的声明修改值,</span></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="如何区分常量指针和指针常量"><a href="#如何区分常量指针和指针常量" class="headerlink" title="如何区分常量指针和指针常量"></a>如何区分常量指针和指针常量</h3><ul><li>一种方式是看 * 和 const 的排列顺序,比如</li></ul><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> <span class="keyword">const</span>* p;<span class="comment">//const * 即常量指针</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span>* p;<span class="comment">//const * 即常量指针</span></span><br><span class="line"><span class="keyword">int</span>* <span class="keyword">const</span> p;<span class="comment">//* const 即指针常量</span></span><br></pre></td></tr></table></figure><ul><li>还一种方式是看const离谁近,即从右往左看,比如</li></ul><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> <span class="keyword">const</span>* p;<span class="comment">//const修饰的是*p,即*p的内容不可通过p改变,但p不是const,p可以修改,*p不可修改;</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span>* p;<span class="comment">//同上</span></span><br><span class="line"><span class="keyword">int</span>* <span class="keyword">const</span> p;<span class="comment">//const修饰的是p,p是指针,p指向的地址不能修改,p不能修改,但*p可以修改;</span></span><br></pre></td></tr></table></figure><h3 id="例子"><a href="#例子" class="headerlink" title="例子"></a>例子</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//结构体类型的定义</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">stu</span></span></span><br><span class="line"><span class="class">{</span></span><br><span class="line"><span class="keyword">char</span> name[<span class="number">50</span>];</span><br><span class="line"><span class="keyword">int</span> age;</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">fun1</span><span class="params">(struct stu * <span class="keyword">const</span> p)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="comment">//p = NULL; //err</span></span><br><span class="line">p->age = <span class="number">10</span>; <span class="comment">//ok</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//void fun2(struct stu const* p)</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">fun2</span><span class="params">(<span class="keyword">const</span> struct stu * p)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line">p = <span class="literal">NULL</span>; <span class="comment">//ok</span></span><br><span class="line"><span class="comment">//p->age = 10; //err</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">fun3</span><span class="params">(<span class="keyword">const</span> struct stu * <span class="keyword">const</span> p)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="comment">//p = NULL; //err</span></span><br><span class="line"><span class="comment">//p->age = 10; //err</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><p>简介:常量指针与指针常量的区别。</p></summary>
<category term="知识" scheme="https://kelecn.top/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="面向对象" scheme="https://kelecn.top/tags/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/"/>
<category term="C++" scheme="https://kelecn.top/tags/C/"/>
<category term="代码" scheme="https://kelecn.top/tags/%E4%BB%A3%E7%A0%81/"/>
<category term="编程" scheme="https://kelecn.top/tags/%E7%BC%96%E7%A8%8B/"/>
<category term="嵌入式" scheme="https://kelecn.top/tags/%E5%B5%8C%E5%85%A5%E5%BC%8F/"/>
</entry>
<entry>
<title>编程过程中遇到的一些问题总结(C++&Java)</title>
<link href="https://kelecn.top/posts/6416/"/>
<id>https://kelecn.top/posts/6416/</id>
<published>2020-02-18T02:05:00.000Z</published>
<updated>2021-04-03T06:51:34.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:(C++&Java)问题总结。</p><a id="more"></a><p>1.Java中的boolean类型变量,只有两个值true ,false;C++也是,不过也可以用 1 0 代替。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//Java boolean 类型</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">HelloWorld</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>{</span><br><span class="line"> <span class="keyword">while</span> (<span class="keyword">true</span>) {</span><br><span class="line"> System.out.println(<span class="string">"I Love YOU!"</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//C++ boolean 类型</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span> *argv[])</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">while</span> (<span class="number">1</span>) {</span><br><span class="line"> <span class="built_in">cout</span><<<span class="string">"I Love YOU!"</span><<<span class="built_in">endl</span>;</span><br><span class="line"> }</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>2.Java一个类中的boolean类型变量,一般用isXxx()类型获取私有变量Xxx;</p><p>注:get开头的方法,一般都表示返回某一个属性值;is开头的方法,一般都是用来表示判断某某内容。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isSex</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> sex;</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><p>简介:(C++&amp;Java)问题总结。</p></summary>
<category term="总结" scheme="https://kelecn.top/categories/%E6%80%BB%E7%BB%93/"/>
<category term="面向对象" scheme="https://kelecn.top/tags/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/"/>
<category term="C++" scheme="https://kelecn.top/tags/C/"/>
<category term="编程" scheme="https://kelecn.top/tags/%E7%BC%96%E7%A8%8B/"/>
<category term="Java" scheme="https://kelecn.top/tags/Java/"/>
</entry>
<entry>
<title>JAVA测试题</title>
<link href="https://kelecn.top/posts/19203/"/>
<id>https://kelecn.top/posts/19203/</id>
<published>2020-02-07T02:05:00.000Z</published>
<updated>2021-04-03T06:51:22.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:JAVA基础测试题。</p><a id="more"></a><h2 id="第一题"><a href="#第一题" class="headerlink" title="第一题"></a>第一题</h2><p>输出9*9口诀表。</p><p><strong>代码:</strong></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> exam;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Exam</span> </span>{</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">1</span>; i < <span class="number">10</span>; i ++)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">for</span>( <span class="keyword">int</span> j = <span class="number">1</span>; j <= i; j++)</span><br><span class="line"> {</span><br><span class="line"> System.out.print(i +<span class="string">" * "</span>+j+<span class="string">" = "</span>+i*j + <span class="string">" "</span>);</span><br><span class="line"> }</span><br><span class="line"> System.out.println();<span class="comment">//换行</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><strong>运行截图:</strong></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/2020-11-08_193731.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/2020-11-08_193731.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII=" alt="2020-05-07_102624.png"></p><h2 id="第二题"><a href="#第二题" class="headerlink" title="第二题"></a>第二题</h2><p>求1+2!+3!+…+20!的和。</p><p><strong>代码:</strong></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> exam;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Exam</span> </span>{</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"><span class="keyword">float</span> s=<span class="number">0</span>,t=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">int</span> n;</span><br><span class="line"> <span class="keyword">for</span> (n=<span class="number">1</span>;n<=<span class="number">20</span>;n++)</span><br><span class="line"> {</span><br><span class="line"> t=t*n; <span class="comment">// 求n!</span></span><br><span class="line"> s=s+t; <span class="comment">// 将各项累加</span></span><br><span class="line"> }</span><br><span class="line"> System.out.println(<span class="string">"1+2!+3!+...+20!="</span>+s);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><strong>运行截图:</strong></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/2020-11-08_193822.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/2020-11-08_193822.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII=" alt="2020-05-07_104101.png"></p><h2 id="第三题"><a href="#第三题" class="headerlink" title="第三题"></a>第三题</h2><p>一个5位数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同。</p><p><strong>代码:</strong></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> exam;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.Scanner;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Exam</span> </span>{</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">int</span> ge,shi,qian,wan,x;</span><br><span class="line">System.out.println(<span class="string">"请输入您想判断的五位数字:"</span>);</span><br><span class="line"> Scanner in = <span class="keyword">new</span> Scanner(System.in);</span><br><span class="line"> x=in.nextInt();</span><br><span class="line"> wan=x/<span class="number">10000</span>;<span class="comment">//万位</span></span><br><span class="line"> qian=x%<span class="number">10000</span>/<span class="number">1000</span>;<span class="comment">//千位</span></span><br><span class="line"> shi=x%<span class="number">100</span>/<span class="number">10</span>;<span class="comment">//十位</span></span><br><span class="line"> ge=x%<span class="number">10</span>;<span class="comment">//个位</span></span><br><span class="line"> <span class="keyword">if</span> (ge==wan&&shi==qian)<span class="comment">//个位等于万位并且十位等于千位</span></span><br><span class="line"> { </span><br><span class="line"> System.out.println(<span class="string">"这是回文数\n"</span>);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> System.out.println(<span class="string">"这是不是回文数\n"</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><strong>运行截图:</strong></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/2020-11-08_193850.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/2020-11-08_193850.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII=" alt="2020-05-07_104434.png"></p><h2 id="第四题"><a href="#第四题" class="headerlink" title="第四题"></a>第四题</h2><p>一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10次反弹多高?</p><p><strong>代码:</strong></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> exam;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Exam</span> </span>{</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"><span class="keyword">double</span> sum = <span class="number">0</span>, high = <span class="number">100</span>;<span class="comment">//sum为路径总和,high表示当前高度</span></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < <span class="number">10</span>; i++) </span><br><span class="line">{</span><br><span class="line">sum = high + high / <span class="number">2</span> + sum;<span class="comment">//一次落地距离+弹起距离+已经过路程</span></span><br><span class="line">high /= <span class="number">2</span>;<span class="comment">//弹起高度为一半</span></span><br><span class="line">}</span><br><span class="line">sum -= high;<span class="comment">//求第10次落地经过路程需减去第10次弹起距离</span></span><br><span class="line">System.out.println(<span class="string">"共经过:"</span>+sum+ <span class="string">"米\n"</span>+<span class="string">"第10次反弹高度为:"</span>+high+<span class="string">"米"</span>);</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><strong>运行截图:</strong></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/2020-11-08_193916.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/2020-11-08_193916.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII=" alt="2020-05-07_104730.png"></p><h2 id="第五题"><a href="#第五题" class="headerlink" title="第五题"></a>第五题</h2><p>猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个; 第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。</p><p><strong>代码:</strong></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> exam;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Exam</span> </span>{</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"><span class="keyword">int</span> x = <span class="number">1</span>;<span class="comment">//第十天剩余桃子数</span></span><br><span class="line"><span class="keyword">int</span> y;<span class="comment">//天数</span></span><br><span class="line"><span class="keyword">for</span>(y=<span class="number">1</span>;y<=<span class="number">9</span>;y++)</span><br><span class="line">{</span><br><span class="line">x=(x+<span class="number">1</span>)*<span class="number">2</span>;<span class="comment">//前一天的剩余桃子数都是今天剩余桃子数加1后的两倍</span></span><br><span class="line">}</span><br><span class="line">System.out.println(<span class="string">"猴子第一天一共摘了"</span>+x+<span class="string">"个桃子。"</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><strong>运行截图:</strong></p><p><img src="https://cdn.jsdelivr.net/gh/kelecn/images@master/2020-11-08_193943.png" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/kelecn/images@master/2020-11-08_193943.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII=" alt="2020-05-07_105048.png"></p>]]></content>
<summary type="html"><p>简介:JAVA基础测试题。</p></summary>
<category term="知识" scheme="https://kelecn.top/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="面向对象" scheme="https://kelecn.top/tags/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/"/>
<category term="代码" scheme="https://kelecn.top/tags/%E4%BB%A3%E7%A0%81/"/>
<category term="编程" scheme="https://kelecn.top/tags/%E7%BC%96%E7%A8%8B/"/>
<category term="Java" scheme="https://kelecn.top/tags/Java/"/>
</entry>
<entry>
<title>面向对象的程序设计实验(C++)</title>
<link href="https://kelecn.top/posts/29708/"/>
<id>https://kelecn.top/posts/29708/</id>
<published>2019-12-25T02:51:34.000Z</published>
<updated>2021-04-03T06:51:06.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:面向对象程序设计(C++)。<br> <a id="more"></a><br>还没写呢^_^</p>]]></content>
<summary type="html"><p>简介:面向对象程序设计(C++)。<br></summary>
<category term="知识" scheme="https://kelecn.top/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="面向对象" scheme="https://kelecn.top/tags/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/"/>
<category term="C++" scheme="https://kelecn.top/tags/C/"/>
<category term="代码" scheme="https://kelecn.top/tags/%E4%BB%A3%E7%A0%81/"/>
<category term="编程" scheme="https://kelecn.top/tags/%E7%BC%96%E7%A8%8B/"/>
<category term="嵌入式" scheme="https://kelecn.top/tags/%E5%B5%8C%E5%85%A5%E5%BC%8F/"/>
</entry>
<entry>
<title>嵌入式开发为什么选择C语言?</title>
<link href="https://kelecn.top/posts/63638/"/>
<id>https://kelecn.top/posts/63638/</id>
<published>2019-11-25T09:08:29.000Z</published>
<updated>2021-04-03T06:50:54.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:嵌入式+C语言=?<br> <a id="more"></a></p><h3 id="1-从语言特点来说"><a href="#1-从语言特点来说" class="headerlink" title="1.从语言特点来说"></a>1.从语言特点来说</h3><p>①C语言有出色的可移植性,能在多种不同体系结构的软/硬平台上运行。</p><p>②简洁紧凑,使用灵活的语法机制,并能直接访问硬件能够直接访问硬件的语言有:汇编和C语言汇编属于低级语言,难以完成一些复杂的功能,但是汇编比C语言访问硬件的效率更高。所以,一般将硬件初始化的工作交给汇编,比较复杂的操作交给C语言。</p><p>③C语言具有很高的运行效率。</p><h3 id="2-嵌入式开发中的地位——开发工具"><a href="#2-嵌入式开发中的地位——开发工具" class="headerlink" title="2.嵌入式开发中的地位——开发工具"></a>2.嵌入式开发中的地位——开发工具</h3><h3 id="3-高级语言中的低级语言:面向过程VS面向对象"><a href="#3-高级语言中的低级语言:面向过程VS面向对象" class="headerlink" title="3.高级语言中的低级语言:面向过程VS面向对象"></a>3.高级语言中的低级语言:面向过程VS面向对象</h3><h5 id="面向过程:"><a href="#面向过程:" class="headerlink" title="面向过程:"></a>面向过程:</h5><p>“面向过程”(Procedure Orien<a href="http://www.elecfans.com/tags/te/">te</a>d)是一种以过程为中心的编程思想。“面向过程”也可称之为“面向记录”编程思想,他们不支持丰富的“面向对象”特性(比如继承、多态),并且它们不允许混合持久化状态和域逻辑。</p><p>面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。面向过程其实是最为实际的一种思考方式,就算是面向对象的方法也是含有面向过程的思想。</p><p>可以说面向过程是一种基础的方法,它考虑的是实际地实现。一般的面向过程是从上往下步步求精,所以面向过程最重要的是模块化的思想方法。</p><h5 id="面向对象:"><a href="#面向对象:" class="headerlink" title="面向对象:"></a>面向对象:</h5><p>面向对象的分析根据抽象关键的问题域来分解系统。面向对象的设计是一种提供符号设计系统的面向对象的实现过程,它用非常接近实际领域术语的方法把系统构造成“现实世界”的对象。</p><p>面向对象程序设计可以看作一种在程序中包含各种独立而又互相调用的对象的思想,这与传统的思想刚好相反:传统的程序设计主张将程序看作一系列函数的集合,或者直接就是一系列对电脑下达的指令。面向对象程序设计中的每一个对象都应该能够接受数据、处理数据并将数据传达给其它对象,因此它们都可以被看作一个小型的“机器”,即对象。</p><h5 id="面向过程和面向对象的区别:"><a href="#面向过程和面向对象的区别:" class="headerlink" title="面向过程和面向对象的区别:"></a>面向过程和面向对象的区别:</h5><p>以一个人从A地到B地为例,面向过程就是需要规划路线,了解路况,自己做好一系列的准备;而面向对象就是坐上一辆出租车,告诉司机我要去B地就可以了,不用关心其他的事情。</p><p>最后,C语言也有他自身的缺陷,比如代码的复用性差,代码的维护性差,扩展性(新增代码时不改变原来的代码)很差。</p>]]></content>
<summary type="html"><p>简介:嵌入式+C语言=?<br></summary>
<category term="知识" scheme="https://kelecn.top/categories/%E7%9F%A5%E8%AF%86/"/>
<category term="编程" scheme="https://kelecn.top/tags/%E7%BC%96%E7%A8%8B/"/>
<category term="嵌入式" scheme="https://kelecn.top/tags/%E5%B5%8C%E5%85%A5%E5%BC%8F/"/>
<category term="硬件" scheme="https://kelecn.top/tags/%E7%A1%AC%E4%BB%B6/"/>
<category term="C语言" scheme="https://kelecn.top/tags/C%E8%AF%AD%E8%A8%80/"/>
</entry>
<entry>
<title>Matlab Gui关于edit keypressfcn的响应</title>
<link href="https://kelecn.top/posts/17834/"/>
<id>https://kelecn.top/posts/17834/</id>
<published>2019-10-02T04:00:00.000Z</published>
<updated>2021-04-03T06:50:42.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:Matlab GUI键盘输入相关代码。</p><a id="more"></a><figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">showmap</span></span></span><br><span class="line"> fig=<span class="built_in">figure</span>( <span class="string">'Name'</span>,<span class="string">'Timer'</span>,<span class="string">'Position'</span>,[<span class="number">0</span>,<span class="number">0</span>,<span class="number">500</span>,<span class="number">500</span>] ,<span class="string">'NumberTitle'</span>,<span class="string">'off'</span>,<span class="string">'visible'</span>,<span class="string">'off'</span>);</span><br><span class="line"> movegui(fig,<span class="string">'center'</span>);</span><br><span class="line"> set(fig,<span class="string">'visible'</span>,<span class="string">'on'</span>);</span><br><span class="line"> ttext= uicontrol(<span class="string">'Style'</span>,<span class="string">'edit'</span>,<span class="string">'Position'</span>,[<span class="number">150</span>,<span class="number">250</span>,<span class="number">200</span>,<span class="number">30</span>],<span class="string">'String'</span>,<span class="string">'Press "Start"'</span>,...</span><br><span class="line"> <span class="string">'KeyPressFcn'</span>,@keyPress);</span><br><span class="line"></span><br><span class="line"> ii=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">keyPress</span><span class="params">(x,y)</span></span></span><br><span class="line"> set(ttext,<span class="string">'string'</span>,num2str(ii));</span><br><span class="line"> ii = ii+<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">end</span></span><br><span class="line"><span class="keyword">end</span></span><br></pre></td></tr></table></figure><!--more--><p>参考文献:<a href="https://mp.weixin.qq.com/s?__biz=MzU5NTAyMTIzOQ==&mid=2247483991&idx=1&sn=0e50c2faa57464846784ef18d54bd608&chksm=fe791e8fc90e9799d139e3860be2fd02afc183d58858959d0d29eb71cc32ed63b68f6a93edfb&scene=21#wechat_redirect">打浦桥程序员</a></p>]]></content>
<summary type="html"><p>简介:Matlab GUI键盘输入相关代码。</p></summary>
<category term="技术" scheme="https://kelecn.top/categories/%E6%8A%80%E6%9C%AF/"/>
<category term="代码" scheme="https://kelecn.top/tags/%E4%BB%A3%E7%A0%81/"/>
<category term="Matlab" scheme="https://kelecn.top/tags/Matlab/"/>
<category term="Gui" scheme="https://kelecn.top/tags/Gui/"/>
</entry>
<entry>
<title>Kelecn的第一条博客!</title>
<link href="https://kelecn.top/posts/59565/"/>
<id>https://kelecn.top/posts/59565/</id>
<published>2019-09-19T09:10:00.000Z</published>
<updated>2021-04-03T06:50:26.000Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>简介:您好!Hexo!</p><a id="more"></a><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"> .::::.</span><br><span class="line"> .::::::::.</span><br><span class="line"> :::::::::::</span><br><span class="line"> ..:::::::::::'</span><br><span class="line"> '::::::::::::'</span><br><span class="line"> .::::::::::</span><br><span class="line"> '::::::::::::::..</span><br><span class="line"> ..::::::::::::.</span><br><span class="line"> ``::::::::::::::::</span><br><span class="line"> ::::``:::::::::' .:::.</span><br><span class="line"> ::::' ':::::' .::::::::.</span><br><span class="line"> .::::' :::: .:::::::'::::.</span><br><span class="line"> .:::' ::::: .:::::::::' ':::::.</span><br><span class="line"> .::' :::::.:::::::::' ':::::.</span><br><span class="line"> .::' ::::::::::::::' ``::::.</span><br><span class="line"> ...::: ::::::::::::' ``::.</span><br><span class="line">````':. ':::::::::' ::::..</span><br><span class="line"> '.:::::' ':'````..</span><br></pre></td></tr></table></figure><p>友情链接:<a href="https://github.com/kelecn">My Github</a>、<a href="https://hexo.io/">Hexo</a></p>]]></content>
<summary type="html"><p>简介:您好!Hexo!</p></summary>
<category term="生活" scheme="https://kelecn.top/categories/%E7%94%9F%E6%B4%BB/"/>
<category term="Hexo" scheme="https://kelecn.top/tags/Hexo/"/>
<category term="Kelecn" scheme="https://kelecn.top/tags/Kelecn/"/>
<category term="日记" scheme="https://kelecn.top/tags/%E6%97%A5%E8%AE%B0/"/>
</entry>
</feed>