找回密码
 注册

QQ登录

只需一步,快速开始

查看: 24229|回复: 29

自制FC无线手柄

  [复制链接]
发表于 2019-5-22 14:16:45 | 显示全部楼层 |阅读模式
本帖最后由 雷精灵2046 于 2019-6-14 09:28 编辑
+ e* h, N$ Z, V) S9 C# ?, K
1 v' Z. M& p. W2 X没有用复杂的分立元件搭建发射接收电路,直接用的现成的2.4G无线模块jdy-40。* ], _# ^# y, E# {
% y' x- p+ n: N' R4 j6 s' G: u

5 d5 d1 t, Z  E5 k) J发射端靠3.7V锂电池供电,用了一片SOP8封装的STC单片机,负责产生连发脉冲,同时负责检测电池电量,电压低于3V左右的时候触发低压中断,低压指示LED就会亮起来告知该充电了。平时发射模块和单片机均处于睡眠状态,有按键按下才会唤醒,从而实现省电。实测睡眠状态下整机电流约1~2uA。板子洗了一下稍微干净了一点。因为对于微功耗设备来说,焊接残余的助焊剂可能会增加漏电流。9 d$ a0 W" ]. e! ^- M

, B; M' y3 L" K' u. J. N- S2 w, Y买了一个火花的FC山寨手柄,去掉里面的牛屎板子,并修正一下塑料挡板,把锂电池和充电模块装进去。1 I& ^. J6 z) e/ v) a& ~7 J
为了减少体积,充电模块裁剪得十分小,并且更换了充电电阻使之适应这个小小的锂电池。这么小容量的电池,也不需要多么大的充电电流是吧?. B0 T# J3 ?/ B1 ^! L* ]
然后统统用热熔胶粘上。充电电流比较小,所以发热很少,不会熔化热熔胶。% b7 X/ G8 y: C# e

1 Q( O+ n2 z3 m' k- r( |
  V2 `! l, j% m4 j8 h% \9 q) D+ ^) c6 u  T; N* B. X: `
最后把按键、导电橡胶和电路板装上去。
9 m$ Q7 B2 u7 H# N1 b精心裁剪了电路板,正好扣上,不会阻碍其他元件,也不会影响后盖和拧螺丝。
$ l3 A1 _8 @/ d4 |2 D! V1 N: D7 a! h  o/ g

  |' u" d0 P4 o5 V0 |4 ?& j完工!
! b4 q, U8 U; g) [5 |1 Z" z5 _; x1 v6 q6 T0 m" \# c4 z$ N1 E2 c& }

) ]& T. M5 X1 E5 l2 H8 m这是充电的MicroUSB插座。旁边的小孔用于透出低压报警LED的光线。
, l( j, x* M+ \5 N0 Q6 U3 b: x' H& k* J* ]

$ q1 F5 z& f1 c: X$ s# O接收端用一片DIP16封装的STC单片机模拟CD4021。为啥要用单片机模拟而不是直接用CD4021?因为jdy-40模块接收端在有按键按下的时候输出高电平,无按键按下输出低电平,和普通手柄正好相反。当然我也可以用两片74HC00或者74HC04之类的逻辑门进行反相,但那就增加了芯片的数量。对于FC手柄这种工作频率并不高的设备来说,STC单片机完全可以胜任模拟工作。
9 S0 ]' C. b; g4 H. F( }7 P# d% k- s  |& n) v% I- i7 G* i( [

" N5 n: i. V6 C/ L3 m
3 r# M/ g; K/ N" ?! @% O电路设计有点小小的错误,所以有几根飞线。原本设计使用低压差LDO是XC6206,结果在做这个接收模块的时候,买的LDO居然找不到了!无奈只好用了AMS1117。幸好对于接收模块来说是5V降到3.3V,1117可以胜任。要是发射端手柄的话,3.7V降到3.3V,那就非得用6206不可了。  U7 d  R; `7 ]3 h9 }9 |7 R
" X) [4 K: ~9 X0 @. k# i  N: i, ^9 U
实测十分灵敏,延迟极小几乎感觉不出来。可惜这山寨手柄的手感并不佳,尤其是方向键,软塌塌的。看来我得买个剪线手柄改装。
3 K& f/ _& u7 y9 j' m
" X" O4 w" u5 [% m9 K这是电路图,有兴趣的朋友可以参考。
0 e. A% f! T- G" @
" Y6 v' X* U, Z/ j5 S
( h- d0 p& P' G  n, f我信奉开源主义,十分痛恨把技术藏着掖着。好东西大家分享嘛!所以两个单片机的源代码大公开!5 h0 T8 x4 |/ @0 B3 H
编译器:Keil 51。, _0 b- S# r" N& X0 a( ^: L3 R

9 P8 e) P7 |. \/ _* F, |发射端:
+ d: m: T$ b, @& o
  1. #include <INTRINS.H>
    * p3 q2 j) M* X. F! K" z' V! ^8 c$ Z
  2. #include "STC15W.h"8 t6 d4 l+ u; {
  3. 6 u; V* r3 \1 x1 V8 j* H

  4. " R' N' [& a+ z8 v) r
  5. /*
    * M( i7 G  n. A
  6. --------------------------
    ' @5 S8 T# n& ?
  7. |1 (OUT)        \__/   (INT1) 8|# }* E( Y0 a$ Z2 V% S0 H' ]
  8. |                                                   |
    7 ?/ _" Y+ E4 z& \
  9. |2 (VCC)                   (INT0) 7|
    7 e5 V4 R+ |2 z5 z
  10. |                 STC15W204S                   |
    " Q, a* U3 }0 k: {, ^: d
  11. |3 (LED)                         (TXD) 6|
    2 O# e0 Q' u) {
  12. |                                                   |9 U( q2 S0 R9 `5 h7 T2 U
  13. |4 (GND)                         (RXD) 5|# @! c% U) p. X
  14. --------------------------0 S- k$ j! H+ A7 H8 W4 F8 t* ?
  15. & G/ A# t) i( w  |" }/ D3 ~
  16. LED ---|<|---[===]--- VCC
    * K5 m# z+ w) M6 s, G
  17.            Red          330
    : \9 }+ U: i" @9 I8 _' L% K5 i

  18. - D( R; B& C. L( Y: ]: c/ \
  19. Fosc = 6MHz
    * U/ c2 K# [% @
  20. */- I, ]$ _) @4 M/ r8 `; L

  21. - M1 V3 m- T5 ]7 f  @
  22. 1 C. t/ c4 `8 q+ a
  23. // 矩形波输出脚& e7 y7 }8 C6 l* O! U
  24. sbit OUT = P5^4;, p. N& v' y3 y$ A
  25. // 低压指示灯引脚
    % I, T, @! r. F0 @, g
  26. sbit LED = P5^5;- I) `. h$ Y2 e- K/ O2 x& }& N

  27. 1 }: u6 {( O2 j
  28. // 停机标志位
    . i; R0 V2 ]9 d7 y; U+ ^
  29. bit isReadyToHalt = 0;4 v& |/ v7 Y! z
  30. * Z/ z; H5 `/ N0 X" [- D
  31. // 矩形波次数累计
    # R8 h( ~2 D; \. f
  32. static volatile unsigned char count = 0;3 o; ]! [7 r" ^0 |9 k) J, \6 M  x7 W

  33. / y  K, D8 e+ K, _5 A' e+ X1 e& x

  34. : m6 I& @* W* ?  h
  35. static void GPIO_Init(){
    0 L# o* C& X! I( i
  36.         // P3口设置为准双向,默认靠内部弱上拉输出高电平# p7 d6 ^3 ?1 G$ g
  37.         P3M0 = 0;
    1 [" [6 R7 y' a9 ?
  38.         P3M1 = 0;
    6 `. l, k2 `) N
  39.         P3 = 0xFF;
    9 s' S6 ?( Q( V1 o2 q
  40.         // P5口设置为准双向,默认靠内部弱上拉输出高电平- e6 B- q/ _1 Z& S/ l* B
  41.         P5M0 = 0;4 B$ {  `4 e3 a" M# w
  42.         P5M1 = 0;) |% a. ^' y7 N0 S% b/ D
  43.         P5 = 0xFF;
    : @( _* O! x# s5 M' c
  44. }. N7 S4 \0 g1 I- t) w
  45.   W  i: A9 Z" }5 Y
  46. static void Timer0_Init(){
    : ?1 Q; c7 U6 k) W1 t
  47.         // 16毫秒@6.000MHz
    ) H; ~. z( d/ n/ B* `- V/ F
  48.         AUXR &= 0x7F;        // 定时器时钟12T模式0 ?4 t' z0 P7 b0 b9 f) n+ C
  49.         TMOD &= 0xF0;        // 设置定时器模式
    * M9 }" f! ?( k3 d
  50.         TL0 = 0xC0;                // 设置定时初值3 u& B' f$ q2 Q
  51.         TH0 = 0xE0;                // 设置定时初值
    ! B# p& \9 ^! y4 ]/ {$ s& b
  52.         TF0 = 0;                // 清除TF0标志
    * G8 u+ ?6 d7 _! W. i9 \: }3 H
  53.         TR0 = 1;                // 定时器0开始计时
    , M; Y, [  j6 k4 y* F/ n
  54. }, w6 E: l' f% L$ x; `0 K

  55. 8 Q9 z& i1 r* F; E) Q" Q
  56. static void Interrupt_Init(){
    0 @. r: h$ C: e) z6 D+ h
  57.         // INT0中断触发类型为下降沿触发3 |$ w) L/ t5 d' V3 E" h
  58.         IT0 = 1;7 ?( H+ M: _9 X2 k& @
  59.         // 允许INT0中断
    : V" w( ^' |; J- Z
  60.         EX0 = 1;7 t- f$ \: C) U9 P1 K$ R* d
  61.         // INT1中断触发类型为下降沿触发$ ?1 M3 r% G; i
  62.         IT1 = 1;9 C" O* P( E5 y* j. y
  63.         // 允许INT1中断) O& m/ F% ?" u! u9 e* E7 x
  64.         EX1 = 1;, t6 X+ d! _' p- j
  65.         // 允许定时器0中断
      G. E1 q, ?# _4 J, h% x! D
  66.         ET0 = 1;$ k% Z0 j8 _+ x3 g0 j% p9 g. Y& x
  67.         // 允许全局中断" r4 W3 v. O6 \) Z' y. M
  68.         EA = 1;0 @( _& _* ?0 A& I2 m
  69. }8 y9 {7 \; |+ K+ u* ?3 @

  70. # `+ U5 s2 Y1 \5 C
  71. static void INT0_Isr() interrupt 0{
    9 ]5 M& \. u# R! N. Z8 J
  72.         // 矩形波次数累计归零
    & Z$ f! u! \" }# a# E" F/ N
  73.         count = 0;9 z4 A6 i) \3 d: g0 A; i7 s
  74.         // 重开定时器0中断* h3 h5 G4 U5 O4 b
  75.         ET0 = 1;
    0 M3 ?6 K0 F9 u
  76. }1 f. ^. l% R; x/ k1 W/ h
  77. # I7 O, n. U6 m9 l* B
  78. static void Timer0_Isr() interrupt 1{: a: M) a( q1 j1 S
  79.         // 输出矩形波
    , K- R5 m+ x1 P- f( n& W4 X
  80.         OUT = ~OUT;7 f. {" I' a7 [! y% ^
  81.         // 累计矩形波次数
    " M- n0 T+ L8 @# R
  82.         count++;
    + a1 r* }, Z( D$ V2 G" H
  83.         // 超过250个矩形波,准备停机1 v& r: N2 N. W* n1 g
  84.         if(count > 250){" o+ v9 C$ x' M
  85.                 count = 0;
    1 P9 \4 t) H% C
  86.                 isReadyToHalt = 1;
    # f* G4 \; q0 D8 b5 y
  87.         }
    $ u  U! g# x  z3 t9 \
  88. }# @0 S$ E5 z9 N6 E9 t( l
  89. ) }9 D) B/ e; A" x; c
  90. static void INT1_Isr() interrupt 2{4 R7 U9 O9 v& ]8 X/ a
  91.         // 矩形波次数累计归零
    / e; p  F3 U/ w
  92.         count = 0;( O2 t6 ]0 b$ D2 t( e
  93.         // 重开定时器0中断
    6 v9 b1 z1 t! l8 n5 V, z
  94.         ET0 = 1;1 |2 c" C: k5 g$ Z: o/ c/ F# y% `! J
  95. }
    7 f. |. t, g: S5 n4 M/ j) y

  96. / z& n; b( g+ i/ J8 k/ s; F
  97. # u: d3 n. u$ P0 g
  98. void main(){3 V9 f# ^5 ?" U, l
  99.         // 初始化P3和P5口
    4 [2 [" u* e% c5 w! `
  100.         GPIO_Init();6 I$ v: f- u4 H+ b4 F
  101.         // 初始化定时器06 _) K8 u* K1 W9 H, [. [9 t" {
  102.         Timer0_Init();0 \$ [  l: k+ A" f; }
  103.         // 初始化中断  ^! r; a! r1 i: ~" o& o
  104.         Interrupt_Init();* q0 Y6 F  A* u$ V1 W! G' P
  105.        
    7 C0 a+ u* @3 ]0 K6 r) e; j
  106.         while(1){
    9 h! G/ I  E2 N0 k; x( Z
  107.                 // 检测电量- ?) h0 a% S3 K9 j) b7 ~) H
  108.                 if(PCON & (1 << 5)){
      @' K9 e0 k# n+ u8 y4 |
  109.                         // 如果电量低,低压指示灯亮
    * ~' U3 `* ?( ~% D
  110.                         LED = 0;
    2 j* y: K2 M3 I0 X8 k2 W
  111.                         // 清电量检测硬件标志位
    # L) D* X- R/ j+ `, a5 e
  112.                         PCON &= ~(1 << 5);  y. D3 t% Z& f0 R4 q
  113.                 }else{
    2 T* m/ M6 _7 p% w6 @" e: S
  114.                         // 电量正常,低压指示灯灭% U1 H! F0 e, z# j) s' n
  115.                         LED = 1;  Z9 B0 x/ [) y; J$ ^8 i, h
  116.                 }
    ' k: K# U$ t1 f, ^

  117. ) r) k7 \" H0 Z3 Y- g5 @' v, D9 J2 b6 X
  118.                 // 检测到停机标志
    * ]; G1 L. q& t3 ^( r+ V. B" }
  119.                 if(isReadyToHalt == 1){1 ?4 ]# p+ A; I* c0 b+ N0 O- Q; y
  120.                         // 暂时关闭定时器0中断
    ' M& i$ [* p! P( L* [! F
  121.                         ET0 = 0;
    9 j! x% _4 {7 G) I' }1 e
  122.                         // 停机之前先把矩形波输出脚置低电平,以方便INT0和INT1唤醒CPU
    ; n8 I. l& O& _* A3 r" h
  123.                         OUT = 0;
    $ q& Y8 F. Q8 j% q. O) E
  124.                         // 停机之前先把低压指示灯灭掉,以省电* r) ?$ z$ G  S( Q3 G
  125.                         LED = 1;6 p0 c) ]3 Q" \5 }4 y
  126.                         // 进入停机模式
    6 C- q7 b5 D5 x+ f4 {3 b
  127.                         PCON |= 0x02;* R4 x1 P1 V  W& m! g
  128.                         _nop_();2 S7 y- r0 I; ]# {" q8 v# E: ~
  129.                         _nop_();
    3 b' d  }$ j% Q' ~$ c* s9 M1 }
  130.                         _nop_();+ E/ q( Y5 j7 p. S8 w
  131.                         _nop_();
    3 ~+ w- q6 h9 s* u3 M7 S, i
  132.                         // 唤醒,清标志位6 P2 i% z0 `- b! w
  133.                         isReadyToHalt = 0;2 ^4 o# [+ z6 }) d
  134.                         // 重开定时器0中断
    1 M) M% i! F" Z/ R2 T2 P
  135.                         ET0 = 1;
    ! v5 j: f! J! Y7 b/ D0 I' A
  136.                 }0 a" I1 p. j  J0 L0 m
  137.         }
    2 F! H4 _# {0 h4 C& z1 S. `2 H
  138. }
    3 G- j' w6 }& E, w3 o8 V
复制代码
) K& s- r* V' \3 [# n9 e2 V
硬件参数配置:
% z- K1 A9 c( E) u, ]2 u
4 A! P4 g: _! @  N+ [
/ H+ G( Y8 w) @接收端:2 g0 z% v" k% O+ s. v& W3 I
  1. #include <INTRINS.H>
    ; g' K8 I# C% c" X: Z: c
  2. #include "STC15W.h"
    3 l+ w- q& D' N6 N- {7 S
  3. ' s' |4 n' P, b5 F$ u
  4. * _- L; |7 i" h: ~5 @1 M% B* @
  5. /*
    2 Y% J0 v" w  z: ?
  6. 4 X% k- A& F- @; l* @- `1 C6 A
  7. *---------------------------*6 D# g; t/ n% e6 l5 n* K
  8. |1 (GPIO2)         \__/  (GPIO1)16|' T. F- {9 p$ q4 H
  9. |                                                        |! L7 Y2 Z0 M  J! r- b
  10. |2 (GPIO3)                   (GPIO0)15|
    8 w+ C' m. z8 C# o" j# ~! P
  11. |                                                        |
    $ u9 B. I- U" N9 R/ N
  12. |3 (GPIO4)                                  14|
    8 F$ t& U6 ?& R# S, r! j$ U
  13. |                                                        |4 L5 y" _9 A* f5 f+ A" h0 A3 l
  14. |4 (GPIO5)                        (DATA)13|
    3 M7 m5 n$ U7 u' l5 ^. J8 m
  15. |                  STC15W204S                |9 {3 o8 ~. w# j" w& s  Q3 o$ l$ a" s
  16. |5 (GPIO6)                   (LATCH)12|
      H3 ~$ @2 R7 ~6 P# r  R+ m: e7 ^
  17. |                                                        |
      N" b0 D5 x2 c' ^6 s, H+ O) J
  18. |6 (VCC)                         (CLK)11|+ g9 k7 b# L8 k/ I- S% {
  19. |                                                          |
    ( `% B: B7 X* h& @4 P- M, B7 N5 q- d
  20. |7 (GPIO7)                         (TXD)10|
    . E( X9 u9 A3 [9 E+ `
  21. |                                                        |3 s6 r0 |% x. G  Z
  22. |8 (GND)                         (RXD) 9|
    1 r: V, R( D( n3 p; h
  23. *---------------------------*
    2 x8 ~, B1 V1 j4 \) C
  24. Fosc = 12MHz
    . y5 K& a9 x; r4 H0 }

  25. 0 y# |" d% s; G7 [$ D4 F
  26. P1.0 -> 上) T: e; B0 E4 Y4 x1 p1 X
  27. P1.1 -> 左8 m3 N& W/ y9 B2 _# d6 X: x
  28. P1.2 -> 下8 M3 `+ J9 e: F- R& u0 w
  29. P1.3 -> 右
    : N7 j' ~5 R; B3 \. Q
  30. P1.4 -> SEL0 c/ y* s3 c' Q4 o
  31. P1.5 -> STA
    3 {5 Y/ G: _% f- W
  32. P5.4 -> B2 G9 E( O6 U0 Q+ J" n
  33. P5.5 -> A" N5 ^8 v3 u* J& Z: k& e

  34. ' S1 H. |8 e1 N  o3 z
  35. */
    3 u; h" e5 Z/ s3 ?

  36. & j+ g/ B  {4 f7 N7 K0 s, y6 {

  37. 1 ~7 n8 D, P1 m5 M
  38. sbit CLK        = P3^2;8 V0 u3 F! p& r3 v+ v% P8 L4 E
  39. sbit LATCH        = P3^3;
    ( ]" {, E* W$ S9 |) r/ ]+ S
  40. sbit DATA        = P3^6;
    / w7 R) ~" ]$ y0 A
  41. 5 _  e0 w9 E: y4 R0 \0 _& `/ x
  42. bit isReady = 0;
    . @" p$ g$ H) _7 \7 n
  43. static unsigned char key = 0;
    - A' J  l, I* T+ h: @, W: B
  44. static unsigned char buf = 0;        // 双缓冲。这个缓冲区保存从P1和P5组合而来的键值
    & ]& e5 O. b( V8 W! C
  45. static unsigned char bufReady = 0;        // 双缓冲。这个缓冲区保存上面那个缓冲区的备份
    1 l/ W* R% P( _, \  b; s
  46. static const unsigned char data mask[] = {0x80, 0x40, 0x10, 0x20, 0x01, 0x04, 0x02, 0x08};        // A B SELECT START UP DOWN LEFT RIGHT。为提升速度,这个表放到RAM中
    5 a5 e. X" P+ Q' B
  47. static unsigned char idx = 0;
      Y0 x% I# {  e9 D
  48. ! i9 a' o! }2 t9 ]2 |& C, [. w
  49. 5 C2 H( \" _& M& k. b) ?( }, W4 |
  50. static void GPIO_Init(){+ }0 y) f8 p( x# o0 @- ]
  51.         // P1口和P5口用于接收并行信号,全部初始化为准双向,依靠内部弱上拉输出高电平% r* g; d8 r9 N8 ?5 R1 S# g
  52.         P1M0 = 0;- D! Q: X1 c$ L% a/ c8 @: \
  53.         P1M1 = 0;& \5 z8 i: p, ]( M" u
  54.         P1= 0xFF;8 S0 V& d% B# l) j
  55.         P5M0 = 0;
    ) d( h; |" R/ ^. b' i8 }7 o7 a7 `' l
  56.         P5M1 = 0;
    ) V1 J( F. M- P  ~
  57.         P5= 0xFF;# k$ k7 @# C1 o: \: ~
  58.         // P3口初始化为准双向
    8 H( R5 b' t$ x/ `4 x
  59.         P3M0 = 0;+ S; G# A8 x9 M
  60.         P3M1 = 0;( P+ S. s& K5 z, C. C! `0 d
  61.         P3 = 0xFF;" ?* N  t- H; {. {+ U
  62. }  P' F! L: N' p( I! G) z* G

  63. ) S! q$ @4 T, _7 ~8 t
  64. static void Interrupt_Init(){
    # N- l+ m3 P: F' ]  y
  65.         // INT0中断(CLK)触发类型为上升沿+下降沿
    % H( F# c3 e% L# M! l& V5 }4 ?# y
  66.         IT0 = 0;6 n: [/ c9 P/ z6 |9 W7 }! M
  67.         // 允许INT0中断6 }8 Z- [2 J' ^3 q
  68.         EX0 = 1;- _# W5 m6 V/ q, A! Y( g" t
  69.         // INT1中断(LATCH)触发类型为上升沿+下降沿6 |5 y& j; h  {0 E# v5 S, {) w' ?
  70.         IT1 = 0;
    . w' c" p  t: C3 p; x  B* R, A% r
  71.         // 允许INT1中断
    4 ?6 Y. j! I7 p8 i4 }( q9 q
  72.         EX1 = 1;
    " w4 g& Y$ Y  H$ x; k
  73.         // 开启全局中断6 d" {, Y9 X' s% r
  74.         EA = 1;
    0 s% ^) N$ y' b# z, j$ e
  75. }" v2 U$ _1 S' ?# X4 A+ H
  76. ) T7 k* i+ v# B! v0 G1 d. W. R9 o, y, E
  77. static void INT0_Isr() interrupt 0{
    % R5 S7 Y. m: I5 D& v$ P+ |
  78.         // 只有已经成功锁存才允许CLK移位
    5 q3 z# i6 n$ P/ @( v& |
  79.         if(isReady == 0)
    : u- r% x7 E/ f# l  d9 r
  80.                 return;
    3 V) M6 x8 z  y$ H/ J1 Y
  81.         // 读当前引脚电平,如果是低电平则说明是下降沿,此时直接忽略该中断
    0 }% C( N2 t/ l& q5 R; K
  82.         if(CLK == 0)1 r( ?. ?( F& _, |; D/ J3 q! s
  83.                 return;& W4 Q9 G' d% L$ y& w9 U
  84.         // CLK上升沿到来的时候,取锁存值的下一位输出
    " @% [5 {$ h& K3 x& W1 _( n! z" Q
  85.         idx++;4 z' j8 ^& S5 X$ u3 K+ l4 I! p
  86.         DATA = key & mask[idx];# L& E+ G/ s/ `3 t
  87.         // 如果已经完成7次移位,则一轮读取完成5 G7 ]- r, K1 B( r  p
  88.         if(idx >= 7)* }9 q* m/ U6 ?. q; l
  89.                 isReady = 0;
    8 a5 D# F6 m4 ^. @% g$ z( G
  90. }
    # ?* n- H' U' y7 `/ F3 z

  91. " S) u& F1 l" [4 z
  92. static void INT1_Isr() interrupt 2{/ v8 f$ W# c0 w+ f
  93.         // 读当前引脚电平,如果是低电平则说明是下降沿,此时直接忽略该中断
    + E2 b# z( h: c2 V# {' j" L
  94.         if(LATCH == 0)
    7 M! e# G! |8 z+ G: p  D% v
  95.                 return;
    ( p7 v) l/ w% l- q
  96.         // 当LATCH上升沿到来的时候,锁存所有按键状态,同时把键值A输出到DATA* D8 q: _1 t% d! a0 ~
  97.         key = bufReady;
    9 G+ G. ]( V/ L
  98.         DATA = key & 0x80;//mask[0];        // 为了加速运算,直接取表中的值而不是读表
    & w% q2 }7 `. t* q
  99.         idx = 0;9 w" Q% W$ f" g
  100.         // 允许CLK进行移位7 X3 I2 J5 t5 `# D" B' {8 ~
  101.         isReady = 1;( G0 q4 ?, v* O2 s" {
  102. }4 F! N4 f% I4 U5 M4 `

  103. % l1 E1 F! u% h: S5 g0 N
  104. void main(){
    $ |! D' o7 g8 x# _# u
  105.         GPIO_Init();
    ! n1 h2 F& B+ t* {5 L
  106.         Interrupt_Init();
    ) J: Z5 @/ A8 R1 v: U
  107.        
    . s' q. D% P5 u4 _; [5 n& _
  108.         while(1){: W8 O2 Y2 R6 t% r- P( B" I/ i
  109.                 //PCON |= 0x01;        // 进入省电模式
    $ l$ l% i) j/ a* v
  110.                 //_nop_();' f# v( I8 ]0 R( x* F& O: e
  111.                 //_nop_();
    . [+ T0 M. g8 N! A
  112.                 //_nop_();( f& z) k- K4 B* W( z
  113.                 //_nop_();
    6 Q4 Z! ~9 u$ v2 w- f+ O+ D) T
  114.                 buf = ~((P1 & 0x3F) | ((P5 << 2) & 0xC0));
    0 n, w7 Y8 e; O2 f8 \: r; N0 c
  115.                 bufReady = buf;
    $ u& g0 O" ]  m, |% r0 b
  116.         }# z( C/ j' L3 E9 ~3 b& g
  117. }/ v/ I9 {: u5 ?8 v1 z7 h1 K
复制代码

- m* G- n/ G, [3 h9 x# I硬件参数配置无特殊要求,晶振频率选择12M即可。# E( J% {! S  Y1 I4 P+ j

; C: Z# H" n& V3 j$ H( a这是编译好的固件。

本帖子中包含更多资源

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

×

评分

参与人数 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& ~; k0 R2 g4 A2 P  P* Y
不错的设计,想问一下楼主,FC的15针公头怎么解决?普通的公头太短了,插不进去FC的扩展接口。 ...
. W" T5 O0 z* A) o3 v+ d
坛友的改造方案
回复

使用道具 举报

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

使用道具 举报

发表于 2019-5-25 12:07:18 | 显示全部楼层
精彩,楼主动手强,也写得很详细。
" A7 a' f* H5 C9 G+ D8 h) 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# {1 l: F3 [( [( y
精彩,楼主动手强,也写得很详细。
- r- ^- l% U: m# f/ L5 D' Y2.4G方案是目前无线的最低延迟吗?

- w. h4 D% v4 M' W$ p我没用过其他无线手柄,所以实在不知道我自己做的这个手柄到底是不是最低延迟。9 e0 k/ f! B7 h
不过根据网上的说法,延迟高低主要是由通信协议的复杂程度,以及数据传输速率决定的。这个模块虽然是2.4G无线模块,但由于协议很简单,所以延迟比较低。
0 @% U$ ?. b  t1 n  {6 o& A我用这个手柄玩一些ACT游戏,比如超级马里奥、忍者龙剑传、热血系列,完全感觉不到延迟,和游戏机自带的手柄没有任何区别。唯一的区别就是这个手柄是用火花山寨手柄改造的,外壳是垃圾回收塑料,粗糙+脆弱,导电橡胶弹性不佳,手感不是一般的差。
% c# @% e9 E# s2 U! p我手里还有十几张板子,等我有空了我再做一套,到时候买一个好一点的手柄改造。
回复

使用道具 举报

 楼主| 发表于 2019-5-29 16:56:14 | 显示全部楼层
ppad 发表于 2019-5-28 17:274 F5 u6 _9 ^% z& z% c4 T9 {0 H
给技术帝赞一个,有半成品发布吗,自己焊接改造就可以,编程实在不会啊 ...
& h/ p/ n  R- L  t3 a: U+ A3 ~
很可惜,我手里没有多余的单片机了,LDO也找不到了,锂电池以及充电模块更是没有了。反正就是该用到的元件基本都没了,所以没法发布半成品。
% a7 a/ h4 P& E. E8 J# r5 `  w两个板子倒是有十几张剩余。
1 Y7 @' L$ r' @5 ^  h8 C$ `你要是有USB转TTL串口板,完全可以自己买这两种单片机,然后我给你编译好的固件,你自己用串口板下载到单片机里面就行了。两个2.4G无线模块也得通过串口板用AT命令设置参数,不过好在我在设计电路的时候就已经预留好了串口,可以直接在线下载和在线设置参数。总的来说并不麻烦。
回复

使用道具 举报

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

" ?$ `2 N5 N% m0 J: d# c1 B4 N- a能得到孙大师的赞誉,不胜荣幸!
3 C/ C6 j3 r& Q2 m0 l" q' D不如开发一个多功能手柄,比如用SFC手柄改造,L/R键配合其他组合键可以用来切换2P~4P、调节连发速度、软重启等各种功能。接收端插到15PIN扩展口。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-3-22 15:55 , Processed in 0.111191 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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