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

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 14190|回复: 27

自制FC无线手柄

  [复制链接]
发表于 2019-5-22 14:16:45 | 显示全部楼层 |阅读模式
本帖最后由 雷精灵2046 于 2019-6-14 09:28 编辑 7 I8 a7 |, W; J& M
8 r; i- D5 i" @7 h
没有用复杂的分立元件搭建发射接收电路,直接用的现成的2.4G无线模块jdy-40。
# f1 x$ Q2 r3 B0 ^' M  Y5 T+ ]. E: K5 K/ W

) P' p8 L- s' X4 h) Q发射端靠3.7V锂电池供电,用了一片SOP8封装的STC单片机,负责产生连发脉冲,同时负责检测电池电量,电压低于3V左右的时候触发低压中断,低压指示LED就会亮起来告知该充电了。平时发射模块和单片机均处于睡眠状态,有按键按下才会唤醒,从而实现省电。实测睡眠状态下整机电流约1~2uA。板子洗了一下稍微干净了一点。因为对于微功耗设备来说,焊接残余的助焊剂可能会增加漏电流。+ M5 B2 n4 M/ S2 o* `

9 G. ?5 n1 A' @! i% j( _" Q/ k买了一个火花的FC山寨手柄,去掉里面的牛屎板子,并修正一下塑料挡板,把锂电池和充电模块装进去。3 T8 H+ A8 \/ ?. }, Z
为了减少体积,充电模块裁剪得十分小,并且更换了充电电阻使之适应这个小小的锂电池。这么小容量的电池,也不需要多么大的充电电流是吧?
1 [' o1 l, J2 h3 S0 j然后统统用热熔胶粘上。充电电流比较小,所以发热很少,不会熔化热熔胶。9 n. N# Q9 R1 B

% E6 F" C5 U/ |" s: @/ @. Y3 R6 `: C

3 J% ~. O  [6 s! l最后把按键、导电橡胶和电路板装上去。
$ _' Y" f( M4 U精心裁剪了电路板,正好扣上,不会阻碍其他元件,也不会影响后盖和拧螺丝。4 w6 {9 a# e7 ~* A) i, e

5 v5 i" V% ]2 s
: e( z+ }8 A, d4 M# V. c7 e: Y$ D; n完工!4 n; u' u: a  u* @! }4 @

/ C8 g" \% ?! F* j3 G" t$ U2 n( N/ |6 {# a& d
这是充电的MicroUSB插座。旁边的小孔用于透出低压报警LED的光线。' g/ D: y3 c2 m% E

, r* d% U9 |/ |1 H4 [" o5 r: C* [$ K6 Z, U; @$ x3 u
接收端用一片DIP16封装的STC单片机模拟CD4021。为啥要用单片机模拟而不是直接用CD4021?因为jdy-40模块接收端在有按键按下的时候输出高电平,无按键按下输出低电平,和普通手柄正好相反。当然我也可以用两片74HC00或者74HC04之类的逻辑门进行反相,但那就增加了芯片的数量。对于FC手柄这种工作频率并不高的设备来说,STC单片机完全可以胜任模拟工作。
3 \" B  _; q. W4 L
2 O+ X5 @: G6 n  J: A7 x. r& `* P6 O
- ^; t9 n( V6 O3 i" N8 I  C
0 C' w: g; x# t6 L1 w9 M( G电路设计有点小小的错误,所以有几根飞线。原本设计使用低压差LDO是XC6206,结果在做这个接收模块的时候,买的LDO居然找不到了!无奈只好用了AMS1117。幸好对于接收模块来说是5V降到3.3V,1117可以胜任。要是发射端手柄的话,3.7V降到3.3V,那就非得用6206不可了。- W* G3 n( t  j) E
/ l: E: e' g" Z/ A* {/ Z4 p
实测十分灵敏,延迟极小几乎感觉不出来。可惜这山寨手柄的手感并不佳,尤其是方向键,软塌塌的。看来我得买个剪线手柄改装。( U  F: Z7 ~5 @9 K$ w8 {* k* ~

( e1 h8 [3 j2 _" |! x9 d4 M# F这是电路图,有兴趣的朋友可以参考。
( ?7 J) q9 D* B' E
; ~$ ^, M: J4 U" d' ~+ E. {' P4 H6 z5 S; ^
我信奉开源主义,十分痛恨把技术藏着掖着。好东西大家分享嘛!所以两个单片机的源代码大公开!
: c# b0 w$ Q+ v; G# v5 n编译器:Keil 51。
/ I9 Q- @/ y; C3 P1 K( J" w! m, L9 L6 {# L! O  N
发射端:
+ o/ K& I0 Q/ |* q' m* ?+ A
  1. #include <INTRINS.H>8 Y* N' r. U6 x( c+ a5 }" t
  2. #include "STC15W.h"
    ( ~5 N. a0 ?) Q, |$ F8 D

  3. " G* D; l6 F# p1 k

  4. 8 J0 Q) I- b& c/ [$ O
  5. /*6 N# U* Y* v. d
  6. --------------------------& h( y( |: N- r6 P
  7. |1 (OUT)        \__/   (INT1) 8|5 N7 I  x& a9 r
  8. |                                                   |5 E# f' F) J+ Z2 U. X
  9. |2 (VCC)                   (INT0) 7|
    . _0 x! I% n: `+ q( H
  10. |                 STC15W204S                   |
    ) v% ^! c( c1 F$ F9 O: h
  11. |3 (LED)                         (TXD) 6|5 X1 w' v! d2 H
  12. |                                                   |
    2 g, S* d) |# I
  13. |4 (GND)                         (RXD) 5|, y' Z  h# S$ b+ e8 b5 _
  14. --------------------------$ p' Z6 A3 L/ |$ v5 m2 l, _. y  s
  15. 6 [2 h# z) k7 A. N+ x
  16. LED ---|<|---[===]--- VCC
    ! ?4 ]9 G9 w. F( c3 P
  17.            Red          330
    : z& a) h% I: J; D" I
  18. 6 c4 [9 \4 l+ C) T* z
  19. Fosc = 6MHz
    - e( @) n, P, K& L
  20. */
    6 r  T4 Q) B2 t( Z

  21. , z4 U: \( ]$ @5 H

  22. ; E9 a; Z+ ]+ p
  23. // 矩形波输出脚
    * F& u% [* }  _. x+ Q% E
  24. sbit OUT = P5^4;
    " J. m8 Y" |$ |
  25. // 低压指示灯引脚6 |1 |6 y/ K- W1 n+ }' d
  26. sbit LED = P5^5;
    & i0 r! b4 \  Z* B# u8 a
  27. + P% d$ T* }6 c# f9 i6 t
  28. // 停机标志位
    4 S( c! q5 {: T- C  v" R
  29. bit isReadyToHalt = 0;
    0 T% U7 D9 x0 V# D% E( L/ v
  30. - S5 L3 M3 i9 ~" O; ?# S1 g
  31. // 矩形波次数累计9 N% g2 w: o; A  ]/ J+ f" N
  32. static volatile unsigned char count = 0;
    : ]) Z; J2 F6 g  u- d1 ]  r

  33. 9 x0 K0 [, c# a* u8 s4 H) x# @" T
  34. 6 n2 @. ^3 L# b0 Q0 f' d
  35. static void GPIO_Init(){
    " z, k* H' q. h) C9 c8 D  h
  36.         // P3口设置为准双向,默认靠内部弱上拉输出高电平/ X$ C) b/ S$ M6 C  C
  37.         P3M0 = 0;
    % o% Y7 n& p7 Z
  38.         P3M1 = 0;0 A& P9 t5 ], |% [5 V0 y
  39.         P3 = 0xFF;/ q* f$ N# f( W$ e
  40.         // P5口设置为准双向,默认靠内部弱上拉输出高电平1 w  R' Z! w8 _, _5 D( s9 q
  41.         P5M0 = 0;
    ' O" Z$ H2 {" x, \- _% `5 O6 @
  42.         P5M1 = 0;
    $ Z' E+ W4 ]- U" r: T: _" T
  43.         P5 = 0xFF;
    3 S9 a; R  @" S1 V# }' y' W. t( w- Y
  44. }
    1 G# M- P$ e# Y; ~
  45. 6 v& J' J6 _) F# M
  46. static void Timer0_Init(){  t0 l; |: h# R$ C) l
  47.         // 16毫秒@6.000MHz/ E9 U" h- I0 ~  _7 Q# P9 u
  48.         AUXR &= 0x7F;        // 定时器时钟12T模式  y. o# Z/ b8 f: k7 X4 Q( _) m
  49.         TMOD &= 0xF0;        // 设置定时器模式
    " B: [3 t) I  Y3 ~" T
  50.         TL0 = 0xC0;                // 设置定时初值
    5 y+ j) x5 W" z: Z( U
  51.         TH0 = 0xE0;                // 设置定时初值; E6 B2 i  ^% N2 j/ y  X
  52.         TF0 = 0;                // 清除TF0标志
    ) Z0 X+ [0 j  |+ U; ^( _& J7 _! q
  53.         TR0 = 1;                // 定时器0开始计时
    % }" Y( H9 ~8 [( `6 u" f
  54. }/ {0 i1 `4 f+ G

  55. ! m' u  i" [0 c7 u- u; _
  56. static void Interrupt_Init(){/ |# K# f$ U1 j- E% @( G
  57.         // INT0中断触发类型为下降沿触发
    * p2 ~$ M# V0 I  I
  58.         IT0 = 1;
    5 f0 G# ^' @, Q$ n* o' X: Z
  59.         // 允许INT0中断1 j2 X% a( D* S2 Q$ z1 ~
  60.         EX0 = 1;
    , x4 i- W' z7 T& S# H. x2 s& v
  61.         // INT1中断触发类型为下降沿触发, C4 R# R3 w) c' x! V- z0 x6 Q
  62.         IT1 = 1;
    2 }& o! G& \% a. d0 Z/ @
  63.         // 允许INT1中断) s- J3 R/ [  `( n9 B( s
  64.         EX1 = 1;( @( ]- c2 I: l' S& ?. n6 `* o
  65.         // 允许定时器0中断
    # C5 H  W3 v( u" I& _
  66.         ET0 = 1;
    0 v0 u$ J( g9 e( c2 C, h+ Z
  67.         // 允许全局中断
    & D; R& z7 R" P3 u" u2 {" \0 ]
  68.         EA = 1;
    6 P- H: c$ o& Z5 [7 I
  69. }
    1 c- [! r% U* {
  70. & Y: U- K9 K: L  |0 M; c
  71. static void INT0_Isr() interrupt 0{
    $ @) ]7 B* `' w5 f/ C
  72.         // 矩形波次数累计归零
    * w- L  @6 V' ?
  73.         count = 0;; m9 L. x& @6 L, I* ~! _9 P
  74.         // 重开定时器0中断  ~* R4 o+ n9 s5 @! P
  75.         ET0 = 1;
    ! Z7 E/ l4 u# l; t' X7 x
  76. }
    " Q; ~: v, t. h3 l
  77. / C! e0 s2 r' h/ R( }  C
  78. static void Timer0_Isr() interrupt 1{
    0 f$ \% n! [$ t- a- I, u
  79.         // 输出矩形波
    8 ?8 D5 n6 |; m+ y
  80.         OUT = ~OUT;) Y/ x: v  o5 S1 I3 I( J
  81.         // 累计矩形波次数$ S* W  ], ~8 }. {9 K) C
  82.         count++;
    / g$ [2 }& b0 ?) u; @
  83.         // 超过250个矩形波,准备停机( Z  @5 f3 i! T' w# ?& `
  84.         if(count > 250){
    5 D+ W: N( b+ f+ e% c
  85.                 count = 0;
    3 s6 q$ ?3 k9 B* c; i
  86.                 isReadyToHalt = 1;1 g+ x; K# x- f* {7 V6 L
  87.         }; \. g: c5 ~6 X9 C6 x2 G) Q1 A
  88. }1 Z* u6 V4 B7 K# `( d+ Z* e, `$ \! |

  89. 3 {5 p1 [2 e6 I) {4 s
  90. static void INT1_Isr() interrupt 2{  n1 U5 J2 B1 [9 [' Q$ C$ ?
  91.         // 矩形波次数累计归零
    2 a' e7 `" F2 ~  ^
  92.         count = 0;
    - z2 c6 `, k8 i8 S0 A
  93.         // 重开定时器0中断
    - H6 q  [7 p! h; q3 A
  94.         ET0 = 1;# o2 U6 i8 H5 e
  95. }
    + G* A: ?# t* L: f0 X
  96. % {  V% i( v! {) X6 ^6 z/ B+ ~
  97. / n* Y0 r! O0 c4 V% ]: L% ^
  98. void main(){
    % `) s6 R- j& J# v9 |2 w9 T0 ]" y: Z
  99.         // 初始化P3和P5口
    1 x1 h$ ^! S9 c' r6 C4 O6 }
  100.         GPIO_Init();+ y) l: ]" v) z0 P! ?
  101.         // 初始化定时器0  Y0 `1 ]/ v: Y  g# v8 `% l
  102.         Timer0_Init();
    ( r( @: X7 H$ I# n6 S% F! s. Y
  103.         // 初始化中断; D, x4 m1 }7 f
  104.         Interrupt_Init();7 |# i7 u1 I7 F, p
  105.         2 ^# }* Y+ K0 @2 B
  106.         while(1){
    2 `  C0 U$ g1 s; |! T6 A) r$ r' e* K, C: {
  107.                 // 检测电量
    6 [* n: y  c" q, z7 W( m" `
  108.                 if(PCON & (1 << 5)){
    . K" p4 c" }9 I$ U7 e7 V9 V
  109.                         // 如果电量低,低压指示灯亮7 u: D5 ^1 L) W+ c- i
  110.                         LED = 0;
    ; s" ], s3 c& }8 a; L
  111.                         // 清电量检测硬件标志位9 D$ X1 p% D1 X
  112.                         PCON &= ~(1 << 5);2 v: \0 {4 {# U: U
  113.                 }else{
    2 J- ]  c% z* m
  114.                         // 电量正常,低压指示灯灭
    ) M5 D8 }* k7 v2 Y4 T2 c
  115.                         LED = 1;
    7 T1 c) d2 `& y! i9 |
  116.                 }. `  ~+ o  F5 }% j2 m: g- C

  117. ) K# H, Z0 N1 N& S7 {7 _# Y. Z
  118.                 // 检测到停机标志/ b6 b- \+ O' g8 P' }+ |
  119.                 if(isReadyToHalt == 1){
    4 Y8 t; b4 d  x+ P3 K1 u8 J) e
  120.                         // 暂时关闭定时器0中断% n$ M' V& G( m
  121.                         ET0 = 0;; q: ~7 z, j( P# I
  122.                         // 停机之前先把矩形波输出脚置低电平,以方便INT0和INT1唤醒CPU8 b* Y4 s" e" \7 N8 G1 X% N
  123.                         OUT = 0;
    + a2 c1 D4 Y# u% h* @
  124.                         // 停机之前先把低压指示灯灭掉,以省电/ H9 I' v3 Z) v/ D/ V/ e$ S9 N3 |0 Y
  125.                         LED = 1;
    9 g% c7 `5 I# l  K. }5 e$ Z  |6 n
  126.                         // 进入停机模式+ q) |( E3 V* G$ }
  127.                         PCON |= 0x02;8 N% p* O4 F- J1 }# D  ?
  128.                         _nop_();- p! A, C1 A+ p, A3 R
  129.                         _nop_();: @+ s* K" C  E4 A8 J
  130.                         _nop_();/ B# J' e! d+ M  ]' g3 f; E# |7 i& K
  131.                         _nop_();
    3 d  W0 s0 t) b6 }0 P5 a
  132.                         // 唤醒,清标志位) \2 |# Q5 H# `( B& Q
  133.                         isReadyToHalt = 0;
    / y: |" X# G  v% j5 ]6 B  |; r
  134.                         // 重开定时器0中断$ v- \3 i+ h3 ?& h
  135.                         ET0 = 1;1 j; S5 }2 @$ r2 `
  136.                 }
    * [  J* @. Q( e, r
  137.         }
    # W; l1 ^+ S4 a
  138. }3 i: @6 V% Z; f" j
复制代码
! a3 o* N( h% y) q7 R- o1 t& m* Y
硬件参数配置:# f0 _: {! V1 d2 @6 M

1 Y$ H, g9 P7 J1 Q
4 E7 M9 u) n4 a6 J" C" n5 t- X接收端:; u# I2 D6 X4 Q; l. q6 \
  1. #include <INTRINS.H>
    ( `: v: b' l6 Z, l0 `
  2. #include "STC15W.h"
    ! F1 O" L6 ]7 y3 l% K8 l

  3. ! @  s7 |6 M$ |( ]8 {
  4. 9 j, x) R/ [0 W# t: }
  5. /*
    , `/ p1 D' m& a' j8 X
  6. 2 [0 N2 d7 ?6 R) B) h
  7. *---------------------------*$ ]) l$ U6 S% I
  8. |1 (GPIO2)         \__/  (GPIO1)16|
    * Y# J9 I3 w4 L/ o, i* l: O& W* ?
  9. |                                                        |
    5 U5 O( |$ z4 O+ W# R. i4 y1 q
  10. |2 (GPIO3)                   (GPIO0)15|0 l3 J/ f+ o% o8 T" @- P% ?
  11. |                                                        |8 {- ?: |) y* d0 C. z
  12. |3 (GPIO4)                                  14|
    # m% O1 B1 {- a
  13. |                                                        |, A! q& u% I; l" y* j6 Z
  14. |4 (GPIO5)                        (DATA)13|
    : t; O. t- l0 w- }/ k+ V) N
  15. |                  STC15W204S                |0 a6 ~( |( c' R  |% b$ e
  16. |5 (GPIO6)                   (LATCH)12|
    ! u. m$ V+ e1 _+ z
  17. |                                                        |+ O) z8 s/ o- X4 c! N
  18. |6 (VCC)                         (CLK)11|
    2 a$ z6 o* H' ?4 o5 b
  19. |                                                          |# r+ r( i4 T3 J. d1 A0 m' x
  20. |7 (GPIO7)                         (TXD)10|
    , d7 B/ s  m5 [1 Y" ^8 U
  21. |                                                        |
    9 t0 h1 L6 {' d+ [7 s, I. h" i- L
  22. |8 (GND)                         (RXD) 9|
    + i3 x3 d1 K, w$ O
  23. *---------------------------** D( D, w% G: F& C
  24. Fosc = 12MHz
    5 r4 _0 q/ ]7 k8 R* d! i" M. @% U" }
  25. 4 g; @# a: C* q% ?: \. ^, o9 y
  26. P1.0 -> 上
    7 w7 Y" j  X- E9 R
  27. P1.1 -> 左" h7 |2 _( t' w+ l6 Y/ W' n
  28. P1.2 -> 下7 R, C8 o" Y# J# \# D3 G
  29. P1.3 -> 右
    3 @6 e& x% F- i4 S0 w( S
  30. P1.4 -> SEL( ~) P) V" t$ J! Q( `$ M5 D
  31. P1.5 -> STA
      }& H1 O0 w9 ^
  32. P5.4 -> B4 F5 e  J5 K# Q7 c5 T5 \. b
  33. P5.5 -> A
    2 ?! f$ H: W$ e5 s
  34. / Z  h# N8 o: O3 l! p
  35. */
    , a; U+ E( F& C6 h  W8 ]6 L% y6 R3 `. i
  36. 4 V- O" P" U; {5 m  O
  37. 8 m* K- G% j" ~9 i
  38. sbit CLK        = P3^2;
    / ^5 ?" I& z* Q! G: \! [
  39. sbit LATCH        = P3^3;! P% F% I2 b! _  [% U$ H6 F  k
  40. sbit DATA        = P3^6;$ D8 t; O1 Y* z8 S! b8 m
  41. 7 N; }& z4 |2 H
  42. bit isReady = 0;
    $ u9 I3 Q2 z& k5 B3 [( s2 U; l7 A
  43. static unsigned char key = 0;  R2 u; B: ?5 R3 y" q% c8 B0 T/ b" s
  44. static unsigned char buf = 0;        // 双缓冲。这个缓冲区保存从P1和P5组合而来的键值
    7 ^) W0 `& }. ~+ e" Y  y1 ^' P
  45. static unsigned char bufReady = 0;        // 双缓冲。这个缓冲区保存上面那个缓冲区的备份
    9 Z. x% ]  S8 m, ~4 p  W* T
  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! ]8 R" A; O4 C
  47. static unsigned char idx = 0;
    & \0 k: K6 h& C) l* f

  48. ) t& W/ `1 X( h% H% K* G5 U

  49. " Z& o; _/ c) }5 `5 T. }( M
  50. static void GPIO_Init(){
    . W! i- E- K/ `( d# U. E9 L
  51.         // P1口和P5口用于接收并行信号,全部初始化为准双向,依靠内部弱上拉输出高电平
    $ c% ~6 Z1 \+ n  [& G
  52.         P1M0 = 0;
    / `+ g2 u6 O8 l. v
  53.         P1M1 = 0;
    6 L3 l, P2 ^# Q7 ~1 m! a
  54.         P1= 0xFF;
    1 Y& y, @2 P. X! N3 C1 i- h
  55.         P5M0 = 0;+ q( `( u) D! \: L
  56.         P5M1 = 0;
    6 z( R0 v- i) \0 ]& u' n- O
  57.         P5= 0xFF;
    2 ]$ K. G5 u, Y
  58.         // P3口初始化为准双向
    $ t  J+ D6 U$ B( O3 k
  59.         P3M0 = 0;
    - |; ^# j+ F* W, O4 a
  60.         P3M1 = 0;
    - {0 U  G5 r9 `2 @
  61.         P3 = 0xFF;
    3 m1 I7 r8 `/ c5 \' G
  62. }- @) }  Z1 D6 q" `4 g( Z7 m

  63. 5 z: O; @# ~0 L5 G7 O
  64. static void Interrupt_Init(){, \6 B. v3 I) K, D
  65.         // INT0中断(CLK)触发类型为上升沿+下降沿
    ; q8 p' Z! q1 z. r; t, h
  66.         IT0 = 0;9 _' r" T6 l$ H. Y( R2 u
  67.         // 允许INT0中断
    ( B. z( i, W6 m7 }: k, P; X
  68.         EX0 = 1;
    . F3 h: N7 L0 h9 j2 m
  69.         // INT1中断(LATCH)触发类型为上升沿+下降沿$ v1 r# a7 ]8 R
  70.         IT1 = 0;: U! G" R8 ^. S+ _: m4 ~: s
  71.         // 允许INT1中断
    : C& F* z+ @/ F/ }) }
  72.         EX1 = 1;
    . Z: u9 i$ l. b" O& ]1 N7 L
  73.         // 开启全局中断
    - T) x* N; W" l/ V
  74.         EA = 1;+ [1 r4 y' u" {# `
  75. }6 X, T) Y2 K1 R4 X

  76. / `% x% F( m0 M2 N% j0 \
  77. static void INT0_Isr() interrupt 0{
    3 R" C; ]8 [" [0 @# _' B9 Z
  78.         // 只有已经成功锁存才允许CLK移位
    8 c# `% C7 ^! n# x, M/ B, P8 g1 |5 P( n
  79.         if(isReady == 0)
    ; W% a+ R4 s! ~" {2 Z6 d
  80.                 return;8 ^! p5 e! G8 ~# t7 L0 Y' o
  81.         // 读当前引脚电平,如果是低电平则说明是下降沿,此时直接忽略该中断1 a, Z7 C0 K$ b2 ?( |+ y
  82.         if(CLK == 0)3 d. @% X& E8 ]- a1 n
  83.                 return;+ }0 p! w- x( w9 |( T
  84.         // CLK上升沿到来的时候,取锁存值的下一位输出
    6 o/ r5 z/ {5 Y
  85.         idx++;
    ( D* d5 U6 Z' _" O
  86.         DATA = key & mask[idx];
    . p! p. E: d6 Y! k0 `  r3 n
  87.         // 如果已经完成7次移位,则一轮读取完成  j; ?% N9 w5 z% Y, T2 X7 `( p
  88.         if(idx >= 7)
    ( i' R' ]0 W& W& j9 o  s
  89.                 isReady = 0;
    $ I& e, H/ J  S: R5 Z9 x
  90. }
    5 s: J3 o& N  c

  91. . b2 U* ?+ F. v, |7 |! t, |
  92. static void INT1_Isr() interrupt 2{) W5 M0 |7 m/ G% ]# q
  93.         // 读当前引脚电平,如果是低电平则说明是下降沿,此时直接忽略该中断
    : b# V% d9 ?) K2 F# x7 X
  94.         if(LATCH == 0)
    ) z0 ]) a2 Y) q2 F7 s. l9 F) D$ z
  95.                 return;
    % m" u3 ?% Q6 j1 I' y* e4 \
  96.         // 当LATCH上升沿到来的时候,锁存所有按键状态,同时把键值A输出到DATA
    3 U) V, l6 ?; _* C$ p$ {
  97.         key = bufReady;- T7 n9 P0 j. h
  98.         DATA = key & 0x80;//mask[0];        // 为了加速运算,直接取表中的值而不是读表: M+ t' O1 H! C  w
  99.         idx = 0;
    9 S6 G& y, M$ M7 h  w1 O) l
  100.         // 允许CLK进行移位
    # J+ e8 a% [+ z
  101.         isReady = 1;: @7 K7 ^: Y( z
  102. }
    5 O- S, N4 G. J4 |' a
  103. + b' i: I' {1 U% K2 L
  104. void main(){
    ! p' ?% o0 M' n3 u& q! c
  105.         GPIO_Init();0 B6 @* ]" {' ?& z+ o4 _
  106.         Interrupt_Init();: B+ @$ e) Z8 P8 P8 @2 D7 U7 x
  107.        
    - [" T. @) z$ {% y1 Y5 ?
  108.         while(1){5 f0 x# Y! Y. }' [' J7 T
  109.                 //PCON |= 0x01;        // 进入省电模式
    5 A# B6 M3 x' K' r8 x$ ?5 C. t. ]7 T
  110.                 //_nop_();
    ' _. }$ h6 G% i, ]2 k
  111.                 //_nop_();% t/ R0 u+ c  @- N$ k2 E% V
  112.                 //_nop_();
    7 |0 H$ Z4 @8 z9 [
  113.                 //_nop_();, E) S5 m/ W$ m9 \+ |: z
  114.                 buf = ~((P1 & 0x3F) | ((P5 << 2) & 0xC0));$ c. l* u/ C* r# Y7 _
  115.                 bufReady = buf;
    # m7 }* E; z. K# v
  116.         }: G. i7 r2 }& V; ~
  117. }
    : `6 O& N+ \: D# w7 X: L9 y/ ^' `
复制代码
! V, K* w7 Q1 j
硬件参数配置无特殊要求,晶振频率选择12M即可。1 g( @1 Y3 T3 K  k3 g

) c/ I4 y5 _1 b1 ^- E. H0 c7 f8 v( U2 u这是编译好的固件。

本帖子中包含更多资源

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

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 D/ O; p- q3 P不错的设计,想问一下楼主,FC的15针公头怎么解决?普通的公头太短了,插不进去FC的扩展接口。 ...

) b: X# i, t! p0 q& i2 i坛友的改造方案
回复

使用道具 举报

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

使用道具 举报

发表于 2019-5-25 12:07:18 | 显示全部楼层
精彩,楼主动手强,也写得很详细。
8 ^' |5 k) k# }8 {0 c  I2.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/ _+ ?+ O# m; [$ F" m
精彩,楼主动手强,也写得很详细。9 J: X2 L8 [4 R/ \
2.4G方案是目前无线的最低延迟吗?

1 h( z. T3 }# ^$ g" K' I- n5 p我没用过其他无线手柄,所以实在不知道我自己做的这个手柄到底是不是最低延迟。+ K' ]" K! l4 A6 V
不过根据网上的说法,延迟高低主要是由通信协议的复杂程度,以及数据传输速率决定的。这个模块虽然是2.4G无线模块,但由于协议很简单,所以延迟比较低。& R. }. `9 D4 Z$ `" R: I
我用这个手柄玩一些ACT游戏,比如超级马里奥、忍者龙剑传、热血系列,完全感觉不到延迟,和游戏机自带的手柄没有任何区别。唯一的区别就是这个手柄是用火花山寨手柄改造的,外壳是垃圾回收塑料,粗糙+脆弱,导电橡胶弹性不佳,手感不是一般的差。  Q) U; Q7 C- l1 t% J4 Y) w" l( ^
我手里还有十几张板子,等我有空了我再做一套,到时候买一个好一点的手柄改造。
回复

使用道具 举报

 楼主| 发表于 2019-5-29 16:56:14 | 显示全部楼层
ppad 发表于 2019-5-28 17:275 r& Y1 V. B1 Y+ x" F# Q
给技术帝赞一个,有半成品发布吗,自己焊接改造就可以,编程实在不会啊 ...

8 Q0 ]/ g4 U- H很可惜,我手里没有多余的单片机了,LDO也找不到了,锂电池以及充电模块更是没有了。反正就是该用到的元件基本都没了,所以没法发布半成品。
3 C9 v9 [8 I) E两个板子倒是有十几张剩余。
" i; Q! C4 ]1 j% V) |* ]4 \8 n你要是有USB转TTL串口板,完全可以自己买这两种单片机,然后我给你编译好的固件,你自己用串口板下载到单片机里面就行了。两个2.4G无线模块也得通过串口板用AT命令设置参数,不过好在我在设计电路的时候就已经预留好了串口,可以直接在线下载和在线设置参数。总的来说并不麻烦。
回复

使用道具 举报

 楼主| 发表于 2019-5-29 17:00:34 | 显示全部楼层
孙大师 发表于 2019-5-28 18:55
! O+ L; X! r0 e( ]0 R! F, p' u非常好,楼主是技术帝,到目前我都还没开发fc的无线套件,等空了,开发一套套件,等玩家自己组装。 ...

$ @2 j/ D5 e2 v5 _* o* w. J能得到孙大师的赞誉,不胜荣幸!& v- L$ N+ v% e* r
不如开发一个多功能手柄,比如用SFC手柄改造,L/R键配合其他组合键可以用来切换2P~4P、调节连发速度、软重启等各种功能。接收端插到15PIN扩展口。
回复

使用道具 举报

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

本版积分规则

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

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

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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