
默认分类 2009-08-24 10:35 阅读1 评论4
字号: 大大 中中 小小
前,左,后避障传感器现在对应中,右,左三路寻线传感器.
#include #include #include "STC12C5410AD.H" #include "sio.h" #define MIN9MS 0x0120 //9ms中心是0x0159 #define MAX9MS 0x01a0 #define MIN45MS 0x0090 //4.5ms中心是0x00ac #define MAX45MS 0x00d0 #define MIN225MS 0x0040 //2.25ms中心是0x0056 #define MAX225MS 0x0080 #define MIN056MS 0x000e //0.56ms中心是0x0015 #define MAX056MS 0x001b #define MIN168MS 0x0020 //1.68ms中心是0x0040 #define MAX168MS 0x0060 sfr ISP_CUNTR = 0xE7; sbit LED1 = P1^1; sbit LED2 = P1^2; sbit IR_FRONT = P3^3; sbit IR_LEFT = P3^4; sbit IR_RIGHT = P3^5; sbit IR_BACK = P1^3; sbit IR_OUT = P1^0; sbit PWM0 = P3^7; sbit MOTO_IN_A1 = P1^7; sbit MOTO_IN_A2 = P1^6; sbit MOTO_IN_B1 = P1^5; sbit MOTO_IN_B2 = P1^4; bit power_stat; static unsigned char car_stat; //小车状态:0,停止;1,前进;2,后退;3,左转;4,右转;ff,自控寻线模式 static unsigned char code led_mod_table[3][20] = { {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0}, {1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0} }; unsigned char idata led_mod = 0; static unsigned char idata led_tick = 0; static unsigned char idata led_ptr = 0; #define IR_SIGNAL_TOTAL 21 #define IR_SIGNAL_VALID 18 static unsigned char code ir_table[IR_SIGNAL_TOTAL] = { 1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0 }; static unsigned char code ir_check_table[IR_SIGNAL_TOTAL] = { 0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0 }; static unsigned char idata ir_ptr = 0; static unsigned char idata front_signal = 0; static unsigned char idata back_signal = 0; static unsigned char idata left_signal = 0; static unsigned char idata right_signal = 0; static bit front_obj = 0, back_obj = 0, left_obj = 0, right_obj = 0; static void delay(unsigned long v) { while (v--) { } } /* * PCA中断计数,根据位置判断信号区域和定义,位置0表示初始,1代表引导码信号,2表示引导码间隔, * 3表示第一个bit的信号,4表示第一个bit的间隔,以次类推... * 更具体见对应的红外线协议. */ static unsigned char idata pca_tick; static unsigned char idata pca_int_count; static unsigned char data pca_int_total; /* 根据引导头确定总长度 */ static unsigned int idata period; /* 红外信号占或空周期计数 */ static unsigned char idata data_buf[6]; /* 红外线协议数据缓冲区 */ static unsigned int idata ccap1; //PCA0上一次的的计数 static unsigned char idata frame_dog; //红外帧看门狗,限定时间未接收完成清除工作 void time0_isr() interrupt 1 { unsigned char tmp; if (ir_table[ir_ptr++]) { IR_OUT = 0; } else { IR_OUT = 1; } ir_ptr %= IR_SIGNAL_TOTAL; tmp = ir_check_table[ir_ptr]; if ((!IR_FRONT && tmp) || (IR_FRONT && !tmp)) front_signal++; if ((!IR_LEFT && tmp) || (IR_LEFT && !tmp)) left_signal++; if ((!IR_RIGHT && tmp) || (IR_RIGHT && !tmp)) right_signal++; if ((!IR_BACK && tmp) || (IR_BACK && !tmp)) back_signal++; if (ir_ptr == 0) { // com_putchar(front_signal); if (front_signal >= IR_SIGNAL_VALID) front_obj = 1; else front_obj = 0; if (back_signal >= IR_SIGNAL_VALID) back_obj = 1; else back_obj = 0; if (left_signal >= IR_SIGNAL_VALID) left_obj = 1; else left_obj = 0; if (right_signal >= IR_SIGNAL_VALID) right_obj = 1; else right_obj = 0; front_signal = 0; back_signal = 0; left_signal = 0; right_signal = 0; } } void time0_initialize(void) { TMOD &= ~0x0F; /* clear timer 0 mode bits */ TMOD |= 0x02; /* put timer 0 into MODE 2 */ TH0 = 0x5C; /* 256 - XTAL*dur/T1_12/1000000, dur=定时器的周期,以us为单位*/ TL0 = 0x5C; /* 100us */ PT0 = 0; /* 时钟0中断低优先级 */ TR0 = 1; ET0 = 1; } static void wakeup (void) interrupt 2 { } static void pca_isr (void) interrupt 6 { unsigned char i, j; if (CCF1) { CCF1 = 0; //清PCA1中断标志 LED1 = IR_RIGHT; LED2 = IR_RIGHT; if (!pca_int_count) { //第一次收到信号 if (!IR_RIGHT) { ccap1 = pca_tick * 256 + CCAP1H; pca_int_count++; } } else { //已经收到一些信号 period = pca_tick * 256 + CCAP1H - ccap1; ccap1 = pca_tick * 256 + CCAP1H; //com_putchar(period / 256); //com_putchar(period % 256); if (pca_int_count == 1) { if (period < MIN9MS || period > MAX9MS) { //9ms pca_int_count = 0; frame_dog = 0; } else pca_int_count++; } else if (pca_int_count == 2) { if (period > MIN225MS && period < MAX225MS) { //2.25ms pca_int_total = 3; pca_int_count++; } else if (period > MIN45MS && period < MAX45MS) { //4.5ms pca_int_total = 67; pca_int_count++; } else { pca_int_count = 0; frame_dog = 0; } } else { if (IR_RIGHT) { if (period > MIN056MS && period < MAX056MS) { //0.56ms if (pca_int_count >= pca_int_total) { //帧接收完毕,下面进行有效分析. if (pca_int_total == 67) { //完整信号,含有引导信号,设备码8bit,设备反码8bit,命令字8bit,命令字反码8bit if ((data_buf[0] ^ data_buf[1] == 0xff) && (data_buf[2] ^ data_buf[3] == 0xff)) { com_putchar(data_buf[0]); com_putchar(data_buf[2]); if (data_buf[0] == 0x40) { switch (data_buf[2]) { case 0x5F: //左 car_stat = 3; break; case 0x5B: //右 car_stat = 4; break; case 0x5A: //上 car_stat = 1; break; case 0x5E: //下 car_stat = 2; break; case 0x56: //菜单 car_stat = 0; break; case 0x0: //数字0 car_stat = 0xff; break; case 0x12: //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 |= (0x01 << j); pca_int_count++; } else if (period > MIN056MS && period < MAX056MS) { //0.56ms // com_putchar(0x00); data_buf &= ~(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 { 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; } } } } void auto_power_down() { delay(30000); ISP_CUNTR = 0x20; //从AP复位并从AP执行 } void main (void) { unsigned char i; unsigned long j; MOTO_IN_A1 = 0; MOTO_IN_A2 = 0; MOTO_IN_B1 = 0; MOTO_IN_B2 = 0; P1M1 = 0xf0; //P1.7~P1.4 强推挽输出 EA = 0; power_stat = 0; time0_initialize(); com_initialize (); /* initialize interrupt driven serial I/O */ com_baudrate (4800); /* setup for 1200 baud */ /* CMOD = 0x01; // #00000000B,PCA空闲计数,PCA计数源=Fosc/12,PCA溢出中断(做一个定时器使用) CCON = 0x00; //PCA中断标志清0,PCA停止计数 CL = 0x0; CH = 0x0; CCAPM1 = 0x31; //PCA1上升下降沿捕获 */ CMOD = 0x03; /* #00000010B,PCA空闲计数,PCA计数源=fosc/2,PCA溢出中断 */ CCON = 0x00; //PCA中断标志清0,PCA停止计数 CL = 0x0; CH = 0x0; CCAPM1 = 0x31; //PCA1上升下降沿捕获 CCAPM0 = 0x42; //PCA0工作模式:8位pwm PCA_PWM0 = 0x00; CCAP0L = 0x20; CCAP0H = 0x20; EPCA_LVD = 1; //允许PCA和低压检测中断 car_stat = 0; pca_tick = 0; pca_int_count = 0; frame_dog = 0; EA = 1; /* Enable Interrupts */ CR = 1; //启动PCA计数 while (1) { if (power_stat) { // auto_power_down(); } if (left_obj || right_obj || front_obj || back_obj) { LED1 = 0; LED2 = 0; } switch (car_stat) { case 0: MOTO_IN_A1 = 0; MOTO_IN_A2 = 0; MOTO_IN_B1 = 0; MOTO_IN_B2 = 0; break; case 0xff: if (!front_obj) { //中线传感器检测到黑线 MOTO_IN_A1 = 1; MOTO_IN_A2 = 0; MOTO_IN_B1 = 1; MOTO_IN_B2 = 0; j = 50000; while (j) { j--; if (front_obj) break; } } else { TURNLEFT: MOTO_IN_A1 = 0; MOTO_IN_A2 = 1; MOTO_IN_B1 = 1; MOTO_IN_B2 = 0; j = 1000000; while (1) { j--; if (!front_obj) { goto EXIT; } if (!left_obj) goto TURNLEFT; if (!back_obj) goto TURNRIGHT; if (j == 0) goto EXIT; } TURNRIGHT: MOTO_IN_A1 = 1; MOTO_IN_A2 = 0; MOTO_IN_B1 = 0; MOTO_IN_B2 = 1; j = 1000000; while (j) { j--; if (!front_obj) goto EXIT; if (!back_obj) goto TURNRIGHT; if (!left_obj) goto TURNLEFT; } } EXIT: /* MOTO_IN_A1 = 0; MOTO_IN_A2 = 0; MOTO_IN_B1 = 0; MOTO_IN_B2 = 0; delay(5000); */ break; default: break; } PCON |= 0x01; }
