nes 红白机模拟器 第3篇 游戏手柄测试 51 STM32
手柄使用的是 CD4021 ,datasheet 上说支持 3V - 15V 。
因为手柄是 5V 供电,2440 开发板上是GPIO 3.3V 电平,STM32 GPIO 也是 3.3V (也兼容5V)电平。
所以先在 STM32 上测试能用后,在接到 2440 开发板上。
正好是 8个键值,用来点 8个 LED 。按下一个键,就会亮一个灯。
c51 :
1 #include <reg52.h> 2 3 sbit CLK = P2 ^ 2; 4 sbit LATCH = P2 ^ 1; 5 sbit DAT0 = P2 ^ 0; 6 7 void Delay10us() //@11.0592MHz 8 { 9 unsigned char i; 10 i = 2; 11 while (--i); 12 } 13 14 unsigned char joypad() 15 { 16 int i; 17 unsigned char cmd = 0; 18 LATCH = 1; 19 Delay10us(); 20 LATCH = 0; 21 for(i=0; i<8;i++) 22 { 23 Delay10us(); 24 if(DAT0) 25 { 26 cmd |= 1<<i; 27 } 28 CLK = 1; 29 Delay10us(); 30 CLK = 0; 31 } 32 LATCH = CLK = 0; 33 return cmd; 34 } 35 36 int main() 37 { 38 unsigned char cmd; 39 CLK = LATCH = DAT0 = 0; 40 Delay10us(); 41 while(1) 42 { 43 cmd = joypad(); 44 //点灯 45 P1 = cmd; 46 } 47 }
STM32 : 主要部分,其它部分源码,可以在STM32分类里面找到。
1 #include "stm32f10x.h" 2 #include "bitband.h" 3 #include "delay.h" 4 5 void SystemInit() 6 { 7 RCC->CR |= RCC_CR_HSEON; /* 外部时钟开 */ 8 while(! (RCC->CR & RCC_CR_HSERDY)); /* 检查标志位判断是否就续 */ 9 10 RCC->CFGR = RCC_CFGR_PPRE1_2; /* APB1低速设备2分频72M/2=36M */ 11 RCC->CFGR |= RCC_CFGR_PLLMULL9; /* PLL 9 倍频 */ 12 RCC->CFGR |= RCC_CFGR_PLLSRC; /* HSE 做为 PLL 输入 */ 13 14 FLASH->ACR |= 2; /* 2个等待状态 72M */ 15 16 RCC->CR |= RCC_CR_PLLON; /* 启用 PLL */ 17 while(! (RCC->CR & RCC_CR_HSERDY)); /* 检查标志位判断是否就续 */ 18 19 RCC->CFGR |=RCC_CFGR_SW_PLL; /* 选择外部时钟作为系统时钟 */ 20 while(2 != ((RCC->CFGR>>2) & 3)); /* 检查标志位判断是否就续 */ 21 } 22 23 u8 joypad() 24 { 25 int i; 26 u8 cmd = 0; 27 GPC_BSRR(1) = 1; 28 delay_us(10); 29 GPC_BRR(1) = 1; 30 for(i=0; i<8;i++) 31 { 32 delay_us(10); 33 //低电平时表示按下了 34 if(0 == GPC_IDR(2)) 35 { 36 cmd |= 1<<i; 37 } 38 GPC_BSRR(0) = 1; 39 delay_us(10); 40 GPC_BRR(0) = 1; 41 } 42 GPC_BRR(0) = 1; 43 GPC_BRR(1) = 1; 44 return cmd; 45 } 46 47 int main(void) 48 { 49 u8 cmd; 50 //引脚启用时钟 IOA IOB IOC 51 RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN; 52 53 GPIOC->CRL = 0; 54 55 //配置LED灯引脚模式 PC7 56 GPIOC->CRL |= GPIO_CRL_MODE7; //MODE 设为 11 :50M 输出模式 57 GPC_BSRR(7) = 1; 58 59 //配置 手柄CLK引脚模式 PC0 60 GPIOC->CRL |= GPIO_CRL_MODE0; //MODE 设为 11 :50M 输出模式 61 //默认 低电平 62 GPC_BRR(0) = 1; 63 64 //配置 手柄LATCH引脚模式 PC1 65 GPIOC->CRL |= GPIO_CRL_MODE1; //MODE 设为 11 :50M 输出模式 66 //默认 低电平 67 GPC_BRR(1) = 1; 68 69 //手柄 DAT0 输入引脚 PC2 70 GPIOC->CRL |= GPIO_CRL_CNF2_1; //10 输入模式 上拉 / 下拉 71 //设置下拉 72 GPC_BRR(2) = 1; 73 74 //循环点亮 75 while(1) 76 { 77 cmd = joypad(); 78 //如果有输入就点LED 79 if(cmd) 80 { 81 GPC_ODR(7) = 0; 82 } 83 else 84 { 85 GPC_ODR(7) = 1; 86 } 87 88 } 89 return 0; 90 }