找回密码
 注册

QQ登录

只需一步,快速开始

查看: 24898|回复: 32

自制FC无线手柄

  [复制链接]
发表于 2019-5-22 14:16:45 | 显示全部楼层 |阅读模式
本帖最后由 雷精灵2046 于 2019-6-14 09:28 编辑
: X* K4 ]8 X  x6 e: c
7 H+ L7 p. O2 U/ n2 j7 x) w没有用复杂的分立元件搭建发射接收电路,直接用的现成的2.4G无线模块jdy-40。
. C5 T) Q8 W8 Q9 F' `9 h1 i8 t/ N0 F& U& O# J6 d

: `6 c! R8 q; `$ g0 Y发射端靠3.7V锂电池供电,用了一片SOP8封装的STC单片机,负责产生连发脉冲,同时负责检测电池电量,电压低于3V左右的时候触发低压中断,低压指示LED就会亮起来告知该充电了。平时发射模块和单片机均处于睡眠状态,有按键按下才会唤醒,从而实现省电。实测睡眠状态下整机电流约1~2uA。板子洗了一下稍微干净了一点。因为对于微功耗设备来说,焊接残余的助焊剂可能会增加漏电流。, e. ^3 ]$ f4 G: _5 V7 |
! q# |- ]3 F$ ]; e0 @
买了一个火花的FC山寨手柄,去掉里面的牛屎板子,并修正一下塑料挡板,把锂电池和充电模块装进去。3 v9 z3 y% B) m3 K
为了减少体积,充电模块裁剪得十分小,并且更换了充电电阻使之适应这个小小的锂电池。这么小容量的电池,也不需要多么大的充电电流是吧?  V6 ~$ m. Q7 R# s. q
然后统统用热熔胶粘上。充电电流比较小,所以发热很少,不会熔化热熔胶。! l7 L. m, I5 d; v$ c

# |: E( E3 R, E; H0 {; }& ^/ _5 }9 [" h8 ]2 \  V6 C0 E
* V/ u. V* H2 Z, e
最后把按键、导电橡胶和电路板装上去。
% c* o/ T2 n+ T* ^& T  q精心裁剪了电路板,正好扣上,不会阻碍其他元件,也不会影响后盖和拧螺丝。, R3 b1 \6 z" O4 s
% J. Z/ M9 V; [3 p
" h9 v  g7 t0 @
完工!! i. `7 i) T7 d( o+ b: t. o
9 t% W8 e. m/ z7 Q

8 M0 _% c3 q! M( j$ e$ f这是充电的MicroUSB插座。旁边的小孔用于透出低压报警LED的光线。4 X4 ]  N+ O/ ~# G+ y  ?& K% V( x

) m. e; r/ E. [6 b( ]% t! e8 {: B
7 P1 {7 J9 A# X/ ]$ G- n接收端用一片DIP16封装的STC单片机模拟CD4021。为啥要用单片机模拟而不是直接用CD4021?因为jdy-40模块接收端在有按键按下的时候输出高电平,无按键按下输出低电平,和普通手柄正好相反。当然我也可以用两片74HC00或者74HC04之类的逻辑门进行反相,但那就增加了芯片的数量。对于FC手柄这种工作频率并不高的设备来说,STC单片机完全可以胜任模拟工作。
8 E; h' C0 [, X% D! m: C2 m( N' d& r! |) }, o% y8 F
1 A' `; O* T7 d

# H. W) g" N+ `% R/ Y电路设计有点小小的错误,所以有几根飞线。原本设计使用低压差LDO是XC6206,结果在做这个接收模块的时候,买的LDO居然找不到了!无奈只好用了AMS1117。幸好对于接收模块来说是5V降到3.3V,1117可以胜任。要是发射端手柄的话,3.7V降到3.3V,那就非得用6206不可了。
% q* k( C( K$ s
. x' e: t1 z  }! p( F! b实测十分灵敏,延迟极小几乎感觉不出来。可惜这山寨手柄的手感并不佳,尤其是方向键,软塌塌的。看来我得买个剪线手柄改装。4 `2 Q/ V+ P$ w& w8 [7 O- J# b
* O; @( |; H4 L' r9 y* a/ ~; I8 C
这是电路图,有兴趣的朋友可以参考。
, @# E' N! i3 n' `. P4 ^
/ B4 u/ w- {; @% }5 ?) ?& \5 p! H% |- O7 u5 r! l
我信奉开源主义,十分痛恨把技术藏着掖着。好东西大家分享嘛!所以两个单片机的源代码大公开!5 V$ l( D7 p9 d
编译器:Keil 51。$ m/ A6 I6 x, O

: n, k1 _$ ?  B% }7 n8 b) B发射端:1 `; R2 J# c6 r
  1. #include <INTRINS.H>! }- M7 C" y* a" \: C2 E
  2. #include "STC15W.h"5 l+ w' w9 j! Y3 p
  3. " m- f3 {9 u. P' d3 y5 r1 R
  4. 7 h/ L7 x+ j* S; ]. c
  5. /*4 ~( R4 w" }7 U) B
  6. --------------------------7 Q) B3 C. a" c( N/ X
  7. |1 (OUT)        \__/   (INT1) 8|
    + ]8 f" }4 P* z& x6 `
  8. |                                                   |
    8 E' P( r4 _, }
  9. |2 (VCC)                   (INT0) 7|
    + B4 }- L0 O) m8 p
  10. |                 STC15W204S                   |
    - {( T. I/ o5 R9 ?: [
  11. |3 (LED)                         (TXD) 6|
    ' O  L  e5 o) {, {
  12. |                                                   |
    : b0 z& y9 }. @# _# j8 h& V0 x
  13. |4 (GND)                         (RXD) 5|! _1 E2 N# d' E& |; K2 N" c
  14. --------------------------
      b* |. S( U" r
  15. ! m; W4 ^! g( `* y, {6 I9 `
  16. LED ---|<|---[===]--- VCC
    . @2 W! v# e; n/ A$ N$ E9 w( A  p
  17.            Red          330
    : [% f7 y2 {6 H4 x+ ~  K2 |
  18. - Q: n2 ^* g5 C+ j. }: M, }
  19. Fosc = 6MHz
    2 S$ C7 F5 V: K* K/ d
  20. */! R  w4 N5 @0 ?) S- K* `8 j
  21. ' C) I0 c3 V3 U; x

  22.   s% O8 U+ }7 q/ C6 c' w
  23. // 矩形波输出脚
    : G0 M% z- E) y  z: G, U+ w
  24. sbit OUT = P5^4;
    , A8 }4 v, m) n
  25. // 低压指示灯引脚- }7 m7 V4 B, o: T* w; D
  26. sbit LED = P5^5;' y+ N- P; b. U$ F5 F( I

  27. # A  C2 D- M$ L( h& O# x& A2 T
  28. // 停机标志位3 q4 i( P: T, D" Y9 Z
  29. bit isReadyToHalt = 0;
    . T2 D6 z  S9 _
  30. . ^' r  ~* n! N7 ?3 V7 L
  31. // 矩形波次数累计
    * A* q/ [- N4 t. k2 P
  32. static volatile unsigned char count = 0;: e5 ^* T+ g. j( @& @  t7 g6 F
  33. % g+ k4 F' w- q# c5 G! y8 p
  34. : q; r) y3 w( I$ B4 e. p. I
  35. static void GPIO_Init(){! ^7 R+ @9 y% `1 n+ C( z
  36.         // P3口设置为准双向,默认靠内部弱上拉输出高电平; n/ Z+ N1 D; R: N& e
  37.         P3M0 = 0;+ g' U1 l) s$ C( h( I& a
  38.         P3M1 = 0;" Q. Y% x; z/ @! T+ w0 Y+ D+ L* w, x2 K
  39.         P3 = 0xFF;
    + W) ~" ~/ D  H  D) m
  40.         // P5口设置为准双向,默认靠内部弱上拉输出高电平
    ' A6 p* p6 V4 T3 k1 x7 y
  41.         P5M0 = 0;3 Y; |  Z, b! f
  42.         P5M1 = 0;
    + |9 N! o! c+ {( h6 C7 x) L7 Y: @
  43.         P5 = 0xFF;
    & J: O7 z2 o6 v9 S& V
  44. }
    ; y7 Z: @+ T) q. C$ I
  45. $ j8 d; |6 u: l, U
  46. static void Timer0_Init(){
    9 W+ T: s& r$ R" P9 u4 G
  47.         // 16毫秒@6.000MHz  S7 N/ G. r/ T
  48.         AUXR &= 0x7F;        // 定时器时钟12T模式/ e$ u# }  q7 d- g) l
  49.         TMOD &= 0xF0;        // 设置定时器模式
    0 T2 W4 Y, ~8 ]; d
  50.         TL0 = 0xC0;                // 设置定时初值5 V6 ~3 f( m, N9 S2 [
  51.         TH0 = 0xE0;                // 设置定时初值
    " |, B2 g: }7 D3 g
  52.         TF0 = 0;                // 清除TF0标志0 A; t! |3 y  b# _3 s6 D' q7 N
  53.         TR0 = 1;                // 定时器0开始计时
    : g! ]- ?2 e1 a- N# g
  54. }
    8 @, i8 o7 y* e" q2 `( M/ ~

  55. 9 [5 f* V" ?; n; c
  56. static void Interrupt_Init(){: \" `& P4 D5 K+ P4 F) j- l# r1 r+ V
  57.         // INT0中断触发类型为下降沿触发
    ( ~, j; V. ^; U# ~0 G" \3 I/ I( J
  58.         IT0 = 1;; T' K2 V- Y7 {+ X" y: q2 M2 ^# s! I
  59.         // 允许INT0中断3 N0 J! X7 |  E2 A: o* a
  60.         EX0 = 1;
    3 e3 }1 f8 W; N$ I' d
  61.         // INT1中断触发类型为下降沿触发) }6 D: m+ T, p/ v( |
  62.         IT1 = 1;
    & `  u" Z# o$ K1 ]1 z
  63.         // 允许INT1中断- ]5 H' w* b8 D7 I
  64.         EX1 = 1;! p4 L6 P  v3 y; T- l1 T
  65.         // 允许定时器0中断8 d) m2 L- S  H' G: i( B9 O
  66.         ET0 = 1;. T5 k+ d6 O" w
  67.         // 允许全局中断
    2 t( X& p6 J; N+ W9 V) m
  68.         EA = 1;/ H3 [$ x. [$ }2 S4 |$ i9 Z5 `
  69. }
    9 ?9 C' [2 \. d) a$ l' w
  70. 5 M: D4 c1 C( ]+ C/ M$ V, k+ f+ z' n
  71. static void INT0_Isr() interrupt 0{
    7 s3 b5 ^+ v+ Z1 K! \) ]- `
  72.         // 矩形波次数累计归零9 V6 i$ e4 u7 g* m3 c9 y/ [1 Z
  73.         count = 0;# e  f: ]$ i" \( j+ u" P
  74.         // 重开定时器0中断
    9 |1 o2 Y! @+ b; o. b2 {. Z
  75.         ET0 = 1;
    9 e1 {) Y2 g" G  f' i- v8 s
  76. }
    # R; b  U3 j3 c0 C! H6 _

  77. ! D: T% K" o7 W0 G
  78. static void Timer0_Isr() interrupt 1{3 q4 _( u9 Z7 R! S, L5 Q
  79.         // 输出矩形波4 A  S8 H# [# y1 ?2 O
  80.         OUT = ~OUT;$ W. u! c6 \( _. P/ _  Z7 h( {) G! g
  81.         // 累计矩形波次数
    ) H, `9 v2 ?7 ~: j# Q
  82.         count++;( G' t6 t$ d5 s" \
  83.         // 超过250个矩形波,准备停机8 Z- ?+ ]+ s% E  D& }, v
  84.         if(count > 250){
    5 @  F$ g$ s. N: O
  85.                 count = 0;
    % f. p; P5 a6 G: _
  86.                 isReadyToHalt = 1;
    1 D8 D4 N9 A) T' Z- p, A
  87.         }- _, U2 \  w$ M2 D/ [- C
  88. }- O$ v) B, R# M6 p
  89. 5 \$ h, v) S' Q' C( A! ^6 B
  90. static void INT1_Isr() interrupt 2{! u- h/ o5 X; n) T7 D: k
  91.         // 矩形波次数累计归零6 u6 k/ y' n7 x8 R% I
  92.         count = 0;
    3 b; s/ \7 r+ }4 M) K
  93.         // 重开定时器0中断
    6 ~- U' X4 U' j. [; s
  94.         ET0 = 1;
    1 Z2 P4 n+ J; e0 J) I  T
  95. }. ?7 Z8 M+ t' v; [' a/ W# T

  96. , `  ]6 e6 T& T/ x8 q% r6 ^
  97. 9 U5 C5 {- a  T' D7 F. }! D/ V
  98. void main(){
    5 o0 `/ J3 [& {4 z3 Y
  99.         // 初始化P3和P5口3 j9 k0 ]. W4 l. ?& ?
  100.         GPIO_Init();% U6 I! A5 f; d3 Q+ G, i. s. ?5 C. M
  101.         // 初始化定时器0
    6 A+ V4 q3 Q5 O" M
  102.         Timer0_Init();: f- m$ n% y3 Z! U, V+ ]
  103.         // 初始化中断) V: y; K" c7 A3 N
  104.         Interrupt_Init();6 I2 i. [8 A; ?' c* Y& W: F
  105.        
    8 G. q) F; t9 D7 B2 m
  106.         while(1){: p4 U: A; z* `8 e& t( C- d
  107.                 // 检测电量
    . [( A  \( ?7 v& @4 n; R
  108.                 if(PCON & (1 << 5)){
    9 d- A9 ~  @, x* t: X& l7 z0 `; }
  109.                         // 如果电量低,低压指示灯亮0 w# H2 u, X2 `4 w( {
  110.                         LED = 0;
    0 `4 }7 v( z5 d  v( R9 _$ ^- ~
  111.                         // 清电量检测硬件标志位
    6 f/ {1 [' p4 X" k* E
  112.                         PCON &= ~(1 << 5);9 Q; S' d  ]# R: ?
  113.                 }else{
    ' U3 j; D5 i3 R9 D9 r
  114.                         // 电量正常,低压指示灯灭& \  C# }6 g2 z& T6 j- B$ T
  115.                         LED = 1;( y6 N" H( F8 t1 w/ P' m, S
  116.                 }% ]  v6 A% p! K
  117. / m% O8 f4 g% j0 x* d- p
  118.                 // 检测到停机标志" z, A9 T% L+ ^. n" K. v: Z+ ?
  119.                 if(isReadyToHalt == 1){
    $ a2 J8 h, a$ K" Z% n# S0 ]
  120.                         // 暂时关闭定时器0中断; F" c) c1 S: k# l' E! Z- \
  121.                         ET0 = 0;
    $ h7 c8 P9 m0 h
  122.                         // 停机之前先把矩形波输出脚置低电平,以方便INT0和INT1唤醒CPU
    % r6 s7 z. h0 a" {
  123.                         OUT = 0;; r" {- C# ]4 J0 `; w# W4 d
  124.                         // 停机之前先把低压指示灯灭掉,以省电0 X4 i: _  u1 |6 N' R, @
  125.                         LED = 1;% }$ e" z7 B3 G( S
  126.                         // 进入停机模式
    9 s: l$ e7 N$ C  D
  127.                         PCON |= 0x02;
    0 T- x  b' S: i% A5 |
  128.                         _nop_();4 X) q" p  ?( H
  129.                         _nop_();' ]8 E7 P7 L: G4 C) I
  130.                         _nop_();
    . d6 o& E. g: o' `5 N1 \# N5 C0 Z( j0 J
  131.                         _nop_();
    8 y" S# z7 a/ }* z$ Z7 ~/ ?% k
  132.                         // 唤醒,清标志位# I& G, d! u1 m( ?* I  S3 T. E9 w
  133.                         isReadyToHalt = 0;
    7 i" q* W+ g/ @  M
  134.                         // 重开定时器0中断
    ! D1 W9 H% W& T; g
  135.                         ET0 = 1;: X, g7 m7 l/ O/ H! F+ Q# [0 ?: D
  136.                 }
    ' i: C% ^8 ]( \) p9 b2 K5 Z
  137.         }% x0 P& ]9 g& |$ F& Q! A8 N* w
  138. }
    ( M+ \! i9 ~0 @/ C) }- _
复制代码
: t% M, k+ j9 m* @2 I
硬件参数配置:* @5 b* L# `3 Y6 Q( n  ]

, M! ?* h1 M: Y8 D- _; T7 u  [3 A+ X2 n; U3 H$ J* h8 @
接收端:1 |. {+ ~+ l& Z  r
  1. #include <INTRINS.H>
    8 P. N3 T* t8 M
  2. #include "STC15W.h"
    & |0 r/ z  c7 t& G7 Z
  3. % h& p  y1 H+ u% a$ {0 |1 W$ j' W
  4. 9 s4 |0 n/ R* c" ^& x- ?) L3 N
  5. /*
    6 `& V, t7 J. D3 s6 H

  6. 9 S$ x2 Z3 w5 l+ w0 M; M
  7. *---------------------------*- p: S6 ?6 T1 b" z0 p8 {; D4 Y
  8. |1 (GPIO2)         \__/  (GPIO1)16|/ I- n: D0 x9 c2 t& u6 U9 ?5 L8 J* Z
  9. |                                                        |
    ! j9 U" o# ?9 u3 g# O0 D# S% B
  10. |2 (GPIO3)                   (GPIO0)15|
    , Q! _' B1 t5 G4 f# X, \' a
  11. |                                                        |7 z" u$ Q6 n- S' T. k1 |* V. @5 l
  12. |3 (GPIO4)                                  14|  j2 V. Q, V" Y. C% [$ L( n
  13. |                                                        |
    1 J  |) D7 j: ^8 W+ ?# ]
  14. |4 (GPIO5)                        (DATA)13|
    % ^) Q: r$ F" b
  15. |                  STC15W204S                |2 b+ l7 @& k: k+ F) u
  16. |5 (GPIO6)                   (LATCH)12|
    + L$ E, i" ^  O* J
  17. |                                                        |
    # n) e) m/ `; d
  18. |6 (VCC)                         (CLK)11|
    3 z3 V2 B" G- g
  19. |                                                          |
    ' `$ s% V( Y, u9 G5 a' Y$ j
  20. |7 (GPIO7)                         (TXD)10|
    / k1 K. W9 O- `- `
  21. |                                                        |$ u& K7 I! G/ r% h
  22. |8 (GND)                         (RXD) 9|
    / G5 k+ a$ R8 [# v& Q
  23. *---------------------------*/ b8 U0 L/ m8 L! e# o5 y- C% |/ z
  24. Fosc = 12MHz' w( t/ {7 h0 Q1 m. p

  25. 0 O( `/ ]4 Y. Q* S
  26. P1.0 -> 上& R: f  S) C) [1 b
  27. P1.1 -> 左
    ' q4 p: p# p/ a- n8 R% e
  28. P1.2 -> 下
    # P* F6 D' j8 S! O! c) h
  29. P1.3 -> 右) S& \# G! d$ `7 L% b! [" h
  30. P1.4 -> SEL
    3 D+ k# u4 w7 l$ i
  31. P1.5 -> STA
      }8 w! L: v9 u
  32. P5.4 -> B8 K/ k- B, ?: ~4 G/ y: F1 n' b
  33. P5.5 -> A
    & x: f) C. ^, E2 l$ r; a! |$ {  S
  34. + \1 [; }3 U3 T# N* g4 R7 `
  35. */
    7 X* u& n+ i- M7 C7 h  H( |
  36. 4 l9 z* I- @7 S$ W

  37. : u! Y2 X" ]" [- \( o4 Y' i  r$ a
  38. sbit CLK        = P3^2;! o5 j7 y; t* O3 b, ]/ c% `
  39. sbit LATCH        = P3^3;; m/ J. T; Y0 `
  40. sbit DATA        = P3^6;0 U  l+ h& e/ E: j/ }) j. \

  41. 0 g) ?# A9 I6 h! N& `
  42. bit isReady = 0;8 {/ V: T5 {6 @# `& y( D2 Q6 S
  43. static unsigned char key = 0;2 ?3 n0 M6 o* H6 E7 d% D
  44. static unsigned char buf = 0;        // 双缓冲。这个缓冲区保存从P1和P5组合而来的键值
    % G" h+ \* ]+ A' |& G5 H' |
  45. static unsigned char bufReady = 0;        // 双缓冲。这个缓冲区保存上面那个缓冲区的备份
    / L* q& U+ o2 A' e5 s1 `) E' F
  46. static const unsigned char data mask[] = {0x80, 0x40, 0x10, 0x20, 0x01, 0x04, 0x02, 0x08};        // A B SELECT START UP DOWN LEFT RIGHT。为提升速度,这个表放到RAM中
      t& t" v& \$ m) N+ ]0 i) S1 B
  47. static unsigned char idx = 0;/ I! N; _. w* l$ `
  48. * ]% }+ O1 f; N( j( w
  49. ( D6 T4 O' Q! f: C
  50. static void GPIO_Init(){0 [" @( s9 G, W
  51.         // P1口和P5口用于接收并行信号,全部初始化为准双向,依靠内部弱上拉输出高电平+ |) m1 U- x* t* b" C
  52.         P1M0 = 0;
    5 g  K) C, c: ^" F# {
  53.         P1M1 = 0;; R2 s2 e6 N$ B4 O
  54.         P1= 0xFF;' p$ L4 z) c4 H
  55.         P5M0 = 0;. E$ O% x8 T$ b9 L7 v( ~
  56.         P5M1 = 0;
    % x# n" {8 H0 H  [* l3 M* E7 W- }
  57.         P5= 0xFF;
    - ^! V, Z) h# P0 @% C8 A2 H2 j# Y
  58.         // P3口初始化为准双向
    9 B. q" ?5 q, E4 ^
  59.         P3M0 = 0;3 }6 G& b5 {- X# p0 a8 e
  60.         P3M1 = 0;, A, [. l3 M0 I4 F' o
  61.         P3 = 0xFF;
    7 ~- P: G( ^9 k5 V2 n# F
  62. }1 U: v  ?+ q4 ?' o) K' \# U

  63. 7 R! U, W* y8 F5 x. _2 {) {! |
  64. static void Interrupt_Init(){
    5 z6 N0 _! h5 O- J% c$ q% O
  65.         // INT0中断(CLK)触发类型为上升沿+下降沿
    # D3 L' E0 N5 ~
  66.         IT0 = 0;
    7 Y% e2 Q- D3 w1 m* [
  67.         // 允许INT0中断
    , k  ~1 q9 T: E$ }0 }) h: |
  68.         EX0 = 1;
    6 w) f) k- T: d. ]
  69.         // INT1中断(LATCH)触发类型为上升沿+下降沿
    6 n9 V, c" j, A" \
  70.         IT1 = 0;
    : ~6 Q6 t+ _8 J0 R
  71.         // 允许INT1中断& r1 o6 S4 H) l- N: T9 C3 o. w7 v
  72.         EX1 = 1;
    . R: h. O. q* K+ x5 d
  73.         // 开启全局中断) N, l8 j( a4 {9 B$ z5 l  a
  74.         EA = 1;
    ' K: {( z0 \$ T
  75. }; e: S6 E1 ?! j+ F
  76. $ _5 p1 T. ~0 D
  77. static void INT0_Isr() interrupt 0{/ v( R! o7 F3 b9 `+ g8 U; H% X  ?
  78.         // 只有已经成功锁存才允许CLK移位
    4 m9 H2 P+ c: K& e. f
  79.         if(isReady == 0)
    # j& E- t* ]8 b
  80.                 return;
      c' \3 |& G! N4 {
  81.         // 读当前引脚电平,如果是低电平则说明是下降沿,此时直接忽略该中断
    ( w  K: @( ]) t+ c; v
  82.         if(CLK == 0)4 Z8 X( T; X# D5 s8 i& ^6 I
  83.                 return;
    ) S$ z% B: v, `- Z. n, n
  84.         // CLK上升沿到来的时候,取锁存值的下一位输出
    1 Q1 f6 D" E$ Q  X8 w, X4 K
  85.         idx++;
    ! Y' X. ^/ d$ Q' g
  86.         DATA = key & mask[idx];
      Y2 U8 ~* u9 k; P! U- g2 G
  87.         // 如果已经完成7次移位,则一轮读取完成
    ' V* w/ z, V1 R' q% \2 U
  88.         if(idx >= 7)" ~$ Z0 Y7 r* }1 m
  89.                 isReady = 0;
    8 W" Q$ c! K7 D3 T6 z
  90. }0 k& J! ?2 y7 ]/ o0 Z! t
  91. 0 @* _! x. N4 S  D
  92. static void INT1_Isr() interrupt 2{" l2 e7 _4 t8 O, x* Q7 p/ Q
  93.         // 读当前引脚电平,如果是低电平则说明是下降沿,此时直接忽略该中断; Q9 r) |0 d/ H( R( L
  94.         if(LATCH == 0)
    ! I+ V6 u( ~/ m+ v
  95.                 return;2 D- h2 \; C( ^0 o. P1 a
  96.         // 当LATCH上升沿到来的时候,锁存所有按键状态,同时把键值A输出到DATA( ~3 l6 c# z* k- i8 C
  97.         key = bufReady;
    9 r# [; `, F% v  H# h' Q
  98.         DATA = key & 0x80;//mask[0];        // 为了加速运算,直接取表中的值而不是读表5 i! e7 |5 X9 z  z% [/ _
  99.         idx = 0;) q) }% Y9 Q' }6 F
  100.         // 允许CLK进行移位/ m8 U' P2 N" l8 x
  101.         isReady = 1;( }6 m3 L( `5 c7 O5 b
  102. }+ d: F  n$ [- m% Q
  103. 3 A' d1 M2 u! ^3 C
  104. void main(){
      P! e* X& a* P. [
  105.         GPIO_Init();
    , W# m8 u/ ?# C7 }! ]2 a3 l
  106.         Interrupt_Init();: d, y) {$ a2 z# D" `
  107.         . O4 B% G# k5 M7 P+ D
  108.         while(1){: u; l+ d6 i- v5 p5 K. g
  109.                 //PCON |= 0x01;        // 进入省电模式
    8 W0 N* }3 y! ?+ v
  110.                 //_nop_();
    # E; z8 V6 ~: x% D8 \( b5 M" u
  111.                 //_nop_();, A$ O2 r5 J5 M- l
  112.                 //_nop_();; S/ e! c# B% g) Y
  113.                 //_nop_();9 s! [' G+ r9 r7 t; j
  114.                 buf = ~((P1 & 0x3F) | ((P5 << 2) & 0xC0));7 A& ?2 N" E# r+ l, k" _
  115.                 bufReady = buf;
    2 g7 _  q5 M# E+ _9 [9 O
  116.         }2 c/ h5 e; k; C# y
  117. }
    7 m0 ~2 m- {8 y4 {1 Q
复制代码

4 T% c. [5 D- I: b, T5 [4 @硬件参数配置无特殊要求,晶振频率选择12M即可。
# P. K! S) V3 l0 w
- m/ o+ a$ U" Z这是编译好的固件。

本帖子中包含更多资源

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

×

评分

参与人数 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
6 n: ?" [& V7 d* ~8 x% S6 i7 c不错的设计,想问一下楼主,FC的15针公头怎么解决?普通的公头太短了,插不进去FC的扩展接口。 ...
# s- g' J" y6 d
坛友的改造方案
回复

使用道具 举报

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

使用道具 举报

发表于 2019-5-25 12:07:18 | 显示全部楼层
精彩,楼主动手强,也写得很详细。. D/ |% y$ H/ K5 z6 s
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
; L+ ]3 R9 O- O, ^0 _, T精彩,楼主动手强,也写得很详细。, G+ j  I( |! F- A( \2 Z
2.4G方案是目前无线的最低延迟吗?
' ^, r% C9 |- P3 z* Z
我没用过其他无线手柄,所以实在不知道我自己做的这个手柄到底是不是最低延迟。
3 e. u2 [7 L/ W0 D  A不过根据网上的说法,延迟高低主要是由通信协议的复杂程度,以及数据传输速率决定的。这个模块虽然是2.4G无线模块,但由于协议很简单,所以延迟比较低。
; d$ I: d$ w- @我用这个手柄玩一些ACT游戏,比如超级马里奥、忍者龙剑传、热血系列,完全感觉不到延迟,和游戏机自带的手柄没有任何区别。唯一的区别就是这个手柄是用火花山寨手柄改造的,外壳是垃圾回收塑料,粗糙+脆弱,导电橡胶弹性不佳,手感不是一般的差。
! S+ _0 m- Y; H7 k  z我手里还有十几张板子,等我有空了我再做一套,到时候买一个好一点的手柄改造。
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2019-5-29 17:00:34 | 显示全部楼层
孙大师 发表于 2019-5-28 18:55
* o4 D# O0 o8 c. l. z% q非常好,楼主是技术帝,到目前我都还没开发fc的无线套件,等空了,开发一套套件,等玩家自己组装。 ...
$ i: V& i+ R3 v, |# a5 s7 H
能得到孙大师的赞誉,不胜荣幸!
& e2 S0 C: u/ \不如开发一个多功能手柄,比如用SFC手柄改造,L/R键配合其他组合键可以用来切换2P~4P、调节连发速度、软重启等各种功能。接收端插到15PIN扩展口。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-5-15 21:50 , Processed in 0.112207 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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