⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mega16implementation.c

📁 可以连发按键驱动不仅电机
💻 C
字号:
/*********************************************
File name			: de_2.c
Chip type           : ATmega16
Program type        : Application
Clock frequency     : 4.000000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 256
*********************************************/

#include <mega16.h>
	#ifndef __SLEEP_DEFINED__
	#define __SLEEP_DEFINED__
	.EQU __se_bit=0x40
	.EQU __sm_mask=0xB0
	.EQU __sm_powerdown=0x20
	.EQU __sm_powersave=0x30
	.EQU __sm_standby=0xA0
	.EQU __sm_ext_standby=0xB0
	.EQU __sm_adc_noise_red=0x10
	.SET power_ctrl_reg=mcucr
	#endif
#include <delay.h>



unsigned char key_stime_counter;		        // 时间计数单元,
bit	key_stime_ok;

// Timer 0 比较匹配中断服务,2ms定时
interrupt [TIM0_COMP] void timer0_comp_isr(void)
{
	if (++key_stime_counter >=5)
	{
		key_stime_counter = 0;
		key_stime_ok = 1;				// 10ms到

	}
}

#define key_input	PIND            	    // 按键输入口
#define key_1        0b11111110
#define key_2        0b11111101
#define key_3        0b11111011
#define key_4        0b11110111
#define key_1_0      0b01111110
#define key_2_0      0b01111101
#define key_3_0      0b01111011
#define key_4_0      0b01110111
#define key_no       0b11111111
#define key_lf       0b10000000
#define key_state_0        0
#define key_state_1        1
#define key_state_2        2
#define key_state_3        3

unsigned char read_key(void)                        //读键状态机,每10-20ms执行一次
{
    static unsigned char key_state = 0,key_old,key_time = 0;
    unsigned char key_press,key_return = key_no;

    key_press = key_input;        // 读按键I/O电平
    switch (key_state)
    {
        case key_state_0:                    // 按键初始态
            if (key_press != key_no)  key_state = key_state_1;    // 键被按下,状态转换到键确认态
            break;
        case key_state_1:                    // 按键确认态
            if (key_press == key_old)        // 与原电平比较(消抖处理)
            {
                key_state = key_state_2; // 按键仍按下,状态转换到计时1
                key_time=0;        // 清0按键时间计数器
            }
            else
                key_state = key_state_0;        // 按键已抬起,转换到按键初始态(消抖)
            break;
        case key_state_2:
            if (key_press != key_old)
            {
                key_state = key_state_0;        //按键已释放(或转按其它键),转换到按键初始态
                key_return = key_old;
            }
             else if(++key_time>=100)          //按键时间计数
            {
               key_state = key_state_3;         //按下时间>1s,状态转换到计时2
               key_time=0;        // 清按键计数器
               key_return = key_press-key_lf;                //过一秒,输出连发命令
            }
            break;
        case key_state_3:
            if (key_press != key_old)  key_state = key_state_0; //按键已释放(或转按其它键),转换到按键初始态
            else
            {
                 if(++key_time>=50)  // 按键时间计数
                 {
                    key_time=0;        // 按下时间>0.5s,清按键计数器
                    key_return = key_press-key_lf;                 //输出连发命令
                 }
            }
            break;
    }
    key_old = key_press;
    return key_return;
}



main()
{
        unsigned char key_value;
        PORTC=0x00;				// PC口的所有位输出"0",LED不亮
        DDRC=0xFF;				// 定义PC口的第0位为输出方式
        PORTD=0xFF;
	DDRD = 0x00;					// PD7为输入方式
	// T/C0 初始化
	TCCR0 = 0x0B;			// 内部时钟,64分频(4M/64=62.5KHz),CTC模式
	TCNT0 = 0x00;
	OCR0 = 0x7C;			// OCR0 = 0x7C(124),(124+1)/62.5=2ms
	TIMSK = 0x02;			// 允许T/C0比较匹配中断
	#asm("sei")			// 开放全局中断

	while (1)
	{
		if (key_stime_ok)				        //注意控制10-20ms执行一次.
		{
			key_stime_ok = 0;				// 10ms到
                        key_value = read_key();

     if (key_value != key_no)                  //判别键值并做相应的处理
     {
          switch (key_value)
          {
               case key_1:
                   PORTC.0 = ~PORTC.0;	// PC口第0位输出取反
                   delay_ms(1000); 		// 调用CVAVR提供的毫秒延时函数,延时1s
  	           PORTC.0 = ~PORTC.0;	// PC口第0位输出取反                //do samething
                   break;
               case key_2:
                   PORTC.1 = ~PORTC.1;	// PC口第1位输出取反
                   delay_ms(1000); 		// 调用CVAVR提供的毫秒延时函数,延时1s
  	           PORTC.1 = ~PORTC.1;	// PC口第1位输出取反                //do samething
                   break;
               case key_3:
                   PORTC.2 = ~PORTC.2;	// PC口第2位输出取反
                   delay_ms(1000); 		// 调用CVAVR提供的毫秒延时函数,延时1s
  	           PORTC.2 = ~PORTC.2;	// PC口第2位输出取反                //do samething
                   break;
               case key_4:
                   PORTC.3 = ~PORTC.3;	// PC口第3位输出取反
                   delay_ms(1000); 		// 调用CVAVR提供的毫秒延时函数,延时1s
  	           PORTC.3 = ~PORTC.3;	// PC口第3位输出取反                //do samething
                   break;


               case key_1_0:
                   PORTC.0 = ~PORTC.0;	// PC口第0位输出取反
                   delay_ms(200); 		// 调用CVAVR提供的毫秒延时函数,延时1s
  	           PORTC.0 = ~PORTC.0;	// PC口第0位输出取反                //do samething
                   PORTC.1 = ~PORTC.1;	// PC口第1位输出取反
                   delay_ms(200); 		// 调用CVAVR提供的毫秒延时函数,延时1s
  	           PORTC.1 = ~PORTC.1;	// PC口第1位输出取反                //do samething
                   PORTC.2 = ~PORTC.2;	// PC口第2位输出取反
                   delay_ms(200); 		// 调用CVAVR提供的毫秒延时函数,延时1s
  	           PORTC.2 = ~PORTC.2;	// PC口第2位输出取反                //do samething
                   PORTC.3 = ~PORTC.3;	// PC口第3位输出取反
                   delay_ms(200); 		// 调用CVAVR提供的毫秒延时函数,延时1s
  	           PORTC.3 = ~PORTC.3;	// PC口第3位输出取反                //do samething
                   break;
               case key_2_0:
                   PORTC.3 = ~PORTC.3;	// PC口第3位输出取反
                   delay_ms(200); 		// 调用CVAVR提供的毫秒延时函数,延时1s
  	           PORTC.3 = ~PORTC.3;	// PC口第3位输出取反                //do samething
                   PORTC.2 = ~PORTC.2;	// PC口第2位输出取反
                   delay_ms(200); 		// 调用CVAVR提供的毫秒延时函数,延时1s
  	           PORTC.2 = ~PORTC.2;	// PC口第2位输出取反
                   PORTC.1 = ~PORTC.1;	// PC口第1位输出取反
                   delay_ms(200); 		// 调用CVAVR提供的毫秒延时函数,延时1s
  	           PORTC.1 = ~PORTC.1;	// PC口第1位输出取反                //do samething
                   PORTC.0 = ~PORTC.0;	// PC口第0位输出取反
                   delay_ms(200); 		// 调用CVAVR提供的毫秒延时函数,延时1s
  	           PORTC.0 = ~PORTC.0;	// PC口第0位输出取反                //do samething
                   break;
               case key_3_0:
                   // do .....
                   break;
               case key_4_0:
                   // do .....
                   break;


           }

      }
    }

  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -