📄 main.c
字号:
break;
case 0x0: //音量-
if (car_stat == 0x05)
{
if (pid.p)
pid.p--;
}
break;
case 0x0D: //<<
GAIN++;
break;
case 0x0F: //>>
if (GAIN)
GAIN--;
break;
case 0x0E: //|<<
pid.d++;
break;
case 0x19: //>>| if (pid.d)
pid.d--;
break;
case 0x1E: //POWER
// power_stat = ~power_stat;
break;
default:
break;
}
}
}
} else { //重复信号,仅含有引导信号
}
pca_int_count = 0;
frame_dog = 0;
} else {
pca_int_count++;
}
} else {
pca_int_count = 0;
frame_dog = 0;
}
} else {
j = (pca_int_count - 3) / 2;
i = j / 8;
j = j % 8;
if (period > MIN168MS && period < MAX168MS) { //1.68ms
// com_putchar(0x01);
data_buf[i] |= (0x01 << j);
pca_int_count++;
} else if (period > MIN056MS && period < MAX056MS) { //0.56ms
// com_putchar(0x00);
data_buf[i] &= ~(0x01 << j);
pca_int_count++;
} else {
pca_int_count = 0;
frame_dog = 0;
}
}
}
}
}
if (CF) { //PCA计数溢出中断,19.6608MHZ晶体大约6.7ms溢出
CF = 0;
pca_tick++;
if (led_tick++ >= 10) {
led_tick = 0;
if (led_mod_table[led_mod][led_ptr++]) {
LED1 = 0;
LED2 = 0;
} else {
if (left_obj || right_obj || front_obj || back_obj) {
LED1 = 0;
LED2 = 0;
} else {
LED1 = 1;
LED2 = 1;
}
}
led_ptr %= 20;
}
if (pca_int_count) {
frame_dog++;
if (frame_dog >= 15) { //100ms后重新开始分析新的红外线数据包
pca_int_count = 0;
frame_dog = 0;
}
}
}
}
int read_black_line() { //读黑线位置.
unsigned char i;
int grayscale_min; //最黑的线
char line_begin, line_end; //黑线对应的传感器的开始和结束位置.
int tmp;
read_sensors(ad_datas);
/*
line_begin = -1; line_end= -1;
for (i = 0; i < 8; i++) {
//com_putchar(ad_datas[i]);
//com_putchar(ad_datas_check[i]);
tmp = (ad_datas[i] * 100);
tmp = tmp / ad_datas_check[i];
ad_datas[i] = tmp;
if (ad_datas[i] <= 40) //灰度<=40%认为下面有部分黑线
{
if (line_begin == -1)
line_begin = i;
else
line_end = i;
}
//com_putchar(ad_datas[i]);
}
if (line_begin == -1)
return -1;
if (line_end == -1)
return line_begin * 10;
return 10*line_begin + (line_end - line_begin) * 10 * ad_datas[line_begin] / (ad_datas[line_begin] + ad_datas[line_end]);
*/
line_begin = 0;
// ad_datas[0] = ad_datas[0] * 100 / ad_datas_check[0];
grayscale_min = 500;
for (i = 1; i < 8; i++) {
//com_putchar(ad_datas[i]);
//com_putchar(ad_datas_check[i]);
tmp = (ad_datas[i] * 100);
tmp = tmp / ad_datas_check[i];
ad_datas[i] = tmp;
if (ad_datas[i] <= grayscale_min)
{
grayscale_min = ad_datas[i];
line_begin = i;
}
//com_putchar(ad_datas[i]);
}
if (grayscale_min < 50) //灰度<50%认为是有效黑线
{
if (line_begin == 0)
line_end = 1;
else if (line_begin == 7)
{
line_begin = 6;
line_end = 7;
} else if (ad_datas[line_begin - 1] < ad_datas[line_begin + 1])
{
line_end = line_begin;
line_begin = line_begin - 1;
} else
line_end = line_begin + 1;
if (ad_datas[line_begin] == 0)
ad_datas[line_begin] = 1;
if (ad_datas[line_end] == 0)
ad_datas[line_end] = 1;
return 10*line_begin + (line_end - line_begin) * 10 * ad_datas[line_begin] / (ad_datas[line_begin] + ad_datas[line_end]);
} else
return -1;
}
void track_line(PID *pid) { //未使用PID算法的版本,四驱车用PID算法效果差些,需要改进,三轮车用PID效果还可以.
int line_pos;
line_pos = read_black_line();
if (line_pos == -1)
{
return;
}
com_putchar(line_pos);
if (line_pos > 45)
{
pwm_moto_left = 255;
pwm_moto_right = 255;
moto_left_forward = 0;
moto_right_forward = 1;
} else if (line_pos < 25) {
pwm_moto_left = 255;
pwm_moto_right = 255;
moto_left_forward = 1;
moto_right_forward = 0;
} else
{
pwm_moto_left = GAIN;
pwm_moto_right = GAIN;
moto_left_forward = 1;
moto_right_forward = 1;
}
}
/*
void track_line(PID *pid) { //使用PID算法的版本,三轮小车效果比较不错.
int p; //P增益
int i; //I增益
int d; //D增益
int gain; //控制量
pid->position = read_black_line();
if (pid->position == -1)
{
// pwm_moto_left = 0;
// pwm_moto_right = 0;
// pid_init(pid);
return;
}
com_putchar(pid->position);
pid->position -= 30;
pid->hisPosition += pid->position; //记录偏差之和
pid->lastPosition[2] = pid->lastPosition[1]; //
pid->lastPosition[1] = pid->lastPosition[0]; //
pid->lastPosition[0] = pid->position; //
p = (pid->p) * (pid->position); //计算比例分量(P)=比例系数*本次位置差
i = (pid->i) * (pid->hisPosition); //计算积分分量(I)=积分系数*偏差之和
d = (pid->d) * ((pid->position) - (pid->lastPosition[2])); //计算微分分量(D)=微分系数*(本次位置差-前3次的位置差)
// 由于采样比较快,用本次位置-前3次位置才有足够大的控制
gain = p + i + d; //P分量和D分量相加,得到控制量
// if (gain > GAIN)
// gain = GAIN;
// if (gain < -GAIN)
// gain = -GAIN;
if (gain > 30)
{
pwm_moto_left = GAIN + gain;
pwm_moto_right = GAIN + gain;
moto_left_forward = 0;
moto_right_forward = 1;
} else if (gain < -30) {
pwm_moto_left = GAIN - gain;
pwm_moto_right = GAIN - gain;
moto_left_forward = 1;
moto_right_forward = 0;
} else
{
pwm_moto_left = GAIN - gain;
pwm_moto_right = GAIN -gain;
moto_left_forward = 1;
moto_right_forward = 1;
}
}
*/
void main (void)
{
unsigned int i;
P2M0 = 0x3C; //P2.2~P2.5 强推挽输出
P3M0 = 0x30; //P3.4,P3.5强输出.
P1ASF = 0xff; //P1.7~P1.0用做AD
i = 0;
MOTO_IN_A1 = 0;
MOTO_IN_A2 = 0;
MOTO_IN_B1 = 0;
MOTO_IN_B2 = 0;
EA = 0;
power_stat = 0;
time0_initialize();
// com_initialize (); /* initialize interrupt driven serial I/O */
// com_baudrate (14400); /* setup for 14400 baud */
/*
CMOD = 0x01; // #00000001B,PCA空闲计数,PCA计数源=Fosc/12,PCA溢出中断(做一个定时器使用)
CCON = 0x00; //PCA中断标志清0,PCA停止计数
CL = 0x0;
CH = 0x0;
CCAPM1 = 0x31; //PCA1上升下降沿捕获
*/
CMOD = 0x03; // #00000011B,PCA空闲计数,PCA计数源=fosc/2,PCA溢出中断
CCON = 0x00; //PCA中断标志清0,PCA停止计数
CL = 0x0;
CH = 0x0;
CCAPM0 = 0x31; //PCA0上升下降沿捕获
/*
CCAPM0 = 0x42; //PCA0工作模式:8位pwm
PCA_PWM0 = 0x00;
CCAP0L = 0x40; //25%占空比,可调节占空比来调节发射功率.低电平驱动.
CCAP0H = 0x40;
*/
// EPCA_LVD = 1; //允许PCA和低压检测中断
ELVD = 1;
car_stat = 0x00;
pca_tick = 0;
pca_int_count = 0;
frame_dog = 0;
EA = 1; /* Enable Interrupts */
CR = 1; //启动PCA计数
now = pca_tick;
delay_ms(200);
read_sensors_check();
while (1)
{
if (power_stat) {
// auto_power_down(); //自动关机
}
switch (car_stat) {
case 0:
/*
MOTO_IN_A1 = 0;
MOTO_IN_A2 = 0;
MOTO_IN_B1 = 0;
MOTO_IN_B2 = 0;
*/
pwm_moto_left = 0;
pwm_moto_right = 0;
break;
case 1:
if (!front_obj) {
/*
MOTO_IN_A1 = 0;
MOTO_IN_A2 = 1;
MOTO_IN_B1 = 0;
MOTO_IN_B2 = 1;
*/
moto_left_forward = 1;
moto_right_forward = 1;
pwm_moto_left = 255;
pwm_moto_right = 255;
} else {
/*
MOTO_IN_A1 = 1;
MOTO_IN_A2 = 0;
MOTO_IN_B1 = 1;
MOTO_IN_B2 = 0;
delay(1000);
*/
car_stat = 0;
}
break;
case 2:
if (!back_obj) {
moto_left_forward = 0;
moto_right_forward = 0;
pwm_moto_left = 255;
pwm_moto_right = 255;
/*
MOTO_IN_A1 = 1;
MOTO_IN_A2 = 0;
MOTO_IN_B1 = 1;
MOTO_IN_B2 = 0;
*/
} else {
/*
MOTO_IN_A1 = 0;
MOTO_IN_A2 = 1;
MOTO_IN_B1 = 0;
MOTO_IN_B2 = 1;
delay(1000);
*/
car_stat = 0;
}
break;
case 3:
if (!left_obj) {
moto_left_forward = 0;
moto_right_forward = 1;
pwm_moto_left = 255;
pwm_moto_right = 255;
/*
MOTO_IN_A1 = 1;
MOTO_IN_A2 = 0;
MOTO_IN_B1 = 0;
MOTO_IN_B2 = 1;
*/
} else {
/*
MOTO_IN_A1 = 0;
MOTO_IN_A2 = 0;
MOTO_IN_B1 = 0;
MOTO_IN_B2 = 0;
*/
}
break;
case 4:
/*
if (!right_obj)
{
MOTO_IN_A1 = 0;
MOTO_IN_A2 = 1;
MOTO_IN_B1 = 1;
MOTO_IN_B2 = 0;
} else {
MOTO_IN_A1 = 0;
MOTO_IN_A2 = 0;
MOTO_IN_B1 = 0;
MOTO_IN_B2 = 0;
}
*/
moto_left_forward = 1;
moto_right_forward = 0;
pwm_moto_left = 255;
pwm_moto_right = 255;
break;
case 5:
track_line(&pid);
continue;
case 0xff:
if (!front_obj) {
moto_left_forward = 1;
moto_right_forward = 1;
pwm_moto_left = 255;
pwm_moto_right = 255;
if (pca_tick - now > 300)
{
pwm_moto_left = 0;
pwm_moto_right = 0;
delay_ms(1000);
now = pca_tick;
}
} else {
i = pca_tick % 3;
if (i == 0 && !left_obj) {
moto_left_forward = 0;
moto_right_forward = 1;
pwm_moto_left = 255;
pwm_moto_right = 255;
delay_ms(300);
} else if (i == 1 && !right_obj) {
moto_left_forward = 1;
moto_right_forward = 0;
pwm_moto_left = 255;
pwm_moto_right = 255;
delay_ms(310);
} else {
pwm_moto_left = 0;
pwm_moto_right = 0;
delay_ms(300);
}
now = pca_tick;
}
break;
default:
break;
}
PCON |= 0x01;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -