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

📄 boat.c

📁 AVR单片机开发的键盘处理程序C源代码希望对单片机初学选手有点帮助
💻 C
字号:
// Last modify time: 2004-8-25 1:33
// Target : M16
// Crystal: 8.0000Mhz

#include <iom16v.h>
#include <macros.h>

#define uchar unsigned char
#define uint  unsigned int
/*调速模块预定义*/
#define MAX_SPEED 510
#define MIN_SPEED -510
#define L_ACCE_COUNT 2
#define L_DECE_COUNT 2
#define L_STEP 1
#define R_ACCE_COUNT 2
#define R_DECE_COUNT 2
#define R_STEP 1
#define SPEED_INC 5

#define SET_L_DIR 	( PORTB |= BIT(PB0) )	//电机方向控制I/O定义
#define RST_L_DIR	( PORTB &= ~BIT(PB0) )
#define SET_R_DIR	( PORTB |= BIT(PB1) )
#define RST_R_DIR	( PORTB &= ~BIT(PB1) )

typedef struct _trap{	int   des_speed;
						int   real_speed;
						uint  acce_count;
						uint  dece_count;
						uint  counter;
						int   step;			//必须用int型,因为速度控制接口函数trap_ctrler的代码结构
					 }trap;
trap  l_trap, r_trap;
uint  l_temp_speed, r_temp_speed;
uint  delay_counter;
/*串口通讯模块预定义*/
#define SCOM_BUF_LEN 20
uchar tbuf[SCOM_BUF_LEN];
uchar rbuf[SCOM_BUF_LEN];
uint key_status;
/*键盘模块预定义*/
#define L_ACCE_KEY		0
#define L_DECE_KEY 		4
#define L_RESUME_KEY	8
#define L_STOP_KEY 		12
#define R_ACCE_KEY		3
#define R_DECE_KEY		7
#define R_RESUME_KEY	11
#define R_STOP_KEY		15
//
#define L_ACCE_KEY_PRESS	7
#define L_DECE_KEY_PRESS	6
#define L_RESUME_KEY_PRESS	5
#define L_STOP_KEY_PRESS	4
#define R_ACCE_KEY_PRESS	3
#define R_DECE_KEY_PRESS	2
#define R_RESUME_KEY_PRESS	1
#define R_STOP_KEY_PRESS	0
uchar key_prev_status;

void delay_ms( uint time );
void rst_ctrl( void );
void pwm_ctrler( trap *pt_l, trap *pt_r );
void trap_ctrler( int l_des_speed, int r_des_speed );
void key_process( uint key_buf );

/**************************** 公共底层函数 ********************************/
void delay_ms( uint time )	//毫秒级延时函数,占用系统时钟TIMER2
{
	for( delay_counter = 0; delay_counter < time; ) WDR();
}

void rst_ctrl( void )
{
	l_trap.des_speed = 0;
	l_trap.real_speed = 0;
	l_trap.acce_count = 0;
	l_trap.dece_count = 0;
	l_trap.counter = 0;
	l_trap.step = 4;
	l_temp_speed = 0;
	r_trap.des_speed = 0;
	r_trap.real_speed = 0;
	r_trap.acce_count = 0;
	r_trap.dece_count = 0;
	r_trap.counter = 0;
	r_trap.step = 4;
	r_temp_speed = 0;
	delay_counter = 0;
	key_status = 0;
	key_prev_status = 0;
}

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

//TIMER1 initialisation - prescale:1
// WGM: 6) PWM 9bit fast, TOP=0x01FF
// desired value: 1Hz
// actual value: 15625.000Hz (100.0%)
void timer1_init(void)
{
 TCCR1B = 0x00; //stop
 TCNT1H = 0xFE; //setup
 TCNT1L = 0x01;
 OCR1AH = 0x00;
 OCR1AL = 0x00;
 OCR1BH = 0x00;
 OCR1BL = 0x00;
 TCCR1A = 0xF2;
 TCCR1B = 0x09; //start Timer
}

//TIMER2 initialisation - prescale:64
// WGM: Normal
// desired value: 1mSec
// actual value:  1.000mSec (0.0%)
void timer2_init(void)
{
	TCCR2 = 0x00; //stop
	ASSR  = 0x00; //set async mode
	TCNT2 = 0x83; //setup
	OCR2  = 0x7D;
	TCCR2 = 0x04; //start
}

//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;
}

#pragma interrupt_handler timer2_ovf_isr:5
void timer2_ovf_isr(void)
{
	TCNT2 = 0x83; //reload counter value
	delay_counter ++;	//用于毫秒级延时
	
	pwm_ctrler( &l_trap, &r_trap );
}

#pragma interrupt_handler uart0_rx_isr:12
void uart0_rx_isr(void)
{
	uchar command,dataLen;
	uchar i;
	CLI();
	command = UDR;
	if ( command== 0x01 ){
		while( !( UCSRA & BIT( RXC ) ) );
		dataLen = UDR;
		for( i = 0; i < dataLen; i ++ ){
			while( !( UCSRA & BIT( RXC ) ) );
			rbuf[i] = UDR;
		}
  		//------------接收数据实时处理区--------------
			key_status = 0;
			key_status &= rbuf[0];
			key_status &= rbuf[1] << 8;
			key_process( key_status );
  		//--------------------------------------------
	} else if ( command == 0x02 ){
		//----------发送实时处理区---------
			if ( l_trap.real_speed < 0 )	tbuf[0] = 1;
			else tbuf[0] = 0;
			tbuf[1] = (uchar)( l_trap.real_speed & 0x00FF );
			tbuf[2] = (uchar)( l_trap.real_speed >> 8 );
			if ( r_trap.real_speed < 0 )	tbuf[3] = 1;
			else tbuf[3] = 0;
			tbuf[4] = (uchar)( r_trap.real_speed & 0x00FF );
			tbuf[5] = (uchar)( r_trap.real_speed >> 8 ); 
		//---------------------------------
		while( !( UCSRA & BIT( RXC ) ) );
		dataLen = UDR;
		for( i = 0; i < dataLen; i ++ ){
			while( !( UCSRA & BIT( UDRE ) ) );
			UDR = tbuf[i];
  		}
 	}
	SEI();
}

//call this routine to initialise all peripherals
void init_devices(void)
{
	//stop errant interrupts until set up
	CLI(); //disable all interrupts
	port_init();
	timer1_init();
	timer2_init();
	uart0_init();

	MCUCR = 0x00;
	GICR  = 0x00;
	TIMSK = 0x40; //timer interrupt sources
	SEI(); //re-enable interrupts
	//all peripherals are now initialised
}

/**************************** PWM调速控制模块 ********************************/

//PWM控制器,电机控制的底层操作代码
void pwm_ctrler( trap *pt_l, trap *pt_r )
{
 	//左电机加减速梯形图控制器
	if ( OCR1A <= pt_l->step )			//当速度减少到一定值时
	{
		OCR1A = pt_l->step;				//保持,高频润滑
		if ( pt_l->des_speed == 0 ){	//当期望值为0时的处理
			pt_l->real_speed = 0;
			SET_L_DIR;
		} else{
			if ( pt_l->des_speed > 0 )	SET_L_DIR;
			else	RST_L_DIR;
			if ( ++ pt_l->counter >= 400 ){
				DDRD |= BIT(PD5);		//刷新PD5为输出
				OCR1A = pt_l->step + 1;
				if( pt_l->des_speed > 0 ) pt_l->real_speed = (int)(OCR1A);	//需要强制类型转换吗?
				else pt_l->real_speed = -(int)(OCR1A);
				pt_l->counter = 0;		//定时计数器清零
			}
		}
	} else if ( pt_l->real_speed < pt_l->des_speed ){
		if ( ++ pt_l->counter == pt_l->acce_count ){
			pt_l->real_speed += pt_l->step;	//加速梯形图
			if ( pt_l->real_speed < 0 ){	//取绝对值
				OCR1A = (uint)(-pt_l->real_speed);
			} else {
				OCR1A = (uint)(pt_l->real_speed);
			}
			pt_l->counter = 0;				//计数器清零
		}
	} else if( pt_l->real_speed > pt_l->des_speed ){
		if ( ++ pt_l->counter == pt_l->dece_count ){
			pt_l->real_speed -= pt_l->step;
			if ( pt_l->real_speed < 0 ){	//取绝对值
				OCR1A = (uint)(-pt_l->real_speed);
			} else {
				OCR1A = (uint)(pt_l->real_speed);
			}
			pt_l->counter = 0;
		}
	}
	//右电机加减速梯形图控制器
	if ( OCR1B <= pt_r->step )			//当速度减少到一定值时
	{
		OCR1B = pt_r->step;				//保持,高频润滑
		if ( pt_r->des_speed == 0 ){	//当期望值为0时的处理
			pt_r->real_speed = 0;
			SET_R_DIR;
		} else{
			if ( pt_r->des_speed > 0 )	SET_R_DIR;
			else	RST_R_DIR;
			if ( ++ pt_r->counter >= 400 ){
				DDRD |= BIT(PD4);		//刷新PD5为输出
				OCR1B = pt_r->step + 1;
				if( pt_r->des_speed > 0 ) pt_r->real_speed = (int)(OCR1B);	//需要强制类型转换吗?
				else pt_r->real_speed = -(int)(OCR1B);
				pt_r->counter = 0;		//定时计数器清零
			}
		}
	} else if ( pt_r->real_speed < pt_r->des_speed ){
		if ( ++ pt_r->counter == pt_r->acce_count ){
			pt_r->real_speed += pt_r->step;	//加速梯形图
			if ( pt_r->real_speed < 0 ){	//取绝对值
				OCR1B = (uint)(-pt_r->real_speed);
			} else {
				OCR1B = (uint)(pt_r->real_speed);
			}
			pt_r->counter = 0;				//计数器清零
		}
	} else if( pt_r->real_speed > pt_r->des_speed ){
		if ( ++ pt_r->counter == pt_r->dece_count ){
			pt_r->real_speed -= pt_r->step;
			if ( pt_r->real_speed < 0 ){	//取绝对值
				OCR1B = (uint)(-pt_r->real_speed);
			} else {
				OCR1B = (uint)(pt_r->real_speed);
			}
			pt_r->counter = 0;
		}
	}
}

//电机速度控制接口函数
void trap_ctrler( int l_des_speed, int r_des_speed )
{
	l_trap.acce_count = L_ACCE_COUNT;			//设定左电机
	l_trap.dece_count = L_DECE_COUNT;
	l_trap.step = L_STEP;
	if ( l_des_speed > ( MAX_SPEED - l_trap.step ) ){			//给定值限幅处理
		l_trap.des_speed = MAX_SPEED - l_trap.step;
	} else if ( l_des_speed < ( MIN_SPEED + l_trap.step ) ){
		l_trap.des_speed = MIN_SPEED + l_trap.step;
	} else {
		l_trap.des_speed = l_des_speed;
	}
	r_trap.acce_count = R_ACCE_COUNT;			//设定右电机
	r_trap.dece_count = R_DECE_COUNT;
	r_trap.step = R_STEP;
	if ( r_des_speed > ( MAX_SPEED - r_trap.step ) ){			//给定值限幅处理
		r_trap.des_speed = MAX_SPEED - r_trap.step;
	} else if ( r_des_speed < ( MIN_SPEED + r_trap.step ) ){
		r_trap.des_speed = MIN_SPEED + r_trap.step;
	} else {
		r_trap.des_speed = r_des_speed;
	}
}

/**************************** 键盘信号处理模块 ********************************/
void key_process( uint key_buf )
{
	if ( key_buf & BIT( L_STOP_KEY ) ){
		l_temp_speed = l_trap.des_speed;
		l_trap.des_speed = 0;
		trap_ctrler( 0, r_trap.des_speed );
		key_prev_status |= BIT( L_STOP_KEY_PRESS );
	} else if ( ( key_buf & BIT( L_RESUME_KEY ) ) && ( key_prev_status & BIT( L_STOP_KEY_PRESS ) ) ){
		l_trap.des_speed = l_temp_speed;
		trap_ctrler( l_trap.des_speed, r_trap.des_speed );
		key_prev_status &= ~BIT( L_STOP_KEY_PRESS );
	} else if ( key_buf & BIT( L_ACCE_KEY ) ){
		trap_ctrler( l_trap.des_speed + SPEED_INC, r_trap.des_speed );
	} else if ( key_buf & BIT( L_DECE_KEY ) ){
		trap_ctrler( l_trap.des_speed - SPEED_INC, r_trap.des_speed );
	}

	if ( key_buf & BIT( R_STOP_KEY ) ){
		r_temp_speed = r_trap.des_speed;
		r_trap.des_speed = 0;
		trap_ctrler( l_trap.des_speed, 0 );
		key_prev_status |= BIT( R_STOP_KEY_PRESS );
	} else if ( ( key_buf & BIT( R_RESUME_KEY ) ) && ( key_prev_status & BIT( R_STOP_KEY_PRESS ) ) ){
		r_trap.des_speed = r_temp_speed;
		trap_ctrler( l_trap.des_speed, r_trap.des_speed );
		key_prev_status &= ~BIT( R_STOP_KEY_PRESS );
	} else if ( key_buf & BIT( R_ACCE_KEY ) ){
		trap_ctrler( l_trap.des_speed, r_trap.des_speed + SPEED_INC );
	} else if ( key_buf & BIT( R_DECE_KEY ) ){
		trap_ctrler( l_trap.des_speed, r_trap.des_speed - SPEED_INC );
	}	
}

void main(void)
{
	init_devices();
	rst_ctrl();
	
	do{
		WDR();
	}while(1);
}

⌨️ 快捷键说明

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