原来在实习的时候公司要求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);//清除中断标志位,否则启动时会进入中断服务函数
}
}