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

📄 demo_9_3.c~

📁 AVR单片机嵌入式系统原理与应用实践例码
💻 C~
字号:
/*********************************************
File name			: demo_9_3.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>
flash char led_7[13]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,	// 字型码
                      0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x40};
			  					// 后3位为 "A","b","-"	
flash char position[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};

char	dis_buff[8];				// 显示缓冲区,存放要显示的8个字符的段码值
char	key_stime_counter;
char	posit;
bit	key_stime_ok;

void display(void)					// 8位LED数码管动态扫描函数
{
	PORTC = 0xff;
	PORTA = led_7[dis_buff[posit]]; 
	PORTC = position[posit]; 
	if (++posit >=8 ) posit = 0;
}

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

#define No_key 	255
#define K1_1	1
#define K1_2	2
#define K1_3	3
#define K2_1	4
#define K2_2	5
#define K2_3	6
#define K3_1	7
#define K3_2	8
#define K3_3	9
#define K4_1	10
#define K4_2	0
#define K4_3	11
#define Key_mask	0b00000111

char read_keyboard()
{	
	static char key_state = 0, key_value, key_line;
    char key_return = No_key,i;
	
	switch (key_state)
	{
		case 0:
			key_line = 0b00001000;
			for (i=1; i<=4; i++)					// 扫描键盘
			{	
				PORTD = ~key_line;					// 输出行线电平
				PORTD = ~key_line;					// 必须送2次!!!
                key_value = Key_mask & PIND;		// 读列电平
				if (key_value == Key_mask)
					key_line <<= 1;				// 没有按键,继续扫描
				else
				{
					key_state++;					// 有按键,停止扫描
					break;						// 转消抖确认状态
				}
			}
			break;
		case 1:
			if (key_value == (Key_mask & PIND))		// 再次读列电平,
			{
				switch (key_line | key_value)		// 与状态0的相同,确认按键
				{								// 键盘编码,返回编码值 
					case 0b00001110:
						key_return = K1_1;
						break;
					case 0b00001101:
						key_return = K1_2;
						break;
 					case 0b00001011:
						key_return = K1_3;
						break;
 					case 0b00010110:
						key_return = K2_1;
						break;
 					case 0b00010101:
						key_return = K2_2;
						break;
					case 0b00010011:
						key_return = K2_3;
						break;
 					case 0b00100110:
						key_return = K3_1;
						break;
 					case 0b00100101:
						key_return = K3_2;
						break;
					case 0b00100011:
						key_return = K3_3;
						break;
 					case 0b01000110:
						key_return = K4_1;
						break;
 					case 0b01000101:
						key_return = K4_2;
						break;
					case 0b01000011:
						key_return = K4_3;
						break;
				}
				key_state++;				// 转入等待按键释放状态
			}
			else
				key_state--;				// 两次列电平不同返回状态0,(消抖处理)
			break;						
		case 2:							// 等待按键释放状态
			PORTD = 0b00000111;			// 行线全部输出低电平
			PORTD = 0b00000111;			// 重复送一次
			if ( (Key_mask & PIND) == Key_mask)
				key_state=0;				// 列线全部为高电平返回状态0
			break;
	}
	return key_return;
}

void main(void)
{
	char i, key_temp;
	
	PORTA = 0x00;							// 显示控制I/O端口初始化
	DDRA = 0xFF;
	PORTC = 0xFF;
	DDRC = 0xFF;
	PORTD = 0xFF;							// 键盘接口初始化
	DDRD = 0xF8;							// PD2、PD1、PD0列线,输入方式,上拉有效
	// 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比较匹配中断

	for (i=0; i<8 ;i++)
	{dis_buff[i]= 12;}		// LED初始显示8个"-"
	#asm("sei")			// 开放全局中断

	while (1)
	{
		if (key_stime_ok)				
		{
			key_stime_ok = 0;				// 10ms到
			key_temp = read_keyboard();		// 调用键盘接口函数读键盘
			if (key_temp != No_key)
			{							// 有按键按下
				for (i=0; i<7; i++)
				{dis_buff[i] = dis_buff[i+1];}	// LED显示左移一位
				dis_buff[7] = key_temp; 		// 最右显示新按下键的键值
			}
		}
	}
}

⌨️ 快捷键说明

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