?? zhudang0617.c
字號:
?
+
/*------------------------------------------------
//阻擋機器人程序
//時間:2004年6月11日
//C口2/3/4/5為兩個主電機的控制
//PORTD 6/7是橫走電機控制,通過兩個繼電器實現PD6低電平是在左邊場地,
PD7低電平在右邊場地
//PORTA 光電尋線,加上橫線數線
//PORTD 2/3 分別是數線和停止檢測
------------------------------------------------*/
/**************宏定義區****************************/
#include <iom16v.h>
#include <macros.h>
#include <eeprom.h>
/**************全局變量***************************/
//按鍵顯示
const char DISCODE[] ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,
0x7c,0x39,0x5e,0x79,0x71,0x00,0x40,0x63,0x70,0x46};
unsigned char Disp_Buff[]={0,0,0,0,};
unsigned char disp_key_count =0; //LED掃描計數
char key_num =0x0f;
char old_key_num =0;
char new_key_num =0;
char key_buff[] ={0,0,0,0};
int key_down_time =0;
char key_delay =0;
int time_count_sys =0; //系統時間計數,1ms為單位
//delay time
unsigned int delay_time_count =0;
//motor
unsigned char pwm_count =0;
unsigned char speed =0;
unsigned char L_speed =0;
unsigned char R_speed =0;
const unsigned char SPEED_H[] ={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
const unsigned char SPEED_M[] ={0,0,1,2,3,4,5,6,7,8, 9,10,11,12,13,14};
const unsigned char SPEED_L[] ={0,0,0,0,0,0,0,1,2,3, 4, 5, 5, 6, 7, 8};
//follow_line
char follow_line_en =0;
//ADC
unsigned int temp =0;
unsigned char adc_channel =0;
unsigned int adc_value1_buff[] ={0,0,0,0,0,0,0,0,};
unsigned int adc_value2_buff[] ={0,0,0,0,0,0,0,0,};
unsigned int adc_value[] ={0,0,0,0,0,0,0,0,};
unsigned int adc_value_buff[] ={0,0,0,0,0,0,0,0,};
unsigned char adc_start_flag =0;
unsigned char adc_get_count =0;
unsigned char adc_value_flag =0;
//H line count
unsigned char line_H_cont =0;
unsigned char line_cont_juge =0;
unsigned char line_cont_en =0;
unsigned char line_H_en =0;
//V Line count
unsigned char V_Line_juge =0;
unsigned char Line_V =0;
unsigned char V_cont_en =0;//開啟橫線數線
unsigned char V_Line_en =0;
//stop juge
unsigned char stop_cont_juge =0;
unsigned char stop_cont =0;
unsigned char stop_juge_en =0;
unsigned char stop_en =0;
//過程變量
unsigned char prog_step =0;
unsigned char robot_go =0;
unsigned char DirectSelect =0;
unsigned char ModelSelect =0;
//中斷
#pragma interrupt_handler timer0_ovf:10
//#pragma interrupt_handler int0_ovf:2
/**************函數申明***************************/
/* 初始化 */
void init_devices(void);
void port_init(void);
//void init_ext(void);
void timer_init(void);
void adc_init(void);
//display & key
void send_data_disp(unsigned char send_data) ;
/* 過程控制函數 */
void followline(unsigned char go_speed,unsigned char direct);
void robot_stop(void);
void Line_Count(void);
void Stop_juge(void);
void Hand_A_open(void);
void Line_V_cont(void);
/* 比賽策略函數 */
void MODEL_A(void);
void MODEL_B(void);
void MODEL_B(void);
void MODEL_B(void);
/**************子函數區***************************/
//----------------------------------------
/* 初始化函數 */
void port_init(void)
{
DDRA = 0x00;
PORTA = 0x00; //光電管AD
DDRB = 0B11100000;
PORTB = 0B00011111;
DDRC = 0B11111100;
PORTC = 0B11111100; //
DDRD = 0B11110000; //PD5
PORTD = 0B11111111;
}
void timer_init(void)
{
TCCR0 =3; //32分頻
TCNT0 =0x83;
TIMSK =0x41; //open timer0 and timer2 中斷使能
}
void adc_init(void)
{
ADMUX = 0; //ADC第0通道輸入
ADCSRA = 0B10010001;//2分頻 //0b10010011; //開ADC,并8分頻
}
void init_ext(void)
{
GICR=0x00; //INT0、INT1、INT2請求外中斷觸發
MCUCR = 0b00001010; //開中斷0、1,下降沿觸發脈沖
// MCUCSR &= 0b10111111; //外中斷2下降沿觸發
GIFR=0Xff; //中斷標志寄存器置1清零
//GICR=0B11000000; //開外中斷
}
void init_devices(void)
{
CLI(); //關中斷
port_init(); //端口初始化
// init_ext(); //外中斷初始化
adc_init(); //adc init
timer_init(); //定時器初始化
SEI(); //開中斷
}
void disp_bit(char disCodeIndex,char bitChoose)
{//按位顯示
PORTB &= 0B11011111;//下拉RCK
send_data_disp(bitChoose);//送位選
send_data_disp(DISCODE[disCodeIndex]);//送段碼
PORTB |= 0B00100000;//反向RCK
}
void send_data_disp(unsigned char send_data)
{//向595送數據串
unsigned char count;
for(count =0;count<8;count++)
{
if(((send_data<<count)&0x80 )==0)
PORTB &=0B01111111;
else
PORTB |=0B10000000;
PORTB |=0B01000000;//送時鐘SCK
PORTB &=0B10111111;
}
}
void Disp_key_group(void)
{ //顯示和鍵值獲取,使用時只需對Disp_Buff[] 刷新。
disp_key_count++;
if(disp_key_count>3) //4個LED的板子(disp_key_count>3)
disp_key_count =0;
disp_bit(Disp_Buff[disp_key_count],1 <<disp_key_count);
if((PINB & 1) ==0)//有鍵按下
key_buff[disp_key_count] =1;
else
key_buff[disp_key_count] =0;
}
void Key_num(void)
{// 鍵值處理及去抖
if(key_buff[disp_key_count] ==1)
new_key_num =disp_key_count;
else
new_key_num =0x0f;
if((old_key_num ==0x0f) && (new_key_num !=0x0f) && (key_delay ==0))//判斷按鍵正按下
key_num =new_key_num;
else if ((old_key_num !=0x0f) && (new_key_num ==old_key_num))//判斷按鍵持續按下
{
key_num =0x0f ;//持續按鍵時不再給出鍵值,只給出空鍵值。
key_down_time++;//記錄按鍵持續按下時間
}//稍微修改一下可以得到比較完整的鍵盤返回碼
else
{
if((old_key_num !=0x0f) && (new_key_num ==0x0f))//按鍵釋放
{
key_num =0x0f;
key_down_time =0;//按鍵時間變量清零
key_delay=50;//去抖動延時50ms
}
}
old_key_num =new_key_num;
}
/* ADC */
Get_ADC_value(char channel)
{ //ADC讀入
ADMUX =channel;
ADCSRA |=0B01000000;
while((ADCSRA &0B00010000) ==0);
temp =ADC;
ADCSRA |=0B00010000;
return temp;
}
/* ADC value Flag get :和與之閾值比較得到判斷標志 */
void ADC_valueFlag_get(void)
{
char i;
for(i =0;i <8;i++)
{
char tempa;
if(adc_value_buff[i] >=adc_value[i])
{
tempa =(1<<i);
adc_value_flag |=tempa;
}
else
{
tempa =~(1<<i);
adc_value_flag &=tempa;
}
}
}
/* ms精確延時函數 */
void delay(unsigned int n)
{//延時
delay_time_count =n;
while(delay_time_count >0);
}
//----------------------------------------------
/* 機器人行走 */
void ADC_base_get(void)
{//閾值采集
char i;
Disp_Buff[2] =17;
Disp_Buff[3] =17;
for(i =0;i <8;i++)
Get_ADC_value(i);//處次采樣,防止ADC誤差
for(i =0;i <8;i++)
{
adc_value1_buff[i] =Get_ADC_value(i);//第一次采樣
}
while(prog_step ==1)
{
Disp_Buff[0] =adc_value1_buff[0]/64;
Disp_Buff[1] =1;
}
for(i =0;i <8;i++)
{
adc_value2_buff[i] =Get_ADC_value(i);//第二次采樣
}
Disp_Buff[0]=adc_value2_buff[0]/64;//顯示第二次采樣值
Disp_Buff[1] =2;
for(i =0;i <8;i++)
{
adc_value[i] =(adc_value1_buff[i]+adc_value2_buff[i])/2;//計算中值
}
EEPROMWriteBytes(0x0000,adc_value,16); //閾值存入EEPROM中
delay(600);
prog_step =0;//跳回初始狀態
}
//follow line
void followline(unsigned char go_speed,unsigned char direct)
{ //尋線主函數
if(direct ==1)
{
switch(adc_value_flag)
{
case 0b00011000://全部在白線上機器人直走
L_speed =SPEED_H[go_speed];
R_speed =SPEED_H[go_speed];
break;
case 0b00011100://稍微在白線的左邊,機器人向右微調
L_speed =SPEED_H[go_speed];
R_speed =SPEED_M[go_speed];
break;
case 0b00001100://稍微在白線的左邊,機器人向右微調
L_speed =SPEED_H[go_speed];
R_speed =SPEED_M[go_speed];
break;
case 0b00001110://稍微在白線的左邊,機器人向右調整
L_speed =SPEED_H[go_speed];
R_speed =SPEED_L[go_speed];
break;
case 0b00000110://稍微在白線的左邊,機器人向右調整
L_speed =SPEED_H[go_speed];
R_speed =SPEED_L[go_speed];
break;
case 0b00000111://稍微在白線的左邊,機器人向右調整
L_speed =SPEED_H[go_speed];
R_speed =SPEED_L[go_speed];
break;
case 0b00000011://稍微在白線的左邊,機器人向右調整
L_speed =SPEED_H[go_speed];
R_speed =SPEED_L[go_speed];
break;
case 0b00111000://稍微在白線的右邊,機器人向左微調
L_speed =SPEED_M[go_speed];
R_speed =SPEED_H[go_speed];
break;
case 0b00110000://稍微在白線的右邊,機器人向左微調
L_speed =SPEED_M[go_speed];
R_speed =SPEED_H[go_speed];
break;
case 0b01110000://在白線的右邊,機器人向左調整
L_speed =SPEED_L[go_speed];
R_speed =SPEED_H[go_speed];
break;
case 0b01100000://在白線的右邊,機器人向左調整
L_speed =SPEED_L[go_speed];
R_speed =SPEED_H[go_speed];
break;
case 0b11100000://在白線的右邊,機器人向左調整
L_speed =SPEED_L[go_speed];
R_speed =SPEED_H[go_speed];
break;
case 0b11000000://在白線的右邊,機器人向左調整
L_speed =SPEED_L[go_speed];
R_speed =SPEED_H[go_speed];
break;
default:
break;
}
}
}
void motor_PWM(void)
{
if(pwm_count <L_speed)
{
PORTC &=0b11111011;
}
else
{
PORTC |=0b00000100;
}
if(pwm_count <R_speed)
{
PORTC &=0b11101111;
}
else
{
PORTC |=0b00010000;
}
}
void ROBOT_GO(unsigned L_SPEED,unsigned R_SPEED)
{
L_speed =L_SPEED;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -