仿真原理图如下
单片机源程序如下:
#include /********************************************* * 定时器初值 *********************************************/ #define T0HIGH 0xec #define T0LOWW 0x8a /********************************************* * *********************************************/ typedef unsigned char u8; typedef unsigned int u16; typedef unsigned long u32; typedef bit BOOL; /********************************************* * 单片机管脚定义 *********************************************/ sbit KEY_ON_PIN = P2^0; sbit KEY_INC_PIN = P2^1; sbit KEY_DEC_PIN = P2^2; sbit MOTO_LEFT = P3^6; sbit MOTO_RIGHT = P3^7; /********************************************* * 按键定义 *********************************************/ #define KEY_NULL 0xff #define KEY_LONG_PERIOD 25 #define KEY_CONTINUE_PERIOD 20 #define KEY_DOWN 0x80 #define KEY_CONTINUE 0x40 #define KEY_UP 0x20 #define KEY_STATE_INIT 0 #define KEY_STATE_WOBBLE 1 #define KEY_STATE_PRESS 2 #define KEY_STATE_LONG 3 #define KEY_STATE_CONTINUE 4 #define KEY_STATE_RELEASE 5 #define KEY_ON_VALUE 1 #define KEY_INC_VALUE 2 #define KEY_DEC_VALUE 3 #define KEY_ON (KEY_ON_VALUE | KEY_DOWN) #define KEY_INC (KEY_INC_VALUE | KEY_DOWN) #define KEY_INC_CON (KEY_INC_VALUE | KEY_CONTINUE) #define KEY_DEC (KEY_DEC_VALUE | KEY_DOWN) #define KEY_DEC_CON (KEY_DEC_VALUE | KEY_CONTINUE) /********************************************* * 常量定义 *********************************************/ #define true 1 #define false 0 #define MOTO_ON MOTO_LEFT = false; MOTO_RIGHT = true #define MOTO_OFF MOTO_LEFT = true; MOTO_RIGHT = true /********************************************* * 全局变量定义 *********************************************/ code u8 DisCode[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0xff}; u8 PWMpercent = 0; u8 DisNum[4] = {0x0a, 0x0a, 0x0a, 0x00}; u8 DisPosition = 0; u8 SecCount = 0; u8 u10msNum = 0; BOOL b10msEvent = false; BOOL b100msEvent = false; BOOL b1secEvent = false; BOOL MotoStart = false; BOOL MotoRun = false; void Key_Prosess(void); void Dynamic_Display(void); void Speed_Display(void); /********************************************* * 主函数 *********************************************/ main() { TMOD = 0x01; TH0 = T0HIGH; TL0 = T0LOWW; TR0 = 1; ET0 = 1; EA = 1; P1 = 0x00; while(1) { if(true == b10msEvent) //10毫秒定时标志 { b10msEvent = false; Key_Prosess(); //按键扫描 Dynamic_Display(); //动态显示 if(true == MotoStart) //如果电机启动 { if(true == MotoRun) { if(--u10msNum == 0) //如果电机转动时间到,停止电机 { MotoRun = false; MOTO_OFF; } } if(true == b1secEvent) //PWM周期为1秒,1秒钟时间到,开始下一个周期 { b1secEvent = false; MotoRun = true; MOTO_ON; u10msNum = PWMpercent; } } } } } /********************************************* * 清显示 *********************************************/ void Num_Clear(void) { u8 i; for(i=0; i<3; i++) { DisNum[i] = 0x0a; } DisNum[3] = 0x00; } /********************************************* * 读键值 *********************************************/ u8 Key_Scan(void) { if(KEY_ON_PIN == false) return KEY_ON_VALUE; if(KEY_INC_PIN == false) return KEY_INC_VALUE; if(KEY_DEC_PIN == false) return KEY_DEC_VALUE; return KEY_NULL; } /********************************************* * 按键状态扫描 *********************************************/ u8 GetKey(void) { static u8 KeyState = KEY_STATE_INIT; static u8 KeyTimeCount = 0; static u8 LastKey = KEY_NULL; //保存按键释放时候的键值 u8 KeyTemp = KEY_NULL ; KeyTemp = Key_Scan(); switch(KeyState) { case KEY_STATE_INIT: //初始状态 if(KEY_NULL != KeyTemp) //有键按下 { KeyState = KEY_STATE_WOBBLE; //进入消抖 } break; case KEY_STATE_WOBBLE: //消抖 KeyState = KEY_STATE_PRESS; break; case KEY_STATE_PRESS: if(KEY_NULL != KeyTemp) { LastKey = KeyTemp; //保存键值,以便在释放按键状态返回键值
上一篇:手把手教你单片机串口通信-基础篇
下一篇:基于51单片机的数字电容测量仪设计
推荐阅读最新更新时间:2024-11-08 12:18