找回密码
 注册

QQ登录

只需一步,快速开始

查看: 21983|回复: 27

自制FC无线手柄

  [复制链接]
发表于 2019-5-22 14:16:45 | 显示全部楼层 |阅读模式
本帖最后由 雷精灵2046 于 2019-6-14 09:28 编辑 8 K# d+ v; {5 c9 |
# y6 e1 h# k+ y- Q% I7 G9 z
没有用复杂的分立元件搭建发射接收电路,直接用的现成的2.4G无线模块jdy-40。8 B+ h$ L# s3 {( y5 \" J

! N6 n; _7 P( s& K1 A" D
2 D5 S( s; r5 `+ E: C. v( o& V* V, ^发射端靠3.7V锂电池供电,用了一片SOP8封装的STC单片机,负责产生连发脉冲,同时负责检测电池电量,电压低于3V左右的时候触发低压中断,低压指示LED就会亮起来告知该充电了。平时发射模块和单片机均处于睡眠状态,有按键按下才会唤醒,从而实现省电。实测睡眠状态下整机电流约1~2uA。板子洗了一下稍微干净了一点。因为对于微功耗设备来说,焊接残余的助焊剂可能会增加漏电流。
. d0 Y  g3 c7 E2 z$ ^, X, }3 p
5 V) _: z& H6 \& r" d买了一个火花的FC山寨手柄,去掉里面的牛屎板子,并修正一下塑料挡板,把锂电池和充电模块装进去。  A5 ~/ h6 `! T( G0 t% }
为了减少体积,充电模块裁剪得十分小,并且更换了充电电阻使之适应这个小小的锂电池。这么小容量的电池,也不需要多么大的充电电流是吧?5 v' p7 \7 ^5 K' k
然后统统用热熔胶粘上。充电电流比较小,所以发热很少,不会熔化热熔胶。
. D9 D; n: n& f$ c
% A8 Z2 {# H" J7 N& ?
8 W- R7 S' v0 U0 s% |2 x
5 _! |' F: W5 n3 I8 I最后把按键、导电橡胶和电路板装上去。1 V0 T+ K. n/ m' d
精心裁剪了电路板,正好扣上,不会阻碍其他元件,也不会影响后盖和拧螺丝。
4 D* w, M( n" U$ w* i
; P; ^0 a' Y$ t' H/ {3 S  v7 F1 _* L, v/ s, E( M" P, A/ m
完工!" h7 {( |' [4 e. S1 ^4 C
, r! g9 O! {- g& A( C
4 f3 u  e# J6 j! a2 }. w6 T, {" ?
这是充电的MicroUSB插座。旁边的小孔用于透出低压报警LED的光线。
6 P6 P4 ?2 H* G, p4 c' F7 I$ V+ z9 X( U" y% J  G* P/ K  N

6 u6 K' a! A, a0 \7 m接收端用一片DIP16封装的STC单片机模拟CD4021。为啥要用单片机模拟而不是直接用CD4021?因为jdy-40模块接收端在有按键按下的时候输出高电平,无按键按下输出低电平,和普通手柄正好相反。当然我也可以用两片74HC00或者74HC04之类的逻辑门进行反相,但那就增加了芯片的数量。对于FC手柄这种工作频率并不高的设备来说,STC单片机完全可以胜任模拟工作。
/ H' n' R2 M( h: |9 I# a6 \- w: Q- W  [8 _8 A
3 @2 o7 ]( R1 q0 K0 u9 P4 W

: ]5 ~- T" d2 ]电路设计有点小小的错误,所以有几根飞线。原本设计使用低压差LDO是XC6206,结果在做这个接收模块的时候,买的LDO居然找不到了!无奈只好用了AMS1117。幸好对于接收模块来说是5V降到3.3V,1117可以胜任。要是发射端手柄的话,3.7V降到3.3V,那就非得用6206不可了。: H5 }) I. @$ t" y+ T# l; H
2 }- U; ]9 U: P6 t' I
实测十分灵敏,延迟极小几乎感觉不出来。可惜这山寨手柄的手感并不佳,尤其是方向键,软塌塌的。看来我得买个剪线手柄改装。* o  x7 _& h" `* }

5 w4 H5 ]3 r0 A. s7 r! V这是电路图,有兴趣的朋友可以参考。6 }' _/ E- h% C9 z0 U: A! }$ x6 Q
6 V: f( c: P; ?0 w: c/ x' U
, o) G, N# |- i. _' p. X
我信奉开源主义,十分痛恨把技术藏着掖着。好东西大家分享嘛!所以两个单片机的源代码大公开!
- [7 ~; R+ l0 Y% s3 {' e编译器:Keil 51。6 n0 J6 C; F. L% [
$ b0 Z+ T3 b4 n6 |7 v. f( i* a
发射端:6 ~; t9 d  Z7 P; A: ?+ b/ r
  1. #include <INTRINS.H>/ U( H5 t. H# _; D- _4 \& _
  2. #include "STC15W.h"
    # `7 R; ^% t  b. X8 w  w
  3. % R" }( `6 q9 ?

  4. ; B7 x. @; n6 W6 O# a, P# N- f
  5. /*- J0 D2 I& [) N' z% @
  6. --------------------------
    6 Z. W* E, s, _
  7. |1 (OUT)        \__/   (INT1) 8|
    & j6 @" Q" t. I& V! O! S
  8. |                                                   |
    6 g" l5 \$ ]# o3 j# g5 S
  9. |2 (VCC)                   (INT0) 7|& A& L/ D! S, v
  10. |                 STC15W204S                   |+ V+ @+ Y. T/ z. }3 C# p- d
  11. |3 (LED)                         (TXD) 6|
    5 f1 E) C1 f/ r7 s8 j' m5 [
  12. |                                                   |
    ! {9 I7 n+ R5 m! `
  13. |4 (GND)                         (RXD) 5|
    : l& M- d% s7 p) h
  14. --------------------------; u' j* K$ o. T9 ?

  15. 8 W# U( ?" X5 I3 [" B7 s
  16. LED ---|<|---[===]--- VCC6 i% |2 }/ @3 B+ s3 c* k3 h/ U
  17.            Red          3309 s: B/ h# R% X; ?2 N# c' {0 T# _& _
  18. & p$ e; m9 P# T. n' W8 R
  19. Fosc = 6MHz
    5 O" w/ a7 }& B" _9 y
  20. */
    5 k! z) t: Z% {- [6 p, Q+ E- }3 Y
  21. % @7 c  g; @, i0 c- n7 {

  22. , M. @$ [9 R; H+ t/ |( w. v
  23. // 矩形波输出脚
    : `% m  h& g% P4 L; F8 n9 x  O
  24. sbit OUT = P5^4;  |; e0 V* R$ F! G
  25. // 低压指示灯引脚- h8 q" S$ a. C7 I1 x, J1 ^
  26. sbit LED = P5^5;
    / }! X+ b4 X; }+ M4 a+ d5 I

  27. 0 i2 B- H6 H1 n6 c3 r, o
  28. // 停机标志位
    $ }; h  f  t% D5 k' ]
  29. bit isReadyToHalt = 0;
      ^% c% M( \! B0 F4 [3 p

  30. & g6 |& R4 [& n- ^2 z* H
  31. // 矩形波次数累计
    ) U3 Q1 o% }* @2 Q
  32. static volatile unsigned char count = 0;! X: j- V/ T( Z! `% i' i) P' J
  33. - Z# o! h/ j+ `) F. v' s/ J
  34. ' d# X- u0 y/ i: @
  35. static void GPIO_Init(){6 ~# F; z1 M$ Z5 a
  36.         // P3口设置为准双向,默认靠内部弱上拉输出高电平5 `4 D: T  I" j0 v) L' z; q
  37.         P3M0 = 0;
    " B: i1 o; e9 }1 [  ]
  38.         P3M1 = 0;
    5 Z. s; x* W% x7 T6 [
  39.         P3 = 0xFF;
    2 g- b$ k! w" {) ~2 w) X
  40.         // P5口设置为准双向,默认靠内部弱上拉输出高电平+ Q9 l$ K; e* U! U* t: f
  41.         P5M0 = 0;1 W+ ~* N* ?6 a$ l9 C
  42.         P5M1 = 0;, U( o# I* ]* T% |9 K
  43.         P5 = 0xFF;0 E; y% b# ^9 \
  44. }8 _" b( A2 G& _$ \% K
  45. 4 q9 e6 E1 w6 m3 a
  46. static void Timer0_Init(){1 L, ]; l" H' f, o
  47.         // 16毫秒@6.000MHz3 g+ o5 T$ G2 r- _; e+ {/ j& m
  48.         AUXR &= 0x7F;        // 定时器时钟12T模式
    # P; }  e- c* Q% A1 [  r  `
  49.         TMOD &= 0xF0;        // 设置定时器模式
      F  d6 j+ [! O$ Q+ c
  50.         TL0 = 0xC0;                // 设置定时初值4 s$ [) _- l# |: n* c! f7 q
  51.         TH0 = 0xE0;                // 设置定时初值
    6 [. _7 K1 r' y
  52.         TF0 = 0;                // 清除TF0标志
    . F/ G: Q2 @/ x, P# e
  53.         TR0 = 1;                // 定时器0开始计时3 l* [. G0 ?; C" O/ }& ^2 m
  54. }* a0 b* b" S. C6 i4 B: ^
  55. ; j  @' G8 {: N0 y% H
  56. static void Interrupt_Init(){8 i! Q. P  G+ m& t/ s* S! V9 q& X
  57.         // INT0中断触发类型为下降沿触发4 g8 l9 ^! f: Q6 b
  58.         IT0 = 1;
    ' G- f8 J# }2 P
  59.         // 允许INT0中断; o9 E( x) H" ?
  60.         EX0 = 1;
    2 z3 a" V+ ]% q, Q  ~7 m
  61.         // INT1中断触发类型为下降沿触发
    * ^( H3 P' c( d! S; o( K# j( F
  62.         IT1 = 1;. {! Q- ~+ i; Z: L8 ~0 I. c
  63.         // 允许INT1中断
    , R) e, h( m9 U, [
  64.         EX1 = 1;
    1 i4 |' [5 R* K( i: I
  65.         // 允许定时器0中断& F4 k, {  N. Y8 s. [- b8 w" W
  66.         ET0 = 1;8 f" J9 M  l0 _4 ^" ~
  67.         // 允许全局中断* j' e  _  \$ N' I
  68.         EA = 1;9 l0 p6 }+ Y2 k0 V; \, Y
  69. }4 d' |- m' e# G( S$ W  K3 V

  70. ' Z( [7 \" G! ~- r4 M0 q% y( i
  71. static void INT0_Isr() interrupt 0{  y3 O4 m" b) B/ b. ]
  72.         // 矩形波次数累计归零; O, s: s: J9 ]9 c  _% G5 N
  73.         count = 0;9 H$ t1 n9 p9 q+ O" A1 h+ `
  74.         // 重开定时器0中断
      e  M) d, `: S. y
  75.         ET0 = 1;
    % t  |1 r; |+ X# j( C
  76. }' g- F3 o! [- v/ {4 s/ A6 D

  77. 9 b) _7 E' E6 c4 _% N4 q1 i
  78. static void Timer0_Isr() interrupt 1{! f7 @* L  [' R. R. J' Q
  79.         // 输出矩形波
    6 s$ m6 `: F" }' H
  80.         OUT = ~OUT;
    $ e4 F3 j* E8 B/ E: R( Q7 {; w0 S
  81.         // 累计矩形波次数
    $ ?+ {$ X6 m+ }& R
  82.         count++;
    & Q  }- J/ o) I2 Y8 U& D
  83.         // 超过250个矩形波,准备停机
    & R* y4 o2 {1 l, F1 \2 d( I
  84.         if(count > 250){
    ! z' G) ?' x- C
  85.                 count = 0;
    & n; x. k+ c% N6 z0 q( N& D/ \) q
  86.                 isReadyToHalt = 1;
    , S9 X9 e+ P  t# F$ A( L
  87.         }
    5 \8 I. w& [) g
  88. }* C! y& h* v/ t: x
  89. 3 o3 g% q5 e. X  Q  f
  90. static void INT1_Isr() interrupt 2{
    3 r1 t: B" y: V1 C7 u; F
  91.         // 矩形波次数累计归零
    4 b( Q# r. s+ l& r" l6 y
  92.         count = 0;) i" A& c$ m& z9 W+ i, I
  93.         // 重开定时器0中断
    ' C7 W' R) f! V" `& b  Z
  94.         ET0 = 1;9 W9 ?4 m8 i! w) @  d, y
  95. }
    * o4 }$ n3 Z! D8 w* B
  96. & a# y) D5 w1 `# A5 V
  97. 1 |% ]+ g3 g# e; ^- W! l  [0 i) Q
  98. void main(){  m( H0 |8 A& C  U# }' U
  99.         // 初始化P3和P5口. Q" Y! P# c" X1 ^( z( B
  100.         GPIO_Init();+ u4 \8 z5 `7 a' P' F  L
  101.         // 初始化定时器0# r$ m# \5 N) h; k) e7 @
  102.         Timer0_Init();- D6 N. z$ P4 X, y- k
  103.         // 初始化中断
    ' t7 D4 D& R$ C7 X, B/ p2 y! |
  104.         Interrupt_Init();% a% j* H  G3 s9 X% Y) d# Z
  105.         . q2 K3 z4 j! S5 V6 z
  106.         while(1){" ~4 X' @& ^5 `! E) I! ^. [6 |3 W9 A
  107.                 // 检测电量0 Z+ B, U0 |) ~, p
  108.                 if(PCON & (1 << 5)){
    4 k9 K- Q, i" U2 J) C7 [- E
  109.                         // 如果电量低,低压指示灯亮
    ) a" P* s6 |7 }% y9 c3 L8 E
  110.                         LED = 0;
    & M2 B6 Y$ L& N
  111.                         // 清电量检测硬件标志位
    2 W' n  R; V, R" V7 w, ]
  112.                         PCON &= ~(1 << 5);
    6 O, x* `. Z% R2 r/ R
  113.                 }else{
    3 @6 x4 g2 [3 m- q+ M
  114.                         // 电量正常,低压指示灯灭/ w& [" ?' W( p9 ~
  115.                         LED = 1;4 ?4 U+ O$ O, O# k8 g/ w
  116.                 }* b( m$ R  L9 S0 z
  117. $ W9 j, z/ ]$ C: N2 b! G; o$ L' D$ V
  118.                 // 检测到停机标志& u; ?  M8 K3 J1 `
  119.                 if(isReadyToHalt == 1){; R% u: T9 |% f' R/ u' U0 w
  120.                         // 暂时关闭定时器0中断
    5 y. ]' B/ \  g
  121.                         ET0 = 0;
    ' Q+ Q3 s6 o1 z$ n& J4 n
  122.                         // 停机之前先把矩形波输出脚置低电平,以方便INT0和INT1唤醒CPU
    ! Y8 b3 ?0 b3 r! B" l# _4 ?
  123.                         OUT = 0;6 E! I3 V/ f, ]# V8 M5 E) |) B
  124.                         // 停机之前先把低压指示灯灭掉,以省电
    1 }' P0 A3 p8 w: ?# b9 K1 E+ R
  125.                         LED = 1;
    ; n2 p% _* w2 o
  126.                         // 进入停机模式
    . N7 L7 q7 K% f) V5 M) X8 O
  127.                         PCON |= 0x02;
    9 j) h( c" a) z
  128.                         _nop_();6 n7 j! ]4 x+ ]% e! X
  129.                         _nop_();
    0 v% i6 ~1 X1 c+ r
  130.                         _nop_();
    % z2 h2 m9 m2 V
  131.                         _nop_();
    % s0 O/ `$ Z+ d5 e% A+ g
  132.                         // 唤醒,清标志位9 G4 ^; u: E1 X. p5 T' u6 T5 ?
  133.                         isReadyToHalt = 0;
    ) X5 [& D+ w+ I0 S
  134.                         // 重开定时器0中断
    $ W  [2 c1 C. ?8 a/ v4 ?4 E
  135.                         ET0 = 1;
    7 `$ C4 D2 N- q: |
  136.                 }
    5 b  B$ M5 e& W! R- J
  137.         }8 j+ d' n* F' o7 @1 v/ J8 D
  138. }0 k+ ^3 U4 {/ g+ H
复制代码
6 z& G7 \' @9 v2 |9 M: O
硬件参数配置:/ p  E# H: Y5 e6 P' B8 l
% M8 r( ?; @5 e+ v- C1 ?( x
  ?- W, d: a% `( s
接收端:8 u( p' p6 E* N* l: y
  1. #include <INTRINS.H>
    5 l% y4 k! Y% [8 h
  2. #include "STC15W.h"" `# |& S' B5 p  `  V

  3. + f  d5 w5 c2 |
  4. ! _5 i8 c4 D0 [+ ^9 Z; A, Q
  5. /*
    3 f9 V+ p% D% b* q$ L6 N
  6. 8 |, V% |- O7 d0 X
  7. *---------------------------*3 G& T0 n9 y3 x
  8. |1 (GPIO2)         \__/  (GPIO1)16|
    % g8 p( b6 s2 X2 v  i  L( T( W7 T
  9. |                                                        |: j( h3 w  _7 `; N' K; A; l+ E1 {
  10. |2 (GPIO3)                   (GPIO0)15|& E6 t& w: N' P( c9 w7 o( U
  11. |                                                        |" v! T! [4 b# ~5 K! a
  12. |3 (GPIO4)                                  14|
    6 _; M) O# @9 W( h
  13. |                                                        |
    4 D# C% V7 @: y8 M: {
  14. |4 (GPIO5)                        (DATA)13|
    : L3 V; V) x4 e8 B
  15. |                  STC15W204S                |" n( U0 V2 P  i0 J
  16. |5 (GPIO6)                   (LATCH)12|
    4 y4 |. V; a- g, F! ?
  17. |                                                        |9 A0 f8 C' o. \: L! I5 \8 d
  18. |6 (VCC)                         (CLK)11|8 ~5 r6 m. `* N% e
  19. |                                                          |8 M7 [3 y- \) C( N3 d, i
  20. |7 (GPIO7)                         (TXD)10|/ c! Y5 ~& J: c/ B
  21. |                                                        |, a4 J% b6 {3 p" k+ Q
  22. |8 (GND)                         (RXD) 9|
    * a$ E$ p( G' n9 D2 J4 g& h1 y& K
  23. *---------------------------*+ z0 f) Y; {- L% q: m* j
  24. Fosc = 12MHz  \/ r7 n& S, d# I
  25. ) t5 V5 w5 d$ d3 I9 T
  26. P1.0 -> 上% v9 X$ s9 b" p9 I! t4 w& M
  27. P1.1 -> 左9 P2 N, A; F0 b) y0 K2 Y% I" I
  28. P1.2 -> 下3 M) s9 q# p* _, q" l7 F$ {+ r) L
  29. P1.3 -> 右
    : D$ E( V  W# ]6 c
  30. P1.4 -> SEL+ L, _1 L8 Z" k% J& I
  31. P1.5 -> STA
    0 c7 d% J: v  m6 l. ]. ]
  32. P5.4 -> B$ ~( P+ H: H& j$ x
  33. P5.5 -> A
    2 N" e5 W/ u! l

  34. , u3 S! u! s. l; ~6 ~7 ?5 g
  35. */
    ( m7 L+ g0 T8 A" t4 }9 x4 x2 G! Q6 T* G
  36. ( b# H, L+ A6 U- m# d1 y* j
  37. 7 T- @- r! r6 p5 g3 V& I
  38. sbit CLK        = P3^2;
    # |3 [* P  X: U) O/ t$ ]# P
  39. sbit LATCH        = P3^3;
    0 m. w; A; N9 M5 F4 c1 P8 x/ r
  40. sbit DATA        = P3^6;, ~: c. t$ ^0 |* @$ c+ R/ e

  41. - r7 M- Q) }- N2 `8 W
  42. bit isReady = 0;
    8 l+ L* ]' @" V& O( N. y' p
  43. static unsigned char key = 0;
    , P8 b. r1 t- _; g0 w4 {* a4 m$ i: [
  44. static unsigned char buf = 0;        // 双缓冲。这个缓冲区保存从P1和P5组合而来的键值
    7 v$ D+ Z' a- d" S0 y7 r' t) N9 l
  45. static unsigned char bufReady = 0;        // 双缓冲。这个缓冲区保存上面那个缓冲区的备份5 s  o$ y: T6 M/ Q: G$ 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中
    ) p; \: B$ p/ i1 E9 L3 |
  47. static unsigned char idx = 0;1 C; q  {8 \3 O/ F$ b

  48. & K( v9 @0 q" {% J  ?7 q
  49. # V4 U) h1 w5 A. C5 Y# x* n
  50. static void GPIO_Init(){3 v+ k/ \# g3 ^, W8 |
  51.         // P1口和P5口用于接收并行信号,全部初始化为准双向,依靠内部弱上拉输出高电平
      g7 g5 e; S& v3 L; _7 |$ X
  52.         P1M0 = 0;; L0 e" H% C3 y! |( T. [( |% ~6 B/ v
  53.         P1M1 = 0;7 q; u- @# ?) R7 S8 X
  54.         P1= 0xFF;
    ) Q2 b/ f0 t& k  f6 p2 x- [; r* q
  55.         P5M0 = 0;
    2 {' k& Z9 C; o, w2 ]  }
  56.         P5M1 = 0;3 o2 w2 U5 f6 Q# \
  57.         P5= 0xFF;
    : R% ~7 n+ y8 l- v
  58.         // P3口初始化为准双向
    " ]: k3 r2 C$ g' ]: l3 o, u5 T
  59.         P3M0 = 0;
    ' w6 [' n7 j$ u' P1 h
  60.         P3M1 = 0;/ a! X, [; f) Y' I
  61.         P3 = 0xFF;0 G3 s3 u' N* A7 O
  62. }9 {; l' h# X8 @3 X7 o' Y/ T

  63. + n9 B2 H5 l: O: Z0 x1 E
  64. static void Interrupt_Init(){
    ! t/ m/ ]! _+ [0 I. r
  65.         // INT0中断(CLK)触发类型为上升沿+下降沿
    ) j/ i3 v/ p' }4 v
  66.         IT0 = 0;
    8 |, c* s" V/ L
  67.         // 允许INT0中断
    % t- K& p) }! V7 H7 N6 |
  68.         EX0 = 1;
    7 ^+ Z+ w2 K+ Z  d
  69.         // INT1中断(LATCH)触发类型为上升沿+下降沿
    / X4 p4 t1 f4 J1 P  b# A- ~  B
  70.         IT1 = 0;
    & r; I$ _2 f) Y0 I5 V3 s9 n$ l) Q7 U
  71.         // 允许INT1中断6 J4 H0 S( f! G( F* |
  72.         EX1 = 1;9 I! b" b* J! m- N6 M5 ]
  73.         // 开启全局中断
    $ |5 l- n6 {1 R2 M, l( v- P3 J
  74.         EA = 1;
    3 N9 N! A/ W+ k5 z
  75. }9 f* X3 o& l4 K8 Q

  76. 7 k( x0 j/ M  T* S( l/ x' |' D
  77. static void INT0_Isr() interrupt 0{5 e  |6 m; T5 b* ]3 g
  78.         // 只有已经成功锁存才允许CLK移位6 [. [8 A) B  r' Q; T! m
  79.         if(isReady == 0)
    6 N2 W! A3 r" u3 e3 P5 _
  80.                 return;7 G2 M3 A( m$ J' \3 w' M! Z$ P; u! B
  81.         // 读当前引脚电平,如果是低电平则说明是下降沿,此时直接忽略该中断
    0 B8 f' k! {# T2 Z4 l
  82.         if(CLK == 0)
    ( y( K, _2 f- C- W: X
  83.                 return;
    0 j( `* X! V. ]" K3 s  c, S% j
  84.         // CLK上升沿到来的时候,取锁存值的下一位输出
    " o9 J6 ~" A  \5 P/ g3 X
  85.         idx++;
    * v, v, w* @0 ?- U& z6 S% u
  86.         DATA = key & mask[idx];% Y) j( b0 b9 H  p& J/ e+ ^3 Z5 d
  87.         // 如果已经完成7次移位,则一轮读取完成
    # T# g9 B8 _9 n( R2 c9 k& W
  88.         if(idx >= 7)
    $ }2 H: G0 A$ {0 q
  89.                 isReady = 0;
    0 r" |# G* Q7 J5 E; B* Q1 b6 I
  90. }
    * ~* J3 k; y8 r4 K; v' k6 u, r& ^) I. C

  91. , E" W. }/ o- h1 W! o. [
  92. static void INT1_Isr() interrupt 2{
    5 q7 m6 W  f# M4 H- x7 {% I5 c
  93.         // 读当前引脚电平,如果是低电平则说明是下降沿,此时直接忽略该中断" ^0 d$ F9 O" g, \+ C
  94.         if(LATCH == 0)
    3 q/ i6 M" @4 f  D6 a
  95.                 return;* b5 u' }1 s: d) P
  96.         // 当LATCH上升沿到来的时候,锁存所有按键状态,同时把键值A输出到DATA1 V& ~+ k! a9 R$ j8 D! A
  97.         key = bufReady;/ u( u$ T+ g  @9 w. f, ]
  98.         DATA = key & 0x80;//mask[0];        // 为了加速运算,直接取表中的值而不是读表" W4 T3 ]( t& c* q; X
  99.         idx = 0;! K' q( s$ Y: }9 O: |
  100.         // 允许CLK进行移位; ?7 m# ~& S& B2 O) @  x
  101.         isReady = 1;
    0 {4 |$ R+ S; W) Y& W
  102. }
    ; y5 h7 t6 T5 H

  103. ' o/ ~2 }& {1 F! r" L( H, o
  104. void main(){
    2 d) ^; j( ?" w* m% U2 O, ~
  105.         GPIO_Init();
      Y4 G- Q2 {( o
  106.         Interrupt_Init();* h/ |6 x4 Z, X9 @9 c
  107.        
    4 ]8 z( ]8 I( c/ o$ p
  108.         while(1){. d. f3 A3 m9 c1 I" d
  109.                 //PCON |= 0x01;        // 进入省电模式+ Z% \. P- `  y9 `, ^* r+ a
  110.                 //_nop_();
    8 {. K! G1 z# |, |
  111.                 //_nop_();4 y2 a, Y8 `" c
  112.                 //_nop_();
    1 K5 [& M6 E& A" h. p0 ]
  113.                 //_nop_();
    ( {4 g6 F& J7 D; E5 b; a0 J
  114.                 buf = ~((P1 & 0x3F) | ((P5 << 2) & 0xC0));- I$ Q( j, g! C' W, d9 m! A9 k
  115.                 bufReady = buf;
    # i  d+ Z2 B; h+ \
  116.         }% x' ~/ G( _, Y" T9 z0 }; c2 l
  117. }
    4 D! o& Y6 N7 O- v6 `6 ^
复制代码
/ r' Z* p6 {- R6 L+ o6 H- u
硬件参数配置无特殊要求,晶振频率选择12M即可。
6 k0 }1 `9 Q2 K
  S. D$ D3 h$ O& a这是编译好的固件。

本帖子中包含更多资源

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

×

评分

参与人数 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
% y4 c  ^% f( A7 H7 p8 P5 j不错的设计,想问一下楼主,FC的15针公头怎么解决?普通的公头太短了,插不进去FC的扩展接口。 ...

3 u8 s3 i. ^0 _2 R坛友的改造方案
回复

使用道具 举报

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

使用道具 举报

发表于 2019-5-25 12:07:18 | 显示全部楼层
精彩,楼主动手强,也写得很详细。
! z1 B9 y3 I9 c: ^- X+ A2.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
1 ?6 s6 x$ O4 C8 c% u精彩,楼主动手强,也写得很详细。
3 G# H0 U! [% \" F  d2.4G方案是目前无线的最低延迟吗?

; o; I* N) r# T: S% c% H: M+ @* G我没用过其他无线手柄,所以实在不知道我自己做的这个手柄到底是不是最低延迟。/ K& J# R" @2 h
不过根据网上的说法,延迟高低主要是由通信协议的复杂程度,以及数据传输速率决定的。这个模块虽然是2.4G无线模块,但由于协议很简单,所以延迟比较低。2 @9 Z- _. G; Q$ R
我用这个手柄玩一些ACT游戏,比如超级马里奥、忍者龙剑传、热血系列,完全感觉不到延迟,和游戏机自带的手柄没有任何区别。唯一的区别就是这个手柄是用火花山寨手柄改造的,外壳是垃圾回收塑料,粗糙+脆弱,导电橡胶弹性不佳,手感不是一般的差。0 j0 u9 J; \$ X' B7 x
我手里还有十几张板子,等我有空了我再做一套,到时候买一个好一点的手柄改造。
回复

使用道具 举报

 楼主| 发表于 2019-5-29 16:56:14 | 显示全部楼层
ppad 发表于 2019-5-28 17:27
. g! n: B- N- C% d0 M5 H6 h给技术帝赞一个,有半成品发布吗,自己焊接改造就可以,编程实在不会啊 ...

1 k/ L- F8 G) P! }" x很可惜,我手里没有多余的单片机了,LDO也找不到了,锂电池以及充电模块更是没有了。反正就是该用到的元件基本都没了,所以没法发布半成品。7 q( I; H6 B. P3 s7 H0 Z
两个板子倒是有十几张剩余。
+ P( d$ H$ f; g3 t' y你要是有USB转TTL串口板,完全可以自己买这两种单片机,然后我给你编译好的固件,你自己用串口板下载到单片机里面就行了。两个2.4G无线模块也得通过串口板用AT命令设置参数,不过好在我在设计电路的时候就已经预留好了串口,可以直接在线下载和在线设置参数。总的来说并不麻烦。
回复

使用道具 举报

 楼主| 发表于 2019-5-29 17:00:34 | 显示全部楼层
孙大师 发表于 2019-5-28 18:55) [0 p! \" H$ X# r4 G) S
非常好,楼主是技术帝,到目前我都还没开发fc的无线套件,等空了,开发一套套件,等玩家自己组装。 ...

* z* g- W2 `- a3 m6 x  A/ E能得到孙大师的赞誉,不胜荣幸!( a, a/ a; B3 _  @" w5 M
不如开发一个多功能手柄,比如用SFC手柄改造,L/R键配合其他组合键可以用来切换2P~4P、调节连发速度、软重启等各种功能。接收端插到15PIN扩展口。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-7-1 16:28 , Processed in 0.117442 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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