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

📄 keyboard._c

📁 AVR单片机开发的键盘处理程序C源代码希望对单片机初学选手有点帮助
💻 _C
字号:
//ICC-AVR application builder : 2004-4-28 13:15:44
// Target : M16
// Crystal: 8.0000Mhz
#include <iom16v.h>
#include <macros.h>
#include <eeprom.h>

#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long

const uchar num_table[] = { 0x3f,0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x40 };
//自定义定时器
uint  delay_counter, scom_counter, key_counter;
//定义通讯缓存
#define SCOM_BUF_LEN 10
uchar tbuf[SCOM_BUF_LEN];
uchar rbuf[SCOM_BUF_LEN];
//显示缓存
uint l_des_speed, r_des_speed;
//键盘缓存
uint key_buf;
//子函数声明
void delay( uint time );
void master( uchar command, uchar* buf, uchar startP, uchar dataLen );
uint scan_key( void );
void display( void );
void error_handle( void );

/******************公共的底层函数区********************/
void delay( uint time )
{
	for( delay_counter = 0; delay_counter < time; ) { WDR(); }
}

uint scan_key( void )
{
	uint key_status = 0;
	PORTC = 0x7F;	//定义管脚输入输出状态
	DDRC  = 0x80;
	if (!(PINC & 0x08))	key_status |= BIT(0);
	if (!(PINC & 0x04))	key_status |= BIT(1); 
	if (!(PINC & 0x04))	key_status |= BIT(2); 
	if (!(PINC & 0x04))	key_status |= BIT(3); 
 	PORTC = 0xBF;
 	DDRC  = 0x40;
	if (!(PINC & 0x08))	key_status |= BIT(4);
	if (!(PINC & 0x04))	key_status |= BIT(5); 
	if (!(PINC & 0x04))	key_status |= BIT(6); 
	if (!(PINC & 0x04))	key_status |= BIT(7); 
	PORTC = 0xDF;
	DDRC  = 0x20;
	if (!(PINC & 0x08))	key_status |= BIT(8);
	if (!(PINC & 0x04))	key_status |= BIT(9); 
	if (!(PINC & 0x04))	key_status |= BIT(10); 
	if (!(PINC & 0x04))	key_status |= BIT(11); 
	PORTC = 0xEF;
	DDRC  = 0x10;
	if (!(PINC & 0x08))	key_status |= BIT(12);
	if (!(PINC & 0x04))	key_status |= BIT(13); 
	if (!(PINC & 0x04))	key_status |= BIT(14); 
	if (!(PINC & 0x04))	key_status |= BIT(15); 
	PORTC = 0xF0;
	DDRC  = 0x0F;
	PORTD |= BIT(PD2);
	DDRD &= ~BIT(PD2);
	return key_status;
}

void master( uchar command, uchar* buf, uchar startP, uchar dataLen )
{ 
	uchar i;
	CLI();
	if ( command == 0x01 ){
		while( !( UCSRA & BIT( UDRE ) ) );
  		UDR = command;
  		while( !( UCSRA & BIT( UDRE ) ) );
  		UDR = dataLen;
  		for( i = startP; i < dataLen + startP; i ++ ){
			while( !( UCSRA & BIT( UDRE ) ) );
   			UDR = tbuf[i];
  		}  
 	} else {
  		while( !( UCSRA & BIT( UDRE ) ) );
  		UDR = command;
  		while( !( UCSRA & BIT( UDRE ) ) );
  		UDR = dataLen;
  		for( i = startP; i < dataLen + startP; i ++ ){
   			while( !( UCSRA & BIT( RXC ) ) );
   			rbuf[i] = UDR;   
  		}
 	}
 	SEI();
}

void port_init(void)
{
	PORTA = 0x00;
	DDRA  = 0xFF;
	PORTB = 0xFF;
	DDRB  = 0xFF;
	PORTC = 0xF0; //m103 output only
	DDRC  = 0x0F;
	PORTD = 0xFF;
	DDRD  = 0x00;
}

//TIMER0 initialisation - prescale:64
// WGM: Normal
// desired value: 1mSec
// actual value:  1.000mSec (0.0%)
void timer0_init(void)
{
	TCCR0 = 0x00; //stop
	TCNT0 = 0x83; //set count
	OCR0  = 0x7D;  //set compare
	TCCR0 = 0x03; //start timer
}

#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
	TCNT0 = 0x83; //reload counter value
	delay_counter ++;
	key_counter ++;
	scom_counter ++;
}

//UART0 initialisation
// desired baud rate: 9600
// actual: baud rate:9615 (0.2%)
// char size: 8 bit
// parity: Disabled
void uart0_init(void)
{
	UCSRB = 0x00; //disable while setting baud rate
	UCSRA = 0x00;
	UCSRC = 0x86;
	UBRRL = 0x00; //set baud rate lo
	UBRRH = 0x00; //set baud rate hi
	UCSRB = 0x98;
}

//Watchdog initialisation
// prescale: 32K cycles
void watchdog_init(void)
{
	WDR(); //this prevents a timout on enabling
	WDTCR = 0x0A; //WATCHDOG ENABLED - dont forget to issue WDRs
}

//call this routine to initialise all peripherals
void init_devices(void)
{
	//stop errant interrupts until set up
	CLI(); //disable all interrupts
	port_init();
	timer0_init(); 
	uart0_init();
	//watchdog_init();
 
	MCUCR = 0x00;
	GICR  = 0x00;
	TIMSK = 0x01; //timer interrupt sources
	SEI(); //re-enable interrupts
	//all peripherals are now initialised
}

//显示
void send_num( uchar index, uchar num )
{
	PORTB = ~BIT( index ); 
	if( index <= 7 ) { PORTA = num_table[num]; }
	else { PORTA = num; }
	delay( 1 );
}

void send_char( uchar index, uchar ch )
{
	PORTB = ~BIT( index );
	PORTA = ch;
	delay(1);
}

void display( void )
{
 	l_des_speed = ( rbuf[2] << 8 ) + rbuf[1];
 	r_des_speed = ( rbuf[5] << 8 ) + rbuf[4];
 	if ( rbuf[0] == 1 ){
		send_char( 7, 0x40 );	//显示'-'
	}
	if ( ( l_des_speed > 99 ) && ( l_des_speed < 999 ) ){
		send_num( 6, l_des_speed / 100 % 10 );
	}
	send_num( 5, (l_des_speed / 10) % 10 );
	send_num( 4, l_des_speed % 10 );
	if ( rbuf[3] == 1 ){
		send_char( 3, 0x40 );	//显示'-'
	}
	if ( ( r_des_speed > 99 ) && ( r_des_speed < 999 ) ){
		send_num( 2, r_des_speed / 100 % 10 );
	}
	send_num( 1, (r_des_speed / 10) % 10 );
	send_num( 0, r_des_speed % 10 );
}

void reset_ctrl( void )
{
	uchar i;
	for( i = 0; i < SCOM_BUF_LEN; i ++ ){
		rbuf[i] = 0;
		tbuf[i] = 0;
	}
	scom_counter = 0;
	delay_counter = 0;
	key_counter = 0;
	l_des_speed = 0;
	r_des_speed = 0;
	key_buf = 0;
	for( delay_counter = 0; delay_counter < 500; ){
		PORTA = 0xFF;
		PORTB <<= BIT(0);
		WDR();
	}
	PORTA = 0x00;
}
//
void main(void)
{
	init_devices();
	reset_ctrl();
	
	do{
		if ( !( PIND & BIT(PD2) ) ){		//键盘扫描
			display();
			display();
			display();
			if( !( PIND & BIT(PD2) ) ){
				key_buf = scan_key();
				tbuf[0] = (uchar)( key_buf & 0x00FF );
				tbuf[1] = (uchar)( key_buf >> 8 );
				master( 0x01, tbuf, 0, 2 );
				key_counter = 0;
				while( !( PIND & BIT(PD2) ) ){
					display();
					if ( key_counter > 9 ) break;
					WDR();
				}
			}
		}
		if ( key_buf & BIT(7) ) send_char( 7, 0x40 );
		if ( key_buf & BIT(6) ) send_char( 6, 0x40 );
		if ( key_buf & BIT(5) ) send_char( 5, 0x40 );
		if ( key_buf & BIT(4) ) send_char( 4, 0x40 );
		if ( key_buf & BIT(3) ) send_char( 3, 0x40 );
		if ( key_buf & BIT(2) ) send_char( 2, 0x40 );
		if ( key_buf & BIT(1) ) send_char( 1, 0x40 );
		if ( key_buf & BIT(0) ) send_char( 0, 0x40 );
		/*
		if ( sys_flag & BIT( SCOM_EN ) ){	//更新显示缓存
			master( 0x02, rbuf, 0, 6 );
			scom_counter = 0;
		}
		*/
		WDR();								//复位看门狗
		display();							//显示
	}while( 1 );
} 

⌨️ 快捷键说明

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