找回密码
 注册

QQ登录

只需一步,快速开始

查看: 26772|回复: 33

自制FC无线手柄

  [复制链接]
发表于 2019-5-22 14:16:45 | 显示全部楼层 |阅读模式
本帖最后由 雷精灵2046 于 2019-6-14 09:28 编辑
) \3 z+ U3 f( x: `+ B. g- i
6 z% Q+ p- `: t没有用复杂的分立元件搭建发射接收电路,直接用的现成的2.4G无线模块jdy-40。( q' Q7 Z2 Q7 h% _5 e

# j4 a& t# K. @; Q, @: L
; ~2 o$ D, a- D: d5 ~$ O9 {发射端靠3.7V锂电池供电,用了一片SOP8封装的STC单片机,负责产生连发脉冲,同时负责检测电池电量,电压低于3V左右的时候触发低压中断,低压指示LED就会亮起来告知该充电了。平时发射模块和单片机均处于睡眠状态,有按键按下才会唤醒,从而实现省电。实测睡眠状态下整机电流约1~2uA。板子洗了一下稍微干净了一点。因为对于微功耗设备来说,焊接残余的助焊剂可能会增加漏电流。* F+ W9 Z7 z" H% u, F. d
! N6 u8 X( f& I1 w; G6 O3 q" y( b
买了一个火花的FC山寨手柄,去掉里面的牛屎板子,并修正一下塑料挡板,把锂电池和充电模块装进去。
; v2 H8 T8 e3 `& T3 Z2 ^9 [7 g为了减少体积,充电模块裁剪得十分小,并且更换了充电电阻使之适应这个小小的锂电池。这么小容量的电池,也不需要多么大的充电电流是吧?
& k7 s1 n9 n& K9 v/ y然后统统用热熔胶粘上。充电电流比较小,所以发热很少,不会熔化热熔胶。1 ?1 Y7 [8 Q: u1 F2 R$ h
/ w# j" t9 ~6 m. E  ~

$ b  l* Q5 e" l8 r$ m% d. C
3 U- [- L( c" x2 u# b最后把按键、导电橡胶和电路板装上去。
- d0 D0 L1 |6 K  B精心裁剪了电路板,正好扣上,不会阻碍其他元件,也不会影响后盖和拧螺丝。/ Q% V* b/ m# A) m
2 x1 X8 d: S1 W6 X
( w4 q/ v5 L4 o7 l% n' Z
完工!
, ^4 j  T9 {; ^2 g& ~( i5 E4 k6 k% O" C4 W- S( L0 A4 i

6 `/ B' T* _9 y! g, w这是充电的MicroUSB插座。旁边的小孔用于透出低压报警LED的光线。; S! F9 @1 e) G7 w2 o# M

: B6 d5 w. t$ e4 q$ u8 k
6 ?5 D: z& f$ r  F/ I; A接收端用一片DIP16封装的STC单片机模拟CD4021。为啥要用单片机模拟而不是直接用CD4021?因为jdy-40模块接收端在有按键按下的时候输出高电平,无按键按下输出低电平,和普通手柄正好相反。当然我也可以用两片74HC00或者74HC04之类的逻辑门进行反相,但那就增加了芯片的数量。对于FC手柄这种工作频率并不高的设备来说,STC单片机完全可以胜任模拟工作。) Q& M* K7 Y$ j  ?; i& s+ u$ {
0 `1 W7 {8 g( Y- n$ z- |* O
8 E" ^5 c! C. U1 d5 J
0 L4 ]# {2 _% \' i, K; w' L& [# Q
电路设计有点小小的错误,所以有几根飞线。原本设计使用低压差LDO是XC6206,结果在做这个接收模块的时候,买的LDO居然找不到了!无奈只好用了AMS1117。幸好对于接收模块来说是5V降到3.3V,1117可以胜任。要是发射端手柄的话,3.7V降到3.3V,那就非得用6206不可了。4 I6 [1 _" b, o2 i/ \
* s  k9 K% S; k' J% z" N5 y$ _; b
实测十分灵敏,延迟极小几乎感觉不出来。可惜这山寨手柄的手感并不佳,尤其是方向键,软塌塌的。看来我得买个剪线手柄改装。8 F1 i( c2 P' o9 a
5 r/ I; |0 X8 ~) l
这是电路图,有兴趣的朋友可以参考。
  Q) o' y9 H( G7 I) M+ }7 G2 _! q& ]& I$ ^" A2 e
% f/ O( a7 U5 p7 _! Z
我信奉开源主义,十分痛恨把技术藏着掖着。好东西大家分享嘛!所以两个单片机的源代码大公开!
4 \' S+ G- {) n% q" G6 y& I) D编译器:Keil 51。+ l4 }0 r; G' z% p5 L: r% i, ?

) C* g7 M1 S4 c发射端:
. y  x8 H5 q' s& |( Y
  1. #include <INTRINS.H>, x3 Y: K; H. l- E
  2. #include "STC15W.h"
    + }1 V6 A) t, A, n+ |
  3. % d8 Y" r$ V! j' M: g) s  j

  4. 5 o+ y  d) A) r; d7 e) m# A/ g
  5. /*7 J0 L2 x' L3 `  ?- c3 v
  6. --------------------------) g9 G2 X9 o( U( D
  7. |1 (OUT)        \__/   (INT1) 8|
    0 x6 c0 k6 b$ t; z- a
  8. |                                                   |
    * O, e5 t# m* S+ D; m4 [: H  T* t
  9. |2 (VCC)                   (INT0) 7|
    9 \3 F/ u: N, e, ~+ k
  10. |                 STC15W204S                   |( w* P% A& D  O! l* l1 @, R6 z
  11. |3 (LED)                         (TXD) 6|
    ) w* C" ]7 E8 }1 q( U; a8 W& f
  12. |                                                   |: q# y0 O/ n% f" S1 o
  13. |4 (GND)                         (RXD) 5|. k  ~+ @" h* W' f2 c* c) ]0 G4 @
  14. --------------------------1 w2 V: y6 L' x" m1 H9 j

  15. 7 ^% n4 L) }% b
  16. LED ---|<|---[===]--- VCC
    # b, v3 Y! ^: V6 k  l" `* c# O) k! _
  17.            Red          330) G% ~0 @% P: }4 I
  18. 0 r& f$ X( c" r3 s3 w: C  Z; p" s, z
  19. Fosc = 6MHz
    . B' [# T5 J# m' s. ]* ]
  20. */1 _; F' m% l& T  k. @7 m

  21. ! c. p9 [! P  y) w  t) U9 i1 a8 X
  22. $ }* F& l3 X* m$ A: T
  23. // 矩形波输出脚8 q9 N6 q, o6 e* m* L; r$ |
  24. sbit OUT = P5^4;8 D5 `& h/ V& Z& P' I
  25. // 低压指示灯引脚- A7 I' h/ m! g: M8 k# z
  26. sbit LED = P5^5;
    ) {6 O) u: g3 i( p; y8 l3 w: O8 f

  27. 1 n3 W7 ?8 ~% P
  28. // 停机标志位: x/ G" Q: O/ s
  29. bit isReadyToHalt = 0;4 L: q% l. n" n0 C) A- ^4 d! U3 b$ j
  30. + E) E, S/ [# y$ F# W: O! `
  31. // 矩形波次数累计
    & P- c% }9 f- i! L
  32. static volatile unsigned char count = 0;; Z4 X* _- r4 k# F, S9 u
  33. 2 }* g. W4 h0 h! i
  34. & J6 H% W% ?% i3 L" h4 Z3 l
  35. static void GPIO_Init(){
    % V8 [! z  @5 _6 X5 B
  36.         // P3口设置为准双向,默认靠内部弱上拉输出高电平
    5 y! z" \0 _! U7 v
  37.         P3M0 = 0;5 S- `0 ^. {- ?  j. ?
  38.         P3M1 = 0;. ~$ C8 O: j* L. ~# y
  39.         P3 = 0xFF;
    9 H) P* T& B, l/ n, ~
  40.         // P5口设置为准双向,默认靠内部弱上拉输出高电平
    ; Z2 e1 \) O# e/ \/ t* q
  41.         P5M0 = 0;8 w, R# R$ n! |% x
  42.         P5M1 = 0;$ J; C" U8 A  t! z. K4 G! e
  43.         P5 = 0xFF;
      \3 `; _' o* H$ E
  44. }
    # P  s& a" I( F' Q3 ]
  45. / `+ c6 C( w4 a6 ^! A  r
  46. static void Timer0_Init(){" ]8 m3 I/ \/ W0 c( j3 y
  47.         // 16毫秒@6.000MHz
    6 t$ L; A9 F/ d& Y2 i
  48.         AUXR &= 0x7F;        // 定时器时钟12T模式
    5 b& A9 R. A7 H; n( U$ P
  49.         TMOD &= 0xF0;        // 设置定时器模式
    2 v+ c& b: G; c4 _3 ^3 d2 o0 D
  50.         TL0 = 0xC0;                // 设置定时初值% c$ Y- J6 X" e' Q9 g/ h" d
  51.         TH0 = 0xE0;                // 设置定时初值0 S- B) f5 C. ^
  52.         TF0 = 0;                // 清除TF0标志: ~6 O; O7 u4 k; O/ G8 g
  53.         TR0 = 1;                // 定时器0开始计时
    9 ^1 i+ n/ ~: I* E: n
  54. }( z7 e# |+ g# z- {# Q3 H
  55. 7 T1 k; w1 W* H% c" }; ^' }
  56. static void Interrupt_Init(){
    % q  u+ O* b* D/ i! h- D% m/ p
  57.         // INT0中断触发类型为下降沿触发5 W  k  i0 b- |  t
  58.         IT0 = 1;
    5 U0 `! R. R  W; h, c
  59.         // 允许INT0中断1 g& L: |4 K) @5 d6 d' d  f
  60.         EX0 = 1;) X0 w, B% Z2 u/ n( P  b: ]
  61.         // INT1中断触发类型为下降沿触发
    : O% {& d+ I, P+ n
  62.         IT1 = 1;: d' j8 F- ]# P5 r: \7 q# ~; L
  63.         // 允许INT1中断
    % h4 O) z% |1 T- D/ N
  64.         EX1 = 1;
    0 i5 ~9 _3 ]6 G, a7 B. B6 a6 i
  65.         // 允许定时器0中断- B  g6 o6 I$ f/ J3 ^1 O% @
  66.         ET0 = 1;
    $ s6 n1 @9 _7 N+ F& Q4 h- `
  67.         // 允许全局中断
    ( V; W4 d9 ?% n5 r- d6 d
  68.         EA = 1;
    " R; I$ Z4 T) l- W+ @
  69. }
    , ^& F- B. W9 R
  70. " u, G- ?" f& m* j4 }
  71. static void INT0_Isr() interrupt 0{
    3 D/ b2 @1 x7 x
  72.         // 矩形波次数累计归零$ k. l  G( k2 e* U
  73.         count = 0;9 U) j% ]% c4 v9 B: ^. @
  74.         // 重开定时器0中断
    8 k2 r$ S. ~; ?" W
  75.         ET0 = 1;
    * V5 V+ F- b6 u, c' s, `# y4 X
  76. }
    ( W' o9 l8 z8 G" z/ n& W0 A( U

  77.   c" j/ a$ H$ s6 Y- i6 l
  78. static void Timer0_Isr() interrupt 1{
    / s0 P7 g3 c) t) G* O3 x- ~
  79.         // 输出矩形波
    - y& U& ?& r$ E- _5 {3 }$ @
  80.         OUT = ~OUT;( ?: s' S1 n% y
  81.         // 累计矩形波次数
    - q- {' M7 v( t  ]5 g
  82.         count++;
    ' K8 `1 c7 `2 b
  83.         // 超过250个矩形波,准备停机4 y6 t8 U& U0 f
  84.         if(count > 250){, D- |# f: j8 U5 b/ y: _
  85.                 count = 0;
    # y$ v- S9 w2 ^# }1 {- r
  86.                 isReadyToHalt = 1;
    3 L( m1 q; P/ s5 E) ~2 E0 G  F
  87.         }
    + U7 w3 O, E+ L. o1 t+ r# D
  88. }2 |$ V/ z2 G, w

  89. * f& l; v; z. G- v
  90. static void INT1_Isr() interrupt 2{
    - E. e% ]5 p- A  i0 c, n$ O
  91.         // 矩形波次数累计归零
    6 q, @' e! a, Z3 |- N6 a
  92.         count = 0;
    $ U$ `8 S" f/ S5 Y; J& \
  93.         // 重开定时器0中断
    8 f! R; e: ?! P2 t* F. v" g
  94.         ET0 = 1;
    5 A; I# I1 i% @4 S
  95. }  x9 W) D" g1 q# z+ O7 q
  96. 5 k' k6 w0 H- u& E
  97. 4 }4 y; h7 R7 ]) }2 B
  98. void main(){1 }7 ?" ?0 [- {
  99.         // 初始化P3和P5口
    % k. G6 f0 g7 J
  100.         GPIO_Init();7 ]# ?/ [6 g. A- i
  101.         // 初始化定时器0
    ) |6 `1 m2 a$ T2 i: N  c1 o
  102.         Timer0_Init();
    0 x* L3 Y2 P" y
  103.         // 初始化中断
    ; D- l6 p" O# d9 ~3 ?
  104.         Interrupt_Init();
    2 V' T7 y4 \& [9 C8 ^/ }
  105.         " Z& g/ p* O5 l1 e5 f
  106.         while(1){: V( L8 A; W/ e
  107.                 // 检测电量- c- k$ x/ J; e' R0 o
  108.                 if(PCON & (1 << 5)){9 \) C( m  b1 K6 r$ c6 D; H
  109.                         // 如果电量低,低压指示灯亮
    4 X. ^' E/ t( u4 X' f0 n5 ^! M
  110.                         LED = 0;
      f5 m" _0 ^: f$ q9 Q$ {
  111.                         // 清电量检测硬件标志位
    & Q4 t% h+ a: v6 N, u, p6 q& w
  112.                         PCON &= ~(1 << 5);
    * l$ ?" G. T. s1 {8 ~3 ~
  113.                 }else{
    " d7 q, }9 ]$ p. b
  114.                         // 电量正常,低压指示灯灭
    7 J8 l1 }: t7 z) [! V
  115.                         LED = 1;, L. Q4 c7 U1 S( }# H5 ]/ }( Z
  116.                 }/ L+ O8 S, q4 K2 N8 ?  h) W

  117. : \- A6 M6 v& h7 k0 R) o" K( g
  118.                 // 检测到停机标志
    / p) F" @2 F2 I7 r3 r0 a% l9 K
  119.                 if(isReadyToHalt == 1){
    $ x6 }, P1 ?. r4 b( L2 h0 x
  120.                         // 暂时关闭定时器0中断
    6 N5 b) `$ f& k3 B" @
  121.                         ET0 = 0;
    ) A7 N3 k0 r0 X) [8 T' F7 Q5 o% n& f
  122.                         // 停机之前先把矩形波输出脚置低电平,以方便INT0和INT1唤醒CPU
    ) Q; M1 m( a3 @2 t. Z& }2 u4 W
  123.                         OUT = 0;
    2 {6 e" \! X0 q; X3 f+ ^
  124.                         // 停机之前先把低压指示灯灭掉,以省电# y; X1 P* S$ I; [" V5 J) [$ ]/ C
  125.                         LED = 1;
    3 U7 B5 G& r1 k- [  h1 t# ~1 D
  126.                         // 进入停机模式1 N. N1 T' z2 F; Z* U
  127.                         PCON |= 0x02;
    ' J- t# C2 `7 ^9 ^; g. Z8 ?
  128.                         _nop_();
      A0 r* {2 p- i& G
  129.                         _nop_();3 I+ v3 r* ~6 f% T" i4 Z# b
  130.                         _nop_();9 f/ p, \5 i4 [; g
  131.                         _nop_();* ]6 L; y6 I7 z
  132.                         // 唤醒,清标志位# c6 H2 C; z( @/ h8 f
  133.                         isReadyToHalt = 0;- b4 A% J# D7 x
  134.                         // 重开定时器0中断) T0 N6 [! B0 [: B: ?9 V4 y! S5 ~& ^
  135.                         ET0 = 1;, y' b; O& B" ^
  136.                 }
    - T1 m+ M& ~2 F1 J9 I* J# X
  137.         }
    + A; j7 v$ O7 w0 _* g& |8 `' k
  138. }
    : r+ |' i9 A  \0 P& d% M$ Q2 `, |: {
复制代码
( T6 P& ?! P* W" v% J
硬件参数配置:  @$ f1 ^4 T: E, ]0 l3 x! ^

) l  C- v* Y' E$ R; Q: {* b6 x; N& |) h+ E
接收端:2 t/ ?" F( F# g: M! I
  1. #include <INTRINS.H>2 M7 r; a( R$ V3 q
  2. #include "STC15W.h"
    * ]3 R: g4 m6 g9 y4 u6 ?7 k

  3. / c) T$ s. V2 g, g! L8 A

  4. 1 O# {1 ?, {6 \. ?5 t
  5. /*" Z1 ^# ^% h0 A" P; h9 @

  6. ( Q6 Q5 r- r: M5 h- {
  7. *---------------------------*
    7 c% Q5 ?7 H# ?6 C* M- `
  8. |1 (GPIO2)         \__/  (GPIO1)16|& P# D* T5 Q9 R  k+ p
  9. |                                                        |
    - ]2 F7 o" ?  @0 q5 X, v8 l+ m
  10. |2 (GPIO3)                   (GPIO0)15|
    7 t& H: l6 g3 k$ s
  11. |                                                        |# Y( [# k# y5 j& j
  12. |3 (GPIO4)                                  14|0 s2 ?6 S0 F9 p9 ]5 P) _; W
  13. |                                                        |
    $ W9 ~- p5 E, x- s6 R+ K7 H
  14. |4 (GPIO5)                        (DATA)13|* o: X+ X7 k; E5 r
  15. |                  STC15W204S                |& D" }' U% e  ~: ?9 g9 }
  16. |5 (GPIO6)                   (LATCH)12|
    & b! c/ z# ?% X
  17. |                                                        |
      C" a% \. r* D# t- g6 G- [
  18. |6 (VCC)                         (CLK)11|' t( ^& I: j1 m5 u& N, j# ^3 s
  19. |                                                          |5 c' V0 }' d5 K+ E  Y! \
  20. |7 (GPIO7)                         (TXD)10|5 G  [4 \5 z% X( P  r
  21. |                                                        |2 l6 J- R. m5 `" E2 R
  22. |8 (GND)                         (RXD) 9|
    6 `, E3 S: b5 f; {; x4 R' d
  23. *---------------------------*, X- {% c8 y2 q. L' I
  24. Fosc = 12MHz
    & L# i4 |1 Q& M$ b6 R, l4 `- y

  25. ) t6 d' b- l2 U( F6 {6 O
  26. P1.0 -> 上
    1 ~) T4 j/ J* N; Z
  27. P1.1 -> 左( |" R+ d4 |5 ?- P' e
  28. P1.2 -> 下
    + `7 g9 g8 i3 G# M! V
  29. P1.3 -> 右% D6 j  T$ g. k2 L
  30. P1.4 -> SEL
    , ~5 h" D& g2 e
  31. P1.5 -> STA# f5 h: u% T. Z& G1 O
  32. P5.4 -> B
    2 A7 H0 F- z: e6 Q$ v6 W, j
  33. P5.5 -> A
    9 O/ G" z" E# A) Z# h
  34. - @; d5 y" O3 V4 o. x  e3 U
  35. */- s4 @( c' Q: U0 |) d+ w

  36. 8 ^# y/ x9 \) e" i8 B% f6 k
  37. ) K; @5 a8 G( Z2 j9 P8 j7 A( U2 H
  38. sbit CLK        = P3^2;( B8 p* u$ l. n. X6 a
  39. sbit LATCH        = P3^3;
    9 [8 L# P: n/ m* C
  40. sbit DATA        = P3^6;$ T& b1 f( s7 |, E
  41. 3 e0 U& {; M# X
  42. bit isReady = 0;5 l/ L/ `( w0 G7 `  `* I
  43. static unsigned char key = 0;
    ' G! O1 G- o2 A- I8 ^
  44. static unsigned char buf = 0;        // 双缓冲。这个缓冲区保存从P1和P5组合而来的键值  \8 x2 d' Y$ H% Z7 w; y+ j7 c
  45. static unsigned char bufReady = 0;        // 双缓冲。这个缓冲区保存上面那个缓冲区的备份
    + i+ w& m5 Y$ t( e2 X7 X
  46. static const unsigned char data mask[] = {0x80, 0x40, 0x10, 0x20, 0x01, 0x04, 0x02, 0x08};        // A B SELECT START UP DOWN LEFT RIGHT。为提升速度,这个表放到RAM中; F) J! R9 |3 a# h! H+ W, q. h
  47. static unsigned char idx = 0;
    1 y8 n3 B; ?, M2 i. g( C5 K
  48. ; N0 k2 u- a. W+ O& N' {! D" V

  49. $ f. _* P  g0 p, L
  50. static void GPIO_Init(){5 ?0 n& y! f* l3 [3 g
  51.         // P1口和P5口用于接收并行信号,全部初始化为准双向,依靠内部弱上拉输出高电平
    ) e# g4 Y! E/ V+ b! \) {( u+ p# ~
  52.         P1M0 = 0;
    2 x3 l  ^: X% H
  53.         P1M1 = 0;% z7 P; w- _4 D( V. q* q# Y
  54.         P1= 0xFF;$ q  l- b1 o, u( S! x' N% ^
  55.         P5M0 = 0;2 C! H$ H8 G0 E# _
  56.         P5M1 = 0;
    ' O+ r3 O4 }4 T) K
  57.         P5= 0xFF;
    1 i( c- m' `" t& P
  58.         // P3口初始化为准双向
    1 J! |' H/ n9 v& {. ?
  59.         P3M0 = 0;% a  X5 Z) G4 r$ ~8 b
  60.         P3M1 = 0;
    + Y* H0 h5 L" ]; n3 ~3 {6 t: |. V3 }
  61.         P3 = 0xFF;* g" v3 p+ ^2 s$ u# Y
  62. }
    ( n) D6 p1 j' v9 f1 X# G$ ~
  63. & ]* D. H) O( x3 H  w% W
  64. static void Interrupt_Init(){
    5 w: V$ }! B) E/ Q  P' o0 s) u/ r8 \
  65.         // INT0中断(CLK)触发类型为上升沿+下降沿: x; Y) J5 M& J. B# z! O
  66.         IT0 = 0;& c$ w* h, |; {; x: ]/ S+ C
  67.         // 允许INT0中断
    1 P2 I0 o4 X% U( h0 F
  68.         EX0 = 1;
    : u7 b; ]0 y) a2 Q8 S: c
  69.         // INT1中断(LATCH)触发类型为上升沿+下降沿
    8 @3 s! ?/ x. |& O0 _0 s
  70.         IT1 = 0;
      f$ Z* n9 v) c/ _! c
  71.         // 允许INT1中断9 I2 A$ C% G$ X  J# G
  72.         EX1 = 1;
    , n* H; M0 C0 \4 m( c
  73.         // 开启全局中断
    - F7 B1 v; {1 `8 @, ?; e' ?
  74.         EA = 1;  M7 o/ \: ]% X  K
  75. }# u4 ]+ i" x3 M4 }+ B: O: I: p& L

  76. ( w" ^  f' q( m" k
  77. static void INT0_Isr() interrupt 0{. m% [3 ]7 J9 ^& S3 b
  78.         // 只有已经成功锁存才允许CLK移位. x" k3 r* c( j' c; h
  79.         if(isReady == 0)
    / U6 S5 O( `! `& V2 ?
  80.                 return;
    7 q' m, ~* O" M. K, M; E5 X" p% W1 f
  81.         // 读当前引脚电平,如果是低电平则说明是下降沿,此时直接忽略该中断
    4 i* K( ~/ p3 h* I
  82.         if(CLK == 0)
    : I$ ?7 q! r. h* [1 b
  83.                 return;
    9 |& V0 i" o# w. l' P4 k
  84.         // CLK上升沿到来的时候,取锁存值的下一位输出
    * e4 n6 z5 |$ U4 g' B
  85.         idx++;2 E! `- I4 l3 z2 D
  86.         DATA = key & mask[idx];
    + P9 T# N- e# G+ }
  87.         // 如果已经完成7次移位,则一轮读取完成! }6 E& j. j3 ~; O# X, r
  88.         if(idx >= 7)# m: Y5 l  ^" T( [
  89.                 isReady = 0;
    , r" F5 O8 q. d3 w5 W2 S
  90. }: o  M8 K5 \; A1 Y

  91. 5 n3 u+ ?  k. J6 v" @0 v9 |
  92. static void INT1_Isr() interrupt 2{
    0 a3 Y2 [; m) }5 I* k$ X: K
  93.         // 读当前引脚电平,如果是低电平则说明是下降沿,此时直接忽略该中断
    3 F* v5 f2 o8 J2 L  ~3 Y' Q
  94.         if(LATCH == 0)) b' g! @3 \1 F: Y* k& w
  95.                 return;# K0 e1 d1 ~2 P/ i* ^- h
  96.         // 当LATCH上升沿到来的时候,锁存所有按键状态,同时把键值A输出到DATA! ~0 e1 m: U3 |  k& c
  97.         key = bufReady;
    ) p- d5 F+ Y# T7 O7 u. L
  98.         DATA = key & 0x80;//mask[0];        // 为了加速运算,直接取表中的值而不是读表
    4 W* r) }+ R. A: j7 Q
  99.         idx = 0;
    8 n3 I4 B5 M. }4 ]% A4 n- `  R8 h6 X2 p
  100.         // 允许CLK进行移位1 \% |* H6 t0 Y
  101.         isReady = 1;
    % V6 B* J, u& z+ s
  102. }+ c  K, u! T% [: F/ S
  103. 5 m  a: _9 X$ g1 u( U
  104. void main(){
    6 {4 G; ^- m  T) z& K  h
  105.         GPIO_Init();  c" E0 A! i; n' v* v
  106.         Interrupt_Init();2 R+ m0 X! ^6 E! f8 g3 R
  107.         + d. W* @( P/ g/ p4 K# W
  108.         while(1){
    3 w1 S6 O# S' W  A0 I
  109.                 //PCON |= 0x01;        // 进入省电模式: Z& @" E" m; f' y! l" _5 t4 Z
  110.                 //_nop_();, P8 O$ z$ k) S& c
  111.                 //_nop_();
    " w5 z3 o  r9 u# ?5 K
  112.                 //_nop_();( B; a2 Z) m# h8 [
  113.                 //_nop_();4 \0 K9 S( c! S9 n
  114.                 buf = ~((P1 & 0x3F) | ((P5 << 2) & 0xC0));
    0 z9 j1 P8 y1 a
  115.                 bufReady = buf;
    " q$ g* b" P% B( b. M- Q+ A& Y
  116.         }( N+ V! ~- l. q8 l5 T; Q6 V
  117. }
    5 i# ?1 j- {% h
复制代码
+ q. i# G+ V6 n# t
硬件参数配置无特殊要求,晶振频率选择12M即可。
+ Z' a) C5 u# r: O8 M7 `
. R- M; ]8 d) M/ Y  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& p* M+ P  Q: w
不错的设计,想问一下楼主,FC的15针公头怎么解决?普通的公头太短了,插不进去FC的扩展接口。 ...
  K' C$ X2 b, b0 [
坛友的改造方案
回复

使用道具 举报

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

使用道具 举报

发表于 2019-5-25 12:07:18 | 显示全部楼层
精彩,楼主动手强,也写得很详细。8 {# {; {5 W/ @6 U+ o% U6 C
2.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:076 a+ Y0 U* F0 _" a" O6 |
精彩,楼主动手强,也写得很详细。
' x% s! V6 K. Z9 U/ S' W2.4G方案是目前无线的最低延迟吗?

: j# c2 w8 W9 {* @) J' a3 S我没用过其他无线手柄,所以实在不知道我自己做的这个手柄到底是不是最低延迟。7 ^1 c  t" `7 W$ [6 p6 j
不过根据网上的说法,延迟高低主要是由通信协议的复杂程度,以及数据传输速率决定的。这个模块虽然是2.4G无线模块,但由于协议很简单,所以延迟比较低。1 @8 f& y5 T1 B/ ^3 o/ e; H
我用这个手柄玩一些ACT游戏,比如超级马里奥、忍者龙剑传、热血系列,完全感觉不到延迟,和游戏机自带的手柄没有任何区别。唯一的区别就是这个手柄是用火花山寨手柄改造的,外壳是垃圾回收塑料,粗糙+脆弱,导电橡胶弹性不佳,手感不是一般的差。1 ~, z4 g0 w) D3 w
我手里还有十几张板子,等我有空了我再做一套,到时候买一个好一点的手柄改造。
回复

使用道具 举报

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

: }3 J2 R1 i7 H# O很可惜,我手里没有多余的单片机了,LDO也找不到了,锂电池以及充电模块更是没有了。反正就是该用到的元件基本都没了,所以没法发布半成品。* {9 C, D% H' k3 _
两个板子倒是有十几张剩余。3 p- c! y9 R  @! _6 Z/ @
你要是有USB转TTL串口板,完全可以自己买这两种单片机,然后我给你编译好的固件,你自己用串口板下载到单片机里面就行了。两个2.4G无线模块也得通过串口板用AT命令设置参数,不过好在我在设计电路的时候就已经预留好了串口,可以直接在线下载和在线设置参数。总的来说并不麻烦。
回复

使用道具 举报

 楼主| 发表于 2019-5-29 17:00:34 | 显示全部楼层
孙大师 发表于 2019-5-28 18:55. h/ Y$ g/ h* }) W9 P* Z" v
非常好,楼主是技术帝,到目前我都还没开发fc的无线套件,等空了,开发一套套件,等玩家自己组装。 ...
/ a: `3 f$ {, Q) d' a/ N
能得到孙大师的赞誉,不胜荣幸!
9 R2 r( k5 U0 l$ D, x不如开发一个多功能手柄,比如用SFC手柄改造,L/R键配合其他组合键可以用来切换2P~4P、调节连发速度、软重启等各种功能。接收端插到15PIN扩展口。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-9-20 23:30 , Processed in 0.313843 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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