📄 boat.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 + -