找回密码
 注册

QQ登录

只需一步,快速开始

查看: 23652|回复: 28

自制FC无线手柄

  [复制链接]
发表于 2019-5-22 14:16:45 | 显示全部楼层 |阅读模式
本帖最后由 雷精灵2046 于 2019-6-14 09:28 编辑
6 }1 C2 N' p$ {) V6 T( @9 o. u% U+ E  d
没有用复杂的分立元件搭建发射接收电路,直接用的现成的2.4G无线模块jdy-40。5 s" |! x( B, Z! ~+ J2 N  D- F

% S! `, Z7 E. T6 A- V" R6 ?! [3 b" h9 q  M  W! v% p: ]7 W  R
发射端靠3.7V锂电池供电,用了一片SOP8封装的STC单片机,负责产生连发脉冲,同时负责检测电池电量,电压低于3V左右的时候触发低压中断,低压指示LED就会亮起来告知该充电了。平时发射模块和单片机均处于睡眠状态,有按键按下才会唤醒,从而实现省电。实测睡眠状态下整机电流约1~2uA。板子洗了一下稍微干净了一点。因为对于微功耗设备来说,焊接残余的助焊剂可能会增加漏电流。! i7 H- n" {( X# R% q# I% f
! ^' w% o$ {; X* _& W7 R% S0 ?9 f
买了一个火花的FC山寨手柄,去掉里面的牛屎板子,并修正一下塑料挡板,把锂电池和充电模块装进去。
" k: Z/ e9 ]" s7 p' ~为了减少体积,充电模块裁剪得十分小,并且更换了充电电阻使之适应这个小小的锂电池。这么小容量的电池,也不需要多么大的充电电流是吧?2 d) V$ h% Z8 x  S
然后统统用热熔胶粘上。充电电流比较小,所以发热很少,不会熔化热熔胶。
9 M# _% c; @$ I! U1 a& j
  X1 h$ h1 v) P4 J! s0 n) B3 y7 I
* l, `% H  P. w: h) F7 H
# U; V, z' _6 v最后把按键、导电橡胶和电路板装上去。
# L6 ?3 q0 i+ `. ~精心裁剪了电路板,正好扣上,不会阻碍其他元件,也不会影响后盖和拧螺丝。
. r% q, p+ J! }5 _/ x+ |
+ n& F) C8 G- t/ {. P+ o3 j/ \$ s0 y, c& D
完工!% N, G$ B8 q  _! S7 b& y$ ?$ U

4 B# ~! B5 N0 A& {9 x4 n- Q/ ?
5 F+ w% t# X! d; C这是充电的MicroUSB插座。旁边的小孔用于透出低压报警LED的光线。0 ~  `4 K3 {1 K9 e

4 I$ Y$ w, R) B( `! y* g
6 h) g' A2 i4 {接收端用一片DIP16封装的STC单片机模拟CD4021。为啥要用单片机模拟而不是直接用CD4021?因为jdy-40模块接收端在有按键按下的时候输出高电平,无按键按下输出低电平,和普通手柄正好相反。当然我也可以用两片74HC00或者74HC04之类的逻辑门进行反相,但那就增加了芯片的数量。对于FC手柄这种工作频率并不高的设备来说,STC单片机完全可以胜任模拟工作。9 ~( M, I9 B  ?; `; x6 ?' i$ d8 q

1 U' Q% o( z0 W1 F, d7 b! O$ p9 o' a1 S' x3 g  o

9 i/ O. w" u& K2 T; W* K: F& S电路设计有点小小的错误,所以有几根飞线。原本设计使用低压差LDO是XC6206,结果在做这个接收模块的时候,买的LDO居然找不到了!无奈只好用了AMS1117。幸好对于接收模块来说是5V降到3.3V,1117可以胜任。要是发射端手柄的话,3.7V降到3.3V,那就非得用6206不可了。1 O) @1 |+ A0 L3 N% W& n% s2 q* _' D

) L8 _% |- d) C- |0 N$ `* F- Q. _实测十分灵敏,延迟极小几乎感觉不出来。可惜这山寨手柄的手感并不佳,尤其是方向键,软塌塌的。看来我得买个剪线手柄改装。
, h8 d8 @8 n! L% L
  k9 A) ?. E5 [5 S这是电路图,有兴趣的朋友可以参考。( k; [& o0 O1 d+ v+ |, F5 b
  u4 `  g  m6 U$ t

7 b9 d4 W; o4 ~/ ~, n) i我信奉开源主义,十分痛恨把技术藏着掖着。好东西大家分享嘛!所以两个单片机的源代码大公开!' h2 y7 P1 V. O; W- f7 H$ N
编译器:Keil 51。, v) L4 g+ V- ?" s
' f* e8 y' u, t8 v, {, `- F% _  h0 L
发射端:% N& X0 o' a5 z6 x( Y& c0 K
  1. #include <INTRINS.H>: Q" f# O* C* q( U' z4 ~/ i
  2. #include "STC15W.h"4 x- m# N2 \2 P6 T! v# g0 Y

  3. , M; j2 G& I* Q
  4. 7 ~2 q; u/ `3 d; U" @0 k2 c
  5. /*3 q) B) j. p) i. R! v
  6. --------------------------: J! N/ Q2 X9 h; j! {4 x7 c
  7. |1 (OUT)        \__/   (INT1) 8|
    ( a' ^9 V7 n5 s& q- z3 Y. y
  8. |                                                   |
    ! F' |% G8 H4 T" p# [' q
  9. |2 (VCC)                   (INT0) 7|( n( m5 Z* n9 J3 N
  10. |                 STC15W204S                   |
    ! e$ }) m) Q: \' h9 j- T" d7 q
  11. |3 (LED)                         (TXD) 6|2 _$ k* i5 q3 z# d
  12. |                                                   |
    6 G- z4 k$ x7 t# f
  13. |4 (GND)                         (RXD) 5|
      V% Q+ f9 T+ L; B$ |) ?8 Q
  14. --------------------------& Y. u4 W5 `$ ~- @! V
  15. 0 X6 Q& d5 p' `# g/ g- ]
  16. LED ---|<|---[===]--- VCC  K# h2 D  Y. v- s7 w; z
  17.            Red          330
    : s% A. O+ |# N2 Y6 V4 H( R+ `
  18. / R) |" @1 y* D. V# N2 [' \6 y! w
  19. Fosc = 6MHz( n* p1 [1 \8 I+ y
  20. */
    . Z4 x/ J$ T3 v2 D/ k" X

  21. $ v, w' Y5 @! r

  22. 1 ?2 F8 |/ {/ Y8 K6 t2 l
  23. // 矩形波输出脚8 O3 G  o/ n5 l( [6 ^$ q' g
  24. sbit OUT = P5^4;7 z6 k. W9 V; T- K
  25. // 低压指示灯引脚
    " A) `0 w" z4 g6 H
  26. sbit LED = P5^5;
    7 O0 q+ V# h% z& g' m4 k6 I
  27. / s6 a( V$ r: C: U% [1 {  y; G" a& H/ m
  28. // 停机标志位* R! [- N+ V6 x% x
  29. bit isReadyToHalt = 0;8 n& @5 ?) w# l2 J

  30. 8 K) v* A3 O1 ]/ X* B
  31. // 矩形波次数累计5 \6 ]: `1 A% t  {; c/ T
  32. static volatile unsigned char count = 0;! B% f* J0 Z# m* N# e
  33. 8 \: z9 I9 U! K6 Y! n+ d
  34. ; q8 P4 B, j0 |+ e. g
  35. static void GPIO_Init(){2 f: K  F8 N9 b1 I
  36.         // P3口设置为准双向,默认靠内部弱上拉输出高电平
    . P2 c$ z0 P3 k, A2 N7 o" D
  37.         P3M0 = 0;( W( ^# T/ N/ c# H: Y/ Q  H* c
  38.         P3M1 = 0;/ g( s2 h! G8 p/ u# M8 b$ f8 a
  39.         P3 = 0xFF;7 \$ g1 u) b. b# y: D6 o
  40.         // P5口设置为准双向,默认靠内部弱上拉输出高电平
    " ]2 n3 j  L3 V5 K/ u
  41.         P5M0 = 0;; A: f2 O! [' x0 U
  42.         P5M1 = 0;" N! q0 ]& T; w2 K- n# |- `
  43.         P5 = 0xFF;. }( V" O2 F! G2 w, [0 [
  44. }
    - A8 m8 B0 D+ ^7 q

  45. / U$ {# m) ~& B5 N, K
  46. static void Timer0_Init(){' q: m1 c# v0 H* e
  47.         // 16毫秒@6.000MHz
    1 ~8 w( T1 X5 c( ]+ a/ _; H
  48.         AUXR &= 0x7F;        // 定时器时钟12T模式+ Q" a+ ]. W' s- X
  49.         TMOD &= 0xF0;        // 设置定时器模式
    ; n1 F* P9 c8 y7 t: V& P+ e$ {) k( x  O
  50.         TL0 = 0xC0;                // 设置定时初值  N! T8 ?1 q8 n4 N+ X4 a
  51.         TH0 = 0xE0;                // 设置定时初值3 u" A& _" @4 W* m" m2 f
  52.         TF0 = 0;                // 清除TF0标志, w9 T- r  _  f7 ~! X
  53.         TR0 = 1;                // 定时器0开始计时- N' d: k( k: A' p# o/ Z
  54. }1 C% S) C) l) m% j) ]

  55. ' r2 F  l$ H* }, T/ {' z. J2 X
  56. static void Interrupt_Init(){9 O9 H4 n4 d5 X5 u- Z0 z3 i7 J/ l+ f
  57.         // INT0中断触发类型为下降沿触发$ j9 E" e; O# M+ _
  58.         IT0 = 1;
    ' s; @  E2 o4 L! S0 l* q4 T+ n+ u
  59.         // 允许INT0中断
    9 I3 P' `: }' z& j( E
  60.         EX0 = 1;
    * H5 Z, O2 A8 I3 v/ m& w9 `, b
  61.         // INT1中断触发类型为下降沿触发
    : Q6 z* Z) Q1 I, T
  62.         IT1 = 1;9 R* M% \% ^; \0 r' P5 e' F
  63.         // 允许INT1中断
    / d/ b0 @0 w' ]
  64.         EX1 = 1;' U" r; N' o" x0 F6 h) h
  65.         // 允许定时器0中断" n- R5 U2 a6 f) Z
  66.         ET0 = 1;
    6 @  C( c) @/ p# D+ u
  67.         // 允许全局中断1 A4 C1 S3 F% A
  68.         EA = 1;
    0 D9 M) v8 D' t5 {
  69. }- l/ f6 m' I& r- N6 c

  70. % o# }2 w4 T7 S$ _! G6 m7 x5 \
  71. static void INT0_Isr() interrupt 0{- v( s3 _9 |7 Q$ e2 k
  72.         // 矩形波次数累计归零# A; b6 V. v5 Y0 R$ I
  73.         count = 0;
    8 m$ T( ~& k8 g! O( n
  74.         // 重开定时器0中断
    ; H, \5 {$ C' e* g
  75.         ET0 = 1;
    - [% Y- S2 M* y6 e, U# U! y* F
  76. }
    3 N. l. {5 q. s& p  j& b0 X' N
  77. 9 y0 D8 ^4 y* b" \& N5 U0 r
  78. static void Timer0_Isr() interrupt 1{3 h  m# N* ]' s
  79.         // 输出矩形波
    & G+ L' t3 Z/ V# Q2 Y& f
  80.         OUT = ~OUT;7 x/ F0 v+ O5 t$ k, Q( V
  81.         // 累计矩形波次数3 R  _* X1 @: z9 @- }& @
  82.         count++;) a! q8 T' Q" s" T' T
  83.         // 超过250个矩形波,准备停机
    , M( c# R7 G( C3 j4 h
  84.         if(count > 250){0 A1 Y+ [# ~( I+ @; E  H: r0 Q& u
  85.                 count = 0;
    ' [! w9 v( C6 G
  86.                 isReadyToHalt = 1;8 b- }4 @9 v) |  L+ v, ?# i
  87.         }; Q# S2 Y, i( k) {8 e$ n, k9 n4 R* w: Z
  88. }, a4 \6 x/ ]  l7 z# ^. e
  89. 1 X; s* q! L5 a8 H6 i' h+ L/ o
  90. static void INT1_Isr() interrupt 2{
    0 j/ c. X: i9 `* J2 a, h9 a
  91.         // 矩形波次数累计归零4 x( q' r' D' K7 v
  92.         count = 0;
    : I* \+ p4 ?" h' \
  93.         // 重开定时器0中断+ n2 `4 k/ U' e; C% H5 d8 N  }( L
  94.         ET0 = 1;, B3 A6 I1 h8 }" q
  95. }$ _2 X3 q, M4 i$ K

  96. ' e4 W, c- \2 d, e. U* J" T
  97. 0 `* l4 I* ~. V  F6 \
  98. void main(){$ m& ]( ^! r1 n7 ]) D2 m
  99.         // 初始化P3和P5口
    " @  |3 b+ B1 J8 _! e
  100.         GPIO_Init();" I5 S+ K+ k% h; `/ C0 u
  101.         // 初始化定时器0
    ; e) t; W3 o2 U$ X7 o6 v: k
  102.         Timer0_Init();( K' k" b3 P; E( g
  103.         // 初始化中断
    7 q1 V5 i7 f4 j
  104.         Interrupt_Init();2 ]; S+ L" e; E6 P" A
  105.         ; [2 O& _* E- }& ^) ^
  106.         while(1){1 v& G# ~7 N9 x
  107.                 // 检测电量' _# i3 R+ z) W
  108.                 if(PCON & (1 << 5)){, |$ F. k' J+ ~6 U$ O
  109.                         // 如果电量低,低压指示灯亮
    4 W9 \- s1 x, _' H( N- [* o# A
  110.                         LED = 0;
    8 I: ]2 ?$ Q" J
  111.                         // 清电量检测硬件标志位
    8 ~- b& j% _* e4 c
  112.                         PCON &= ~(1 << 5);6 B! X9 `( E( g! Y, U  B' O, |
  113.                 }else{
    ; G) [, e; `- B3 h8 \8 G" Q% {
  114.                         // 电量正常,低压指示灯灭
    2 ~8 L6 h; @6 @1 G3 s: ^4 n# D; D
  115.                         LED = 1;
    $ z5 I) i6 T+ }  |* W2 R
  116.                 }
    ( s9 {4 E6 n4 ^- S

  117. , w7 y3 D* }7 s/ Y8 O+ c* U3 T
  118.                 // 检测到停机标志: v7 v9 I4 d: ?. ?, K+ B6 l
  119.                 if(isReadyToHalt == 1){
    2 u; A8 m% \( e" ]0 K$ V
  120.                         // 暂时关闭定时器0中断
    ) o1 |4 \/ R% B. u6 A( O0 t
  121.                         ET0 = 0;
    + D. x$ J' T( J  J# F
  122.                         // 停机之前先把矩形波输出脚置低电平,以方便INT0和INT1唤醒CPU' i- x8 l  l4 g! V! Q" K7 p
  123.                         OUT = 0;: u) R2 G7 [6 h& [
  124.                         // 停机之前先把低压指示灯灭掉,以省电9 b. y0 n/ W& V2 o/ Y2 u1 ?
  125.                         LED = 1;
    6 u: O/ f- N; r* u7 s" a/ k$ Z
  126.                         // 进入停机模式
    % F) U  w* B; ]% T; \3 A
  127.                         PCON |= 0x02;: r* b1 f, B; ^7 c# c& p. ^
  128.                         _nop_();$ J# |' ]+ G) D; C7 x- J
  129.                         _nop_();
    * `& K* ]' B" J0 @" [* H& J
  130.                         _nop_();
    3 p# H; M6 D: y" M5 w
  131.                         _nop_();
    8 V" C: M. B' L. E& k
  132.                         // 唤醒,清标志位7 X) B# O; K2 t3 A% A3 M
  133.                         isReadyToHalt = 0;
    7 R- w6 k, Z% S# u2 r
  134.                         // 重开定时器0中断8 g: T, S/ K1 N) \# x
  135.                         ET0 = 1;
    , w. Q6 ?" ?1 c' _* r5 }/ X- M
  136.                 }
    1 N9 k/ K; Z, _5 x9 w6 s2 [
  137.         }4 w" m! S! I( o) z! `2 L" g5 ?9 p' u. R% ^
  138. }/ i9 i$ t8 J3 u' c  W# J
复制代码

, W4 q: f/ `& y硬件参数配置:3 [0 v9 A& Z2 o- T# C
8 l" ]1 Z3 P9 Z" `& ^# L- x( R  a. X

# v5 e1 Q: {* s接收端:. {; i5 t) |  N* W1 {
  1. #include <INTRINS.H>1 I, w! N, {. q7 u1 Q8 P7 ~
  2. #include "STC15W.h"/ X5 G. R2 t4 {3 p

  3. ' E: ?% Z; i9 \* Z7 u% `, X( W

  4. # x. @+ Z4 O2 w( s: ]
  5. /*9 ]" v& s8 ^/ z( o
  6. + e, U7 v/ ?, N7 ~# S
  7. *---------------------------*
    3 t. {; p, z( i
  8. |1 (GPIO2)         \__/  (GPIO1)16|
    ; A7 n. A: F  w" g  c8 Y- s
  9. |                                                        |
    ( F3 h0 n5 \5 d3 e" p# T: @
  10. |2 (GPIO3)                   (GPIO0)15|
    : @. M6 P/ \$ T$ n: ]4 d; l
  11. |                                                        |4 g' w: I/ F5 M2 r# _' t5 e7 r8 d+ a
  12. |3 (GPIO4)                                  14|4 P/ N0 F4 `- }+ W1 i. r* e: _
  13. |                                                        |+ O/ r9 {& x: }) ^2 u& H. G
  14. |4 (GPIO5)                        (DATA)13|8 c9 L/ Q' M. t
  15. |                  STC15W204S                |* C) j/ e/ V' W/ J2 P# E" q. b$ ~
  16. |5 (GPIO6)                   (LATCH)12|
    4 A1 W, _2 R' u! T
  17. |                                                        |
    % Q6 R0 }' f( s# \% }" Y* S! N
  18. |6 (VCC)                         (CLK)11|
    6 ]6 `2 r% h% c- D1 ]
  19. |                                                          |, E# N, i# w; c0 v) ~, ~
  20. |7 (GPIO7)                         (TXD)10|
    3 n0 R4 [" Y" v1 n* t- o& x
  21. |                                                        |
    - r3 Y8 f6 [4 P* |7 X. z  n
  22. |8 (GND)                         (RXD) 9|$ g5 m( w+ G' T1 z. p$ \  n
  23. *---------------------------*, g, V5 r& q# @$ ?, k
  24. Fosc = 12MHz
    5 H' S. d  x) X- L. _( s

  25. ! _; w' M- x) `
  26. P1.0 -> 上
    ; E1 A( F' H% X1 ]
  27. P1.1 -> 左6 t4 P$ {5 q- J
  28. P1.2 -> 下
    9 C8 B; {; s# Q0 [' A
  29. P1.3 -> 右
    . H1 l) M6 F% c1 |6 T
  30. P1.4 -> SEL8 `! s6 k( e9 ~; \0 \. L+ ^
  31. P1.5 -> STA0 E) B9 h: I( y( |+ m6 [+ g
  32. P5.4 -> B
    5 S5 f0 x1 p: I5 a
  33. P5.5 -> A
    % x" d! _' i( `; O% n
  34. 9 K# |! _0 I' Q0 v/ w
  35. */
    - g* G- T5 M, E7 o2 z& Q2 L
  36. ) W6 G& F  A4 b& u* P+ o
  37. ) B2 `/ y% I# y. }  J
  38. sbit CLK        = P3^2;
    . W- R1 d+ ]& C# {: n
  39. sbit LATCH        = P3^3;
    $ J! H+ X9 x; o
  40. sbit DATA        = P3^6;
    4 o$ ~: S/ M$ o  ]

  41. 8 W1 \! ~: I* W% `" [$ x
  42. bit isReady = 0;
    : B% N5 g* C, e7 S4 k' Q9 Q/ r
  43. static unsigned char key = 0;2 ^2 y  b) M+ X7 a3 i! e3 }
  44. static unsigned char buf = 0;        // 双缓冲。这个缓冲区保存从P1和P5组合而来的键值. z; d" M- A9 q7 v) _% }2 o( l
  45. static unsigned char bufReady = 0;        // 双缓冲。这个缓冲区保存上面那个缓冲区的备份
    ' F) @# \( j7 Y6 q0 k  z' r
  46. static const unsigned char data mask[] = {0x80, 0x40, 0x10, 0x20, 0x01, 0x04, 0x02, 0x08};        // A B SELECT START UP DOWN LEFT RIGHT。为提升速度,这个表放到RAM中0 ?- Q" T- a. j; O2 t. {& @) R
  47. static unsigned char idx = 0;# q$ c/ z) f. X# U, t8 S* y! ?

  48. , }" m+ S( m8 m1 d1 S1 ]

  49. + t* M' h; L+ E- y+ a) X! q- {4 N
  50. static void GPIO_Init(){
    + E6 Y: T( P/ r, }1 i1 Y/ h+ C" C1 S
  51.         // P1口和P5口用于接收并行信号,全部初始化为准双向,依靠内部弱上拉输出高电平
    8 _2 N. k0 Q! ]5 ^1 C2 o
  52.         P1M0 = 0;
    2 R( R! A' z* g  T& }& J
  53.         P1M1 = 0;: w! i5 t5 O9 G/ L9 C. O' C' l
  54.         P1= 0xFF;
    7 K4 H6 R7 t0 ?3 ^
  55.         P5M0 = 0;
    2 c% d! ?$ ^- R' p# M
  56.         P5M1 = 0;1 Y! F6 L, z- [) W5 f( x
  57.         P5= 0xFF;
    5 f; [6 q4 o$ o; ]2 m. A) T
  58.         // P3口初始化为准双向( X  O& N! v, W5 `+ ~+ a
  59.         P3M0 = 0;
    % q5 m. Z8 a+ [( r/ x" x
  60.         P3M1 = 0;8 _; ?# H4 [& F, {
  61.         P3 = 0xFF;
    9 u' l+ |! B, |
  62. }& C& N2 f& g5 I5 z7 v2 p  M) @8 K' s- B
  63. ; l/ _# G. r* f0 s# k' Z
  64. static void Interrupt_Init(){
    $ ^  w& ^4 R  ]6 Y' p, k
  65.         // INT0中断(CLK)触发类型为上升沿+下降沿
    ) ]3 e, o$ m. q8 {& t/ R
  66.         IT0 = 0;2 U- F' T( V7 [8 A6 O# d; H- S6 A
  67.         // 允许INT0中断% h; J. d2 [( O9 t
  68.         EX0 = 1;8 b" G5 F8 Q) a- E. D
  69.         // INT1中断(LATCH)触发类型为上升沿+下降沿5 h" @5 W* m; l( g' W/ c
  70.         IT1 = 0;
    & E  U% j2 t3 k; K1 f
  71.         // 允许INT1中断2 ~( y8 S4 v: V  E) f
  72.         EX1 = 1;# U5 @, D2 l) q% s- N4 ]
  73.         // 开启全局中断" K$ J4 r: E( M) n7 u0 n* N
  74.         EA = 1;" Q. m" O7 N5 P& p6 H& R# t0 h0 j
  75. }: d0 U; @! E' _+ n, R' C3 C

  76. ( x9 U* W' k  o+ b
  77. static void INT0_Isr() interrupt 0{
    ! ?) P. ^' R3 w8 \" m, U7 H& E: l
  78.         // 只有已经成功锁存才允许CLK移位( A5 q, a- R( r- E2 A
  79.         if(isReady == 0)' r" Y" u6 [. X
  80.                 return;+ t% \7 [7 w( t* M# r
  81.         // 读当前引脚电平,如果是低电平则说明是下降沿,此时直接忽略该中断
      T  h( j# e% i9 M
  82.         if(CLK == 0)
    - L1 E: n# u: j4 a
  83.                 return;
    / b+ P5 ^$ a4 M! \
  84.         // CLK上升沿到来的时候,取锁存值的下一位输出
    4 R# R( n, a4 u
  85.         idx++;
      d' [9 K7 r1 z8 @& r: Z5 J& w) z
  86.         DATA = key & mask[idx];
    & k% j: \) S6 T, F0 q$ B
  87.         // 如果已经完成7次移位,则一轮读取完成$ l  G! X- w" e
  88.         if(idx >= 7)
    . B0 u, b$ A& t3 Z% {
  89.                 isReady = 0;
    ; ^3 a+ f8 ?! M) |! f
  90. }: Y- g" }5 ^1 ]7 b( W; j. X- s
  91. . F# i, f$ o8 c  n
  92. static void INT1_Isr() interrupt 2{
    9 H7 W1 J4 Q: V  e
  93.         // 读当前引脚电平,如果是低电平则说明是下降沿,此时直接忽略该中断: P: t5 G$ B0 j# {; o
  94.         if(LATCH == 0)
    3 @3 ?4 C/ H, U4 t
  95.                 return;
    0 |; D' G- Q3 {& C0 m
  96.         // 当LATCH上升沿到来的时候,锁存所有按键状态,同时把键值A输出到DATA
    ( P, q/ @2 L( R' Q2 @3 I
  97.         key = bufReady;
    ) z$ F+ Y& b+ s( M; _
  98.         DATA = key & 0x80;//mask[0];        // 为了加速运算,直接取表中的值而不是读表6 s  G/ E* K' g- S# l6 S
  99.         idx = 0;
    - k/ C  F3 P3 ?3 t6 A
  100.         // 允许CLK进行移位) R, P  {+ [- d: `5 ?+ ?& [
  101.         isReady = 1;, V- H7 B4 ^, f
  102. }1 S# V4 T; U! S

  103. / H+ @( n+ h1 G2 x! e8 t
  104. void main(){
      e5 Q, ?4 n1 I+ d1 g$ {
  105.         GPIO_Init();) e) _3 `+ c) @! v) z
  106.         Interrupt_Init();+ I6 ?( {* j: k" y) q* t
  107.         ( p+ p3 i7 z7 [0 b0 N/ Z: _
  108.         while(1){" q# T9 y( a( s; |3 l
  109.                 //PCON |= 0x01;        // 进入省电模式$ o9 V8 q  Y6 s7 B* {+ q
  110.                 //_nop_();
    4 K( K; `+ {! x' c8 @" x& E9 Q/ a' a
  111.                 //_nop_();
    + q3 l- m; P. ?/ Q, X( O0 t1 J
  112.                 //_nop_();% c. m( x$ u" ]9 T4 l/ t( Z
  113.                 //_nop_();
    - K: l2 p  d1 p% o( {/ C2 |
  114.                 buf = ~((P1 & 0x3F) | ((P5 << 2) & 0xC0));  C1 l7 S- P. \! e# ]* @
  115.                 bufReady = buf;5 ?- I. w! @* C; e& j$ O
  116.         }
    5 r7 Z% o; u0 S4 @( M  v
  117. }  W  Z2 ?( _% M1 |5 ~1 F. q+ L
复制代码

; e$ X# _4 k5 u( A7 N0 Z硬件参数配置无特殊要求,晶振频率选择12M即可。% O7 R9 O( Y3 f

- Q& X- P9 k1 n" I! G这是编译好的固件。

本帖子中包含更多资源

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

×

评分

参与人数 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# z& k2 l: C% A. G
不错的设计,想问一下楼主,FC的15针公头怎么解决?普通的公头太短了,插不进去FC的扩展接口。 ...
- e- A9 E9 i. s
坛友的改造方案
回复

使用道具 举报

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

使用道具 举报

发表于 2019-5-25 12:07:18 | 显示全部楼层
精彩,楼主动手强,也写得很详细。
+ o  Q% \1 U5 w2 ?4 J6 e2.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
! y, G/ e* U6 \, [精彩,楼主动手强,也写得很详细。/ w3 N7 `* N: ]5 ~3 E6 |2 S
2.4G方案是目前无线的最低延迟吗?

7 P. C2 u( [+ k. j6 a' C我没用过其他无线手柄,所以实在不知道我自己做的这个手柄到底是不是最低延迟。
, U2 x. n0 N$ d不过根据网上的说法,延迟高低主要是由通信协议的复杂程度,以及数据传输速率决定的。这个模块虽然是2.4G无线模块,但由于协议很简单,所以延迟比较低。
& d" V( d6 m0 W2 G. i8 F# |  J我用这个手柄玩一些ACT游戏,比如超级马里奥、忍者龙剑传、热血系列,完全感觉不到延迟,和游戏机自带的手柄没有任何区别。唯一的区别就是这个手柄是用火花山寨手柄改造的,外壳是垃圾回收塑料,粗糙+脆弱,导电橡胶弹性不佳,手感不是一般的差。
0 K2 B1 c# Y& e& ~, f  A  S我手里还有十几张板子,等我有空了我再做一套,到时候买一个好一点的手柄改造。
回复

使用道具 举报

 楼主| 发表于 2019-5-29 16:56:14 | 显示全部楼层
ppad 发表于 2019-5-28 17:27
# \# Q1 Y$ S! Y! G' i给技术帝赞一个,有半成品发布吗,自己焊接改造就可以,编程实在不会啊 ...

2 m" l) y! R8 z  \8 b: D0 |很可惜,我手里没有多余的单片机了,LDO也找不到了,锂电池以及充电模块更是没有了。反正就是该用到的元件基本都没了,所以没法发布半成品。
) {+ T; Z4 K+ K+ j& @两个板子倒是有十几张剩余。, Z7 \8 n# P* i8 x
你要是有USB转TTL串口板,完全可以自己买这两种单片机,然后我给你编译好的固件,你自己用串口板下载到单片机里面就行了。两个2.4G无线模块也得通过串口板用AT命令设置参数,不过好在我在设计电路的时候就已经预留好了串口,可以直接在线下载和在线设置参数。总的来说并不麻烦。
回复

使用道具 举报

 楼主| 发表于 2019-5-29 17:00:34 | 显示全部楼层
孙大师 发表于 2019-5-28 18:55
4 Q, a4 z- c4 a* J& j& X非常好,楼主是技术帝,到目前我都还没开发fc的无线套件,等空了,开发一套套件,等玩家自己组装。 ...

' L2 X) E1 _" W- Y# _" G能得到孙大师的赞誉,不胜荣幸!
! Q: {  Z; W; A9 q6 T# }: m不如开发一个多功能手柄,比如用SFC手柄改造,L/R键配合其他组合键可以用来切换2P~4P、调节连发速度、软重启等各种功能。接收端插到15PIN扩展口。
回复

使用道具 举报

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

本版积分规则

Archiver|手机版|小黑屋|Video Game Do It Yourself ( 闽ICP备14000865号-1|闽公网安备35018102240098号 )

GMT+8, 2026-2-5 08:10 , Processed in 0.100321 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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