/* ***************************************************** */
// 工 程 : N76E003AT20核心板
// 文件名 : GPIO
// 处理器 : N76E003AT20(TSSOP20)
// 编译环境 : Keil4 C51
// 系统时钟 : 内部RC时钟频率16MHz
// 功能说明 :
// 版 本 : V1.0
// 生成日期 : 2016-10-28
/* ***************************************************** */
// 功能: GPIO模式测试
//***********************************************************************************************************
// File Function: N76E003 GPIO demo code
//***********************************************************************************************************
#include <stdio.h>
#include "N76E003.h"
#include "Define.h"
#include "Common.h"
#include "Delay.h"
#include "SFR_Macro.h"
#include "Function_define.h"
#define Key1 P30 // 按键开关引脚
//#define T0_10MS 64203 //算法:65536-16000000/1000/12 ,16000000/1000/12是 12T模式1MS的值
UINT16 T0_CNT=0;
UINT8 u8TH0_Tmp,u8TL0_Tmp;
UINT8 SystemTime0_5Ms_cnt=0;
#define TH0_INIT 53333 //定义重装的初值 高位 定时5mS
#define TL0_INIT 53333 //定义重装的初值 低位
bit SystemTime0_5Ms=0; //定时器5的 5mS系统时标
// 枚举类型
/* ***************************************************** */
enum KeyState{StateInit,StateAffirm,StateSingle,StateRepeat};
/* ***************************************************** */
/********************************************************
* 函数名称:GPIO_init
* 输 入:无
* 输 出:无
* 功能描述: i/o口初始化
********************************************************/
void GPIO_init() // 端口初始化
{
P0M1=0x00; //如果板上P0口接了下拉电阻,上电后将补拉成低电平 若要想输出高电平 必设成推挽输出
P0M2=0x1f; // 将P0端口接LED灯的引脚配置为推挽输出
P1M1=0x00;
P1M2=0x07; // 将P1端口接LED灯的引脚配置为推挽输出
P3M1=0x00;
P3M2=0x00; // 将P3端口配置为准双向弱上拉方式
P0=0Xe0;; // 关闭P0口接的所有灯
P1=0Xf8;; // 关闭P1口接的所有灯
}
/* *****************************************************
* 函数名称:KeyScan(void)
* 函数功能:扫描按键
* 入口参数:无
* 出口参数:无
* 功能描述:基于状态机的
/* ***************************************************** */
void KeyScan(void)
{
static UINT16 KeyStateTemp = 0,KeyTime = 0;
UINT8 num;
bit KeyPressTemp;
KeyPressTemp=Key1; //读取I/O口的键值
switch(KeyStateTemp)
{
case StateInit: //按键初始状态
if(!KeyPressTemp) //当按键按下,状态切换到确认态
KeyStateTemp = StateAffirm;
break;
case StateAffirm: //按键确认态
if(!KeyPressTemp) //抖动已经消除
{
KeyTime = 0;
KeyStateTemp = StateSingle; //切换到单次触发态
}
else KeyStateTemp = StateInit; //还处于抖动状态,切换到初始态
break;
case StateSingle: //按键单发态
if(KeyPressTemp) //按下时间小于1s且按键已经释放
{
KeyStateTemp =StateInit; //按键释放,则回到初始态
P03=~P03; //LED取反 松手后有效
}
else if(++KeyTime >300) //按下时间大于3s(300*10ms)
{
KeyStateTemp = StateRepeat; //状态切换到连发态
KeyTime = 0;
}
break;
case StateRepeat: //按键连发态
if(KeyPressTemp)
KeyStateTemp = StateInit; //按键释放,则进初始态
else //按键未释放
{
if(++KeyTime > 10) //按键计时值大于100ms(10*10ms)
{
KeyTime = 0;
num++; //键值每过100ms加一次
if(8==num)
num = 0;
}
break;
}
break;
default: //KeyStateTemp = KeyStateTemp = StateInit;
break;
}
}
void main (void)
{
GPIO_init(); // IO端口初始化 // Define in Function_define.h
TIMER0_MODE1_ENABLE;
clr_T0M; //设置定时器0为12T
//set_T0M;
u8TH0_Tmp = (65536-TH0_INIT)/256;
u8TL0_Tmp = (65536-TL0_INIT)%256;
TH0 = u8TH0_Tmp;
TL0 = u8TL0_Tmp;
set_ET0; //开启 Timer0 中断
set_EA; //开启 总中断
set_TR0; //Timer0 开启
while(1)
{
if(SystemTime0_5Ms==1)
{
SystemTime0_5Ms=0;
SystemTime0_5Ms_cnt++;
if(SystemTime0_5Ms_cnt==2)
{
SystemTime0_5Ms_cnt=0;
KeyScan(); //每5MS 扫描一次按键
}
}
}
}
/************************************************************************************************************
* TIMER 0 interrupt subroutine
************************************************************************************************************/
void Timer0_ISR (void) interrupt 1 //interrupt address is 0x000B
{
TH0 = u8TH0_Tmp;
TL0 = u8TL0_Tmp;
SystemTime0_5Ms=1;
T0_CNT++;
if(T0_CNT==100)
{
T0_CNT=0;
P12 = ~P12; // GPIO1 toggle when interrupt
}
}
|