⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test.c

📁 《增强型8051单片机实用开发技术》例程代码
💻 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 + -