📄 test.c
字号:
#include"stc12c5a.h" //包含STC12C5A60S2单片机的寄存器定义头文件
#include"ISD51.h" //包含ISD51调试功能所需头文件
#define _DEBUG //启用ISD51调试功能
sbit P37=P3^7;
sbit steerPWM=P4^2;
unsigned char speed; //给定速度--实际为驱动电机PWM的占空比
unsigned int duty=78,duty1; //驱动舵机PWM占空比
unsigned char b[7]; //路经检测二值化后的值
char locate; //黑线偏差坐标
char locate_hist; //历史黑线偏差坐标
bit black_flag; //检测到黑线的标志变量
void T0_ISR(void) interrupt 1 //定时器0中断--在IO上产生周期为20ms的PWM波形驱动舵机
{
static unsigned int period=0;
period++;
if(period<=duty) steerPWM=1;
else steerPWM=0;
if(period>=1000) //计数1000次实现定时20ms
{
period=0;
duty=duty1;
}
}
void PWM1_init(void) //PWM初始化--驱动电机用
{
CMOD=0x80; //PCA 在空闲模式下停止 PCA 计数器工作
//PCA 时钟模式为fosc/12,禁止 PCA 计数器溢出中断
CCON=0x0; //禁止PCA计数器工作,清除中断标志、计数器溢出标志
CL=0x0; //清0计数器
CH=0x0;
CCAPM1=0x02; //设置模块1
PCA_PWM1=0x00;
}
void TIMER_init(void) //定时器初始化
{
TMOD=0x22; //定时器01都为工作方式2
TL0=0xee;
TH0=0xee; //自动装入初值,定时20us,
TR0=1; //启动定时器0
ET0=1; //允许定时器0中断
TH1=0xFD; //产生9600bps的时间常数
TL1=0xFD;
TR1=1; //启动定时器1
}
void AD_init(void) //AD初始化
{
unsigned int i;
ADC_CONTR=0x80; //开A/D转换电源,第一次使用时要打开内部模拟电源
for (i=0;i<10000;i++); //适当延时
P1ASF=0xff; //P1口 7路AD转换 AD0--AD6
}
char abs(char data1) //求绝对值子程序
{
data1=(data1<0)?(-data1):data1;
return data1;
}
void Get_data(void) //获取路径信息
{
unsigned int i;
unsigned int res,resl; //AD结果暂存
unsigned char status=0; //AD转换状态
unsigned int a[7]; //路经检测的AD采样值
black_flag=0;
ADC_CONTR=0x80; //打开AD电源
for (i=0;i<10000;i++); //适当延时
for(i=0;i<7;i++)
{
ADC_CONTR=(0x80|i); //设定转换通道
ADC_CONTR|=0x08; //开始AD转换
status=0;
while(status==0) //等待转换完
{
status=ADC_CONTR&0x10;
}
ADC_CONTR&=0xE7; //清零
res=ADC_RES; //读AD转换结果
resl=ADC_RESL;
a[i]=res*256+resl;
if(a[i]<0x02ff) b[i]=0; //二值化
else
{
b[i]=1;
black_flag=1;
}
}
}
void main (void)
{
AUXR1=0x44; //PWM1转到P4.3口,AD高两位存在ADC_RES
PCON|=0x80; //波特率加倍
SCON=0x50; //8位可变波特率,无校验
//P1M0=0x00; //P1口用作AD口,设为输入
//P1M1=0xff;
P37=1;
#ifdef _DEBUG
ISDinit (); //初始化ISD51
#endif
TIMER_init();
AD_init();
PWM1_init();
CR=1; //允许PCA计数
EA = 1; //允许全局中断
while(1)
{
Get_data(); //获取路径信息
if(black_flag==1) //能够检测到黑线时
{
locate=((-12)*b[0]+(-8)*b[1]+(-4)*b[2]+0*b[3]+4*b[4]+8*b[5]+12*b[6])/(b[0]+b[1]+b[2]+b[3]+b[4]+b[5]+b[6]);
//计算偏差坐标 -12 0 12
locate_hist=locate; //保存历史
}
else //检测不到黑线时,偏差用历史值
locate=locate_hist;
duty1=72+locate*5/4; //根据偏差计算转角
if(duty1<62) duty1=58; //转角限幅
if(duty1>88) duty1=93;
speed=0x8e-5*abs(locate); //根据偏差给定速度
CCAP1L=speed;
CCAP1H=speed;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -