文章归档友情连接照片地图

STM32的单键开关与GPIO复习

分类:电子设计  作者:rming  时间:2012-07-16

用到的东西大都是GPIO的知识了,首先硬件上如图

软件设计:

在之前做的GPIO口基础上,这里顺便也把GPIO口的软件设计再复习下吧

GPIO_Init() 首先把GPIO->CRL或者CRH里设置IO状态,然后在GPIO->ODR或者IDR里初始化默认的输入输出数据

LED0和LED1的头文件设置里,是通过PAin()和PAout()两个自建的函数里通过位带操作直接用LED0和LED1操作bitn,如:操作PA3 则LED0=PAout(3) ,具体的实现方法可以查看代码:

//LED.H
#ifndef __LED_H
#define __LED_H
#include "sys.h"
#define LED0 PAout(8)
#define LED1 PDout(2)
void led_init(void);
#endif

 

 //sys.H L44
//IO口操作,只对单一的IO口!
//确保n的值小于16!
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入
#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入
#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入
#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出
#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入
#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出
#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入
#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出
#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入
#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出
#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入

一块贴下设置LED的代码吧,感觉这部分挺核心的,启用PORT时钟,清除原状态,设置端口输出状态,设置端口输入输出数据。

//LED.C
#include <stm32f10x_lib.h>
#include"led.h"
void led_init(void)
{
//APB2ENR外设时钟使能
RCC->APB2ENR|=1<<2;	//使能PORTA时钟
RCC->APB2ENR|=1<<5;	//使能PORTD时钟
GPIOA->CRH&=0XFFFFFFF0;	//清除原状态
GPIOA->CRH|=0X00000003;	//PA8推挽输出
GPIOA->ODR|=1<<8;	//PA8输出数据位高电平
GPIOD->CRL&=0XFFFFF0FF;	//清除原状态
GPIOD->CRL|=0X00000300;	//PD2推挽输出
GPIOD->ODR|=1<<2;	//PD2输出数据位高电平
}
最后是键盘扫描的程序了,提前些好的键盘扫描子程序,然后再主循环里抓取键值,执行相应的操作。
其中对键盘的初始化,还是使用到了位带操作,原理与DS0和DS1的设置时相似的。
键盘的扫描程序同51的类似,同样的道理,51的矩阵键盘也可以移植到这里。
//KEY.C
#include <stm32f10x_lib.h>
#include "key.h"
#include "delay.h"
//按键输入初始化函数 驱动代码
//PA0 13 15设置成输入模式
void key_init(void)
{
RCC->APB2ENR|=1<<2; //使能PORTA外部时钟
GPIOA->CRL&=0XFFFFFFF0;//PA0设置成输入
GPIOA->CRL|=0X00000008;
GPIOA->CRH&=0X0F0FFFFF;//PA13 PA15设置成输入模式
GPIOA->CRH|=0X80800000;
GPIOA->ODR|=1<<13;//PA13上拉(默认下拉)
GPIOA->ODR|=1<<15;//PA15上拉(默认下拉)
}
//按键处理函数
//返回按键值
//0,没有按键按下
//1,KEY0按下
//2,KEY1按下
//3,KEY2按下 WK_UP
//函数有按键响应优先级 KEY0>KEY1>KEY2
u8 key_scan(void)
{
static u8 key_up=1; //按键松开标志
//JTAG_Set(JTAG_SWD_DISABLE);
if(key_up&&(KEY0==0||KEY1==0||KEY2==1))
{
delay_ms(10);//去抖动
key_up=0;
if(KEY0==0)
{
//JTAG_Set(SWD_ENABLE);
return 1;
}else if(KEY1==0)
{
//JTAG_Set(SWD_ENABLE);
return 2;
}else if(KEY2==1)
{
//JTAG_Set(SWD_ENABLE);
return 3;
}
}else if(KEY0==1&&KEY1==1&&KEY2==0) key_up=1;
//JTAG_Set(SWD_ENABLE);
return 0;//无按键按下
}
最后这个是主循环,没什么可说的了,抓取键值,做出相应的处理。
//MAIN.C
#include <stm32f10x_lib.h>
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
#include "key.h"
int main(void)
{
u8 t;
Stm32_Clock_Init(9);
delay_init(72);
led_init();
key_init();
while(1)
{
t=key_scan();//子函数抓取键值 查询方式
if(t)
{
switch(t)
{
case 1:
LED0=!LED0;
break;
case 2:
LED1=!LED1;
break;
case 3:
LED0=!LED0;
LED1=!LED1;
break;
}
}else delay_ms(10);
}
}

项目文件下载:proj4



提交评论