| 
            
            
             
              【程序】 #include <stm32f10x.h> unsigned char table[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e, 0xbf};  void delay(void) {  uint16_t i;  for (i = 0; i < 20000; i++); } void display(uint8_t n) {  GPIO_ResetBits(GPIOB, 0xff00);  GPIO_SetBits(GPIOB, n << 8); } int main(void) {  GPIO_InitTypeDef in, out;  uint8_t col, row;  uint8_t i, keycode;    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);    // 默认输入/输出模式  in.GPIO_Mode = GPIO_Mode_IPU;  out.GPIO_Mode = GPIO_Mode_Out_PP;  out.GPIO_Speed = GPIO_Speed_2MHz;    // PB8~15用作数码管显示,为输出  out.GPIO_Pin = 0xff00;  GPIO_Init(GPIOB, &out);    display(0xbf); // 默认显示'-'  while (1)  {   // 第一步:和行扫描法一样,先将行线作为输出线, 列线作为输入线   out.GPIO_Pin = 0x0f;   GPIO_Init(GPIOA, &out);   in.GPIO_Pin = 0xf0;   GPIO_Init(GPIOA, &in);   GPIO_ResetBits(GPIOA, 0x0f); // 行线全输出0   col = GPIO_ReadInputData(GPIOA) & 0xf0; // 读取列线的值      // 按键消抖   if (col != 0xf0)   {    delay();    col = GPIO_ReadInputData(GPIOA) & 0xf0;    if (col != 0xf0)    {     // 第二步:从列线输出全0信号,再读取行线的输入值     out.GPIO_Pin = 0xf0;     GPIO_Init(GPIOA, &out);     in.GPIO_Pin = 0x0f;     GPIO_Init(GPIOA, &in);     GPIO_ResetBits(GPIOA, 0xf0);     row = GPIO_ReadInputData(GPIOA) & 0x0f;          // 行线有非1值的情况下才继续     // 防止出现按下了6显示的却是2的错误情况     if (row != 0x0f)     {      // 第三步:计算键码      row = ~row & 0x0f;      col = ~col >> 4 & 0x0f;      keycode = 0;      for (i = 0; i < 4; i++)      {       if (row & 1)       {        keycode = i * 4;        break;       }       row >>= 1;      }      for (i = 0; i < 4; i++)      {       if (col & 1)       {        keycode += i;        break;       }       col >>= 1;      }      display(table[keycode]);            while ((GPIO_ReadInputData(GPIOA) & 0x0f) != 0x0f);     }    }   }  } }
               
             |