手柄使用的是 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 }