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

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 14193|回复: 27

自制FC无线手柄

  [复制链接]
发表于 2019-5-22 14:16:45 | 显示全部楼层 |阅读模式
本帖最后由 雷精灵2046 于 2019-6-14 09:28 编辑 8 s. K+ K4 e# C5 x+ e6 V
  N! ^8 _; r9 q5 U1 }5 V% g
没有用复杂的分立元件搭建发射接收电路,直接用的现成的2.4G无线模块jdy-40。5 n+ J0 x, b2 v( j2 H' p3 ~0 n& j
2 ]4 ^) u: S/ L1 E7 a
: |. f0 U" T8 D! }0 H  a
发射端靠3.7V锂电池供电,用了一片SOP8封装的STC单片机,负责产生连发脉冲,同时负责检测电池电量,电压低于3V左右的时候触发低压中断,低压指示LED就会亮起来告知该充电了。平时发射模块和单片机均处于睡眠状态,有按键按下才会唤醒,从而实现省电。实测睡眠状态下整机电流约1~2uA。板子洗了一下稍微干净了一点。因为对于微功耗设备来说,焊接残余的助焊剂可能会增加漏电流。
' o5 z+ g7 Z1 X7 Z' n7 O, f2 q, u& m# s- H7 e7 Q- c* H
买了一个火花的FC山寨手柄,去掉里面的牛屎板子,并修正一下塑料挡板,把锂电池和充电模块装进去。
' o: A" U, {  ]为了减少体积,充电模块裁剪得十分小,并且更换了充电电阻使之适应这个小小的锂电池。这么小容量的电池,也不需要多么大的充电电流是吧?
% A1 ?  ~$ y/ L8 a然后统统用热熔胶粘上。充电电流比较小,所以发热很少,不会熔化热熔胶。& z0 Z0 Q4 I6 |0 N

) `* @) S! i/ M4 ]
- T- p2 N% A; f4 K9 X3 X
5 t- q8 @& S1 k, \: b  |5 \2 T最后把按键、导电橡胶和电路板装上去。5 M* S5 R5 C  O. ]
精心裁剪了电路板,正好扣上,不会阻碍其他元件,也不会影响后盖和拧螺丝。+ x) y0 A! c/ ?$ \; h  B& ^. C
( E0 d/ N" I  \1 ]+ l* r5 M
( S" w. o: y! l7 f+ y
完工!+ m7 M( |( @3 v/ L( [: {+ U

- N% J2 L$ A5 c
% M( q' ~; E3 k# `这是充电的MicroUSB插座。旁边的小孔用于透出低压报警LED的光线。
8 [: N5 o4 j0 E; h3 G9 d4 \
/ ~2 y; u/ ^/ n  @, p. S3 U4 T0 @3 _" m$ V; E
接收端用一片DIP16封装的STC单片机模拟CD4021。为啥要用单片机模拟而不是直接用CD4021?因为jdy-40模块接收端在有按键按下的时候输出高电平,无按键按下输出低电平,和普通手柄正好相反。当然我也可以用两片74HC00或者74HC04之类的逻辑门进行反相,但那就增加了芯片的数量。对于FC手柄这种工作频率并不高的设备来说,STC单片机完全可以胜任模拟工作。
  t: E% W+ p: L4 x2 w! t3 g+ K* z. s# ~

5 L) w# r6 c* D. w$ s( P0 U" V( P/ x3 l
电路设计有点小小的错误,所以有几根飞线。原本设计使用低压差LDO是XC6206,结果在做这个接收模块的时候,买的LDO居然找不到了!无奈只好用了AMS1117。幸好对于接收模块来说是5V降到3.3V,1117可以胜任。要是发射端手柄的话,3.7V降到3.3V,那就非得用6206不可了。2 G9 |$ s+ ]( X
6 m9 v. a' u# D2 K+ h! ^$ @4 K
实测十分灵敏,延迟极小几乎感觉不出来。可惜这山寨手柄的手感并不佳,尤其是方向键,软塌塌的。看来我得买个剪线手柄改装。0 y# N9 p! F" j; _9 _
( ~* Q" d0 b7 l
这是电路图,有兴趣的朋友可以参考。8 I; m+ W9 h3 z9 l
7 W0 Y/ q( N  k- v' k

- N4 ?8 J; ^% q- y6 C' ]我信奉开源主义,十分痛恨把技术藏着掖着。好东西大家分享嘛!所以两个单片机的源代码大公开!
5 Q" j9 e; a5 p7 ?! l$ l编译器:Keil 51。+ V( e5 Z5 `7 Y( w) F' ]0 E/ i- t
3 ^' k- N1 B& j6 {7 Y
发射端:
% @8 O" D. ^. M* M% K, W
  1. #include <INTRINS.H>$ U( J0 U5 n' B" _/ f% T% l
  2. #include "STC15W.h"7 \5 d+ A4 H& x9 t. w( l
  3. , p0 q4 K8 ?, ]
  4. 3 N. m+ m9 E2 Y* H8 Y
  5. /*
    : p+ y  q+ Y9 d& [
  6. --------------------------
    " E, E# ?7 F7 i& L4 E7 q' P: M
  7. |1 (OUT)        \__/   (INT1) 8|. o$ |8 V! Y) c8 p) G7 m0 X
  8. |                                                   |3 O* V  _5 N# C9 C2 t0 X
  9. |2 (VCC)                   (INT0) 7|0 |9 e  D- S9 h) M; A  `1 K
  10. |                 STC15W204S                   |
    ) }6 w% L* E0 D
  11. |3 (LED)                         (TXD) 6|" _9 v* c2 j+ z3 Z
  12. |                                                   |
    $ u' f7 p  Z8 I0 L: a  Y3 N; z
  13. |4 (GND)                         (RXD) 5|
    ) x( [5 f& G$ W! w9 V
  14. --------------------------
    * u$ G- W9 y; z! B- e. D4 i' S" n
  15. * q& j0 a9 @  j, \& j7 ~
  16. LED ---|<|---[===]--- VCC: p" U1 Q" l  @
  17.            Red          330* S& _! c% H# h' m2 e. N
  18.   s0 d4 X: C  \, W
  19. Fosc = 6MHz
    4 O, c& i7 P* @7 S
  20. */
    % h- O9 c5 x% R# K% d6 j( O" E
  21. ; v% |  Y0 \, e+ E0 m+ G) c2 K
  22. ; i; G) t0 Q- o5 R- ]
  23. // 矩形波输出脚+ D0 ^/ X8 k( ~
  24. sbit OUT = P5^4;+ a: O) w/ \$ x8 A- B
  25. // 低压指示灯引脚
    4 _  ~+ f- A, M2 P. p
  26. sbit LED = P5^5;5 p. j$ f6 k. H& f& @% @$ m2 Z8 E- r

  27. : `/ Z$ K+ I: j1 A
  28. // 停机标志位( o' ~( q$ o1 G* b! Q* a
  29. bit isReadyToHalt = 0;5 }) P2 P$ V+ i9 x8 [' r& g
  30. 0 |) l, f8 t8 b$ r
  31. // 矩形波次数累计1 _0 q- L6 z* T, K9 _3 @* G  z
  32. static volatile unsigned char count = 0;6 |5 S  f9 w6 D5 a- J7 B
  33. 5 Z* s3 h# N# u' v

  34. 8 ?5 F! R# n* B$ K- h
  35. static void GPIO_Init(){
      X0 M5 A0 W$ ?: g: j6 M
  36.         // P3口设置为准双向,默认靠内部弱上拉输出高电平
    7 L/ T- Y- E: M; D: e; F! l7 \
  37.         P3M0 = 0;& X- j5 g8 k- P2 u0 A! W
  38.         P3M1 = 0;/ _# ]* P' {2 D/ w2 q
  39.         P3 = 0xFF;# N( j8 c' [5 `& U; j7 |& q0 x
  40.         // P5口设置为准双向,默认靠内部弱上拉输出高电平
    0 _, j1 T, H$ H7 i
  41.         P5M0 = 0;$ A2 d( g) ]: ?+ t; U
  42.         P5M1 = 0;0 p5 E$ U0 u$ [1 }
  43.         P5 = 0xFF;% j  M% J% l# M) n% D8 H8 u0 a) H
  44. }7 |) G9 D5 s5 n/ l4 g* [9 e. Q0 Y$ C
  45. ' t" }' g- |2 o
  46. static void Timer0_Init(){( a- u! q; U% G/ x0 T' @6 k0 Z/ v, _) a
  47.         // 16毫秒@6.000MHz8 m0 {6 [# {! ?8 j
  48.         AUXR &= 0x7F;        // 定时器时钟12T模式$ q9 l. \& [+ T  U4 ]& G
  49.         TMOD &= 0xF0;        // 设置定时器模式
    & O- y$ w3 u2 Q- f6 X: W
  50.         TL0 = 0xC0;                // 设置定时初值
    . [9 Z2 A7 L7 g8 f
  51.         TH0 = 0xE0;                // 设置定时初值2 ?+ n/ f* ?! z  F! c$ M- Q
  52.         TF0 = 0;                // 清除TF0标志! F2 E1 d8 K# N, J& M8 d4 t4 x
  53.         TR0 = 1;                // 定时器0开始计时
    ! ]. \, x2 E5 ?3 g
  54. }
    / `- r7 I" T$ Q8 P; d6 u4 W1 m5 F
  55. $ H; h; \+ _% n- i
  56. static void Interrupt_Init(){8 U/ m( m# \4 ^2 d9 F  G, L
  57.         // INT0中断触发类型为下降沿触发
    * @3 |8 S" Z9 E$ p
  58.         IT0 = 1;  ~% I% b& U6 i) |( @0 m  ^! h
  59.         // 允许INT0中断! s% t) @# _* \
  60.         EX0 = 1;
    9 R3 n8 k$ ~; `- z
  61.         // INT1中断触发类型为下降沿触发9 W9 t4 R6 w; ]' X7 s4 s4 f0 ^: Q
  62.         IT1 = 1;
      C, d) b6 c7 Z/ P
  63.         // 允许INT1中断
    0 e8 Q- b$ p9 |* d9 z; N
  64.         EX1 = 1;
    1 `7 |# u' m) O; a- H. C* U  m% P; U0 Y
  65.         // 允许定时器0中断  P' N  Z3 B, V: x9 c/ d0 z
  66.         ET0 = 1;
    & @4 P) U( e3 z* t* h
  67.         // 允许全局中断
    3 \6 W# Y4 Z) n2 V" N
  68.         EA = 1;
    . `9 \& G! n& V0 ^( H' ^8 u
  69. }
      |) {! h3 _  B+ L

  70. ; X/ l) k" ]; [- E
  71. static void INT0_Isr() interrupt 0{
    " w$ R' \5 |0 A) Y
  72.         // 矩形波次数累计归零
    ( N1 H  F" c* H; b1 V9 W! j' \- F8 w
  73.         count = 0;
    / V8 h, T+ {+ T
  74.         // 重开定时器0中断$ n7 }7 w' H9 K4 K" x
  75.         ET0 = 1;+ v% Y/ r7 d' g* p5 \( e
  76. }3 {$ l$ g: M- _# T6 m' |8 r
  77. : y9 a; S$ W. S" B* n
  78. static void Timer0_Isr() interrupt 1{0 {7 p/ U, T& P& |. s  k( u" `
  79.         // 输出矩形波
    6 H! f4 ^, B1 k
  80.         OUT = ~OUT;, F! m) u* q; ~9 M. b
  81.         // 累计矩形波次数& D9 h7 c8 Q6 J* u) P  b
  82.         count++;1 o! f  J# d6 ^1 Z
  83.         // 超过250个矩形波,准备停机
    ' ^; E  Y& m* G) J& p* e* X
  84.         if(count > 250){
    $ T) V' W7 w* w% |2 ]# K( B4 D6 b( H% j1 y
  85.                 count = 0;& M0 p/ d$ @+ a: R$ s2 U, L
  86.                 isReadyToHalt = 1;
    # ]. X; i* @6 p8 g1 D
  87.         }
    ; s3 c  i# K) N7 L+ J/ Y
  88. }
    2 k3 E, ^3 l$ d# R- g+ K

  89. 4 `% {% B" h4 C( d' e
  90. static void INT1_Isr() interrupt 2{. Q( R  X# ]! X5 s& T. N; \3 D
  91.         // 矩形波次数累计归零8 o- X9 V  {* O  e% F
  92.         count = 0;
    ) ?* `4 m/ d6 w
  93.         // 重开定时器0中断7 h  Z4 ~/ K3 [- Q1 o
  94.         ET0 = 1;
    7 x8 ?; ]( D+ k5 E# {7 Q
  95. }
      j. J/ s( g3 W9 ?$ H
  96.   J, O, Z  [& ^/ a4 v$ b  W$ v" v

  97. " U/ ~! F3 N# ^
  98. void main(){
    - V  v- N/ f0 D9 F
  99.         // 初始化P3和P5口8 E8 u3 P2 `5 z
  100.         GPIO_Init();7 ^; i9 G" C6 a) z# N
  101.         // 初始化定时器00 `) J  U8 Q! p
  102.         Timer0_Init();
    0 ~& i( Y4 G& P& M- J4 H1 X: K
  103.         // 初始化中断
    9 G) ^( V1 V5 P: @/ @, b/ Y
  104.         Interrupt_Init();6 P6 e! K  w% x- o5 c5 f, S
  105.        
    ( E0 o7 i: n5 b9 ^/ E
  106.         while(1){/ v% m! e2 u2 [9 X
  107.                 // 检测电量7 W3 w) }4 o+ o) @8 O6 D( b  {( U4 K
  108.                 if(PCON & (1 << 5)){1 U9 t& k+ l( ^- y# j
  109.                         // 如果电量低,低压指示灯亮
    ' w$ _; }4 f/ z7 A$ ^
  110.                         LED = 0;7 G7 X- Y9 I" _
  111.                         // 清电量检测硬件标志位. ?, R2 U% \8 F" E4 s$ V: K; c
  112.                         PCON &= ~(1 << 5);
    / v0 n7 B% n9 ?  k: B
  113.                 }else{3 R; F) \3 h3 y5 x1 G' o5 ^: }+ _8 Q
  114.                         // 电量正常,低压指示灯灭# Y% ^% a. H3 {2 s; ?% o* ^
  115.                         LED = 1;  Q7 r% g+ j9 u
  116.                 }8 R# W. d2 _0 u: D8 k) s5 f% r( k
  117. : L2 F& F5 c) h/ C
  118.                 // 检测到停机标志
    ' S5 V* Z4 M: a* D4 e4 P
  119.                 if(isReadyToHalt == 1){" t  g/ y1 V) ?4 _/ Z8 h" ?/ o7 L
  120.                         // 暂时关闭定时器0中断
    / \4 E8 b2 J* H& v* o: {9 Z
  121.                         ET0 = 0;: n$ S( K9 i0 t
  122.                         // 停机之前先把矩形波输出脚置低电平,以方便INT0和INT1唤醒CPU$ {! O% T1 ]1 {' x- W% Q
  123.                         OUT = 0;3 ?' V/ |; d$ b* ~% A2 ^
  124.                         // 停机之前先把低压指示灯灭掉,以省电' u2 [! k# V; e: `: ?
  125.                         LED = 1;& l$ ^5 F! e& \9 A2 C3 J8 g
  126.                         // 进入停机模式
    + c5 X0 E' }1 K
  127.                         PCON |= 0x02;
    6 d, p& R) x& j% y; S) o' Z
  128.                         _nop_();+ b/ {& x: d# x6 ~& u7 S. k0 C4 o
  129.                         _nop_();
    : F3 l( b2 @& F  Q
  130.                         _nop_();
    5 `+ K$ Z) r. ?: J* Q
  131.                         _nop_();7 j  u8 V1 j; j0 j; }. O
  132.                         // 唤醒,清标志位. v) h: V/ L7 `- d( y5 J% ?
  133.                         isReadyToHalt = 0;
    " r! K9 x$ J4 v# o
  134.                         // 重开定时器0中断
    3 m- Y, u. q# Q4 X& K2 B7 g
  135.                         ET0 = 1;/ K  L& a" I' S+ A6 ^
  136.                 }& p* s, T0 {0 q6 n/ c
  137.         }
    5 Y! N+ A* \/ A, A6 D. i# t# `# ?' w) a
  138. }0 H0 V# j( m2 X5 D' f2 W3 `
复制代码
: ]# ^6 y* _9 |5 n, X
硬件参数配置:5 |+ A* c' V; q; h& a  ]3 j

7 F5 o# A  t& e8 }7 C' Q9 n
2 j( I% b( _( |; ~: v1 h接收端:
, s; O5 z- ]  b
  1. #include <INTRINS.H>" \% m. w+ _: K) V7 w& c
  2. #include "STC15W.h"7 {" @5 b: U9 `% y/ k

  3. ' ^2 P( P- R0 I- O4 n( |
  4. ' o0 s/ B( w( ^7 J; t
  5. /** \5 ~) ~# H5 \5 r) X; ]
  6. " Y& _& l9 h! ~# S3 O
  7. *---------------------------*
    + L8 [# f5 q4 I) L5 O% ~
  8. |1 (GPIO2)         \__/  (GPIO1)16|6 d' O; f, W4 Z+ s) {6 S  g( o& m
  9. |                                                        |/ ?4 G0 c+ ^% `+ b8 L5 a4 o
  10. |2 (GPIO3)                   (GPIO0)15|
      a+ z% R% v0 W  @2 t
  11. |                                                        |
    / O- C1 o' U( A( d7 L
  12. |3 (GPIO4)                                  14|
    ' v- E. G, k; ~
  13. |                                                        |
    : u# h3 n" t! x% H2 _
  14. |4 (GPIO5)                        (DATA)13|, j6 x( U, N5 j6 L! ?( g
  15. |                  STC15W204S                |
    $ P5 C- |+ F0 |( b( {8 j# d: G2 V- P
  16. |5 (GPIO6)                   (LATCH)12|% z* i! F1 u0 K% T0 c
  17. |                                                        |
    $ F8 ~  m; `0 V0 R% R
  18. |6 (VCC)                         (CLK)11|) z3 U$ c) u* g6 n& V( |  B
  19. |                                                          |5 P6 F! t  M1 `1 N2 K
  20. |7 (GPIO7)                         (TXD)10|
    7 x0 G- {7 z: g: G
  21. |                                                        |
    0 e7 Q3 ^( L  V' A9 j# g+ R
  22. |8 (GND)                         (RXD) 9|
    - G! B6 P: I$ y' w& Y$ _5 ]
  23. *---------------------------*+ X/ r4 V5 @4 B- H" u7 @. o3 I1 ?9 g
  24. Fosc = 12MHz; V6 E" n. u% x* q; \! X9 ]

  25.   X5 w) ~6 f# Y) K. H6 Z+ P0 b
  26. P1.0 -> 上
    7 N0 `( }$ C* j* i5 [
  27. P1.1 -> 左
    4 x, D6 X! z6 v# g+ _
  28. P1.2 -> 下
    / ~) K: X" L2 r
  29. P1.3 -> 右
    0 N& n3 g% a1 v' P
  30. P1.4 -> SEL
    - S& _8 e) K* D( j( @* F
  31. P1.5 -> STA+ ]4 ]1 _- A/ g
  32. P5.4 -> B1 |# Q( c4 l- R. p* Z2 r% t
  33. P5.5 -> A5 |: Q4 |: H+ h+ g3 w, i

  34. ! Y+ g& B+ V9 u/ m6 n
  35. */) O: v7 c8 L- k8 t- \) R- |# Z& ^

  36. 1 p' U5 U. ~& [/ s
  37. - Y0 F3 e+ N, ^
  38. sbit CLK        = P3^2;+ F( ~3 F8 e7 C4 F6 ?# o: _% m
  39. sbit LATCH        = P3^3;
    3 b# ?3 d. p# U1 @
  40. sbit DATA        = P3^6;
    , T* U  y: F) Y1 f" I* y* ]* A
  41. 2 j! P  N* B! H
  42. bit isReady = 0;5 ~6 U, v+ J6 ]
  43. static unsigned char key = 0;' w3 N2 H$ _; w# F
  44. static unsigned char buf = 0;        // 双缓冲。这个缓冲区保存从P1和P5组合而来的键值% o7 S0 D4 |' I7 T! P5 L/ Z+ J
  45. static unsigned char bufReady = 0;        // 双缓冲。这个缓冲区保存上面那个缓冲区的备份8 u6 t- U1 X' N: S- v4 p: w
  46. static const unsigned char data mask[] = {0x80, 0x40, 0x10, 0x20, 0x01, 0x04, 0x02, 0x08};        // A B SELECT START UP DOWN LEFT RIGHT。为提升速度,这个表放到RAM中
    / k! |! ^8 {5 s' k2 C
  47. static unsigned char idx = 0;+ N" D5 P) p6 ]2 c0 n9 Q; e
  48. 7 ~/ `( n7 Z0 ~

  49. 0 |: D$ X0 c- Q' P! r6 r3 |; @
  50. static void GPIO_Init(){2 V+ b4 W5 g( p2 Q+ Z7 ^7 n* E) _! `
  51.         // P1口和P5口用于接收并行信号,全部初始化为准双向,依靠内部弱上拉输出高电平
    , a/ i5 R+ d. H0 ]$ w
  52.         P1M0 = 0;! a: H6 N8 D# g: Z
  53.         P1M1 = 0;) `9 W1 t5 W1 U# h8 |/ p
  54.         P1= 0xFF;- L- D" X2 i0 e. c; R0 [. L
  55.         P5M0 = 0;
    : U6 A$ Q' A) e
  56.         P5M1 = 0;
    0 f8 _( q3 ^8 I9 I, r* A3 E
  57.         P5= 0xFF;
    * Q( [3 E, G& U# b- n
  58.         // P3口初始化为准双向9 w/ r+ v! v' F. k% W
  59.         P3M0 = 0;- ]  z7 O) r4 q7 ]' S( l
  60.         P3M1 = 0;
    ' b- r0 Y; q$ z0 c% V
  61.         P3 = 0xFF;
    & C& e( ]* y  m  i$ f2 }, d
  62. }# B  x- G, r9 i3 J" V  Z# M

  63. : g( A5 j! q1 z1 B5 }
  64. static void Interrupt_Init(){1 f& M$ h6 v3 H* [2 j7 d, \: @, w1 J+ T
  65.         // INT0中断(CLK)触发类型为上升沿+下降沿
    5 v6 p* O. B1 A5 Z: x1 H0 D9 u/ m
  66.         IT0 = 0;
    ; E7 j/ i: r5 @* ~, P5 j" M5 S
  67.         // 允许INT0中断) c5 ^9 u0 T- ^2 C2 p  l6 u
  68.         EX0 = 1;5 P% }* Q5 Q4 W2 N0 T* C
  69.         // INT1中断(LATCH)触发类型为上升沿+下降沿6 D# X8 j& [& C$ h
  70.         IT1 = 0;
    ; S6 b$ R; b4 z/ T, d
  71.         // 允许INT1中断9 L  q+ G; Z( \; L
  72.         EX1 = 1;
    / [3 |0 ?2 S7 |& p) Y- ], c
  73.         // 开启全局中断! e: G7 y7 J! Z3 u5 C
  74.         EA = 1;
    " w7 [, d: ~! n  c/ p
  75. }6 L$ s* A+ J7 T9 w

  76. ' o( L' [: S6 O* p6 q
  77. static void INT0_Isr() interrupt 0{
    , J1 @5 e0 [* {3 x$ G1 Q: S) {7 n
  78.         // 只有已经成功锁存才允许CLK移位; U0 v  ~  f: p- b$ M4 ]- D
  79.         if(isReady == 0)
      m0 B* r* b7 n& w
  80.                 return;# Z6 f: a& I& t# Z+ n
  81.         // 读当前引脚电平,如果是低电平则说明是下降沿,此时直接忽略该中断2 R, A/ _; L* ~. f
  82.         if(CLK == 0)
    8 T2 Y" i2 \0 c) f, q
  83.                 return;! a/ ~2 B+ c1 E, v4 {
  84.         // CLK上升沿到来的时候,取锁存值的下一位输出
    + o# `' y* I3 b" r0 N  s# v4 N
  85.         idx++;8 l. X: V9 X# O  T
  86.         DATA = key & mask[idx];, m# e7 w. S1 D
  87.         // 如果已经完成7次移位,则一轮读取完成
    * B' ^6 s+ W) j* A! t
  88.         if(idx >= 7)9 _/ C/ [- _: Y  [4 D8 @
  89.                 isReady = 0;
    # k, S: [+ t' D# p& @
  90. }
    ; {# Z2 w) u/ |

  91. : `0 C8 D" M5 c9 f( }% ]% O
  92. static void INT1_Isr() interrupt 2{  L5 ]# w- ^# [9 l% f
  93.         // 读当前引脚电平,如果是低电平则说明是下降沿,此时直接忽略该中断1 }3 B, J+ w; v: h# ?0 C# O# V
  94.         if(LATCH == 0)
    9 p. w6 A" |6 c, }* B0 c3 h2 [
  95.                 return;0 e5 \' K* ~$ u
  96.         // 当LATCH上升沿到来的时候,锁存所有按键状态,同时把键值A输出到DATA
    " {5 ~) u9 k6 e7 N- y
  97.         key = bufReady;, n' j. o% u- F. j& D- b
  98.         DATA = key & 0x80;//mask[0];        // 为了加速运算,直接取表中的值而不是读表
    . |0 E  W1 B' ?" p6 U* x
  99.         idx = 0;- e% J* N- Z9 Q& i
  100.         // 允许CLK进行移位
    3 O6 H# Z6 B! c/ g: i3 E
  101.         isReady = 1;3 \9 i; ^: P$ Z4 g
  102. }
    6 w0 B& ^+ r, u7 S! H8 D
  103. - p( _- b% C6 G( K& j" C
  104. void main(){7 S' ^* L+ R2 c: ^$ t
  105.         GPIO_Init();0 N7 X: y, l+ J; X; `+ o
  106.         Interrupt_Init();
    : a2 L# U( w  T
  107.        
    " C0 H7 ?" v9 K# }8 [8 z
  108.         while(1){: H$ {' d& L" X9 P0 A% H1 {
  109.                 //PCON |= 0x01;        // 进入省电模式
    7 W% m" \" y/ W/ k. r; j  z6 n" _
  110.                 //_nop_();! L( s4 a( c- j, U
  111.                 //_nop_();
    ; Q2 `. w, M% m4 z/ ~
  112.                 //_nop_();$ N6 j$ p/ v( k9 B! X
  113.                 //_nop_();1 E' `4 u' w5 j$ ?
  114.                 buf = ~((P1 & 0x3F) | ((P5 << 2) & 0xC0));
    8 w3 x9 J5 N; J
  115.                 bufReady = buf;
    . C9 ?$ W  k4 E  J: v1 R
  116.         }
    . V, X. \& c( Q, G
  117. }1 k7 t6 W5 s: [& t
复制代码

9 M5 F: L2 E( X硬件参数配置无特殊要求,晶振频率选择12M即可。1 f8 j  l( S1 G
& X* g/ L/ ?+ ~6 v8 N; p/ j
这是编译好的固件。

本帖子中包含更多资源

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

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
# K  y, \# D. s* [4 l) B3 }) _不错的设计,想问一下楼主,FC的15针公头怎么解决?普通的公头太短了,插不进去FC的扩展接口。 ...

. |" A0 H, R  O. g- E坛友的改造方案
回复

使用道具 举报

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

使用道具 举报

发表于 2019-5-25 12:07:18 | 显示全部楼层
精彩,楼主动手强,也写得很详细。% F0 ^; O$ I0 l* {6 r2 B
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:07
! C* P# L( u7 z8 j. c精彩,楼主动手强,也写得很详细。
5 Z; J* d8 t1 S# \. j2.4G方案是目前无线的最低延迟吗?

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

使用道具 举报

 楼主| 发表于 2019-5-29 16:56:14 | 显示全部楼层
ppad 发表于 2019-5-28 17:277 i0 |' K& y/ W! ?
给技术帝赞一个,有半成品发布吗,自己焊接改造就可以,编程实在不会啊 ...

1 a" {" R( c3 p, u) u很可惜,我手里没有多余的单片机了,LDO也找不到了,锂电池以及充电模块更是没有了。反正就是该用到的元件基本都没了,所以没法发布半成品。/ ^# ?* x; Y; L
两个板子倒是有十几张剩余。
. s: W( b* Z8 R# y9 m3 F你要是有USB转TTL串口板,完全可以自己买这两种单片机,然后我给你编译好的固件,你自己用串口板下载到单片机里面就行了。两个2.4G无线模块也得通过串口板用AT命令设置参数,不过好在我在设计电路的时候就已经预留好了串口,可以直接在线下载和在线设置参数。总的来说并不麻烦。
回复

使用道具 举报

 楼主| 发表于 2019-5-29 17:00:34 | 显示全部楼层
孙大师 发表于 2019-5-28 18:55
7 U& h* H) r$ s% }7 C# w; K非常好,楼主是技术帝,到目前我都还没开发fc的无线套件,等空了,开发一套套件,等玩家自己组装。 ...

# Y$ G% h% D+ H" p5 ~: Q/ ~能得到孙大师的赞誉,不胜荣幸!7 Z5 p5 x" ~1 U( S# l' v
不如开发一个多功能手柄,比如用SFC手柄改造,L/R键配合其他组合键可以用来切换2P~4P、调节连发速度、软重启等各种功能。接收端插到15PIN扩展口。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-3-29 23:49 , Processed in 0.057426 second(s), 14 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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