找回密码
 注册

QQ登录

只需一步,快速开始

查看: 24756|回复: 32

自制FC无线手柄

  [复制链接]
发表于 2019-5-22 14:16:45 | 显示全部楼层 |阅读模式
本帖最后由 雷精灵2046 于 2019-6-14 09:28 编辑 , z8 Z, J, M( J3 V6 t' {" H

! r. N/ g/ j' S3 W* Q- F5 J# t没有用复杂的分立元件搭建发射接收电路,直接用的现成的2.4G无线模块jdy-40。) M5 G: n1 X7 o: i5 ~3 |0 T9 K; g3 P

" a( M# l- L: E6 {/ f7 I
9 u1 R3 o, c& U" A. E发射端靠3.7V锂电池供电,用了一片SOP8封装的STC单片机,负责产生连发脉冲,同时负责检测电池电量,电压低于3V左右的时候触发低压中断,低压指示LED就会亮起来告知该充电了。平时发射模块和单片机均处于睡眠状态,有按键按下才会唤醒,从而实现省电。实测睡眠状态下整机电流约1~2uA。板子洗了一下稍微干净了一点。因为对于微功耗设备来说,焊接残余的助焊剂可能会增加漏电流。& V- c- A% {2 v6 l8 o4 e
- x- f; }+ }$ S- O, `
买了一个火花的FC山寨手柄,去掉里面的牛屎板子,并修正一下塑料挡板,把锂电池和充电模块装进去。
# F& V3 c: C8 c% `8 J9 J% |" w' a为了减少体积,充电模块裁剪得十分小,并且更换了充电电阻使之适应这个小小的锂电池。这么小容量的电池,也不需要多么大的充电电流是吧?
* Q3 u0 z6 G( f5 `+ G) B然后统统用热熔胶粘上。充电电流比较小,所以发热很少,不会熔化热熔胶。0 {8 d; m6 K/ F: a$ I+ k. j

8 W7 P2 Y) @, b& U% k
, j' v2 I  [" b/ O+ a- P. _0 D6 [+ X2 ]/ C
最后把按键、导电橡胶和电路板装上去。
. n6 o9 F* U& z8 h9 o" |, q精心裁剪了电路板,正好扣上,不会阻碍其他元件,也不会影响后盖和拧螺丝。& H# N4 a/ v2 t8 U
) q) ?: C( Q  i+ B+ T1 t9 T

7 l7 z" N' o3 K完工!
5 G+ N% R4 y4 |8 f
% u( u2 `0 G6 }! z9 U
; b$ C+ a7 c- Q7 X! G这是充电的MicroUSB插座。旁边的小孔用于透出低压报警LED的光线。
/ c" r( c# x) X
, C+ J; }7 C2 Z* t, n" y  U4 F; J( C" a, t( L( `. _1 m
接收端用一片DIP16封装的STC单片机模拟CD4021。为啥要用单片机模拟而不是直接用CD4021?因为jdy-40模块接收端在有按键按下的时候输出高电平,无按键按下输出低电平,和普通手柄正好相反。当然我也可以用两片74HC00或者74HC04之类的逻辑门进行反相,但那就增加了芯片的数量。对于FC手柄这种工作频率并不高的设备来说,STC单片机完全可以胜任模拟工作。
1 O& g! ?2 _5 {
5 Y0 S+ C7 ^& ?; n; V4 `1 s
9 t5 r1 M. F9 `8 Y9 h7 C. R; B2 H" p+ @
电路设计有点小小的错误,所以有几根飞线。原本设计使用低压差LDO是XC6206,结果在做这个接收模块的时候,买的LDO居然找不到了!无奈只好用了AMS1117。幸好对于接收模块来说是5V降到3.3V,1117可以胜任。要是发射端手柄的话,3.7V降到3.3V,那就非得用6206不可了。( r: G( V/ L+ V+ z3 Y
' U* v' Q, S$ z4 x' P4 J0 _- L
实测十分灵敏,延迟极小几乎感觉不出来。可惜这山寨手柄的手感并不佳,尤其是方向键,软塌塌的。看来我得买个剪线手柄改装。, k. l- E' t: v& X
2 e) l, r! x) y$ [
这是电路图,有兴趣的朋友可以参考。
' \2 X4 h$ d' h
' m# U$ T& G9 N1 p6 G: T+ \+ B+ H% s* Z
我信奉开源主义,十分痛恨把技术藏着掖着。好东西大家分享嘛!所以两个单片机的源代码大公开!! c8 y: Z2 o! u. P* j
编译器:Keil 51。
2 g: I2 h4 t& ^$ T! E3 f# ]: S3 n+ B+ Y
发射端:
- Q$ \$ `9 u6 h! M5 F) `2 u0 O
  1. #include <INTRINS.H>
    ; H; V3 M5 \& ^- Q# e9 i7 z9 ^% t
  2. #include "STC15W.h"- c8 s0 n3 g! ]: I

  3. , O; }3 k6 n& K& ?+ W4 d/ ?
  4.   t4 h. L1 d" l) Y
  5. /*( l5 x# \* u/ @! t- h2 o5 U8 u
  6. --------------------------
    + C; @/ C1 K2 `1 R
  7. |1 (OUT)        \__/   (INT1) 8|
    . E& Y5 `$ c' N- j) ~/ y! m/ l
  8. |                                                   |  h5 j* C( Q! B4 n) I
  9. |2 (VCC)                   (INT0) 7|
    3 B& o8 g1 l! ]  i+ ^
  10. |                 STC15W204S                   |
    5 I7 |  E" \* r6 J4 q' l4 s7 Y
  11. |3 (LED)                         (TXD) 6|- E$ S6 Y, K8 H% g
  12. |                                                   |
    9 A& b/ P$ T, Q" {, a' o: j
  13. |4 (GND)                         (RXD) 5|
    ! ^3 W$ B/ G& ]* N
  14. --------------------------% E3 q- K- I+ h" c2 v

  15. / Y1 u+ J( Y! t% H' o
  16. LED ---|<|---[===]--- VCC& C3 W+ e. r" L) p4 z& u$ w! l% x
  17.            Red          330/ I2 T* S8 K' D( K. @
  18. # T+ _. K3 A7 F) s: C4 I) M5 i
  19. Fosc = 6MHz0 |" D' `% j+ \  y' V9 q2 w4 t
  20. */! A. ^' ^. R1 V; Z" O4 w( a! q
  21. , U0 h& e- J' I5 t6 M4 }$ B# P, ]9 ~
  22. - l9 e; n, A9 R+ N5 u4 R. k' ]
  23. // 矩形波输出脚- f1 |  s" A  H5 u; |! n: ^+ s7 j
  24. sbit OUT = P5^4;: K  s! h7 V9 l* c7 W* m
  25. // 低压指示灯引脚/ {8 K" H" M3 ]4 p8 p  ]( K5 ?. E
  26. sbit LED = P5^5;
    ( _( w( s5 q6 \  }( _
  27. % M, M7 ?' Q; p% l2 t" f
  28. // 停机标志位
    1 X) e6 X- }, f  \3 a# l" y4 N
  29. bit isReadyToHalt = 0;
    0 M6 E0 {* v' g' N  Y
  30. 3 x) K; B7 s5 y, n/ D. ]
  31. // 矩形波次数累计
    + Q2 T; f7 H( |% z+ T
  32. static volatile unsigned char count = 0;
    $ J" g* ]4 q: I0 ^- g& n0 @
  33. ' M5 n  S2 [- r. D; r! |" z4 k1 u
  34. ( C# n, S0 Y7 Q& I% I+ d
  35. static void GPIO_Init(){" U! l( K8 c+ E" z1 o, @7 M  [
  36.         // P3口设置为准双向,默认靠内部弱上拉输出高电平; x7 f; _; ~0 }7 z/ T/ G
  37.         P3M0 = 0;9 G, h, R# e9 g- J
  38.         P3M1 = 0;
    ! [! E7 o* R7 h2 S: l
  39.         P3 = 0xFF;
    6 Z# }7 @' `7 Y# s' m8 F+ H
  40.         // P5口设置为准双向,默认靠内部弱上拉输出高电平" `9 X8 c. |: _: ~5 [& V3 U1 A
  41.         P5M0 = 0;9 p9 r" t) A: U' k4 _* R* l
  42.         P5M1 = 0;
    $ T: l9 X& l6 H0 ^* X# |
  43.         P5 = 0xFF;+ D) ~" R, \: C, v% }3 W
  44. }
    - K, t, _4 b2 C5 j0 |; }

  45. + y. J* i, a# C+ j- K$ b4 ~
  46. static void Timer0_Init(){
    2 g  H5 e; }1 O/ P$ \6 V
  47.         // 16毫秒@6.000MHz. K& i) N& y( N& `7 O& D
  48.         AUXR &= 0x7F;        // 定时器时钟12T模式
    8 {" {2 a; {& q! Q
  49.         TMOD &= 0xF0;        // 设置定时器模式; r# Z! y- k  @6 [6 E) T( Q0 N
  50.         TL0 = 0xC0;                // 设置定时初值; |! P7 e( C4 G5 F2 f( [
  51.         TH0 = 0xE0;                // 设置定时初值+ h9 o- A$ r  {) j; a0 a. l5 y
  52.         TF0 = 0;                // 清除TF0标志
    + s+ R6 q2 m4 P1 K- L
  53.         TR0 = 1;                // 定时器0开始计时' s; @. J( A4 u3 `& `
  54. }8 C- @) G: q/ L0 @! M; E
  55. + [  u" Y* K; F0 L+ i% u  _' |
  56. static void Interrupt_Init(){
    2 S& c/ e; D! F% {5 C
  57.         // INT0中断触发类型为下降沿触发
    4 P$ c$ Z1 n& N8 w, ~
  58.         IT0 = 1;4 n/ L3 L  C( Y: \% K
  59.         // 允许INT0中断- F% Q& r+ r' m  B
  60.         EX0 = 1;8 p1 P$ ^8 a( j4 h
  61.         // INT1中断触发类型为下降沿触发
    2 Q2 V8 @; ]5 z! u
  62.         IT1 = 1;# S0 H. M0 J6 [5 @5 c
  63.         // 允许INT1中断+ C9 ^0 W* \5 Z) {% |
  64.         EX1 = 1;
    9 F& n% O5 L2 i- j1 g
  65.         // 允许定时器0中断: H, H$ `& i8 d, _+ f5 u
  66.         ET0 = 1;- f' _$ j! s, J- q7 g$ _0 y
  67.         // 允许全局中断; o& Z$ \) J  A9 E( {
  68.         EA = 1;1 V% ~* k. e% i7 ~0 |, P7 }
  69. }
    & G" a" j! E( [) Y& P+ ]: }5 z  M
  70. ' d0 S3 A/ s; p# h
  71. static void INT0_Isr() interrupt 0{5 a& H& ?+ G; E) j% ?4 c
  72.         // 矩形波次数累计归零5 G3 t: `/ k- _& p& o
  73.         count = 0;& }) S8 p7 z% N9 S  S5 Y; ?& B# h: b! a
  74.         // 重开定时器0中断
    2 q. n( o# Z& a8 A6 C( t! ]$ V% a8 ?: a, V
  75.         ET0 = 1;
    ! E6 m3 J! H- \
  76. }
      h7 v9 q7 P  F: K6 f9 L# b
  77. 4 E% [7 O; m7 k6 M7 L5 |3 @
  78. static void Timer0_Isr() interrupt 1{' j9 ^9 \$ x6 J$ j# J
  79.         // 输出矩形波
    / u9 N. u8 g1 q
  80.         OUT = ~OUT;
    / L5 r2 F. w0 x, {* r
  81.         // 累计矩形波次数" N4 y2 t+ {* E1 _8 b+ l# a
  82.         count++;
    9 R( E( G. c- a: ?) k7 ?: \3 o# H4 B6 d
  83.         // 超过250个矩形波,准备停机0 V- {  s9 [% O$ ~' x
  84.         if(count > 250){# J$ B$ A1 v0 W5 @; H& a2 G
  85.                 count = 0;
    " H6 K* d8 H/ w. W5 i) u8 q
  86.                 isReadyToHalt = 1;
    3 [3 G  \0 u) o0 Y: q% I* }# x
  87.         }
    6 G+ Z4 s# i5 U9 S- @6 V0 Y. a
  88. }
    6 r% N5 g8 Z: ^5 B" _
  89. 2 [3 d# R7 r; U2 l: T# z9 \2 ~
  90. static void INT1_Isr() interrupt 2{  C  e5 J: X2 S8 j& W% W1 h
  91.         // 矩形波次数累计归零
    + h" I2 R/ \5 E% W+ J
  92.         count = 0;7 B3 L* r* @7 J* F
  93.         // 重开定时器0中断
    , l! T8 Z  z$ M7 {9 k7 j' g
  94.         ET0 = 1;3 K. X6 r. n: }$ S
  95. }
    * G; r8 X) G/ l  r  I& Z- o2 ]/ K

  96. 3 h3 a, j6 R5 F* A

  97. ! \# z; Y2 ^# o3 ^: i/ z
  98. void main(){  N  q" k/ c* Q0 B
  99.         // 初始化P3和P5口. n( o& Y' c/ E# d7 A
  100.         GPIO_Init();
    0 e% j/ @' f$ O8 Z, U1 v- Q
  101.         // 初始化定时器04 d. h7 z) z9 F" j; J7 f
  102.         Timer0_Init();, r4 M) L: _) M
  103.         // 初始化中断
    . [( i! [# k3 W
  104.         Interrupt_Init();0 K2 d. g* c: Y: P* }0 e( l, s+ e
  105.         5 Y, \% {8 r( {; b1 x3 u+ e. y
  106.         while(1){( n& }( V5 H. q; _
  107.                 // 检测电量
    : {8 G- Y% k! H, `/ M6 {5 s
  108.                 if(PCON & (1 << 5)){
    8 B0 E  u" T) d) L
  109.                         // 如果电量低,低压指示灯亮3 l) _9 o- G" v
  110.                         LED = 0;2 N' [7 A) S4 U; v
  111.                         // 清电量检测硬件标志位
    8 d1 W0 L' \4 e. a0 K1 C
  112.                         PCON &= ~(1 << 5);8 r4 E8 F2 X7 \. D  X
  113.                 }else{
    9 h, ^# T# n. H$ y
  114.                         // 电量正常,低压指示灯灭5 R. \! }, w2 h7 c- z. A
  115.                         LED = 1;
    3 d* i7 O; {( i4 V( z
  116.                 }* I5 n6 z7 Y8 e" w; S4 `; q& K6 G
  117. : L$ g' c! G. }0 U7 D$ {
  118.                 // 检测到停机标志- `6 X$ U; c* j; r, \
  119.                 if(isReadyToHalt == 1){
    # ]3 x% f- y; X/ ^! g
  120.                         // 暂时关闭定时器0中断
    , Q+ y  }# m& y8 k6 s/ E- F
  121.                         ET0 = 0;4 N( A. O, S7 L9 ~1 g
  122.                         // 停机之前先把矩形波输出脚置低电平,以方便INT0和INT1唤醒CPU
    4 D& f5 S( ^$ z5 ^
  123.                         OUT = 0;- y8 Y& V3 i8 ~" f! A: N
  124.                         // 停机之前先把低压指示灯灭掉,以省电
    4 n9 _/ [  l7 P: q1 a
  125.                         LED = 1;
    : a4 ?3 Z1 ], A. V# Z# Q8 i2 w
  126.                         // 进入停机模式
    0 ?1 o' i; q8 G! k
  127.                         PCON |= 0x02;
    ' _9 J6 t6 r- k" a: C% Q1 @; P( h
  128.                         _nop_();/ f7 C2 y4 M; l* ?
  129.                         _nop_();0 ~+ v; `2 g4 I" y3 v
  130.                         _nop_();
    ( \  k; o% ]- u( l; K1 o6 B
  131.                         _nop_();
    6 A. ^7 A% T  Y, j# H6 f- Z/ A
  132.                         // 唤醒,清标志位
    % o1 @0 [  ]0 a9 x& _( b/ W- T  o
  133.                         isReadyToHalt = 0;- s* i; p8 S- K# A
  134.                         // 重开定时器0中断1 I4 A/ F* ]3 V3 G/ j
  135.                         ET0 = 1;
      P0 G: ^+ k) i
  136.                 }9 b7 I$ _3 z1 B& D& t
  137.         }
    $ l. m% z3 x) M- l4 W$ K% g
  138. }
    0 \/ j& x" ?8 o2 A8 X! g1 F, H
复制代码
5 |. G6 D0 k7 q  J& l9 m7 v
硬件参数配置:
4 f# p9 V2 N' ^) h  ]$ k2 o
# u2 E: d9 i& w" g' E9 S5 W2 V  f6 x! V! ~0 P/ ], V6 K2 q
接收端:. Q1 K' k2 [6 d$ f; t8 t5 h( B
  1. #include <INTRINS.H>
    6 ?* ?; }; G" |3 a6 H
  2. #include "STC15W.h": j- m! `6 z6 [$ p0 O1 Y/ z8 Z# [
  3. . ?+ h3 y. g. p) I, Z. C3 I

  4. 1 [) ^/ S# L; K& k
  5. /*2 G/ `0 k8 i7 K4 F% g
  6. - u1 @5 ?% }+ a0 M! u: H
  7. *---------------------------*
    1 @/ i* I7 H  v6 j$ L+ d
  8. |1 (GPIO2)         \__/  (GPIO1)16|
    ) c- K6 C7 K& m# V* p
  9. |                                                        |
    ! T, j" p, ~6 B1 ~; W5 v
  10. |2 (GPIO3)                   (GPIO0)15|4 {$ O4 J4 v5 E
  11. |                                                        |. O- H: s( X1 n
  12. |3 (GPIO4)                                  14|; k" B3 I9 Y8 p
  13. |                                                        |9 F2 e  y) J6 `* E$ h2 C
  14. |4 (GPIO5)                        (DATA)13|: ^1 z3 Y4 n8 g5 Q2 |2 ]/ |
  15. |                  STC15W204S                |7 o6 h% E9 M8 ]% W* g6 M% f
  16. |5 (GPIO6)                   (LATCH)12|8 a2 e- \4 t. V5 G
  17. |                                                        |
    0 v4 e" Q, n6 B' l& u' ]9 c, z5 ~
  18. |6 (VCC)                         (CLK)11|
    / I7 v4 Z5 R' g/ ?( t5 e
  19. |                                                          |
    , m, o9 e% J4 I- b3 D
  20. |7 (GPIO7)                         (TXD)10|7 r" n/ [, |3 a" f2 X3 ^0 i( B
  21. |                                                        |; h! `, j) ~! E# i& t
  22. |8 (GND)                         (RXD) 9|9 w7 S/ O- {+ ?
  23. *---------------------------*
    . R2 _( l, R9 l
  24. Fosc = 12MHz: ~- t) o! Z# E# S: S7 e

  25. # t; S1 j4 I1 L$ ^* N5 l
  26. P1.0 -> 上; i) A% F# g- O/ Y( X
  27. P1.1 -> 左4 v# w! a/ X  P8 k7 [4 J
  28. P1.2 -> 下
    8 L0 Z3 ~. s  v5 z) ?
  29. P1.3 -> 右
    9 i* x# ~5 y' g; X; c2 v; F1 x  Y/ p
  30. P1.4 -> SEL; t6 |/ {3 ?! p5 H0 F  F0 p/ `
  31. P1.5 -> STA
    8 y. c% L9 \& x6 M
  32. P5.4 -> B
    : W  Y$ t: n4 c3 f( E  |
  33. P5.5 -> A
    3 v" O( G" f: \/ C% _9 I: Z
  34. ( [7 A$ R; i! c1 |
  35. */% e: V' H% y- U0 ^2 s
  36. 1 p  q0 n$ c3 H. c( S8 g1 N
  37. 3 {) ~/ K2 U8 W- {; P
  38. sbit CLK        = P3^2;2 X- g% N* _1 z4 E
  39. sbit LATCH        = P3^3;
    4 o+ b' U" S) x1 P
  40. sbit DATA        = P3^6;
    4 V3 @* F. |3 i/ |$ i! `

  41. 9 j3 f) H  ?, ]/ ]* z# C, z
  42. bit isReady = 0;
    ; E3 i# _7 z; P
  43. static unsigned char key = 0;& K. f* t8 v3 Y5 k  ?2 Q$ k% L
  44. static unsigned char buf = 0;        // 双缓冲。这个缓冲区保存从P1和P5组合而来的键值7 D1 z5 ?5 w* u8 w* x7 q- X
  45. static unsigned char bufReady = 0;        // 双缓冲。这个缓冲区保存上面那个缓冲区的备份
    ; P0 d# _" p7 @  k4 ]5 O
  46. static const unsigned char data mask[] = {0x80, 0x40, 0x10, 0x20, 0x01, 0x04, 0x02, 0x08};        // A B SELECT START UP DOWN LEFT RIGHT。为提升速度,这个表放到RAM中$ D  P' f  q6 b/ V
  47. static unsigned char idx = 0;! |, a& h. O! S7 n! g8 j
  48. " a! Z/ @: l2 C" h1 c8 ?
  49. * I" k) O* p# L8 h
  50. static void GPIO_Init(){. ^- P. J+ s7 I" M" \* U/ e/ I
  51.         // P1口和P5口用于接收并行信号,全部初始化为准双向,依靠内部弱上拉输出高电平% y' ]! R: }, V9 Y
  52.         P1M0 = 0;9 j! K- Q4 y5 K9 S$ G8 P( N4 l
  53.         P1M1 = 0;: r6 ~8 k. N  c
  54.         P1= 0xFF;' a' z' h; l, Y( i0 ]+ c
  55.         P5M0 = 0;/ S5 l" l1 p1 C. G4 T( U. M! A6 R
  56.         P5M1 = 0;  ~: \2 B6 U% q
  57.         P5= 0xFF;# u6 z; ~- e& c/ q. H$ G
  58.         // P3口初始化为准双向
    ! \$ Y5 Y/ G, E
  59.         P3M0 = 0;/ I' @. e4 x, c  m* @5 M5 Y9 T5 t
  60.         P3M1 = 0;
    4 e% n3 o) M8 b4 d% }. `5 a1 u
  61.         P3 = 0xFF;
    % }( g7 Z# f; t3 k8 Z* w# S9 D9 s2 b
  62. }
    - e9 O6 L- K9 g; }0 U6 J5 ^
  63. 0 `, |$ q1 A( Y1 l
  64. static void Interrupt_Init(){$ }$ l, Z. A# k  O/ V
  65.         // INT0中断(CLK)触发类型为上升沿+下降沿8 \% i% l8 {# x( V
  66.         IT0 = 0;
    3 }& u- C- x' l# f' }
  67.         // 允许INT0中断% S# Z) l0 _  j  i+ N5 v
  68.         EX0 = 1;1 s6 T# i5 z4 o: M
  69.         // INT1中断(LATCH)触发类型为上升沿+下降沿2 }% B6 p5 E! O: A' \
  70.         IT1 = 0;
    * f( x! g& Y: b- @1 X7 I
  71.         // 允许INT1中断# u& F: p; P  j- n0 g, W
  72.         EX1 = 1;% m: |' }5 @: `5 B
  73.         // 开启全局中断/ r- J/ G( ]6 Q0 N& u
  74.         EA = 1;/ e- b# d  }4 u: K/ u" e. a
  75. }
    ( I+ S: M4 u2 c1 y% c6 I3 a  G
  76. ; A, ]- ^, ^! D& A; i. C" ]! |
  77. static void INT0_Isr() interrupt 0{" _; t* Q$ m9 D9 _( j
  78.         // 只有已经成功锁存才允许CLK移位
    3 m+ g4 |0 F" Y$ S
  79.         if(isReady == 0)% b2 y* @. c1 v& G
  80.                 return;6 v5 s" e% A* ^! {( G7 h
  81.         // 读当前引脚电平,如果是低电平则说明是下降沿,此时直接忽略该中断# \  S! j# N/ D' a( E/ [+ }# f
  82.         if(CLK == 0)! t. E) Z5 Y. q
  83.                 return;& y" ^7 B9 S& w9 z) y
  84.         // CLK上升沿到来的时候,取锁存值的下一位输出8 {  ^3 ~3 I1 p4 e" h. Z) a* N) n4 c* l7 `/ Q
  85.         idx++;/ ]) N1 I( E$ Z* D8 o
  86.         DATA = key & mask[idx];
    ) q' U& ?2 W6 [( i7 T/ G8 W1 j
  87.         // 如果已经完成7次移位,则一轮读取完成) R7 \5 H9 p" Y! Q* c, C
  88.         if(idx >= 7)
    8 U: t( I. r% C1 K! r: l- u; a
  89.                 isReady = 0;
    , b. N: X  @5 h0 }! y7 I
  90. }
    ' R' n4 U8 t& B* O9 o( |

  91. ' x9 B1 o" w: y( S- K+ G
  92. static void INT1_Isr() interrupt 2{3 ~# O6 M- V* A; i; v
  93.         // 读当前引脚电平,如果是低电平则说明是下降沿,此时直接忽略该中断9 O! x1 Y- D( b- J
  94.         if(LATCH == 0)
    3 U! ~! X* r& e1 x
  95.                 return;
    : ?7 F2 @1 u2 Q4 `; @
  96.         // 当LATCH上升沿到来的时候,锁存所有按键状态,同时把键值A输出到DATA! Z& t; g! @. i2 H4 f
  97.         key = bufReady;
      P' l! l6 Y0 i) h) v
  98.         DATA = key & 0x80;//mask[0];        // 为了加速运算,直接取表中的值而不是读表
    2 p5 B3 P; k6 ]
  99.         idx = 0;
    0 Z' Y' D' B8 I# M
  100.         // 允许CLK进行移位8 V1 B0 ?4 {  z" f/ J; I
  101.         isReady = 1;# H! ?4 T  s7 I
  102. }
    3 V$ h& I; j5 a# t1 |9 w

  103. 1 u5 L' A8 |& C, i5 c
  104. void main(){* e( d' ?+ _$ Y. ~7 A& o7 J# C7 b* o
  105.         GPIO_Init();3 ?8 e/ h7 m* B' L9 ~
  106.         Interrupt_Init();: }+ M2 Y0 x" N( X: p. ?1 u+ N
  107.         , a7 [8 z  Q; j: H2 \) A
  108.         while(1){
    # b; a0 h5 N6 U' ~9 r
  109.                 //PCON |= 0x01;        // 进入省电模式
    2 R1 H9 Y. p  v+ [
  110.                 //_nop_();
    ; n  J' b* ^" v! Z
  111.                 //_nop_();
    8 i3 t( W& C( |
  112.                 //_nop_();
    0 H8 c/ Q* X7 E  g& |4 L, K- m
  113.                 //_nop_();
    0 B0 o9 @. p$ j
  114.                 buf = ~((P1 & 0x3F) | ((P5 << 2) & 0xC0));- H+ D( G5 I. N8 J
  115.                 bufReady = buf;
    7 R1 N0 F# X/ T) M+ m" I
  116.         }4 X/ a6 o( e: J4 l+ M$ e3 H+ K
  117. }7 [; C& F- g3 ?7 d( n! c/ W
复制代码

. N3 W( ^, T$ |硬件参数配置无特殊要求,晶振频率选择12M即可。
7 p7 d7 J* X) k: g& U7 h* H! `
" x& l! V/ U% w* O- O这是编译好的固件。

本帖子中包含更多资源

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

×

评分

参与人数 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# S) m1 j' S不错的设计,想问一下楼主,FC的15针公头怎么解决?普通的公头太短了,插不进去FC的扩展接口。 ...
) t, Y' j: \7 r6 U( ~* C! C
坛友的改造方案
回复

使用道具 举报

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

使用道具 举报

发表于 2019-5-25 12:07:18 | 显示全部楼层
精彩,楼主动手强,也写得很详细。* Q& Y, m; ]8 C$ y& Y& [9 j+ V$ Q7 H
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
3 M: y2 u6 |( N0 V精彩,楼主动手强,也写得很详细。7 O! X- k6 U3 d9 [7 D+ F
2.4G方案是目前无线的最低延迟吗?

+ C/ |- ]9 \% G4 H+ [! \- F我没用过其他无线手柄,所以实在不知道我自己做的这个手柄到底是不是最低延迟。
3 u6 V; N+ H$ [  i不过根据网上的说法,延迟高低主要是由通信协议的复杂程度,以及数据传输速率决定的。这个模块虽然是2.4G无线模块,但由于协议很简单,所以延迟比较低。
8 Z7 B; L% g5 p1 Q我用这个手柄玩一些ACT游戏,比如超级马里奥、忍者龙剑传、热血系列,完全感觉不到延迟,和游戏机自带的手柄没有任何区别。唯一的区别就是这个手柄是用火花山寨手柄改造的,外壳是垃圾回收塑料,粗糙+脆弱,导电橡胶弹性不佳,手感不是一般的差。
' Y' L8 a7 A* P) f3 X我手里还有十几张板子,等我有空了我再做一套,到时候买一个好一点的手柄改造。
回复

使用道具 举报

 楼主| 发表于 2019-5-29 16:56:14 | 显示全部楼层
ppad 发表于 2019-5-28 17:27' O; q7 o' F4 c3 z9 j
给技术帝赞一个,有半成品发布吗,自己焊接改造就可以,编程实在不会啊 ...
: A4 c$ ~4 ^: B- r& S
很可惜,我手里没有多余的单片机了,LDO也找不到了,锂电池以及充电模块更是没有了。反正就是该用到的元件基本都没了,所以没法发布半成品。  D8 }5 P% h; q
两个板子倒是有十几张剩余。# z  R6 g2 P( m, O" ?/ w8 S6 [# g
你要是有USB转TTL串口板,完全可以自己买这两种单片机,然后我给你编译好的固件,你自己用串口板下载到单片机里面就行了。两个2.4G无线模块也得通过串口板用AT命令设置参数,不过好在我在设计电路的时候就已经预留好了串口,可以直接在线下载和在线设置参数。总的来说并不麻烦。
回复

使用道具 举报

 楼主| 发表于 2019-5-29 17:00:34 | 显示全部楼层
孙大师 发表于 2019-5-28 18:55
! L: r& X2 H+ f! ?非常好,楼主是技术帝,到目前我都还没开发fc的无线套件,等空了,开发一套套件,等玩家自己组装。 ...
9 i% V2 Q7 r9 T, K% p
能得到孙大师的赞誉,不胜荣幸!  ~9 S) h) j. ^/ f" V
不如开发一个多功能手柄,比如用SFC手柄改造,L/R键配合其他组合键可以用来切换2P~4P、调节连发速度、软重启等各种功能。接收端插到15PIN扩展口。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-4-24 17:03 , Processed in 0.102751 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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