/////////////////////////////////////////
//功能:智能车循两个十字路口停下
//时间: 2012-6-10
//单位:合肥凌翔信息科技有限公司
////////////////////////////////////////
#include<STC.h>
#include<iom16v.h> //*
#include<math.h>
#include<stdio.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define PWM_R CCAP0H
#define PWM_L CCAP1H
#define sei() SREG|=0X80 //*
#define cli() SREG|=0X7F
//EEPROM控制寄存器位定义:
#define EERE 0
#define EEWE 1
#define EEMWE 2
#define WWRIE 3
sbit s1=P2^0; /* L298的Input 1 */
sbit s2=P2^1; /* L298的Input 2 */
sbit s3=P2^2; /* L298的Input 3 */
sbit s4=P2^3; /* L298的Input 4 */
sbit start=P0^5;
int led0=0,led1=0,led2=0,led3=0,led4=0,led5=0,led6=0;
int LED[7]=0,LED_white[7]=0,LED_black[7]=0;
char flag0=0,flag1=0,flag2=0,flag3=0,flag4=0,flag5=0,flag6=0;
char sum=0;
char value=0,last_value=0; //Value为权值算法的值
char count=0; //count为黑色的权值计算值
int line_st=0; //line_st为十字线个数
char line_l=0,time_cn=0; //line_l为车的循线状态,0为正常、1为丢失、2为横线 ;time_cn为控制横线不重复计算。
//---------与STC12C5A32S2单片机PWM相关的寄存器声明------------------
/*sfr CCON = 0xD8; //PCA控制寄存器
sfr CMOD = 0xD9; //PCA模式寄存器
sfr CCAPM0 = 0xDA; //PCA模块0模式寄存器 //模块0对应P1.3/CEX0/PCA0/PWM0(STC12C5A60S2系列)
sfr CCAPM1 = 0xDB; //PCA模块1模式寄存器 //模块1对应P1.4/CEX1/PCA1/PWM1(STC12C5A60S2系列)
sfr CL = 0xE9; //PCA 定时寄存器 低位
sfr CH = 0xF9; //PCA 定时寄存器 高位
sfr CCAP0L = 0xEA; //PCA模块0的 捕获寄存器 低位
sfr CCAP0H = 0xFA; //PCA模块0的 捕获寄存器 高位
sfr CCAP1L = 0xEB; //PCA模块1的 捕获寄存器 低位
sfr CCAP1H = 0xFB; //PCA模块1的 捕获寄存器 高位
sfr PCA_PWM0 = 0xF2; //PCA PWM 模式辅助寄存器0
sfr PCA_PWM1 = 0xF3; //PCA PWM 模式辅助寄存器1
sbit CF = 0xDF; //PCA计数溢出标志位
sbit CR = 0xDE; //PCA计数器 运行控制位
sbit CCF1 = 0xD9; //PCA模块1中断标志
sbit CCF0 = 0xD8; //PCA模块0中断标志
*/
// ------------------------------------------------------------
//P1ASF寄存器:8位,对应P1口8根口线,用于指定哪根口线用作ADC功能
//哪个口用作ADC就应置相应的位为“1”,注意:不能位寻址
//------------------------------------------------------------------
#define ADC_POWER 0x80 //ADC电源开
#define ADC_SPEED 0x60 //设为90个时钟周期ADC一次
#define ADC_START 0x08 //ADC启动控制位设为开
#define ADC_FLAG 0x10 //ADC结束标志位
//--------------------------------------------------//
//----------void delay_ms( )------------------------//
//--------------延时函数---------------------------//
//--------------------------------------------------//
void delay_ms(unsigned int nCount)
{
unsigned int j = 0,i=0;
for (j = nCount; j != 0; j--)
for(i = 7960; i != 0; i--);
}
//--------------------------------------------------//
//----------void PWM_init( )------------------------//
//---------PWM硬件输出初始化P4.2/P4.3、I/0输出-------//
//--------------------------------------------------//
void PWM_init()
{
CCON = 0x04;
AUXR1=0x40;
CH = CL = 0x00;
CMOD = 0x00;
CCAPM0 = 0X42; //8位PWM输出,无中断
CCAPM1 = 0X42;
CR = 1;
PWM_R=0;
PWM_L=0;
DDRA=0xff; //*
PORTA=0xff;
}
//--------------------------------------------------//
//------void m1pwm(bit dir,unsigned char pwm)-------//
//---------电机1 系统pwm控制 方向和pwm 0-ff---------//
//---------0为低电平--------------------------------//
//---------控制右电机--------------------------------//
void m1_spwm(bit dir,unsigned char pwm){
if(dir){
PWM_L =0xff-pwm; // 电机1 pwm调节
s1=1; // 正向
s2=0;
}
else{
PWM_L =0xff-pwm; // 电机1 pwm调节
s1=0; // 反向
s2=1;
}
}
//--------------------------------------------------//
//------void m2_pwm(bit dir,unsigned char pwm)-------//
//---------电机2 系统pwm控制 方向和pwm 0-ff---------//
//---------0为低电平--------------------------------//
//---------控制左电机------------------------------//
void m2_spwm(bit dir,unsigned char pwm){
if(dir){
PWM_R=0xff-pwm; // 电机1 pwm调节
s3=1; // 正向
s4=0;
}
else{
PWM_R =0xff-pwm; // 电机1 pwm调节
s3=0; // 反向
s4=1;
}
}
//-------------------------------------------------------------
/*
ADC_CTRL寄存器:
ADC_POWER SPEED1 SPEED0 ADC_FLAG ADC_STAR CHS2 CHS1 CHS0
1 2 3 4 5 6 7 8
第 1 位: =1 打开ADC电源;=0 关闭ADC电源; ADC前要一定要打开
第2-3位: =1 1 90个时钟周期ADC一次; =1 0 180个时钟周期ADC一次;
=0 1 360个时钟周期ADC一次; =0 0 540个时钟周期ADC一次;
第4位: ADC结束标志位,每次ADC结束时自动=1,需要用软件清零才可以进行下一次ADC
第5位: ADC启动控制位,置“1”则ADC转换开始,转换结束后为0
第6-7-8位:ADC通道选择 000-->P1.0 ........111-->P1.7
*/
//-------------------------------------------------------------
void ADC_int(uchar n) //第n通道ADC初始化函数
{ n&=0x07; //确保n=0----7通道
AURX1|=0x04; //转换结果存储格式:数据的高2位放ADC_RES,低8位放ADC_RESL
P1ASF=1<<n; //将P1.n设为ADC采样功能
}
//---------------------------------------------------------------
uint ADC_GET(unsigned char n) //第n通道ADC采样函数
{
unsigned int adc_data;
n&=0x07; //确保n=0----7通道
ADC_RES=0; //清零
ADC_RESL=0; //清零
ADC_CONTR=0; //清零,以便重构
ADC_CONTR|=(ADC_POWER|ADC_SPEED|n|ADC_START); //打开AD转换电源、设定转换速度、设定通道号、AD转换开始
_nop_();_nop_();_nop_();_nop_();_nop_(); //延时4个时钟周期左右
while(!(ADC_CONTR&ADC_FLAG)); //等待转换结束 =0x10 ADC_FLAG位=1
adc_data=(ADC_RES&0x03)*256+ADC_RESL; //转换结果计算,取高位结果存储器的低2位 + 低位结果存储器
ADC_CONTR&=~ADC_FLAG; //清零转换结束标志位(ADC_FLAG位=0)
return adc_data; //返回ADC的值(0----1023)
}
//--------------------------------------------------//
//----------void back( )---------------------------//
//-----------刹车函数------------------------------//
//--------------------------------------------------//
void back()
{
s1=0;s2=1;
s3=0;s4=1;
PWM_L=10;PWM_R=10;
}
//--------------------------------------------------//
//----------void stop( )---------------------------//
//-----------停车函数------------------------------//
//--------------------------------------------------//
void stop()
{
PWM_L=250;
PWM_R=250;
}
//-----------------------------------------------------------------//
//----------void value_count( )------------------------------------//
//-----------7路传感器扫描函数-------------------------------------//
//---------以下的LED0-LED6的参数值需要参赛选手进行自行设置---------//
void value_count(void)
{
count=0;
if(led0>LED[0]) //通道0
{
flag0=-6; //flag1=1表示传感器照在黑线上
count++;
}
else flag0=0;
if(led1>LED[1]) //通道1
{
flag1=-4;
count++;
}
else flag1=0;
if(led2>LED[2]) //通道2
{
flag2=-2;
count++;
}
else flag2=0;
if(led3>LED[3]) //通道3
{
flag3=0;
count++;
}
else flag3=0;
if(led4>LED[4]) //通道4
{
flag4=2;
count++;
}
else flag4=0;
if(led5>LED[5]) //通道5 就这个有问题
{
flag5=4;
count++;
}
else flag5=0;
if(led6>LED[6]) //通道6
{
flag6=6;
count++;
}
else flag6=0;
sum=flag0+flag1+flag2+flag3+flag4+flag5+flag6;
//以下是计算横线个数
//以下是计算横线个数
value