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

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 14758|回复: 27

自制FC无线手柄

  [复制链接]
发表于 2019-5-22 14:16:45 | 显示全部楼层 |阅读模式
本帖最后由 雷精灵2046 于 2019-6-14 09:28 编辑
% c9 `5 k) F4 v0 Y& o
: w, [5 |2 q7 d5 u* E+ [没有用复杂的分立元件搭建发射接收电路,直接用的现成的2.4G无线模块jdy-40。- X. C# A% j; f
2 a* M  n1 F" u4 A( v
: P* y/ W% E0 ~5 z
发射端靠3.7V锂电池供电,用了一片SOP8封装的STC单片机,负责产生连发脉冲,同时负责检测电池电量,电压低于3V左右的时候触发低压中断,低压指示LED就会亮起来告知该充电了。平时发射模块和单片机均处于睡眠状态,有按键按下才会唤醒,从而实现省电。实测睡眠状态下整机电流约1~2uA。板子洗了一下稍微干净了一点。因为对于微功耗设备来说,焊接残余的助焊剂可能会增加漏电流。
8 D4 I) K4 @' s! J  u' k+ O/ c9 E$ W
! K' i! }3 i' m( w) h买了一个火花的FC山寨手柄,去掉里面的牛屎板子,并修正一下塑料挡板,把锂电池和充电模块装进去。
. [6 W) A+ U& U为了减少体积,充电模块裁剪得十分小,并且更换了充电电阻使之适应这个小小的锂电池。这么小容量的电池,也不需要多么大的充电电流是吧?: i, M! N2 F) m, j; `1 g. E* ^
然后统统用热熔胶粘上。充电电流比较小,所以发热很少,不会熔化热熔胶。8 ^( E6 W. y5 I" j$ ]
- v+ _1 e4 O# L3 R

0 L1 z) a6 D% T: T2 W7 R
: _/ z/ q) \4 `+ B! X1 I最后把按键、导电橡胶和电路板装上去。' |  [. b9 _( W1 p
精心裁剪了电路板,正好扣上,不会阻碍其他元件,也不会影响后盖和拧螺丝。
* M: \$ D* Z2 A! J; A, Q
1 b6 n' F8 }- z6 o& f( }
9 z" M, a" @3 E. B9 D完工!
. u7 \$ Q+ R+ i" i4 J1 }9 \5 H+ ^7 b  e2 F9 D

3 b& w( B* w% ^  W这是充电的MicroUSB插座。旁边的小孔用于透出低压报警LED的光线。
0 _# l% J8 Z  b7 T9 D2 z( c6 y2 W3 v3 o2 q' P  }9 a1 W
3 J6 y7 t! j+ `2 r' W2 K
接收端用一片DIP16封装的STC单片机模拟CD4021。为啥要用单片机模拟而不是直接用CD4021?因为jdy-40模块接收端在有按键按下的时候输出高电平,无按键按下输出低电平,和普通手柄正好相反。当然我也可以用两片74HC00或者74HC04之类的逻辑门进行反相,但那就增加了芯片的数量。对于FC手柄这种工作频率并不高的设备来说,STC单片机完全可以胜任模拟工作。, s; F0 q0 ^" r9 t% ^' p

/ \) L: R( D9 J* A& O
* ^/ J+ q: X! B! g/ t  j- Y5 v
( X* I7 I5 w/ g. l5 F电路设计有点小小的错误,所以有几根飞线。原本设计使用低压差LDO是XC6206,结果在做这个接收模块的时候,买的LDO居然找不到了!无奈只好用了AMS1117。幸好对于接收模块来说是5V降到3.3V,1117可以胜任。要是发射端手柄的话,3.7V降到3.3V,那就非得用6206不可了。
, S' C" I9 k, W! C- h
" W% P7 D7 k' n) v  }% B实测十分灵敏,延迟极小几乎感觉不出来。可惜这山寨手柄的手感并不佳,尤其是方向键,软塌塌的。看来我得买个剪线手柄改装。6 R1 m7 Q! S: R! e
$ O% E- B; y0 n5 u, H* c5 A
这是电路图,有兴趣的朋友可以参考。
" C3 G" S8 \% i6 B; h) N3 h8 r  `* ^4 E' Y* `( D" }8 }
4 Y* {4 A5 z( i* A( p- j* Z
我信奉开源主义,十分痛恨把技术藏着掖着。好东西大家分享嘛!所以两个单片机的源代码大公开!; X' K) S& h5 b7 L# t
编译器:Keil 51。
/ y; |% b4 }0 g3 B+ f; U: \' O- ]
& S9 a) H- d9 v  I; s发射端:
  T$ T* N" S9 V& N, i
  1. #include <INTRINS.H>
    6 ?+ L$ R$ B. N
  2. #include "STC15W.h") Y! r- ]8 c6 O* ?* I

  3. 7 Z; R6 K6 F2 {+ j7 G1 E* F
  4. 4 v$ I# j- J4 D
  5. /*
    % e+ H8 D% x1 o  c
  6. --------------------------
    5 T) g- |. ?5 c. J
  7. |1 (OUT)        \__/   (INT1) 8|
    ; j$ A- `3 c- b
  8. |                                                   |6 M3 m7 G4 ?* a
  9. |2 (VCC)                   (INT0) 7|
    # A% C' ?( n: u4 M0 l
  10. |                 STC15W204S                   |
    * N% a  a, |8 B* h. L
  11. |3 (LED)                         (TXD) 6|
    $ Y2 \# ]+ I* N0 Z( E8 j# d
  12. |                                                   |
    / G$ X! q. h+ O" w8 g. k
  13. |4 (GND)                         (RXD) 5|/ q. @; W) [3 b' g$ x
  14. --------------------------1 \' g  d" X/ k1 \5 I: _0 O/ i

  15. 1 Y7 D: k# V" j& J
  16. LED ---|<|---[===]--- VCC
    1 q4 d$ m, R5 F3 O
  17.            Red          330! I: c( B6 N  q9 p) K; O3 W: f
  18. & d; M; r" ~* N% `, y1 b+ e% a
  19. Fosc = 6MHz
    $ K! O# d0 P0 S5 s8 n
  20. */
    ; W2 n3 g6 j+ [7 x& d
  21. 3 g1 O3 C- j. J  k# f/ ~) t
  22. : T+ Q) U9 v+ ~$ ~# i* s7 [
  23. // 矩形波输出脚
    $ R7 P+ J  f! O9 X  e. O
  24. sbit OUT = P5^4;$ G% H( ^) @) t5 H+ @
  25. // 低压指示灯引脚' I0 }5 [1 h4 R& C4 j" G
  26. sbit LED = P5^5;
    ' i% a# x; v3 |+ {3 b

  27. * p9 |- u+ X- s$ l$ p  j0 S
  28. // 停机标志位1 k" C0 h. e  f5 }: s+ R5 `
  29. bit isReadyToHalt = 0;
    / b6 s- [9 X6 z6 X# F. h  D3 S. h
  30. & x+ ?  s; P# `0 T
  31. // 矩形波次数累计1 Q6 [! r& w! f
  32. static volatile unsigned char count = 0;
    + \# u: J' l  l$ O9 i. r  `( ?

  33. / u! ]( a4 A$ C2 o7 e( H
  34. 7 l4 X1 h. T$ p% G! K
  35. static void GPIO_Init(){
    " g" ?4 ?1 g* l0 ^
  36.         // P3口设置为准双向,默认靠内部弱上拉输出高电平
    2 Y, G3 W) k+ x4 g6 _2 u8 B; ^* c
  37.         P3M0 = 0;( }9 a$ i# }# y' X1 q3 [0 V9 U* `
  38.         P3M1 = 0;) r  J9 L; }6 l; [
  39.         P3 = 0xFF;
    + _' s3 Q  n8 G9 C, F
  40.         // P5口设置为准双向,默认靠内部弱上拉输出高电平* _# M4 x  A6 `/ ~6 I4 ~$ n
  41.         P5M0 = 0;
    - O8 ^4 y. |4 @. G$ q) p
  42.         P5M1 = 0;% N+ C7 B! Z( s$ n( p
  43.         P5 = 0xFF;
    ) G; J. n9 ~8 c3 _
  44. }3 |- |8 B0 Z8 u% U8 b
  45. 3 d& g2 }3 e& T$ ~& ]1 E
  46. static void Timer0_Init(){
    1 [) e& r7 @4 l' S  ?7 ~; ]
  47.         // 16毫秒@6.000MHz
    6 `% U4 \" p. d) g% f- \/ U! G9 i
  48.         AUXR &= 0x7F;        // 定时器时钟12T模式! t1 ~' o8 D8 m- @$ _9 a1 P: G
  49.         TMOD &= 0xF0;        // 设置定时器模式7 Q9 o$ ?$ e5 y, b6 |
  50.         TL0 = 0xC0;                // 设置定时初值
    / ]1 `* h" Z2 W/ M! ?* G
  51.         TH0 = 0xE0;                // 设置定时初值
    + O5 x* w) `, f
  52.         TF0 = 0;                // 清除TF0标志! t5 R9 i( `+ m$ h  i2 D5 x% }/ ~
  53.         TR0 = 1;                // 定时器0开始计时+ V, W- u3 q7 ~% e7 U
  54. }. T3 x5 N& H" _
  55. 8 ~( P; l1 w. v/ ?
  56. static void Interrupt_Init(){
    7 C4 y& \: f: X$ b" d1 Y7 x
  57.         // INT0中断触发类型为下降沿触发) e, E6 C% a- h: U5 D" c( z+ `: Q
  58.         IT0 = 1;
    5 }1 F! C* o. h; g. F+ ]+ v4 T/ K
  59.         // 允许INT0中断
    ; v+ |; k! L( z* U
  60.         EX0 = 1;; Y- q6 M0 ]  X
  61.         // INT1中断触发类型为下降沿触发0 B3 t7 B7 W7 ^/ K
  62.         IT1 = 1;
    % v; l- Z8 v" s6 S: C% r
  63.         // 允许INT1中断  X( Y: Z# h0 |% f
  64.         EX1 = 1;4 e) r4 S( {5 I
  65.         // 允许定时器0中断
    ; L; @/ u) y  o1 H
  66.         ET0 = 1;2 K" i9 ^) D8 P! C
  67.         // 允许全局中断( m5 a6 u, u3 c4 K) B
  68.         EA = 1;
    3 F* n5 \! ^$ Q, a9 R( f/ y
  69. }5 i  N# C, K  }6 n2 X( @0 u
  70. 3 T& W5 f3 H9 J- m8 P1 t
  71. static void INT0_Isr() interrupt 0{) u" e, z% v. @1 Y4 L
  72.         // 矩形波次数累计归零! [, K% l  r4 e
  73.         count = 0;+ S) `+ T3 I' v- n5 c+ F5 \6 I
  74.         // 重开定时器0中断
    6 Z: r8 p* |" e5 V- a: H
  75.         ET0 = 1;" A2 s( c' p9 [. g9 B  T) u
  76. }
    " L7 T: f4 f) W, U- l
  77. - @7 n: }9 E6 |+ x
  78. static void Timer0_Isr() interrupt 1{
    . Y; R2 J+ W' I8 h
  79.         // 输出矩形波
    $ ?8 ~) t7 T4 d$ d% A5 u' m& _& Y
  80.         OUT = ~OUT;
    / _1 l7 C% T1 S6 ~
  81.         // 累计矩形波次数
    / B/ F. {  g' N, R. M  E9 o! g! n+ C
  82.         count++;
    4 S* K  F. w# }$ E9 F
  83.         // 超过250个矩形波,准备停机
    # |: a, U9 P1 p, @
  84.         if(count > 250){4 n. z2 T0 |- m) @; f  J1 T
  85.                 count = 0;9 e+ A" W2 @% o2 P: j
  86.                 isReadyToHalt = 1;4 B$ r4 b% ]9 C  X3 X' ~
  87.         }
    * ^: R3 L$ o( U1 Z+ d# O: C9 @' h
  88. }
    0 ~* K6 x: N. E) X7 F

  89. # L9 O9 p8 T$ ?" x
  90. static void INT1_Isr() interrupt 2{
    5 F( b% j$ y# V  U( `0 O% {+ U4 R
  91.         // 矩形波次数累计归零3 @& c8 t8 A. {- {& Y
  92.         count = 0;
    . g4 k5 J6 d4 [; p# \
  93.         // 重开定时器0中断
    9 H+ ?: [# s! q
  94.         ET0 = 1;0 s6 q4 q4 E* i  [
  95. }$ i+ N. q6 s( _4 J& O/ K1 r
  96. 8 R0 t) ^5 W5 ~$ _- @2 X' }6 r

  97. 2 @) Y! x! J/ D4 i: ]* O- e
  98. void main(){
    : q7 f( E: G: _4 w4 ]# i9 _7 B
  99.         // 初始化P3和P5口" t0 I+ k, P/ \- D' C6 [* M
  100.         GPIO_Init();4 ]' m$ o4 ~9 d( |2 U% ]
  101.         // 初始化定时器07 e# L% R5 M0 _) c; u! m- m
  102.         Timer0_Init();, P3 p3 l" c- r5 Z8 K7 f2 q
  103.         // 初始化中断( E8 X0 W* Y" |
  104.         Interrupt_Init();
    9 {1 m% @: w* n2 e. \
  105.        
    / S! T4 S; k8 G. H
  106.         while(1){% c6 i0 Q3 Y! {+ n8 ~
  107.                 // 检测电量
    , [, {% \' y( y: N! \
  108.                 if(PCON & (1 << 5)){2 F; ^+ g6 r, B0 ]& A
  109.                         // 如果电量低,低压指示灯亮) \$ C* X8 G2 w: ^- {3 [5 n
  110.                         LED = 0;
    . P6 s! c/ P, h$ ^: b/ T  d% h) P
  111.                         // 清电量检测硬件标志位
    , m' Z9 ]' [& m& E
  112.                         PCON &= ~(1 << 5);4 a" v, _9 J; r- w# N
  113.                 }else{+ ?7 T" F9 h) ]; I0 y
  114.                         // 电量正常,低压指示灯灭
    ) l/ ^9 d; S, |  a0 J0 S0 F2 j
  115.                         LED = 1;% d& l5 i! F  o6 W7 r5 R1 R" h
  116.                 }/ b/ A& W% y: l# e# x  y
  117. / A4 p% u3 F; R- A  P
  118.                 // 检测到停机标志
    3 ~6 R# x* d9 _8 a5 c4 f
  119.                 if(isReadyToHalt == 1){( q5 N0 y7 D6 a/ |/ _9 w
  120.                         // 暂时关闭定时器0中断- z6 C7 j; \, Z. [
  121.                         ET0 = 0;4 @- ~2 ?* `( V' h: i6 J: E
  122.                         // 停机之前先把矩形波输出脚置低电平,以方便INT0和INT1唤醒CPU6 H9 ?2 H' S$ E* Y: T. ^" b( q
  123.                         OUT = 0;
    5 x, ~- C3 Q6 _" |( i
  124.                         // 停机之前先把低压指示灯灭掉,以省电: B! }! i/ _! {
  125.                         LED = 1;
    " D9 y3 Q( y7 V$ w1 m
  126.                         // 进入停机模式4 C5 c" \" |; j3 k- q6 x
  127.                         PCON |= 0x02;
    ) g. _& q' Z) {" h9 K3 T
  128.                         _nop_();" f' d& M; a! q  w7 z9 X3 p; a- J
  129.                         _nop_();
    5 l2 J, h- t; Z  y. `
  130.                         _nop_();+ _% ?# A! ~( K# g/ q
  131.                         _nop_();
    ) \) X% s$ f( v5 h7 ^
  132.                         // 唤醒,清标志位0 }0 E  e3 T9 S2 }, w0 X# D( I
  133.                         isReadyToHalt = 0;$ x5 }- C) V/ m, C- q0 ?: u
  134.                         // 重开定时器0中断
    6 c; s1 @; V# G: U9 z
  135.                         ET0 = 1;% }! m) C% M$ A* t
  136.                 }5 i0 f  Q! L* N/ R: N/ N0 p
  137.         }
    2 e7 Y0 |3 s5 X2 @# a
  138. }5 Y4 r0 [: E: Q& j2 Q6 m
复制代码
6 [( l0 B+ H/ s4 G: `: X2 `: {4 Q
硬件参数配置:
: ?* p: P4 t# a; j9 a, q
. O+ Y4 J; ^& g2 w: e% u( G( U7 P+ f8 z) o
接收端:
+ |2 S1 V# E' {! I
  1. #include <INTRINS.H>3 q5 o) D0 h, N' L+ P# Y
  2. #include "STC15W.h"; L; Z* T. c3 E0 [2 ]

  3. ) ~3 U( x$ y0 F# K* U+ l

  4. ! u& Q, W4 z9 b3 p
  5. /*
    2 t+ s* R% s6 f5 W5 y

  6. - J! K* S, |# q- f4 @
  7. *---------------------------*
    1 H7 k1 p  V$ e1 j0 x4 b
  8. |1 (GPIO2)         \__/  (GPIO1)16|
    ) I; F" J. Y, u9 n
  9. |                                                        |( r$ t! O9 p5 ~) C
  10. |2 (GPIO3)                   (GPIO0)15|  ^& Q( l7 s0 D/ W6 e
  11. |                                                        |
    2 S7 O  y' B3 |0 z# ?# |) j
  12. |3 (GPIO4)                                  14|, }) O0 z# S' U: Y
  13. |                                                        |6 }$ ~2 A8 N- I9 B
  14. |4 (GPIO5)                        (DATA)13|
    7 v! s# N6 |! ]& f
  15. |                  STC15W204S                |# n2 Q( F9 R5 ~( v0 d, {1 i% o
  16. |5 (GPIO6)                   (LATCH)12|
    2 F5 c- q/ M/ n1 g- I
  17. |                                                        |  M' P! ^. }# T& W8 W, e
  18. |6 (VCC)                         (CLK)11|2 W* r! Q: W0 T9 G4 G2 I- [
  19. |                                                          |
    6 g4 U3 s* {* E+ c: L) ?) d3 U
  20. |7 (GPIO7)                         (TXD)10|0 ?- ]( O; e& B
  21. |                                                        |
    % E% T. f3 N) S% m# a
  22. |8 (GND)                         (RXD) 9|
    ! W8 T6 x8 f: ^5 u
  23. *---------------------------*0 \4 g1 T. \$ [. l0 M6 N
  24. Fosc = 12MHz# }, n" {0 X1 D" r/ i" t

  25. : Y. M$ ?' D4 r: W+ g
  26. P1.0 -> 上: X( |2 C. `2 U
  27. P1.1 -> 左) N+ V- v. ?; R5 L& v7 ~
  28. P1.2 -> 下9 u3 u' @  k. \( q* F
  29. P1.3 -> 右$ o, j, L, I$ p7 s* c
  30. P1.4 -> SEL
    3 ?  J7 i! P( }. c0 k1 F; r
  31. P1.5 -> STA; ]* q9 _7 j+ {% C
  32. P5.4 -> B
    7 ~. z0 U4 {; |+ q" C7 k) n( w
  33. P5.5 -> A+ u1 \9 ?/ ?  f( y* E7 K

  34. 1 n4 v4 x0 d- P4 ^( v4 l, m8 A  X8 E: `
  35. */
    0 K2 _( j0 ]* K& {

  36. ( `- t" I8 _2 C$ [- i+ E* k; n5 A. p

  37. 6 z2 S( c7 {; K  ~4 m$ H
  38. sbit CLK        = P3^2;& _& [7 C# v7 w2 z1 q
  39. sbit LATCH        = P3^3;+ m  |2 [* d; h+ \* P
  40. sbit DATA        = P3^6;
    * X! S& h. n9 o* ~+ O* Q

  41. / [$ W: P; w+ A9 M0 K5 ]
  42. bit isReady = 0;+ i: q4 x, w# g( G, E; U
  43. static unsigned char key = 0;" o. ^9 k  J1 e, a6 R3 }2 K
  44. static unsigned char buf = 0;        // 双缓冲。这个缓冲区保存从P1和P5组合而来的键值
    5 O3 \* T& T% o9 E& U
  45. static unsigned char bufReady = 0;        // 双缓冲。这个缓冲区保存上面那个缓冲区的备份
    4 g# \$ @% H) w3 n/ m  j# ]! J9 ~
  46. static const unsigned char data mask[] = {0x80, 0x40, 0x10, 0x20, 0x01, 0x04, 0x02, 0x08};        // A B SELECT START UP DOWN LEFT RIGHT。为提升速度,这个表放到RAM中
    9 {& a, T! z8 l4 q1 d8 f2 N5 g
  47. static unsigned char idx = 0;
    : F" p! u. ]* k1 K" s: G

  48. ; b8 I! n2 i. W

  49. 4 r0 S! i8 v8 ]' z
  50. static void GPIO_Init(){$ @, |6 i! [$ S- z
  51.         // P1口和P5口用于接收并行信号,全部初始化为准双向,依靠内部弱上拉输出高电平
    ) `9 W% U8 t- B$ _; d  x/ N
  52.         P1M0 = 0;, ]- M8 Z7 E$ Z
  53.         P1M1 = 0;% ]. [% z1 V5 U  X
  54.         P1= 0xFF;3 \. b7 |3 y: `, r
  55.         P5M0 = 0;6 l& x# g4 [4 t: N3 p- N" g3 K
  56.         P5M1 = 0;
    * S) q0 v; N/ v6 H8 F# |. Y
  57.         P5= 0xFF;' m" x) s4 q. T
  58.         // P3口初始化为准双向
    ! A# Q' G$ s$ q4 c2 j5 d
  59.         P3M0 = 0;0 M+ {& k: g/ T4 }8 T* l, q2 ^; i
  60.         P3M1 = 0;
    $ X$ T9 f8 ~# m$ T# ]
  61.         P3 = 0xFF;' z9 H& P# W& K( u3 E: z* f. `
  62. }/ H; o! P0 j  a4 P* k

  63. : N7 K1 U+ ?: v& ~1 ]. v# T
  64. static void Interrupt_Init(){
    3 d. t- m; A% e- ~
  65.         // INT0中断(CLK)触发类型为上升沿+下降沿6 i4 {% ^9 F+ l, f. l
  66.         IT0 = 0;
    $ w) F: ^5 }& n8 R4 x3 k, K' S
  67.         // 允许INT0中断$ f. J7 X) [: O; D: i8 @% s6 @
  68.         EX0 = 1;7 h) C: Z. k* q
  69.         // INT1中断(LATCH)触发类型为上升沿+下降沿
    8 v) {, q- ^. h4 G! {
  70.         IT1 = 0;, x* U  I$ M; e; }, w
  71.         // 允许INT1中断
    3 ]2 ?- `2 `: }( l/ E
  72.         EX1 = 1;; ^7 v$ q) Z4 \1 T& |8 b
  73.         // 开启全局中断0 T% S3 W7 \7 D6 Q% O4 ~/ s# n3 J
  74.         EA = 1;. m# Y, Q6 ?, H" V
  75. }
    * j$ D  o" ~. w) s  S+ H8 L

  76. ' V4 z9 I; L4 T% z
  77. static void INT0_Isr() interrupt 0{
    . p6 [  i  D4 y1 R) p
  78.         // 只有已经成功锁存才允许CLK移位+ @" E3 R/ t) P+ |6 E$ g2 Y$ T
  79.         if(isReady == 0)1 K7 m4 H6 D+ G4 |. I  G% Y% L
  80.                 return;
    8 _5 h4 m9 O5 h: x) m- N# ~
  81.         // 读当前引脚电平,如果是低电平则说明是下降沿,此时直接忽略该中断
    8 |& S; W. J$ A% |$ v. P9 S
  82.         if(CLK == 0)
    $ k8 G+ U8 v$ }, y& ]
  83.                 return;
    9 H9 {2 F; ^- L. ]
  84.         // CLK上升沿到来的时候,取锁存值的下一位输出
    ) j! P% L( {0 R7 h9 X
  85.         idx++;
    . @0 L/ T8 q3 j( S, O
  86.         DATA = key & mask[idx];
    " p; W7 U& O6 S5 Y3 A8 D3 h
  87.         // 如果已经完成7次移位,则一轮读取完成2 ^/ k& b) H6 E$ W
  88.         if(idx >= 7)* l$ |/ r! @# d6 v0 H9 @9 B
  89.                 isReady = 0;8 o8 t# B, g& Y
  90. }
    1 _) n" u1 C7 \! l% Z2 e* _
  91. * O2 \. D2 _9 N9 l
  92. static void INT1_Isr() interrupt 2{
    ; \1 w! Y/ F$ P. b
  93.         // 读当前引脚电平,如果是低电平则说明是下降沿,此时直接忽略该中断7 D4 |0 [. p5 E( u; n& a. r$ l: y# P
  94.         if(LATCH == 0)/ A3 n2 i8 S' [" v! n
  95.                 return;
    : D; L7 P6 V* ~0 q/ M4 v* s; q
  96.         // 当LATCH上升沿到来的时候,锁存所有按键状态,同时把键值A输出到DATA" ]' U0 f# M$ J9 \
  97.         key = bufReady;% t& ^  h4 B: x% j! m) f& y. f: g
  98.         DATA = key & 0x80;//mask[0];        // 为了加速运算,直接取表中的值而不是读表
    : L( }+ x! K. t9 r4 [- \! k) v
  99.         idx = 0;
    : I: }% D$ R! i' d
  100.         // 允许CLK进行移位$ j4 u+ h1 t( I& s
  101.         isReady = 1;
    1 H# U1 V, H' \" T# w
  102. }3 \6 W: }4 I7 h) {6 e# {7 q3 |
  103. / Y8 g, x+ f0 {( I
  104. void main(){  I- U# i! G4 L6 ^/ P, x
  105.         GPIO_Init();
    * w1 U0 T( R2 s; y1 a! F. |
  106.         Interrupt_Init();# \8 S" B* J: y+ e
  107.         : z, v! B# \4 l% F
  108.         while(1){6 N" ~, P7 L9 w: `* W+ c
  109.                 //PCON |= 0x01;        // 进入省电模式% _( }; P& C% c) x
  110.                 //_nop_();
    & C/ r! @2 K7 D; `
  111.                 //_nop_();: J# l  ]) }6 o- a2 J
  112.                 //_nop_();! ~) v9 d& _9 x9 O/ }% r* y0 B2 i
  113.                 //_nop_();7 f; C/ m  n; B' L
  114.                 buf = ~((P1 & 0x3F) | ((P5 << 2) & 0xC0));4 @7 \0 R# \- x, {  [
  115.                 bufReady = buf;2 w* D! D$ ^2 q8 s, W  a
  116.         }- \5 A. k" l; {8 t0 p* x
  117. }
    3 F* q2 M$ r/ j/ D# r- e5 R1 S
复制代码

7 P7 i; p& c2 |0 n硬件参数配置无特殊要求,晶振频率选择12M即可。
& u" o0 P" g1 W6 p5 h9 Y( D! W! V0 {" y8 C/ M6 U  h; ^7 A- i
这是编译好的固件。

本帖子中包含更多资源

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

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
1 @# _' l/ Q  B5 y不错的设计,想问一下楼主,FC的15针公头怎么解决?普通的公头太短了,插不进去FC的扩展接口。 ...
" [0 }# _' o- i7 q% l# W
坛友的改造方案
回复

使用道具 举报

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

使用道具 举报

发表于 2019-5-25 12:07:18 | 显示全部楼层
精彩,楼主动手强,也写得很详细。
7 ^" }' F3 W% p( p1 G2.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:078 [- z- ~; m( Z8 Q. g* U
精彩,楼主动手强,也写得很详细。
- }" L. [, i. l0 h" k2.4G方案是目前无线的最低延迟吗?
' G( }4 g( z2 r( A0 ]  U# I' c
我没用过其他无线手柄,所以实在不知道我自己做的这个手柄到底是不是最低延迟。
" g( }- k, N. b不过根据网上的说法,延迟高低主要是由通信协议的复杂程度,以及数据传输速率决定的。这个模块虽然是2.4G无线模块,但由于协议很简单,所以延迟比较低。6 {0 d. I6 M6 L5 v& g( l6 y+ G  L
我用这个手柄玩一些ACT游戏,比如超级马里奥、忍者龙剑传、热血系列,完全感觉不到延迟,和游戏机自带的手柄没有任何区别。唯一的区别就是这个手柄是用火花山寨手柄改造的,外壳是垃圾回收塑料,粗糙+脆弱,导电橡胶弹性不佳,手感不是一般的差。% h6 p6 F, W4 l0 m
我手里还有十几张板子,等我有空了我再做一套,到时候买一个好一点的手柄改造。
回复

使用道具 举报

 楼主| 发表于 2019-5-29 16:56:14 | 显示全部楼层
ppad 发表于 2019-5-28 17:27
0 K" L( _; y: V# z给技术帝赞一个,有半成品发布吗,自己焊接改造就可以,编程实在不会啊 ...
: P9 H. C4 n( q4 j/ \
很可惜,我手里没有多余的单片机了,LDO也找不到了,锂电池以及充电模块更是没有了。反正就是该用到的元件基本都没了,所以没法发布半成品。+ W* ^% m  l0 t4 j$ ]" X  k( w
两个板子倒是有十几张剩余。
7 Q; ~! s7 [) o你要是有USB转TTL串口板,完全可以自己买这两种单片机,然后我给你编译好的固件,你自己用串口板下载到单片机里面就行了。两个2.4G无线模块也得通过串口板用AT命令设置参数,不过好在我在设计电路的时候就已经预留好了串口,可以直接在线下载和在线设置参数。总的来说并不麻烦。
回复

使用道具 举报

 楼主| 发表于 2019-5-29 17:00:34 | 显示全部楼层
孙大师 发表于 2019-5-28 18:55
* W4 [8 a/ F# v5 _非常好,楼主是技术帝,到目前我都还没开发fc的无线套件,等空了,开发一套套件,等玩家自己组装。 ...
  K) C2 F# ~- X+ R- o0 C# Y
能得到孙大师的赞誉,不胜荣幸!+ q* t4 ]6 V6 d' D" E! C
不如开发一个多功能手柄,比如用SFC手柄改造,L/R键配合其他组合键可以用来切换2P~4P、调节连发速度、软重启等各种功能。接收端插到15PIN扩展口。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-28 01:07 , Processed in 0.057730 second(s), 14 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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