IO口分時復用的簡單實現


原來在實習的時候公司要求IO口的分時復用,按鍵與數碼管顯示

這里用stm32和仿真想簡單實現一下,但是不太成功,希望有大神指點。后面也會陸續更新各種按鍵方法和不同的數碼管

大概的方法就是用定時器不斷地去切換IO口的狀態,讀取按鍵的時候把鍵值保存,數碼管顯示的時候顯示,一直反復

 

 #include "stm32f10x.h"

char flag;

u16 table[]={0x3f,0x30,0x6d,0x79,0x72,0x5b,0x5f,0x31,0x7f,0x7b,0x77,0x5e,0x0f,0x7c,0x4f,0x47};

void delay(u8 cnt)
{int i,j;
for(i=0;i<cnt;i++)
{
    for(j=0;j<10000;j++){;}
}
}


void TIM2_Init(u16 CNT)
{//初始化
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //時鍾使能
    
  TIM_TimeBaseStructure.TIM_Period = CNT-1;  //重裝值,
    TIM_TimeBaseStructure.TIM_Prescaler =7200-1; //分頻系數,72M/7200=10KHz,其他依此類推
    TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設置時鍾分割:TDTS = Tck_tim
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上計數模式
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);     //把上述數值寫入對應寄存器
 
    TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);            //使能或者失能指定的TIM中斷
    
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;            //TIM2中斷
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占優先級0級
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //從優先級3級
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
    NVIC_Init(&NVIC_InitStructure);                 //把上述數值寫入對應寄存

    TIM_Cmd(TIM2, ENABLE);  //使能TIM2
}
void My_GPIO_Init_LED(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; //設定要操作的管腳
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //設置為推挽輸出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // IO口速度為50MHz
    GPIO_Init(GPIOA, &GPIO_InitStructure);

}

void My_GPIO_Init_KEY(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; //設定要操作的管腳
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // IO口速度為50MHz
    GPIO_Init(GPIOA, &GPIO_InitStructure);

}
int main()
{int i;
u16 keycode;
TIM2_Init(500);//50ms中斷一次
    while(1)
    {GPIO_ResetBits(GPIOA,GPIO_Pin_7);
        if(flag==1)
        {    
            My_GPIO_Init_KEY();
            keycode=GPIO_ReadInputData(GPIOA);
            flag=0;
        }
        My_GPIO_Init_LED();
        switch(keycode)
    {    
        case 0x00FE: GPIO_Write(GPIOA,table[1]);    break;
        case 0x00FD:GPIO_Write(GPIOA,table[2]);    break;
        case 0x00FB:GPIO_Write(GPIOA,table[3]);    break;
        case 0x00F7:GPIO_Write(GPIOA,table[4]);    break;
        case 0x00EF:GPIO_Write(GPIOA,table[5]);    break;
        case 0x00DF:GPIO_Write(GPIOA,table[6]);    break;
        case 0x00BF:GPIO_Write(GPIOA,table[7]);    break;
        default :GPIO_Write(GPIOA,table[0]);    
    }
    }
    
}
void TIM2_IRQHandler(void)//每次產生一個中斷溢出事件就會進入一次中斷函數
{
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)//檢測是否為溢出中斷
    {
        GPIO_SetBits(GPIOA,GPIO_Pin_7);
        flag=1;
                delay(100);
                TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//清除中斷標志位,否則啟動時會進入中斷服務函數
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM