找回密码
 注册

QQ登录

只需一步,快速开始

查看: 26718|回复: 33

自制FC无线手柄

  [复制链接]
发表于 2019-5-22 14:16:45 | 显示全部楼层 |阅读模式
本帖最后由 雷精灵2046 于 2019-6-14 09:28 编辑
2 `. A, F0 B* d; x' R% s& m" b0 j% h8 K: A% n5 Y
没有用复杂的分立元件搭建发射接收电路,直接用的现成的2.4G无线模块jdy-40。
, f+ Y1 i; O& k/ b9 @6 V
# c1 F; q) O  ~- V7 l0 ~, V- M- T3 _( K  j  Q
发射端靠3.7V锂电池供电,用了一片SOP8封装的STC单片机,负责产生连发脉冲,同时负责检测电池电量,电压低于3V左右的时候触发低压中断,低压指示LED就会亮起来告知该充电了。平时发射模块和单片机均处于睡眠状态,有按键按下才会唤醒,从而实现省电。实测睡眠状态下整机电流约1~2uA。板子洗了一下稍微干净了一点。因为对于微功耗设备来说,焊接残余的助焊剂可能会增加漏电流。. L5 S: @; U, B/ Y
" J& Q# a1 b0 A1 W$ m; J
买了一个火花的FC山寨手柄,去掉里面的牛屎板子,并修正一下塑料挡板,把锂电池和充电模块装进去。  U# X7 m: p4 h; R% F
为了减少体积,充电模块裁剪得十分小,并且更换了充电电阻使之适应这个小小的锂电池。这么小容量的电池,也不需要多么大的充电电流是吧?- a1 F9 o/ e+ E- d& _0 c
然后统统用热熔胶粘上。充电电流比较小,所以发热很少,不会熔化热熔胶。
* e: u* x& w1 H$ J* h. Y, x& L: e3 L0 n
* w- Z% r3 h8 ~4 M
2 e. z& K9 j, |3 T; C  n. z7 i2 P( U
最后把按键、导电橡胶和电路板装上去。
- M5 @2 l3 U7 Z9 i- e精心裁剪了电路板,正好扣上,不会阻碍其他元件,也不会影响后盖和拧螺丝。
- c" Y! f, q& Q- v0 u
5 {& j6 x, W* p2 I4 \% [" q8 \4 `" T$ @1 S
完工!9 ~7 Y, t% c2 @: A' |% v7 }
  j; g; ?: q, T, ~, z* y: j- y2 V/ m
/ n2 `* x! q9 a2 a& J  R
这是充电的MicroUSB插座。旁边的小孔用于透出低压报警LED的光线。
$ Z/ f2 h  t" @# W% e% i' d% H8 q( L1 b, I& J- m, L: r3 x9 h

1 E3 ], k  |3 C0 Y9 q! j4 m接收端用一片DIP16封装的STC单片机模拟CD4021。为啥要用单片机模拟而不是直接用CD4021?因为jdy-40模块接收端在有按键按下的时候输出高电平,无按键按下输出低电平,和普通手柄正好相反。当然我也可以用两片74HC00或者74HC04之类的逻辑门进行反相,但那就增加了芯片的数量。对于FC手柄这种工作频率并不高的设备来说,STC单片机完全可以胜任模拟工作。
) n+ J0 e; p( R% U: B5 B& _& [. S5 T% B4 Q# H* N" B

: Q  _' A0 I8 K# W% ~
5 S. B. w4 D& a2 c电路设计有点小小的错误,所以有几根飞线。原本设计使用低压差LDO是XC6206,结果在做这个接收模块的时候,买的LDO居然找不到了!无奈只好用了AMS1117。幸好对于接收模块来说是5V降到3.3V,1117可以胜任。要是发射端手柄的话,3.7V降到3.3V,那就非得用6206不可了。
- L- r0 E6 E' |$ H* @
9 M8 h2 a) y. _实测十分灵敏,延迟极小几乎感觉不出来。可惜这山寨手柄的手感并不佳,尤其是方向键,软塌塌的。看来我得买个剪线手柄改装。: G6 u) Y- o5 ^/ Z, i

0 m4 g1 R: G$ Q+ e2 f这是电路图,有兴趣的朋友可以参考。
/ p7 g$ a" \1 X8 T# c/ H
% A6 n2 w5 x8 d5 v# \+ y8 B' F
* m; D; C8 }% {: g我信奉开源主义,十分痛恨把技术藏着掖着。好东西大家分享嘛!所以两个单片机的源代码大公开!
% C2 j8 z; b. J' Z$ ?3 y0 q编译器:Keil 51。* }7 V% J2 j5 n, A1 N- D/ o
5 z7 |8 l, [; w9 j2 [! {9 ]
发射端:2 f. P& b  w, [2 J5 L' l
  1. #include <INTRINS.H>
    % m$ }8 Z$ a$ F/ L" w. o6 p
  2. #include "STC15W.h"1 \1 ]- @- }. [% _$ z

  3. 5 L- J- X. x4 a
  4. & `9 W8 J/ Y5 ~6 ?6 c
  5. /*
    6 F0 b& E5 _! J  k1 x, ]$ y
  6. --------------------------, M- d& g& ~0 b2 R* J
  7. |1 (OUT)        \__/   (INT1) 8|/ a6 t0 C7 ^8 n1 Z
  8. |                                                   |" S0 I6 \8 T+ r' h" M# {$ P
  9. |2 (VCC)                   (INT0) 7|% D/ R: H' K6 `
  10. |                 STC15W204S                   |
    / e" k) [  G  p
  11. |3 (LED)                         (TXD) 6|) p4 M9 I4 x2 F( V. H8 L
  12. |                                                   |
    # Y9 F+ H& T7 z
  13. |4 (GND)                         (RXD) 5|
    & _1 [, x; v: v
  14. --------------------------
    & j8 j) ^. Q; a5 H5 K: t* z

  15. ) o; ^- ~/ g& t5 R: X
  16. LED ---|<|---[===]--- VCC
    0 L" s! [7 T8 e7 n4 m
  17.            Red          330
    ! P% L+ h/ K: R) X" W

  18. # D9 D- K( U+ K8 _4 i
  19. Fosc = 6MHz8 S/ ~3 h5 w3 s8 g. a  J1 v. J, a
  20. */
    . E4 p/ ^1 a& |$ o+ u# [7 K

  21. / L7 W( a% `+ V1 O' \+ C

  22. ; x4 ~0 N9 S6 q0 d* e% B
  23. // 矩形波输出脚8 N$ B* r; I$ w8 \
  24. sbit OUT = P5^4;. p8 @- T; |6 I2 ]  x* g3 Z& }
  25. // 低压指示灯引脚
      C$ C1 \8 F; O( \/ L& g
  26. sbit LED = P5^5;
    5 ], V0 H; z  d9 @  x( W
  27. & B* V' R% _2 y5 c( P5 ?3 @! m
  28. // 停机标志位# f) T6 |& _, S& }5 l7 r8 _% ?
  29. bit isReadyToHalt = 0;: N, w9 K$ j7 t! O9 W
  30. : g" c6 {: D6 n6 n) N
  31. // 矩形波次数累计
    4 K. Y& ]* {2 v: B  R
  32. static volatile unsigned char count = 0;
    . }; _  y7 Q! f' z6 a
  33. " b4 v7 W8 C7 o! F: x
  34. 8 u- O) [: q7 v/ v2 s
  35. static void GPIO_Init(){7 R5 h. N, T+ e  O  D
  36.         // P3口设置为准双向,默认靠内部弱上拉输出高电平/ e/ {- b1 ]5 u6 o' H4 m3 q% r
  37.         P3M0 = 0;# e  p; f7 E4 a) p8 L
  38.         P3M1 = 0;
    & H+ G. T2 f1 X$ I8 U) }8 E. K/ k
  39.         P3 = 0xFF;
    5 k! R7 T0 w1 `4 N" H
  40.         // P5口设置为准双向,默认靠内部弱上拉输出高电平  A: S' p) n9 O9 p, v$ `2 l1 E
  41.         P5M0 = 0;1 X  H4 I) z' F8 B- j- l
  42.         P5M1 = 0;+ n4 Y$ P1 X. W+ H' {) V' F
  43.         P5 = 0xFF;
    5 k% r4 C5 h$ l, ~0 w
  44. }
      h' P; u4 ?1 O9 K! p0 X" o. s
  45. / H/ G: r* c/ B4 ~5 v0 `
  46. static void Timer0_Init(){
    ( ?; F5 }* r$ s6 G6 ?8 Z
  47.         // 16毫秒@6.000MHz
    1 Y6 Q5 ?% ^/ G$ O2 W( ]' C! {
  48.         AUXR &= 0x7F;        // 定时器时钟12T模式! _# f1 x$ y# S& l2 s" n
  49.         TMOD &= 0xF0;        // 设置定时器模式
    2 `+ A3 c9 A) I2 I$ a4 c
  50.         TL0 = 0xC0;                // 设置定时初值
    $ _- c  K- n4 J- K7 |' ^' }
  51.         TH0 = 0xE0;                // 设置定时初值7 X7 u( x" i5 f
  52.         TF0 = 0;                // 清除TF0标志
    7 A" ^2 {  A  U5 ~4 Y% s# w. b
  53.         TR0 = 1;                // 定时器0开始计时' k" C# C4 W5 _- ^. d9 Y" \2 |
  54. }  h& Z! x, q& B, l  g9 _
  55. & M9 p  @1 v% a. d9 m& t
  56. static void Interrupt_Init(){" [3 e& I: w9 t. Z, N1 O( `( o, U* {
  57.         // INT0中断触发类型为下降沿触发
    1 N" |9 Y* i2 t0 f2 [- K( Q6 P: ?0 Q! x/ Y
  58.         IT0 = 1;' {; j+ k- S" R+ S
  59.         // 允许INT0中断
    ' B0 v3 z. t2 D! {5 F: e
  60.         EX0 = 1;
    2 X3 @, I" z7 f; ]
  61.         // INT1中断触发类型为下降沿触发+ V* ~8 q0 a6 M- A) r3 n/ P
  62.         IT1 = 1;
    ; p, [1 F! d1 |: K8 S5 j) M) a
  63.         // 允许INT1中断
    + G- s! V& f5 Q* |
  64.         EX1 = 1;
    5 u: I. q2 u! c  E- M  o; j8 l( Z
  65.         // 允许定时器0中断
    7 C- `" f& v+ b: g1 r
  66.         ET0 = 1;. m5 J# Q. ~! f2 G! Q8 |4 f' J
  67.         // 允许全局中断* _5 h- t" _9 B' b; ]% o
  68.         EA = 1;
      ?  o+ i* \2 x& q, A/ r
  69. }) s7 ?& s% r* Q' J- p/ X

  70. , `! S, S) t& W4 K+ ^7 ?& u
  71. static void INT0_Isr() interrupt 0{
    6 j# U' C* D9 E6 M2 G
  72.         // 矩形波次数累计归零
    9 W; d  p' r& h8 m: ^
  73.         count = 0;
    7 W4 b1 F6 z9 m' |
  74.         // 重开定时器0中断+ z7 P9 W* o" J% M( V; V. U. W
  75.         ET0 = 1;# Q5 P  v$ u$ e8 M, P' L# ?
  76. }
    ) ^8 N3 R3 o+ S5 @# J
  77. ; }% W5 }1 j2 D- f9 k9 c
  78. static void Timer0_Isr() interrupt 1{
    ; O3 V. f- S8 E- T2 d
  79.         // 输出矩形波" L# c) r3 _0 Z$ ]7 R0 N: P: k3 K' h" Y
  80.         OUT = ~OUT;: Q; t3 a' c6 K
  81.         // 累计矩形波次数+ N5 H5 u# W" `
  82.         count++;
    5 G; k5 |' K+ m' r! r, @1 m5 u
  83.         // 超过250个矩形波,准备停机
    3 l. K3 J1 v9 E% I
  84.         if(count > 250){
    8 f+ P& C& n& p& I
  85.                 count = 0;
    6 e* O! B4 D) }$ Z
  86.                 isReadyToHalt = 1;
    ! k3 ]9 R7 n+ u& p) U
  87.         }
    7 Q" _6 N$ @* E# N2 }9 @/ \
  88. }
    ; \& j0 p( r. i& }/ `

  89. 6 C7 X. y5 _/ u3 f( D. Z# p$ o
  90. static void INT1_Isr() interrupt 2{+ E. M- t4 ?" m' _* y) @
  91.         // 矩形波次数累计归零
    ! }3 ?* M2 S8 S
  92.         count = 0;
    # @- M$ T2 h* O' a- a
  93.         // 重开定时器0中断
    ( I6 Z2 }# r9 U: U% v! Z$ ?* M
  94.         ET0 = 1;
    9 m. l# V& J  t. p
  95. }
    ; s; a6 D9 l+ k

  96. " ~9 f- ?* e* \
  97. 4 k  I( q6 Z" w0 y4 o+ D
  98. void main(){/ h$ M# [  C7 @' ^* b" q! R* x
  99.         // 初始化P3和P5口0 n, N7 n; ]6 n7 `/ Q+ x
  100.         GPIO_Init();5 T. Q* k' Y) {1 @) ]2 u; n* {: r' E
  101.         // 初始化定时器0
    ; S" ^/ H: h& N- r6 C9 t
  102.         Timer0_Init();) Q+ P4 w! j2 A5 ^, M; F
  103.         // 初始化中断1 n9 Y8 B+ F) Q' V
  104.         Interrupt_Init();5 q- ~& \" s* V- Z
  105.         * Z& E8 t; l! e" Q: }
  106.         while(1){! s9 p0 h1 U  Q4 f, V
  107.                 // 检测电量* a/ q4 ]" w' @0 f% {' d
  108.                 if(PCON & (1 << 5)){
    2 e" t% `+ V7 C( r; }6 s  o
  109.                         // 如果电量低,低压指示灯亮! J/ j+ S, }: {3 h
  110.                         LED = 0;* Y" ^1 }; q& ]6 h" }+ i+ e
  111.                         // 清电量检测硬件标志位
    8 ~3 g/ [8 i8 r5 b# }& M
  112.                         PCON &= ~(1 << 5);8 n; v: f, _) e% u  P) O
  113.                 }else{
    / S! s# I! g9 `9 n4 r
  114.                         // 电量正常,低压指示灯灭, G: Q8 E9 X4 r& t; v
  115.                         LED = 1;
    & F- ]: s: r# I1 _; T9 Q, V' M" S
  116.                 }
    7 T( H/ `, n3 P$ _) T

  117. : l  D+ K: U0 R& q2 }2 R& k8 t4 i
  118.                 // 检测到停机标志$ |4 p' H( C9 y4 z/ |
  119.                 if(isReadyToHalt == 1){
    # A" Q! J) w6 |  k- r/ h7 @! ?
  120.                         // 暂时关闭定时器0中断
    3 l$ E: Y! U2 v0 I8 u6 O
  121.                         ET0 = 0;
    " d: ?! p! S2 @0 M. t6 }: |
  122.                         // 停机之前先把矩形波输出脚置低电平,以方便INT0和INT1唤醒CPU2 n2 K, `/ [4 o6 R- N+ A
  123.                         OUT = 0;
      s* _# L: z( q- t3 U2 I
  124.                         // 停机之前先把低压指示灯灭掉,以省电
    7 y  K0 G# p% r* d
  125.                         LED = 1;. g) x  x( {' h& {" @4 y
  126.                         // 进入停机模式
    , v  W$ S. _; M+ Q: U) }. r
  127.                         PCON |= 0x02;
    ; Y8 U* p1 _1 b$ z* ^3 P& r  [& S
  128.                         _nop_();; y$ z7 n) b8 r6 |7 C
  129.                         _nop_();
    5 o) ]) G0 e6 W" ?
  130.                         _nop_();
    1 \0 S0 W8 P9 ~  s
  131.                         _nop_();- x) t+ @# f% j! I% T# o
  132.                         // 唤醒,清标志位
    4 r2 s" |, q' D
  133.                         isReadyToHalt = 0;
    ! o1 b. Q! W7 C: t
  134.                         // 重开定时器0中断
    7 B: M' g; `. |0 `" M) Q4 T2 m
  135.                         ET0 = 1;
    ( w8 {& j9 N; {8 X
  136.                 }
    " i* f  j( b. P0 q# j8 R  j3 B
  137.         }
      F7 _7 {# ~: |, p  Q3 u; r
  138. }
    6 ~9 R0 k$ k% h( X: y4 X0 P$ K" S- C
复制代码

! j- i0 ^8 `  a. @8 |$ n硬件参数配置:
5 _7 n+ T4 s0 q+ L; w! x; w4 I; m* k# L: {( h' K. p
8 T: E! x, c6 y* _6 g# c- a
接收端:
4 J% `& T- s/ a3 S+ |3 i$ s
  1. #include <INTRINS.H>8 a2 t& J% T# o/ `, V! d* T0 O
  2. #include "STC15W.h"
    ' t! B" J. A+ R
  3. / a, B# Y$ g% d" s: C: t
  4. * I6 S) x) l' ^# t' S- @( S
  5. /*
    * Z" `7 E, j; Q5 p
  6. + X7 q$ b$ E% q
  7. *---------------------------*
    2 _+ ?+ }5 }3 L  D. i& L$ E
  8. |1 (GPIO2)         \__/  (GPIO1)16|
    8 A+ O. Z3 U7 l  z6 K
  9. |                                                        |; E+ R: w: F4 y+ ?* \
  10. |2 (GPIO3)                   (GPIO0)15|
    7 R* ]% k  P/ S3 l5 B
  11. |                                                        |& l5 Z. K, z' B# A4 d$ d$ K
  12. |3 (GPIO4)                                  14|
    3 ^$ [1 J2 e4 {7 N: P' O' ]
  13. |                                                        |
    ; E+ A- I, ~3 m7 _% f
  14. |4 (GPIO5)                        (DATA)13|
    + a: B$ T- u# X- m5 E0 {' w
  15. |                  STC15W204S                |% O# v. f) T4 G3 |; j
  16. |5 (GPIO6)                   (LATCH)12|, e' T4 S$ A7 W! g
  17. |                                                        |3 T8 W& `& y$ q! m* W5 [5 _" T
  18. |6 (VCC)                         (CLK)11|
    % x. {5 Y2 ~4 _
  19. |                                                          |
    : O2 X: m6 E1 T9 {$ Z
  20. |7 (GPIO7)                         (TXD)10|
    7 v4 s* h  g+ J
  21. |                                                        |
    8 l* U2 ^! O0 ~# q( R+ {
  22. |8 (GND)                         (RXD) 9|
    , ^. [' P4 v5 |9 f" m: l
  23. *---------------------------*
    6 w2 x/ b8 M3 G2 e1 k) ^: O) S: Z
  24. Fosc = 12MHz
    4 C0 z5 p5 `  ~( P/ O. L4 V

  25. ! O7 l. e7 d6 Y' [* ~4 D! x
  26. P1.0 -> 上
    3 Z, s- P. Z) `# I# i5 o/ k1 t
  27. P1.1 -> 左
    " T5 f$ v: f/ g2 A$ n6 H
  28. P1.2 -> 下
    ( f/ e4 j! K0 v* t) ~
  29. P1.3 -> 右/ u9 o( ~5 }9 M. g- M; y
  30. P1.4 -> SEL
    5 j; q6 B: B& S  \. [8 E
  31. P1.5 -> STA
    2 Y/ W9 h  U0 U* p  u
  32. P5.4 -> B
    ! e$ n4 j8 p- q. g# S
  33. P5.5 -> A
    1 ~8 ]9 m  a5 ?3 ~4 z* Z- r
  34. * y# j( m9 D# u& z
  35. *// d& X4 M# I" t% {) C3 d
  36. ! P0 |' l0 i- r0 A

  37. . k, t$ o4 H# w
  38. sbit CLK        = P3^2;
    # h8 j  n, B- p) G. s$ p; W8 G
  39. sbit LATCH        = P3^3;
    1 F  U7 c0 M) i9 h( G, C
  40. sbit DATA        = P3^6;
    ( W3 Y, s7 L, Z8 i# \" V2 ^+ j

  41. $ ^5 s& Q- A4 y* i
  42. bit isReady = 0;
    ; z! {6 O' [# x1 K* X
  43. static unsigned char key = 0;: T- l% C7 `9 E% `( M
  44. static unsigned char buf = 0;        // 双缓冲。这个缓冲区保存从P1和P5组合而来的键值
    , b1 x# `0 l9 L. o. t
  45. static unsigned char bufReady = 0;        // 双缓冲。这个缓冲区保存上面那个缓冲区的备份
    % q8 p; a& ?( r
  46. static const unsigned char data mask[] = {0x80, 0x40, 0x10, 0x20, 0x01, 0x04, 0x02, 0x08};        // A B SELECT START UP DOWN LEFT RIGHT。为提升速度,这个表放到RAM中
    4 H: j( U7 B& P. j$ K
  47. static unsigned char idx = 0;+ Y) Y- o$ h; W5 _
  48. 6 p4 l. O: Y1 q' ?; _
  49. $ z& n0 ]0 G1 K
  50. static void GPIO_Init(){) h8 D- d3 M; l' U% ~$ Y# W% y7 O
  51.         // P1口和P5口用于接收并行信号,全部初始化为准双向,依靠内部弱上拉输出高电平
    . b2 b, t' _6 d0 s! |  ?, v
  52.         P1M0 = 0;
    3 V8 I8 V  _( ~( _
  53.         P1M1 = 0;4 ^$ f" Y$ U: ]4 p# ~7 O
  54.         P1= 0xFF;2 f3 m4 N% H0 z; _# x2 V8 Z# b
  55.         P5M0 = 0;3 I# H( e# y2 V+ ~
  56.         P5M1 = 0;
    & J. z* D- A( y& v
  57.         P5= 0xFF;
    0 {  q3 n0 d  h4 @0 i
  58.         // P3口初始化为准双向
    % s# Q/ @3 {- W% b
  59.         P3M0 = 0;& l/ ^4 O. N! Y7 X
  60.         P3M1 = 0;- F$ D, ]- _& |
  61.         P3 = 0xFF;* x; Y5 U/ u* `3 ~" O3 Y
  62. }1 p: P& d0 K' i/ O4 t% K+ ^1 m
  63. , d* c) }8 D& }- h
  64. static void Interrupt_Init(){  _+ U% a  R' _5 n4 \, u: K
  65.         // INT0中断(CLK)触发类型为上升沿+下降沿
    / O+ h8 [2 k5 ?( r/ `: q
  66.         IT0 = 0;7 q8 [* e) f0 F
  67.         // 允许INT0中断5 r1 x  h3 `/ O% F  x0 a, V
  68.         EX0 = 1;9 Y+ ^5 J6 D4 ?7 T
  69.         // INT1中断(LATCH)触发类型为上升沿+下降沿: _4 d) D- F* i  n! u( P* R; p
  70.         IT1 = 0;* P0 T& [+ e- K& d6 b
  71.         // 允许INT1中断
    ) n) V) G5 c. A8 o6 H1 g& T6 d
  72.         EX1 = 1;: w& I1 l0 A4 t  G: o4 L
  73.         // 开启全局中断8 d% ^& |+ V3 U7 l
  74.         EA = 1;. j/ j1 W' U+ X  h. b" }
  75. }
    $ H/ x8 b9 e& i$ w" E6 C; v
  76. 3 w+ F# n1 Y/ A1 ^% {* [$ i
  77. static void INT0_Isr() interrupt 0{
    4 Z+ z0 j, }* u5 C( Z. g
  78.         // 只有已经成功锁存才允许CLK移位
    . c4 H  N8 Q! h9 `4 l; e
  79.         if(isReady == 0)
    3 f5 J1 w5 o; B. M3 k
  80.                 return;
    2 P( v: b* C* X) |
  81.         // 读当前引脚电平,如果是低电平则说明是下降沿,此时直接忽略该中断9 c1 I$ z4 s. s" ^
  82.         if(CLK == 0)
    ( _! w4 j. S9 ~$ B  p1 O
  83.                 return;
    ' N& L% T9 |$ Q! R* e; o7 `' _
  84.         // CLK上升沿到来的时候,取锁存值的下一位输出3 o4 X" x( U$ `9 f. l* W
  85.         idx++;
    " @  t1 R" v- x7 x
  86.         DATA = key & mask[idx];
    , e' Y: v* _; q4 N
  87.         // 如果已经完成7次移位,则一轮读取完成9 v0 o" j/ f* s- D
  88.         if(idx >= 7)4 b) B% V% y& [3 `, k0 ]" E- Y3 r
  89.                 isReady = 0;
    , }: w, k8 D6 d* t( @5 A7 B
  90. }
    * X' k" f$ l3 S  ]+ x9 |1 d
  91. # c3 k) x' M6 U' _0 t% V! }- U2 L* e( D
  92. static void INT1_Isr() interrupt 2{* R# V1 @/ _3 r: y! C
  93.         // 读当前引脚电平,如果是低电平则说明是下降沿,此时直接忽略该中断4 U7 ]/ x& o6 ^: y, U. R* C# V( m
  94.         if(LATCH == 0)2 v! v" }9 a* B/ T0 g
  95.                 return;$ }/ f; b; _* Q- z- O+ ?
  96.         // 当LATCH上升沿到来的时候,锁存所有按键状态,同时把键值A输出到DATA) x, [, y: p, W3 y, m
  97.         key = bufReady;
    $ F( ?2 }3 c0 Z1 ~
  98.         DATA = key & 0x80;//mask[0];        // 为了加速运算,直接取表中的值而不是读表: w- T+ X! A( I  A. `2 o+ i
  99.         idx = 0;
    4 M' u. B' W: M
  100.         // 允许CLK进行移位2 a# D2 ]1 S* H
  101.         isReady = 1;
    . ?" b& }/ N* t  U* t9 q
  102. }
    : d( r% @6 G5 G- m$ F  n3 A6 e

  103. ; k1 y, ]- N* F1 o. T" U' u
  104. void main(){* I! j# H, ]$ |- ~8 [
  105.         GPIO_Init();& h# y% H$ H  H- ]$ m
  106.         Interrupt_Init();6 b3 Q% S  b0 D) b7 [
  107.        
    4 S5 O6 \8 w/ a$ t
  108.         while(1){
    8 {7 C" [/ r" L; g
  109.                 //PCON |= 0x01;        // 进入省电模式4 R) ?2 R7 `  V4 u( L6 X# c5 t
  110.                 //_nop_();
    . r/ e; s+ X1 x; w. l
  111.                 //_nop_();3 R/ }- C( h& u- c' _2 i
  112.                 //_nop_();. L! ~- r% S! m4 ]$ Z
  113.                 //_nop_();* ?4 G& T, d+ d) {
  114.                 buf = ~((P1 & 0x3F) | ((P5 << 2) & 0xC0));
    2 g1 x. z. h$ T- g; A2 \* R
  115.                 bufReady = buf;
    0 b6 N( I3 u& }) J5 Z3 r2 M  w
  116.         }3 f( a1 t2 [0 c# u3 d
  117. }
    : w) }$ T" P: U0 W2 G
复制代码

5 x" J3 x; }9 g- {硬件参数配置无特殊要求,晶振频率选择12M即可。& ~8 t3 q5 T( _
% h5 Q, S& t* _% }# o" G" M1 K
这是编译好的固件。

本帖子中包含更多资源

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

×

评分

参与人数 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
% I- Q# H( x! j0 X6 e不错的设计,想问一下楼主,FC的15针公头怎么解决?普通的公头太短了,插不进去FC的扩展接口。 ...
; o0 B4 F6 Z  k& H, a! b4 G
坛友的改造方案
回复

使用道具 举报

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

使用道具 举报

发表于 2019-5-25 12:07:18 | 显示全部楼层
精彩,楼主动手强,也写得很详细。8 H& R' a1 Z* Z  I
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
6 x+ w! ~% \1 ^6 R* ~精彩,楼主动手强,也写得很详细。
1 a3 I/ O# ~1 d* ]2.4G方案是目前无线的最低延迟吗?

& ]! i7 u3 @. b+ k我没用过其他无线手柄,所以实在不知道我自己做的这个手柄到底是不是最低延迟。# j) s0 ~$ N, Z. N& \) s
不过根据网上的说法,延迟高低主要是由通信协议的复杂程度,以及数据传输速率决定的。这个模块虽然是2.4G无线模块,但由于协议很简单,所以延迟比较低。
' q. P5 Q6 T' c4 F2 ~我用这个手柄玩一些ACT游戏,比如超级马里奥、忍者龙剑传、热血系列,完全感觉不到延迟,和游戏机自带的手柄没有任何区别。唯一的区别就是这个手柄是用火花山寨手柄改造的,外壳是垃圾回收塑料,粗糙+脆弱,导电橡胶弹性不佳,手感不是一般的差。
3 j; M- C1 p" V2 E, D0 L3 Y我手里还有十几张板子,等我有空了我再做一套,到时候买一个好一点的手柄改造。
回复

使用道具 举报

 楼主| 发表于 2019-5-29 16:56:14 | 显示全部楼层
ppad 发表于 2019-5-28 17:27
# M) A5 \& p; i2 N5 l) |! V$ l给技术帝赞一个,有半成品发布吗,自己焊接改造就可以,编程实在不会啊 ...
% H4 d6 D* f/ \- [, b
很可惜,我手里没有多余的单片机了,LDO也找不到了,锂电池以及充电模块更是没有了。反正就是该用到的元件基本都没了,所以没法发布半成品。
0 T6 a; j- L7 B, c( X两个板子倒是有十几张剩余。
4 J& E# ]9 ^7 _  {" ]6 N; G$ s! @你要是有USB转TTL串口板,完全可以自己买这两种单片机,然后我给你编译好的固件,你自己用串口板下载到单片机里面就行了。两个2.4G无线模块也得通过串口板用AT命令设置参数,不过好在我在设计电路的时候就已经预留好了串口,可以直接在线下载和在线设置参数。总的来说并不麻烦。
回复

使用道具 举报

 楼主| 发表于 2019-5-29 17:00:34 | 显示全部楼层
孙大师 发表于 2019-5-28 18:55
8 W$ H2 F, t9 o/ }. ?" c# t7 t* o) j非常好,楼主是技术帝,到目前我都还没开发fc的无线套件,等空了,开发一套套件,等玩家自己组装。 ...
. B8 j# _( H2 u! t* {
能得到孙大师的赞誉,不胜荣幸!
! E2 u& w* V, S, o# v# l& M6 j5 h不如开发一个多功能手柄,比如用SFC手柄改造,L/R键配合其他组合键可以用来切换2P~4P、调节连发速度、软重启等各种功能。接收端插到15PIN扩展口。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-9-15 14:03 , Processed in 0.111595 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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