电玩DIY [ VG DIY ] - Video Game Do It Yourself

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 14177|回复: 27

自制FC无线手柄

  [复制链接]
发表于 2019-5-22 14:16:45 | 显示全部楼层 |阅读模式
本帖最后由 雷精灵2046 于 2019-6-14 09:28 编辑
# F' D3 @1 D5 r2 p% e5 [/ _. R' I5 o0 s. C4 A
没有用复杂的分立元件搭建发射接收电路,直接用的现成的2.4G无线模块jdy-40。
  q7 [) {4 W: ~# z0 N7 j- f5 y) o8 N* R. y
, \& O1 [9 p) Q( r
发射端靠3.7V锂电池供电,用了一片SOP8封装的STC单片机,负责产生连发脉冲,同时负责检测电池电量,电压低于3V左右的时候触发低压中断,低压指示LED就会亮起来告知该充电了。平时发射模块和单片机均处于睡眠状态,有按键按下才会唤醒,从而实现省电。实测睡眠状态下整机电流约1~2uA。板子洗了一下稍微干净了一点。因为对于微功耗设备来说,焊接残余的助焊剂可能会增加漏电流。
- k' ^, j  i0 d7 N* w1 }; e- W, J. u/ o0 M1 i! \
买了一个火花的FC山寨手柄,去掉里面的牛屎板子,并修正一下塑料挡板,把锂电池和充电模块装进去。
7 _5 ^7 Z. k1 _为了减少体积,充电模块裁剪得十分小,并且更换了充电电阻使之适应这个小小的锂电池。这么小容量的电池,也不需要多么大的充电电流是吧?
6 o7 H/ c0 u* ~+ Y) V4 v然后统统用热熔胶粘上。充电电流比较小,所以发热很少,不会熔化热熔胶。; ~' Q6 J8 r2 {1 N

( A) E) x, y: L. d% d3 L
) P4 m( X9 _" N  ~. I0 o) z9 R; N0 g0 a
最后把按键、导电橡胶和电路板装上去。. L8 w6 @$ b3 L- v; L* V  ^9 K
精心裁剪了电路板,正好扣上,不会阻碍其他元件,也不会影响后盖和拧螺丝。- T, o4 x. }" E
. o5 _! o  `+ b! w9 W

+ x2 z& o% o# ?; t! ~0 W9 k完工!
" d3 P0 [7 O' A3 n7 B% m( q7 V6 x# n" k; r' v

1 M4 `; A5 e- R$ x这是充电的MicroUSB插座。旁边的小孔用于透出低压报警LED的光线。
5 p# ~' A+ }* _/ G, m' u/ Y$ A& M6 a! C

' y. i( k! Q  s5 c/ O7 y$ D接收端用一片DIP16封装的STC单片机模拟CD4021。为啥要用单片机模拟而不是直接用CD4021?因为jdy-40模块接收端在有按键按下的时候输出高电平,无按键按下输出低电平,和普通手柄正好相反。当然我也可以用两片74HC00或者74HC04之类的逻辑门进行反相,但那就增加了芯片的数量。对于FC手柄这种工作频率并不高的设备来说,STC单片机完全可以胜任模拟工作。
6 o! [, ~) F, O5 [$ m3 d6 h/ r4 d
1 M9 l* t" |1 P1 G( V% ]2 F7 P

2 |9 n! d* P# d, S" ~1 B# x/ }电路设计有点小小的错误,所以有几根飞线。原本设计使用低压差LDO是XC6206,结果在做这个接收模块的时候,买的LDO居然找不到了!无奈只好用了AMS1117。幸好对于接收模块来说是5V降到3.3V,1117可以胜任。要是发射端手柄的话,3.7V降到3.3V,那就非得用6206不可了。8 l" Q  W8 b6 v' z+ D# e
! a' P! n+ d2 [: K* O, T; |
实测十分灵敏,延迟极小几乎感觉不出来。可惜这山寨手柄的手感并不佳,尤其是方向键,软塌塌的。看来我得买个剪线手柄改装。: |' V2 |  B3 X6 N  T4 e
; E( z# ?- x; m) Y
这是电路图,有兴趣的朋友可以参考。
7 i! J1 K1 ^& V1 F& o0 ?; D0 |! [9 M1 @0 e; D: u' R

; H9 [5 H* t1 x% x0 E, e) j/ T2 j我信奉开源主义,十分痛恨把技术藏着掖着。好东西大家分享嘛!所以两个单片机的源代码大公开!' I8 u: ]7 \2 T9 i/ ^$ H5 d- k/ F4 |. E' B
编译器:Keil 51。, u5 X8 U5 e' ?4 X8 o# v1 X
* I6 p; E% ^6 C% b
发射端:; k- R- W3 e+ j+ Q3 m! a
  1. #include <INTRINS.H>0 ]: G. k6 p( x8 Y' r% D
  2. #include "STC15W.h"% U# P8 p6 ?$ X1 n! o& P. y

  3. ! l% {4 g1 H- Q( p, h

  4. , T$ {+ ]5 x! i
  5. /*+ G- Q2 v+ j2 f, ~8 X* J  V1 L: A
  6. --------------------------3 @; y9 i( h3 U5 W1 L" C9 D6 b
  7. |1 (OUT)        \__/   (INT1) 8|
    . Z9 J, W; |, M0 s0 Y9 {
  8. |                                                   |
    # Q- W8 |; E6 m* e' d* S
  9. |2 (VCC)                   (INT0) 7|
    - E3 w6 T2 R. b: d3 N  C" v8 I
  10. |                 STC15W204S                   |
    $ X5 h' }3 p4 _0 ^
  11. |3 (LED)                         (TXD) 6|
    5 E% U; @) c, q3 A7 V7 }& W* ^
  12. |                                                   |
    - K5 K7 m1 I: g6 P& U) ~& Q
  13. |4 (GND)                         (RXD) 5|- j1 X  a, Y+ K0 O
  14. --------------------------
    6 ?2 T1 Z  B2 a% Y" ~" O

  15. 7 |6 N2 o: A+ Y5 n
  16. LED ---|<|---[===]--- VCC$ l$ V# h8 k/ `
  17.            Red          330
    6 U2 l  x' D# m3 q$ b! Z
  18. 9 G! x( D3 d# i. @; v7 o2 D
  19. Fosc = 6MHz
      t$ r  v! S: T1 Y4 [7 P
  20. */% Z' H$ }" q& k* s" e

  21. 5 @$ h/ p9 r/ h1 L: b
  22. 6 d6 E4 _, l: A* `) y
  23. // 矩形波输出脚" ?+ M& g6 U+ d) V, ?
  24. sbit OUT = P5^4;
    & w, w* ^! z5 v9 G% N& j* [
  25. // 低压指示灯引脚6 }* N2 P: c$ }4 f% ?8 E& O
  26. sbit LED = P5^5;. g+ `. p3 ], `) [9 e- i8 m
  27. , `) u" ^9 i$ D4 P
  28. // 停机标志位
    + y4 D. f- d! F, L( i0 t2 s+ m
  29. bit isReadyToHalt = 0;  g& Z9 d7 U% m  w( j, b' r
  30. - G/ Y1 F9 d) [! l# a( ^
  31. // 矩形波次数累计* l" H/ ?+ g: m0 w5 k# J  b; ]. B
  32. static volatile unsigned char count = 0;
    , D  ]- M1 [' [7 A; J

  33. . _" }- X! ?* _7 z" r4 N3 q. ~

  34. " e# L) P$ l( \  t9 ^/ j- Y
  35. static void GPIO_Init(){' @; D6 q9 o* X
  36.         // P3口设置为准双向,默认靠内部弱上拉输出高电平
    ' a9 f& d, m9 F
  37.         P3M0 = 0;; p! x- c5 V) s/ p& u0 C$ t9 r
  38.         P3M1 = 0;5 a% N+ p# P' ^4 H3 ~
  39.         P3 = 0xFF;* g/ k* L. N9 D& o
  40.         // P5口设置为准双向,默认靠内部弱上拉输出高电平5 L# `9 T8 e4 A, M
  41.         P5M0 = 0;7 W4 H- H4 D* y. y$ ~: K9 I
  42.         P5M1 = 0;
    8 `/ ^( B, t' T( x; V- [  \
  43.         P5 = 0xFF;
      v% @0 f8 L5 I' A
  44. }. q* F& e) d: [4 k( q" K

  45. 6 j. M+ S# R  A9 E
  46. static void Timer0_Init(){1 I: q2 A5 g+ f+ S" D
  47.         // 16毫秒@6.000MHz
    ; E# F2 i4 S% R4 @3 c
  48.         AUXR &= 0x7F;        // 定时器时钟12T模式* a! K" X+ r  a. k  T8 U
  49.         TMOD &= 0xF0;        // 设置定时器模式9 ]9 r9 @% W; E% n
  50.         TL0 = 0xC0;                // 设置定时初值
    * n4 M) z. r7 K1 x) Y" h2 O4 E
  51.         TH0 = 0xE0;                // 设置定时初值# J: j) h# l; t: ^: Q
  52.         TF0 = 0;                // 清除TF0标志& `5 A  g/ s% q
  53.         TR0 = 1;                // 定时器0开始计时: ~3 ^$ \% E0 j( x! g
  54. }
    ( p! R3 b# G% \' q1 p# r

  55. # o% O4 n9 y% Q# n3 P+ a+ u$ [
  56. static void Interrupt_Init(){1 r+ S& o& X* g$ e, V! F& C
  57.         // INT0中断触发类型为下降沿触发9 \1 ?& w( w+ K2 p5 \* V& U- P
  58.         IT0 = 1;
    : j! W1 V7 ^  p' I: ]& e. w" V) q
  59.         // 允许INT0中断
    ! }  p* y! k, x$ D& h
  60.         EX0 = 1;" V/ _. I* F% h
  61.         // INT1中断触发类型为下降沿触发: Q; l* I$ N5 q: O4 ~  [9 M) Z$ c8 E
  62.         IT1 = 1;
    " \* j0 }" X, e' E
  63.         // 允许INT1中断2 T9 u. [- Q5 m
  64.         EX1 = 1;( [6 e4 U3 r+ H9 j% |3 z# n( J1 e# J$ V
  65.         // 允许定时器0中断
    . E1 `* f) y. T" V; D, `& @, a
  66.         ET0 = 1;/ D) ?/ m1 j: b7 S" t( F% p0 @2 \
  67.         // 允许全局中断0 x) B3 _- A# I9 b* `2 u" j& ^
  68.         EA = 1;
    * R! d# w( ?: K3 X- E
  69. }
    0 i2 D# u6 k3 u% R' u

  70. $ j- k( @4 a  O' O/ n
  71. static void INT0_Isr() interrupt 0{& x. d( \1 Z: Q  O: Y- U
  72.         // 矩形波次数累计归零1 ?% i2 W( Z4 H6 i; v2 b
  73.         count = 0;! h1 ^. N) D* E( V7 D
  74.         // 重开定时器0中断2 h/ s/ A$ h* |3 X& r2 W
  75.         ET0 = 1;: s4 o# I, ^% n4 F1 @5 D  ^' A; N( F8 S. ?
  76. }1 b6 P' J8 O9 A$ P

  77. 3 d5 k) T% P7 E8 }) L! C
  78. static void Timer0_Isr() interrupt 1{
    6 z4 E: ^* t3 l* t' Y& `3 p) n
  79.         // 输出矩形波5 b; l/ K( V. `  p: `! i/ i
  80.         OUT = ~OUT;/ ^* T0 p5 u# k; K3 `
  81.         // 累计矩形波次数
    $ q* w0 c" x, i& }
  82.         count++;
    / k' w4 }# F( t; m& l
  83.         // 超过250个矩形波,准备停机
    9 G+ G& h5 I. e! p, ~
  84.         if(count > 250){6 O, l! W) @0 P# W
  85.                 count = 0;
    7 S+ K6 o5 ?3 b$ R' c: b
  86.                 isReadyToHalt = 1;9 J% |6 s& y% `+ M/ x: k1 l) Y  Q/ A9 H4 U
  87.         }, O: j" g& X% D/ L* [
  88. }
    : d8 y2 H9 @* l7 Z2 h

  89. ) {# L; e  F# H0 {  U
  90. static void INT1_Isr() interrupt 2{
    8 w% G1 N. @  [; J
  91.         // 矩形波次数累计归零
    $ s8 I4 J) @9 l8 T  A
  92.         count = 0;
    9 ~, H+ _# m* m4 T& W$ ~
  93.         // 重开定时器0中断/ k. x( M+ ^, g5 n* k& |+ k: c, Y
  94.         ET0 = 1;* v3 y8 m; ]0 ]; C- g$ ^, X
  95. }* j; ~4 O! |, x% b2 f6 e2 {' ?; z

  96. / k6 k- A. E5 M& `# \
  97. . U9 Z" E# X# h: ~! Y& D6 M- H
  98. void main(){
    - Y7 @- t7 v7 E3 J
  99.         // 初始化P3和P5口' n5 c2 X- ^8 w- l$ O8 h0 w1 C
  100.         GPIO_Init();4 e2 `* j$ I/ l" Y& f( @9 G
  101.         // 初始化定时器0
    0 o" w4 o- d5 f2 L9 _
  102.         Timer0_Init();
    8 @. V) x. T  P! g9 G; u
  103.         // 初始化中断$ G) [/ ?" S" k
  104.         Interrupt_Init();. d7 |6 n  f9 A( R
  105.        
    ! J) a1 {. S# A, N
  106.         while(1){
    ; G) G" x( {8 M- v4 X
  107.                 // 检测电量
    5 a4 ]- R: `& i& d
  108.                 if(PCON & (1 << 5)){
      _; g" f' r) j; g% S
  109.                         // 如果电量低,低压指示灯亮
    1 z! H; G' v: e" C
  110.                         LED = 0;. j. x+ `9 R  @- f; V0 V
  111.                         // 清电量检测硬件标志位. R7 N& f( R! n
  112.                         PCON &= ~(1 << 5);
    : f8 G  q; e+ Z  s7 J, G0 ~( ^
  113.                 }else{
    , S! N3 o" b1 \8 Z
  114.                         // 电量正常,低压指示灯灭: y* t/ f4 ?( N  B6 J
  115.                         LED = 1;
    / O$ v5 S  b0 z9 }4 N. h) r9 i: R; o
  116.                 }
    8 O$ R/ d' X5 q
  117.   c, |1 k, m. _$ Z. n! ~( X# f
  118.                 // 检测到停机标志
    + f% z9 o1 i1 P; A! N: S
  119.                 if(isReadyToHalt == 1){
    8 I. |5 R4 G& F: s* k
  120.                         // 暂时关闭定时器0中断
    ' R/ Y) `3 _% |7 N
  121.                         ET0 = 0;
    % o  ]# Z( L) u6 Y* m
  122.                         // 停机之前先把矩形波输出脚置低电平,以方便INT0和INT1唤醒CPU; V5 W# M- @5 ^: z" \# T- x
  123.                         OUT = 0;
    & S5 x; L& n, p
  124.                         // 停机之前先把低压指示灯灭掉,以省电* I1 l! l1 N' n- o0 h( X
  125.                         LED = 1;
    5 S: [: n: g$ e5 z& d
  126.                         // 进入停机模式1 Z3 n, E* m" V6 O1 t
  127.                         PCON |= 0x02;+ w% V4 _! j1 J4 ^
  128.                         _nop_();0 ~1 ]' ^2 W( c& ~% @* b
  129.                         _nop_();+ {8 r/ e1 w- C9 H
  130.                         _nop_();5 }9 M. V9 }; m3 k/ W6 u8 H
  131.                         _nop_();
    & ?  ^) W' E/ z6 q, }' V
  132.                         // 唤醒,清标志位
    4 B' u& ^) v4 J9 P+ z
  133.                         isReadyToHalt = 0;
    $ b) X. {* d( \6 W2 p
  134.                         // 重开定时器0中断1 Z# f( u8 O% A1 }
  135.                         ET0 = 1;
    % g% E/ N: ]6 P$ l" q
  136.                 }
    8 N/ p2 G' x5 r* H
  137.         }3 `" N2 H% J3 B. T- {  _
  138. }$ Z0 L  [6 j1 q
复制代码
2 b2 J+ }$ h" h
硬件参数配置:  D3 b/ a4 c' f
% @4 ?* F* A$ z( b# s2 A
7 Z; x5 u* r2 y# X, P- j1 U
接收端:
/ b. ~: n' Z" _, F) S& h
  1. #include <INTRINS.H>
      h6 x: b5 H" t6 U9 y. Y- u, j
  2. #include "STC15W.h"
    0 v2 q# i9 n6 |+ `( e0 q: @  m
  3. 5 s: Q& w; j  Y* D% R
  4. % e4 q( `! K* |1 V% O6 n! _
  5. /*
    * Q' Q6 s' V* ]4 e
  6. 4 S  M' Y5 x& C, E
  7. *---------------------------*
    4 i# g( {4 v9 a  G3 a; [
  8. |1 (GPIO2)         \__/  (GPIO1)16|' Q" D: Y* \  U
  9. |                                                        |
    - y5 y; y0 a4 B: ?# _+ }
  10. |2 (GPIO3)                   (GPIO0)15|
    8 I8 h+ T8 k; T6 @! p7 X/ B9 H
  11. |                                                        |
    5 w9 }0 O! J6 g/ T* R) e( X$ W$ i. T" i
  12. |3 (GPIO4)                                  14|" ?! g% I6 t9 t2 P
  13. |                                                        |; u" s& H* X0 j& ~: R" }
  14. |4 (GPIO5)                        (DATA)13|- Y* t& h; }6 g6 D5 d1 N3 M
  15. |                  STC15W204S                |) n' H6 F; K9 @0 w+ K
  16. |5 (GPIO6)                   (LATCH)12|
    4 M% M3 l8 L+ ]+ v1 `
  17. |                                                        |0 \( _5 p9 I7 u+ f2 L5 S
  18. |6 (VCC)                         (CLK)11|+ k8 Z5 X$ K' B. R& X
  19. |                                                          |
    8 M6 {0 o' [% Z* h
  20. |7 (GPIO7)                         (TXD)10|8 u# R2 M4 E- P# b  M& s" G
  21. |                                                        |
    ) p$ A' X8 J" ~& B/ E
  22. |8 (GND)                         (RXD) 9|
    . [" m" V( V: l% b. @
  23. *---------------------------*
    * M+ ]: ?- w1 J) R* P2 H
  24. Fosc = 12MHz
    6 h/ i+ Y, R4 a) q
  25. 7 Z( H' f4 R: d  g5 v5 d- i
  26. P1.0 -> 上( x8 q& I; R1 R  M8 B
  27. P1.1 -> 左
    * A: e# G, G7 u/ v
  28. P1.2 -> 下. e1 E0 W2 g6 F% J1 z0 N% ?
  29. P1.3 -> 右
    ! b+ G/ S7 E; [. E
  30. P1.4 -> SEL
    4 V3 e3 b: Y4 y, H7 x4 B
  31. P1.5 -> STA
    ' n7 Y3 v3 a9 |5 o7 Y  A
  32. P5.4 -> B3 p" M+ Z# a% N3 L9 w9 y
  33. P5.5 -> A! U7 i; `% W0 x/ R

  34. , I8 S" j  g' p0 H) R& f' h  C
  35. */# K6 ?( c1 f# d( f+ `
  36. ' u3 v# O  m" q, D
  37. 0 X8 q7 t& O. i( w' K5 e* w
  38. sbit CLK        = P3^2;7 ^$ n& p5 d; t: T+ a. c* P
  39. sbit LATCH        = P3^3;
    , I! ?. D& F  ]8 F7 ?
  40. sbit DATA        = P3^6;  S5 L, `0 |& [* O' T

  41. 5 z7 t, s+ r8 \5 ?, Z! c
  42. bit isReady = 0;
    + x7 p8 W. ^  H8 `3 P2 N
  43. static unsigned char key = 0;
    4 O$ R; I; `1 W/ a
  44. static unsigned char buf = 0;        // 双缓冲。这个缓冲区保存从P1和P5组合而来的键值
    1 m5 S6 e" k( H9 ?( W8 G
  45. static unsigned char bufReady = 0;        // 双缓冲。这个缓冲区保存上面那个缓冲区的备份
    3 F: G  }" h8 d: \. ^
  46. static const unsigned char data mask[] = {0x80, 0x40, 0x10, 0x20, 0x01, 0x04, 0x02, 0x08};        // A B SELECT START UP DOWN LEFT RIGHT。为提升速度,这个表放到RAM中6 [# G  R. Z8 \- \( b# k
  47. static unsigned char idx = 0;2 t0 a$ m. {- B/ n  |: w4 \  @/ a
  48. . r% T) q9 X5 m3 I
  49. & x) h0 z: s, ]( J
  50. static void GPIO_Init(){; [& j% P4 U) U2 [! J
  51.         // P1口和P5口用于接收并行信号,全部初始化为准双向,依靠内部弱上拉输出高电平, L4 a. J, o: {! M
  52.         P1M0 = 0;) {/ V$ V) g* {3 E4 q; A1 M& a; H
  53.         P1M1 = 0;" l2 p4 O" j6 H! b* H  |
  54.         P1= 0xFF;) }0 b' O; z6 E; g
  55.         P5M0 = 0;
    / |' R' t/ E0 \4 c8 W$ D& V# i
  56.         P5M1 = 0;7 G) `; z) m/ F- y, Y+ L
  57.         P5= 0xFF;/ N9 D2 g; G. o6 S
  58.         // P3口初始化为准双向
    / N/ P/ Y: u' \7 ]$ x( p
  59.         P3M0 = 0;
    5 ^8 W) T2 x8 P+ a. F: X' b
  60.         P3M1 = 0;7 K0 L( w7 [1 H  i
  61.         P3 = 0xFF;
    & z! J+ h5 L- A: L5 s2 t
  62. }7 \, n+ ^( P- n* k" [
  63. $ A( v' x5 r  q& \- H/ c! k' ]! g
  64. static void Interrupt_Init(){* {7 ^8 B- s& ^  B4 H! e5 y
  65.         // INT0中断(CLK)触发类型为上升沿+下降沿
    . _, j& x9 `" M3 d( K$ P4 O# n
  66.         IT0 = 0;
    - c5 {+ p4 f6 T+ l9 m8 }
  67.         // 允许INT0中断
    : ~) O# g  Z* \3 B* h) t7 }9 t9 ~
  68.         EX0 = 1;
    5 i! @( b+ ?" q- }3 ^
  69.         // INT1中断(LATCH)触发类型为上升沿+下降沿
    9 e0 r2 ~$ ^, g; J3 W9 v- A( [
  70.         IT1 = 0;% e3 k4 M) L$ S6 L$ Y, u5 l
  71.         // 允许INT1中断6 `) \. T1 ^# W8 ]5 F& ~+ k; Y' ?9 P
  72.         EX1 = 1;
    2 }7 E0 N$ g" [0 X
  73.         // 开启全局中断
    ! ~3 f+ O/ z# z3 A* T
  74.         EA = 1;2 Y$ H, @% A5 r- {4 ^
  75. }
    ( h& A5 Q4 N( u6 z  R$ S* s7 A
  76.   s; f* H( x% g* l; R
  77. static void INT0_Isr() interrupt 0{0 E4 E- ^$ Q4 g0 ^, y9 ]# F6 \
  78.         // 只有已经成功锁存才允许CLK移位% f( e( E6 Q  ^
  79.         if(isReady == 0)
    7 j% d6 Y* E- S  L# X! {* P5 a
  80.                 return;
    ) P5 [; {; E3 ]! L! F% K9 R
  81.         // 读当前引脚电平,如果是低电平则说明是下降沿,此时直接忽略该中断
    " s+ b; X% p' D9 y4 C
  82.         if(CLK == 0)
    1 z2 l8 x) N6 C' ]
  83.                 return;
    9 Z2 {5 _6 G, J3 u2 B
  84.         // CLK上升沿到来的时候,取锁存值的下一位输出
    1 {" j6 |; L/ b, C
  85.         idx++;* N8 z3 y  u2 q/ x6 e3 d
  86.         DATA = key & mask[idx];: ?7 D8 V- M( r9 l/ u6 K& V
  87.         // 如果已经完成7次移位,则一轮读取完成: T1 z& F+ R. b0 v+ r
  88.         if(idx >= 7)9 s! {+ G: y" r, X) S
  89.                 isReady = 0;" I7 D# t& {( F; i
  90. }
    ' s: q8 `- W( L$ i
  91. $ I! _" s! K  G+ D3 X9 d! B$ Y
  92. static void INT1_Isr() interrupt 2{4 E+ v! Q1 G0 D# }  G
  93.         // 读当前引脚电平,如果是低电平则说明是下降沿,此时直接忽略该中断
    , H/ n# N! T  W- |  Y2 V
  94.         if(LATCH == 0)
    0 Z0 l" {, V- \+ i& g# j" I4 }
  95.                 return;" |7 n& c0 ]( E5 g1 g- [: ?/ c; ]' t
  96.         // 当LATCH上升沿到来的时候,锁存所有按键状态,同时把键值A输出到DATA; B+ {' u! O2 S
  97.         key = bufReady;  B# q. u! t" z2 ]+ N, M6 w1 L( q7 O
  98.         DATA = key & 0x80;//mask[0];        // 为了加速运算,直接取表中的值而不是读表
    1 B' e- y6 R  Y! B
  99.         idx = 0;" o/ J2 s9 \: F+ R$ D3 @
  100.         // 允许CLK进行移位+ ^' p0 h' {& K2 k) w" G, m; I
  101.         isReady = 1;
    : q2 Z" u) Z  J$ i' q  ^* h
  102. }
    : N: ~+ o1 S% T! k3 K

  103. $ R1 ?# u+ e+ ]; l. r& J; w
  104. void main(){
    9 \/ N3 {3 y( \* D+ N& K* E
  105.         GPIO_Init();
    - g9 i5 |% g# S( z4 K0 ?
  106.         Interrupt_Init();
    , \8 z! e+ H$ l5 D8 A
  107.        
    & Q# ~3 s3 n* n* r- ~: f( [
  108.         while(1){
    ) K$ I* |* x; Q
  109.                 //PCON |= 0x01;        // 进入省电模式
    9 E& H8 ?1 }2 F3 ]3 g1 u0 H' c
  110.                 //_nop_();
    / k6 _( f! I' A# |+ C  H
  111.                 //_nop_();
    - ~" q" Z  Q; J5 s2 B) U
  112.                 //_nop_();
    ; `! U4 I3 O! M% f" s2 E2 e& V0 O7 X( n
  113.                 //_nop_();
    9 \& O: u( N* s
  114.                 buf = ~((P1 & 0x3F) | ((P5 << 2) & 0xC0));' x6 l8 V0 ~' s* K
  115.                 bufReady = buf;
    " }* d6 `6 F" W/ b% V# a: {
  116.         }$ ]5 K9 I) A0 E4 A
  117. }- w2 E$ c! X$ `, M
复制代码
4 A5 F7 q3 `/ O; l+ ^9 P& Q
硬件参数配置无特殊要求,晶振频率选择12M即可。; _! Q! s1 ~# |

$ R3 H* y* d$ P0 s* @- r- N这是编译好的固件。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

评分

参与人数 3威望 +1 Diy币 +3 热血 +110 收起 理由
sion + 5 顶一个
5911 + 5
xunxun + 1 + 3 + 100

查看全部评分

回复

使用道具 举报

发表于 2019-5-23 10:05:23 | 显示全部楼层
不错的设计,想问一下楼主,FC的15针公头怎么解决?普通的公头太短了,插不进去FC的扩展接口。
回复

使用道具 举报

 楼主| 发表于 2019-5-23 11:27:39 | 显示全部楼层
69yuan 发表于 2019-5-23 10:05
* ?& P6 F6 u/ G8 {. C不错的设计,想问一下楼主,FC的15针公头怎么解决?普通的公头太短了,插不进去FC的扩展接口。 ...
$ C0 w" R$ f' h* W/ U! O
坛友的改造方案
回复

使用道具 举报

发表于 2019-5-25 10:42:27 | 显示全部楼层
高手的无私奉贤值得表扬,辛苦了!
回复

使用道具 举报

发表于 2019-5-25 12:07:18 | 显示全部楼层
精彩,楼主动手强,也写得很详细。
# d! F+ p5 n) s( u( q/ D6 X2.4G方案是目前无线的最低延迟吗?
回复

使用道具 举报

发表于 2019-5-28 17:27:23 | 显示全部楼层
给技术帝赞一个,有半成品发布吗,自己焊接改造就可以,编程实在不会啊
回复

使用道具 举报

发表于 2019-5-28 18:55:54 | 显示全部楼层
非常好,楼主是技术帝,到目前我都还没开发fc的无线套件,等空了,开发一套套件,等玩家自己组装。
回复

使用道具 举报

 楼主| 发表于 2019-5-29 16:49:20 | 显示全部楼层
xunxun 发表于 2019-5-25 12:07% ?1 L% q5 H9 s% l% J
精彩,楼主动手强,也写得很详细。
& T8 E' d2 D) x/ \- G0 Q2.4G方案是目前无线的最低延迟吗?
5 l* `" X  L) f8 K' C) o) j* k
我没用过其他无线手柄,所以实在不知道我自己做的这个手柄到底是不是最低延迟。$ ?9 p- u9 [8 G6 X. q# @: Y
不过根据网上的说法,延迟高低主要是由通信协议的复杂程度,以及数据传输速率决定的。这个模块虽然是2.4G无线模块,但由于协议很简单,所以延迟比较低。' l9 c1 h' P3 S, U
我用这个手柄玩一些ACT游戏,比如超级马里奥、忍者龙剑传、热血系列,完全感觉不到延迟,和游戏机自带的手柄没有任何区别。唯一的区别就是这个手柄是用火花山寨手柄改造的,外壳是垃圾回收塑料,粗糙+脆弱,导电橡胶弹性不佳,手感不是一般的差。" Y  j- Q5 ^6 j0 U8 ]
我手里还有十几张板子,等我有空了我再做一套,到时候买一个好一点的手柄改造。
回复

使用道具 举报

 楼主| 发表于 2019-5-29 16:56:14 | 显示全部楼层
ppad 发表于 2019-5-28 17:27$ h* n8 M0 `. A5 F
给技术帝赞一个,有半成品发布吗,自己焊接改造就可以,编程实在不会啊 ...

1 U" w1 o: a( g9 Z. V; y. T& n8 f很可惜,我手里没有多余的单片机了,LDO也找不到了,锂电池以及充电模块更是没有了。反正就是该用到的元件基本都没了,所以没法发布半成品。! i: `& X! i: ^* |* n% Z- E# a
两个板子倒是有十几张剩余。. ~8 F$ |) B7 N# k2 ^
你要是有USB转TTL串口板,完全可以自己买这两种单片机,然后我给你编译好的固件,你自己用串口板下载到单片机里面就行了。两个2.4G无线模块也得通过串口板用AT命令设置参数,不过好在我在设计电路的时候就已经预留好了串口,可以直接在线下载和在线设置参数。总的来说并不麻烦。
回复

使用道具 举报

 楼主| 发表于 2019-5-29 17:00:34 | 显示全部楼层
孙大师 发表于 2019-5-28 18:559 T( X' R  a7 b* c
非常好,楼主是技术帝,到目前我都还没开发fc的无线套件,等空了,开发一套套件,等玩家自己组装。 ...

, {* f, f; g( q5 s( U能得到孙大师的赞誉,不胜荣幸!
2 Y* c) ~& i8 p; J" D不如开发一个多功能手柄,比如用SFC手柄改造,L/R键配合其他组合键可以用来切换2P~4P、调节连发速度、软重启等各种功能。接收端插到15PIN扩展口。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|Video Game Do It Yourself ( 闽ICP备14000865号 )

GMT+8, 2024-3-29 16:12 , Processed in 0.059573 second(s), 14 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表