找回密码
 注册

QQ登录

只需一步,快速开始

查看: 26716|回复: 33

自制FC无线手柄

  [复制链接]
发表于 2019-5-22 14:16:45 | 显示全部楼层 |阅读模式
本帖最后由 雷精灵2046 于 2019-6-14 09:28 编辑
  E0 w* Q! u6 b3 Z% O0 i
1 G0 S. ]* r0 L# s1 T4 M没有用复杂的分立元件搭建发射接收电路,直接用的现成的2.4G无线模块jdy-40。2 t6 F1 h- V8 b+ y! S' Z

$ c' M. ^8 ?( Z' x  k
6 n0 N0 Y7 X( F' T8 Q7 C/ l发射端靠3.7V锂电池供电,用了一片SOP8封装的STC单片机,负责产生连发脉冲,同时负责检测电池电量,电压低于3V左右的时候触发低压中断,低压指示LED就会亮起来告知该充电了。平时发射模块和单片机均处于睡眠状态,有按键按下才会唤醒,从而实现省电。实测睡眠状态下整机电流约1~2uA。板子洗了一下稍微干净了一点。因为对于微功耗设备来说,焊接残余的助焊剂可能会增加漏电流。( M" C$ B3 T  a' ~3 T; @( \! ]  U9 k
7 Z5 ]" J( H$ H- D9 A
买了一个火花的FC山寨手柄,去掉里面的牛屎板子,并修正一下塑料挡板,把锂电池和充电模块装进去。
& x8 m5 A! C9 o为了减少体积,充电模块裁剪得十分小,并且更换了充电电阻使之适应这个小小的锂电池。这么小容量的电池,也不需要多么大的充电电流是吧?
5 Z. Z- W. L. T, ^: U7 q6 k3 a然后统统用热熔胶粘上。充电电流比较小,所以发热很少,不会熔化热熔胶。
3 U) T, G* b! o* J; _
8 X' X/ Z4 p. a
" m0 E5 [' M8 W( J' A% M5 x( V) ?$ [. `
最后把按键、导电橡胶和电路板装上去。
. v2 P6 [; b' k% Q* K: o% m精心裁剪了电路板,正好扣上,不会阻碍其他元件,也不会影响后盖和拧螺丝。' K# a0 C+ m* ^' C# A; z

1 |7 m4 e  v8 [* ?7 n! k- Q* x8 S3 x7 I4 A* w. L8 y
完工!
# I, {/ I: y5 N  C$ }# o
  C( s. x) y6 G, m. L
6 X/ Q1 }, l- n3 E这是充电的MicroUSB插座。旁边的小孔用于透出低压报警LED的光线。) `  w2 Z  _, v

; |9 h) y! |/ @: {8 I0 x- y! Q  y. w) v: S
接收端用一片DIP16封装的STC单片机模拟CD4021。为啥要用单片机模拟而不是直接用CD4021?因为jdy-40模块接收端在有按键按下的时候输出高电平,无按键按下输出低电平,和普通手柄正好相反。当然我也可以用两片74HC00或者74HC04之类的逻辑门进行反相,但那就增加了芯片的数量。对于FC手柄这种工作频率并不高的设备来说,STC单片机完全可以胜任模拟工作。
5 K# c' v1 |/ t) L& J( s/ U7 W! w9 n& O* n2 Z

# |% i/ i5 j& a
3 A+ P9 R( s& W. o" O0 `电路设计有点小小的错误,所以有几根飞线。原本设计使用低压差LDO是XC6206,结果在做这个接收模块的时候,买的LDO居然找不到了!无奈只好用了AMS1117。幸好对于接收模块来说是5V降到3.3V,1117可以胜任。要是发射端手柄的话,3.7V降到3.3V,那就非得用6206不可了。" T' R: T9 b$ E+ n/ l
/ E1 ~3 y. ]% i( r$ e
实测十分灵敏,延迟极小几乎感觉不出来。可惜这山寨手柄的手感并不佳,尤其是方向键,软塌塌的。看来我得买个剪线手柄改装。* y& n0 g3 |9 k7 @+ M1 p
- E+ P% l+ n# ]8 d
这是电路图,有兴趣的朋友可以参考。
# B4 f: p* S9 A% |5 F' D
. i+ _& m: s+ D, g' d
2 u) x2 n: F; a6 F+ N我信奉开源主义,十分痛恨把技术藏着掖着。好东西大家分享嘛!所以两个单片机的源代码大公开!) I$ S$ W) Z4 N
编译器:Keil 51。! G, `7 F( L0 [5 b, y0 l
0 ?; J( G3 u/ h" p
发射端:
% [5 }; \$ }! m* z) A. p
  1. #include <INTRINS.H>
      D% X/ B; P; W! r2 u
  2. #include "STC15W.h"
    3 o, x# H- |/ v3 x* Q/ [

  3. : s  ~* h6 z- m" m* y

  4. ! _. l3 G0 Q3 q) [
  5. /*2 |2 g/ p  \% s( ], {& w
  6. --------------------------9 ?6 Z0 M8 L" a0 _/ [0 @3 q
  7. |1 (OUT)        \__/   (INT1) 8|
    8 \2 e/ d8 t7 I4 k4 P
  8. |                                                   |
    ' N! R1 T) a  \5 N5 y7 n/ ~3 M
  9. |2 (VCC)                   (INT0) 7|
    ! N5 u8 f1 S0 [, \8 w2 Z+ i
  10. |                 STC15W204S                   |8 {4 L( S3 R3 e* ~# L
  11. |3 (LED)                         (TXD) 6|4 @; H4 j9 w* |* w9 t* `4 U
  12. |                                                   |, j+ @3 J* L% R, @3 t: G# D
  13. |4 (GND)                         (RXD) 5|' T" X) W: A8 N7 F; z  D
  14. --------------------------9 m) \, H! Y/ h

  15. / d, w$ A7 h% T" G- s6 G. r/ A
  16. LED ---|<|---[===]--- VCC& ^! x$ v% ~$ L( z; f
  17.            Red          330
    % T' [4 K4 ~  Y- Q& h

  18. 8 E6 h0 o) J( {/ L* K, y- |* b
  19. Fosc = 6MHz
    / I9 @0 b' m( U8 b
  20. */
    % P3 k4 d* Z! n; s
  21. 7 o' P$ H+ K# Y( o
  22. 9 O4 {4 k  m9 @4 B0 S
  23. // 矩形波输出脚% w4 l3 ~- F) h; ~
  24. sbit OUT = P5^4;
    ' _3 ~4 G/ {5 @, G
  25. // 低压指示灯引脚+ E4 ]/ p2 p* o: p9 L" j
  26. sbit LED = P5^5;! p  Y" Y7 \( a* y9 V0 ^6 `

  27. 0 Q0 H; u  z: }0 M: g" S
  28. // 停机标志位
    5 A; V4 S  y* s7 f& s
  29. bit isReadyToHalt = 0;
      J# E: L- G4 G/ v  w* H

  30. ; p6 L4 q- \& ?) S- L' F
  31. // 矩形波次数累计
    & g& q# n3 h" o: x
  32. static volatile unsigned char count = 0;
    , \/ j8 X8 M" c+ M4 k0 _

  33. : [" ^! s- R3 F' W8 k( ^

  34. 4 }2 h* u' a" X
  35. static void GPIO_Init(){
    + A: f+ E* K7 C, U0 ]- B
  36.         // P3口设置为准双向,默认靠内部弱上拉输出高电平$ o' A, K- \( G- S0 i# b% N1 p
  37.         P3M0 = 0;* I) W, q4 L+ Z$ r* c2 |$ n
  38.         P3M1 = 0;- M" p" Y6 I' t( Y) `" p0 Q& S
  39.         P3 = 0xFF;1 }9 L* e9 a1 R5 s' ]
  40.         // P5口设置为准双向,默认靠内部弱上拉输出高电平, m# }3 z0 t8 L- H% s' o* B
  41.         P5M0 = 0;
    ; g7 u/ a, u( _7 b6 x4 s+ [2 [
  42.         P5M1 = 0;
    3 W! x& G* L% ^
  43.         P5 = 0xFF;
    8 M, n) [9 v/ k0 G. l
  44. }" s" K/ L. E, J; [6 _0 ]- E
  45. * B% ]! g5 k$ X$ t2 `* }( v
  46. static void Timer0_Init(){) F3 \7 V7 p1 z
  47.         // 16毫秒@6.000MHz
    , a" L. y" Y1 ]* u
  48.         AUXR &= 0x7F;        // 定时器时钟12T模式
    " j" m- K3 V" b8 r
  49.         TMOD &= 0xF0;        // 设置定时器模式
    4 \4 l% u& T( ?& V( Q$ Z2 S3 m
  50.         TL0 = 0xC0;                // 设置定时初值
    " U, d' P- c2 t8 i" Y/ C
  51.         TH0 = 0xE0;                // 设置定时初值. v+ s( H3 v: q, q3 M
  52.         TF0 = 0;                // 清除TF0标志
    " i4 J: R+ q! ]4 o) U! o) u
  53.         TR0 = 1;                // 定时器0开始计时. k+ M: k2 D, ^6 w9 N% e$ ^
  54. }; Z; j5 d1 T2 k* S4 I

  55. * m- \4 N0 ^8 d* h' h. u. }5 Y
  56. static void Interrupt_Init(){0 g! R1 b! q, J# K: y  M, e4 i! H
  57.         // INT0中断触发类型为下降沿触发; Y: w3 z3 _! K
  58.         IT0 = 1;+ a9 Y& J3 l  W+ ?4 G4 b% _. B5 Y
  59.         // 允许INT0中断. o- ]! W; _# o( D2 h4 F) L' l/ u
  60.         EX0 = 1;& t4 s( l1 j  Q+ Q
  61.         // INT1中断触发类型为下降沿触发
    6 R3 y3 y5 d7 I  n/ {1 z5 T# b9 g/ H
  62.         IT1 = 1;
    7 ^8 F% e9 @2 L. V9 m& W7 m
  63.         // 允许INT1中断- |$ L, D- c5 \" T& `% @
  64.         EX1 = 1;
    . B( \% D* _! x' ], y  R' c  H! u8 w0 _
  65.         // 允许定时器0中断4 i2 a; Q. O/ E( p* E! Y
  66.         ET0 = 1;; a  y9 f, V) R' c6 O7 G
  67.         // 允许全局中断
    7 _8 y: A; j1 z9 `% F0 j
  68.         EA = 1;* U7 i3 J! V8 Z3 V
  69. }1 v8 E% j7 O! A/ n' B

  70. 9 U/ s! c* \' X# u1 c$ ^
  71. static void INT0_Isr() interrupt 0{
    , |8 O3 L$ }1 u5 X* |9 N
  72.         // 矩形波次数累计归零, x1 C7 G! y1 L0 b' r
  73.         count = 0;
    / x0 \* H! a1 d, E0 }
  74.         // 重开定时器0中断
    8 ~" z+ i# o5 h
  75.         ET0 = 1;8 i* T5 j/ q$ v8 }
  76. }$ u: D" n$ Z' p4 I6 l8 F! G1 T

  77. 5 X8 I# m6 w5 \  l# c
  78. static void Timer0_Isr() interrupt 1{
      A! {$ w9 M- T/ [1 f
  79.         // 输出矩形波1 O) g1 _  b" u% g
  80.         OUT = ~OUT;( O2 {( I- R: z
  81.         // 累计矩形波次数
    ) {% w$ w( @  l" P- }
  82.         count++;% @& C5 I4 Q: M) Z2 }3 C2 X
  83.         // 超过250个矩形波,准备停机* k# ~. W3 {" R# ^3 _
  84.         if(count > 250){
    ; Y8 N9 m7 e6 \# A) @  }
  85.                 count = 0;' V4 ~$ X, u% f) ?0 ~
  86.                 isReadyToHalt = 1;
    1 ]& q. D& B% }, F' Y  s
  87.         }
    , o( D5 ?' G, a5 N, K& ?
  88. }# @& h! g1 F( s) ], S& D
  89. , M2 E) Y. e9 V1 P/ E9 K1 w' Q. V
  90. static void INT1_Isr() interrupt 2{1 L9 i8 X* Q  K4 z) F+ [$ q
  91.         // 矩形波次数累计归零
    ' h% G4 p/ b$ {/ n8 Y, Z' T+ A$ u8 A
  92.         count = 0;5 @4 W6 ~& I, z& j
  93.         // 重开定时器0中断
    / u3 L4 n/ m7 B8 k+ b' o
  94.         ET0 = 1;4 |) a# j- y7 ~/ i9 w. M4 o* U* c
  95. }( @% z  X7 K! p( P. s2 c

  96. ' E& `! |- @8 N- ~; `0 e

  97. 2 a+ u; n( `8 x
  98. void main(){$ x0 R  B7 E# U
  99.         // 初始化P3和P5口
    : x* Z, Y3 H$ o( g; M- N4 x( ~
  100.         GPIO_Init();
    ; e# V) y% z6 {9 i3 p
  101.         // 初始化定时器05 J; R- x  R  R+ h5 K4 @2 y
  102.         Timer0_Init();& M- t$ W9 E) a8 R5 m
  103.         // 初始化中断
    * A6 ~+ K; e( T( H- f3 t/ x5 G# t
  104.         Interrupt_Init();8 U0 n$ v( w& \0 C3 C
  105.        
    2 q% o3 m  d( R! `
  106.         while(1){: p/ t3 c* P, t$ J& f4 ^
  107.                 // 检测电量7 N2 p1 ?( C) f2 F& ]% |7 k
  108.                 if(PCON & (1 << 5)){
    # _6 B2 d3 P; [
  109.                         // 如果电量低,低压指示灯亮0 B$ O$ X3 o6 ~- i5 \
  110.                         LED = 0;
    ( a* j  F' c9 \1 r& Q% T7 d) o
  111.                         // 清电量检测硬件标志位2 O: E! Q& i  @
  112.                         PCON &= ~(1 << 5);7 {( f% R: ?' t% R+ J
  113.                 }else{& N+ J. r, {) O0 L
  114.                         // 电量正常,低压指示灯灭2 {9 q) i: N- {2 H0 \
  115.                         LED = 1;
    0 W9 ^7 m- Q2 d1 H5 `( K2 j* ?0 B
  116.                 }! i8 x  b; V  Z& t
  117. . B/ Q  h5 L( t$ g
  118.                 // 检测到停机标志. o0 O/ }, a) L3 ~9 Z' {
  119.                 if(isReadyToHalt == 1){
    / S1 P) @  a; v. Y
  120.                         // 暂时关闭定时器0中断
    / w* M5 G- F7 p! }/ @% `  m
  121.                         ET0 = 0;9 A  ]: E) o4 Q: L5 {% P9 I" x# c7 E- ~
  122.                         // 停机之前先把矩形波输出脚置低电平,以方便INT0和INT1唤醒CPU. T! I2 y5 n( t2 ^0 b! N" b  O& Z
  123.                         OUT = 0;
    # t9 o* L) r8 _% V+ d0 P: J. e8 {, X
  124.                         // 停机之前先把低压指示灯灭掉,以省电
    1 e# Q3 G5 E$ ?1 v
  125.                         LED = 1;
    # u9 r8 N% t( c5 {6 N* D8 w
  126.                         // 进入停机模式
      j1 Z8 O& x/ y
  127.                         PCON |= 0x02;9 [9 _& n; b& V0 k& @  V6 b
  128.                         _nop_();
    - U6 L/ x  X3 e7 Q. |" Q
  129.                         _nop_();1 g$ w) Z6 ?' I) P8 X5 C7 f+ ?/ D2 P
  130.                         _nop_();
    % I; f3 a, C& N/ o2 K0 \
  131.                         _nop_();; i) t4 S* K: D( |- y1 x5 w
  132.                         // 唤醒,清标志位
    9 E( s3 \4 W' x9 Q
  133.                         isReadyToHalt = 0;
    * l* F+ R: i+ N8 X/ f6 L
  134.                         // 重开定时器0中断
    7 u  G- e5 }) p' f7 U1 k
  135.                         ET0 = 1;, _0 q2 C6 Q; b* W- r' _  T
  136.                 }
    3 m! ?( b$ W, e5 U- }( |
  137.         }
    7 c, n' K. }: u7 b0 R, y
  138. }+ q+ h8 \& M! o: Y" }0 d2 [" J
复制代码
, @6 {- p* G$ L* B$ j7 ~
硬件参数配置:
( y' i! f; V3 \& I$ I/ R1 ]/ p5 Z3 \! D. e) h) ]9 d( b
& ?  P  G7 L1 T
接收端:4 K$ g9 d# _! Y: |5 G& c; _# H. N
  1. #include <INTRINS.H>
    0 Z9 p& t& r7 g* p
  2. #include "STC15W.h"6 U9 C% T7 @" P* R% K+ A- M, |

  3. # K' p0 P- g2 |; d# l

  4. , x' o5 m) `0 U( G, q2 _: e
  5. /*2 B5 N4 S2 d! r7 T" B' t
  6. 4 k! P& W& |4 S8 c
  7. *---------------------------*  L( o* h# K& f, z2 ~0 f8 z
  8. |1 (GPIO2)         \__/  (GPIO1)16|) Y6 H& U+ J4 A& E. S( n
  9. |                                                        |
    / D  i( ?; [+ j
  10. |2 (GPIO3)                   (GPIO0)15|
    5 [5 ~' l; v1 w" _2 z  M) `% d
  11. |                                                        |
    # j0 V3 h7 p/ U
  12. |3 (GPIO4)                                  14|
    ) K) H. w* s( ~- ~) l3 R
  13. |                                                        |% C; m# d- n: m9 r
  14. |4 (GPIO5)                        (DATA)13|
    , O# D5 C# G) u' {$ i$ s9 _
  15. |                  STC15W204S                |
    2 w6 I# E3 }. P! [: s9 E; @
  16. |5 (GPIO6)                   (LATCH)12|! N% B" f+ {3 a5 \5 Y" Z
  17. |                                                        |6 n6 A. d+ ]3 L0 Y: z# ^
  18. |6 (VCC)                         (CLK)11|
    & ^: ?* R; ?# I% |. q0 w4 N' _; D7 R
  19. |                                                          |" C4 \" |+ S, s+ a
  20. |7 (GPIO7)                         (TXD)10|
    - I& @2 m# X! z8 v7 R$ U* P
  21. |                                                        |
    ; V% {- g0 M/ _
  22. |8 (GND)                         (RXD) 9|, x- P6 X0 J/ d# S, w
  23. *---------------------------*% M0 X; a& e9 a' A4 S5 g
  24. Fosc = 12MHz
    5 Y0 I: }1 b5 i  h1 v. B' Q4 ]
  25. " @2 P/ M7 T* M) b2 x
  26. P1.0 -> 上* j' c" s: J  v
  27. P1.1 -> 左
    1 w* m2 p4 q" ?- A9 d
  28. P1.2 -> 下9 C" @& @2 I9 E9 o/ C: E) b7 J
  29. P1.3 -> 右
    & g/ j: f0 Q0 a6 ?2 v
  30. P1.4 -> SEL
    6 c: h! n9 X2 h8 M
  31. P1.5 -> STA; K& E6 c! B. x( B* e; D% C) v; A
  32. P5.4 -> B5 ^/ }/ _& P9 w* A# U5 d
  33. P5.5 -> A3 [8 d% @2 h$ S" G+ v; T7 @2 }8 ^

  34. 0 x* q) E' j& H
  35. */$ R) ]# }+ E: I( q+ b
  36. / I5 s# k# _, U* i" c, {& u) u
  37.   U) u6 `" m: }: g! P
  38. sbit CLK        = P3^2;7 ?1 r$ R- h" q: s6 R; G  q
  39. sbit LATCH        = P3^3;- T, n7 n* Y$ n. E: N
  40. sbit DATA        = P3^6;; C0 Y8 F7 P2 u' K. q# o( M
  41. 1 }; u* I: O: j& S2 L
  42. bit isReady = 0;) y) u5 m# n4 t4 a/ v: q. ^7 B
  43. static unsigned char key = 0;; H+ F$ O& n, k' Y
  44. static unsigned char buf = 0;        // 双缓冲。这个缓冲区保存从P1和P5组合而来的键值/ v* A, m2 d9 o8 L* J
  45. static unsigned char bufReady = 0;        // 双缓冲。这个缓冲区保存上面那个缓冲区的备份  ]* U  \. d) M, W4 k
  46. static const unsigned char data mask[] = {0x80, 0x40, 0x10, 0x20, 0x01, 0x04, 0x02, 0x08};        // A B SELECT START UP DOWN LEFT RIGHT。为提升速度,这个表放到RAM中; N  {7 G. W( P; x" [
  47. static unsigned char idx = 0;! N+ e6 G% E/ d! p+ X5 p
  48. / V0 A1 W1 ^$ z1 v, s+ M! S
  49. 6 f( k. l; [# Q0 }! C
  50. static void GPIO_Init(){8 y* `9 A2 z' \
  51.         // P1口和P5口用于接收并行信号,全部初始化为准双向,依靠内部弱上拉输出高电平
    1 Q8 s. T" |- G0 S& w6 M
  52.         P1M0 = 0;
    + [" J/ R9 {. f$ B6 y
  53.         P1M1 = 0;; n2 F# i9 p( A6 |- C
  54.         P1= 0xFF;% J- k. s( O  G2 f" o( B
  55.         P5M0 = 0;
    : \4 K! }' E3 V7 Y
  56.         P5M1 = 0;
    3 l. ?2 ^) k5 b' M6 o
  57.         P5= 0xFF;( j  \" w1 d/ A  M
  58.         // P3口初始化为准双向) @: W! ?( ]3 M
  59.         P3M0 = 0;# z2 M3 }6 {, i# w7 e# G5 L% P
  60.         P3M1 = 0;
    1 {! `4 V3 {5 h' O$ A5 l$ q. @
  61.         P3 = 0xFF;
    . I2 f) g! ~4 z; b; O/ s
  62. }
    % U3 e  q+ N8 Q! W" K, {

  63. * S4 B# S. f1 R; H8 @3 k
  64. static void Interrupt_Init(){) z# G! o/ Q$ K- f; f6 U1 U6 ~
  65.         // INT0中断(CLK)触发类型为上升沿+下降沿
    6 s; ~2 P! {! t& l- S
  66.         IT0 = 0;, L: U$ z/ p9 L2 t
  67.         // 允许INT0中断( R" v$ |& T  u) L0 ]" H
  68.         EX0 = 1;
    9 j' c  s6 e# v/ `5 R
  69.         // INT1中断(LATCH)触发类型为上升沿+下降沿$ H- s) d- {8 q  S0 q: b/ K, x
  70.         IT1 = 0;2 u4 v! Q, t& k$ g' Y7 Y; z% Q4 e( `
  71.         // 允许INT1中断
    4 X5 ^* h% @! x7 n& p5 b& z+ ?% K9 e
  72.         EX1 = 1;
    2 @5 I! {; }! ]$ j2 I0 Z8 v# k3 @
  73.         // 开启全局中断
    1 @# g. y4 U  r: t6 s
  74.         EA = 1;, I, _9 E, g. k4 A; I
  75. }
    / y5 O5 f( y: p$ }. [, e! L- l
  76. - a5 |; B! I; o9 |' m' A$ O( I" A
  77. static void INT0_Isr() interrupt 0{. ?" E) ?' A2 |0 F# |
  78.         // 只有已经成功锁存才允许CLK移位! K6 f' X! O! d
  79.         if(isReady == 0)
    $ R) {" Q2 Q. Y- {8 T
  80.                 return;
    6 B2 n0 p) u% f
  81.         // 读当前引脚电平,如果是低电平则说明是下降沿,此时直接忽略该中断
      S8 ^0 @6 `- w  _" J+ u; ?- l
  82.         if(CLK == 0)
    0 d# K( c$ ?: d. @' j
  83.                 return;
    * F& y6 X3 S) O  N4 Z1 @8 I3 Q9 U, o
  84.         // CLK上升沿到来的时候,取锁存值的下一位输出+ ~7 k# j  Y) i/ O; \4 }0 y1 C/ ]
  85.         idx++;
    ' C, x/ |2 o& Z9 P
  86.         DATA = key & mask[idx];
    # c/ T. b: \- E
  87.         // 如果已经完成7次移位,则一轮读取完成8 x" w, y% s  }; Q  _
  88.         if(idx >= 7)
    ) w7 \, h  a6 [1 Z! _) `
  89.                 isReady = 0;
    ' W( q* S$ ~" x4 H) A, e
  90. }
    + N6 L  q/ k' D9 D

  91. : C$ d3 w5 K" L' b3 O. C( I9 A
  92. static void INT1_Isr() interrupt 2{
    2 s4 I. f. R5 q: U* J* Z
  93.         // 读当前引脚电平,如果是低电平则说明是下降沿,此时直接忽略该中断9 t  z# f. E& }. r/ y; A3 p
  94.         if(LATCH == 0)
    ) p1 Y: G% b. q
  95.                 return;1 C( _7 k# S9 A5 y, e6 D% g. F
  96.         // 当LATCH上升沿到来的时候,锁存所有按键状态,同时把键值A输出到DATA  w' f) X- v, O
  97.         key = bufReady;. j+ L' b3 C. Y' b( i
  98.         DATA = key & 0x80;//mask[0];        // 为了加速运算,直接取表中的值而不是读表
    7 |- B9 n6 s( {* d; P
  99.         idx = 0;
    7 j* ]; u: n6 C# n0 M- ^: T3 [) a" v
  100.         // 允许CLK进行移位
    $ |" L- p+ m3 J, G: t* m
  101.         isReady = 1;
    3 W! N* ?) Y- S* Z
  102. }/ a" c7 }6 Y, t* ^

  103. ; t0 z% e4 d$ J7 N/ [, H
  104. void main(){5 A/ ]) Z9 K1 }- Q8 L8 a
  105.         GPIO_Init();' j1 p0 Y4 w5 r( g+ V4 ~) x
  106.         Interrupt_Init();
    . c9 @7 @! M% t! F# h
  107.         2 I3 |( \4 R" Q
  108.         while(1){& E' o3 ]. T+ i. K( [
  109.                 //PCON |= 0x01;        // 进入省电模式
    ' b3 m1 |2 d& K9 n' P$ h" J0 }
  110.                 //_nop_();
    . i3 r! u+ `7 m7 f* S* t6 M
  111.                 //_nop_();
    & B/ E) g& @3 W1 c% {
  112.                 //_nop_();6 v7 U" p1 w% i: J+ e8 _" F
  113.                 //_nop_();
    , z" a, m0 ?% K5 R& K* M2 B0 @
  114.                 buf = ~((P1 & 0x3F) | ((P5 << 2) & 0xC0));
    8 n; F, R. m8 H* {
  115.                 bufReady = buf;
    - c0 G5 g* H/ _$ L- S& _! r
  116.         }2 S7 j" Q2 W5 B0 ?/ H/ i( y1 T
  117. }
    ( l! n* u! ~7 ]
复制代码

# L9 `+ t  T6 J& w硬件参数配置无特殊要求,晶振频率选择12M即可。8 r; D" ?# T( X! p1 d
; r& o4 M( P8 k$ w% P. ~" t# X' i
这是编译好的固件。

本帖子中包含更多资源

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

×

评分

参与人数 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:056 ^; J! S% R2 n/ P% d: ]
不错的设计,想问一下楼主,FC的15针公头怎么解决?普通的公头太短了,插不进去FC的扩展接口。 ...
8 k& Q1 _/ P9 _1 h
坛友的改造方案
回复

使用道具 举报

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

使用道具 举报

发表于 2019-5-25 12:07:18 | 显示全部楼层
精彩,楼主动手强,也写得很详细。& |8 [6 f5 s& Q( ?; n
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; x2 I0 g3 u  J
精彩,楼主动手强,也写得很详细。
" {3 [0 p  c0 ~; l5 w2.4G方案是目前无线的最低延迟吗?

; s1 E6 W7 c% p( U0 s我没用过其他无线手柄,所以实在不知道我自己做的这个手柄到底是不是最低延迟。$ S* O* I6 H4 m# k7 ]& {* V0 v
不过根据网上的说法,延迟高低主要是由通信协议的复杂程度,以及数据传输速率决定的。这个模块虽然是2.4G无线模块,但由于协议很简单,所以延迟比较低。
# ?4 e' @+ q7 Q; F我用这个手柄玩一些ACT游戏,比如超级马里奥、忍者龙剑传、热血系列,完全感觉不到延迟,和游戏机自带的手柄没有任何区别。唯一的区别就是这个手柄是用火花山寨手柄改造的,外壳是垃圾回收塑料,粗糙+脆弱,导电橡胶弹性不佳,手感不是一般的差。) C( t- W4 [/ l$ o
我手里还有十几张板子,等我有空了我再做一套,到时候买一个好一点的手柄改造。
回复

使用道具 举报

 楼主| 发表于 2019-5-29 16:56:14 | 显示全部楼层
ppad 发表于 2019-5-28 17:278 l. x4 @+ F7 {: C7 G4 }% n. e* T
给技术帝赞一个,有半成品发布吗,自己焊接改造就可以,编程实在不会啊 ...

/ g' W& P+ m( P/ c0 s  Y很可惜,我手里没有多余的单片机了,LDO也找不到了,锂电池以及充电模块更是没有了。反正就是该用到的元件基本都没了,所以没法发布半成品。
; G5 ?( I1 w$ h2 X8 r  l' `两个板子倒是有十几张剩余。, n9 r0 h+ M0 G& z  F4 C+ F
你要是有USB转TTL串口板,完全可以自己买这两种单片机,然后我给你编译好的固件,你自己用串口板下载到单片机里面就行了。两个2.4G无线模块也得通过串口板用AT命令设置参数,不过好在我在设计电路的时候就已经预留好了串口,可以直接在线下载和在线设置参数。总的来说并不麻烦。
回复

使用道具 举报

 楼主| 发表于 2019-5-29 17:00:34 | 显示全部楼层
孙大师 发表于 2019-5-28 18:55
' J  Y7 l: T1 t. p非常好,楼主是技术帝,到目前我都还没开发fc的无线套件,等空了,开发一套套件,等玩家自己组装。 ...
: j# @  ^) @6 r5 g' F
能得到孙大师的赞誉,不胜荣幸!
* h9 }$ y" i' J7 b5 y: D不如开发一个多功能手柄,比如用SFC手柄改造,L/R键配合其他组合键可以用来切换2P~4P、调节连发速度、软重启等各种功能。接收端插到15PIN扩展口。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-9-15 13:09 , Processed in 0.237012 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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