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

📄 rainwipereeprom v20

📁 用L293步进电机驱动芯片做的步进电机驱动器.
💻
字号:
/********************************
名称:雨刷控制器
日期:2007-06-23
作者:Mavinger
版本:
V1.0:2007-07-8 ,创建此版本

V2.0:2006-11-5 ,修改外部晶振为11.0592M


硬件:
1.控制单片机: 12C5052AD
2.步进电机驱动器: L293D




********************************/

#include "../code/STC12C5410AD.h"
//#include "../code/STC89C51RC.h"
#include <INTRINS.h>
#include <math.h>
#include <stdio.h>

//数据类型定义
typedef unsigned char byte;
typedef unsigned int  word;
typedef unsigned long dword;

//24M
//#define  Timer_H    0xFF		//0.1ms
//#define  Timer_L    0x38
#define  Timer_H    0xFF		//0.01ms
#define  Timer_L    0xEC

#define RunDegree   350
#define HighSpeed   2
#define LowSpeed    5
#define FordRun			1
#define BackRun			0


//电机驱动控制

//input
sbit Run_Mode	=P3^5; 
sbit Stop_Mode	=P3^4;
sbit Speed_Mode	=P3^3;

//output
sbit Step_EN1	=P1^7;
sbit Step_EN2	=P1^6;

sbit Out_A0  	=P1^3;
sbit Out_A1     =P1^2; 
sbit Out_B0     =P1^1; 
sbit Out_B1     =P1^0; 


#define Open	1
#define Close   0
#define ON      1
#define OFF     0

#define OK  1
#define Error 0


/*---命令---*/
#define READ_Data_Memory_Command			 0x01     /*  字节读应用程序区和数据存储区   */
#define PROGRAM_Data_Memory_Command          0x02        /*  字节编程应用程序区和数据存储区 */
#define SECTOR_ERASE_Data_Memory_Command     0x03        /*  扇区擦除应用程序区和数据存储区 */

#define Wait_Time 		 0x05      //CPU等待时间 20M:0x01    40M: 0x00
#define In_One_Sector  512    //扇区大小: 512字节

/*------ISP_CONTR -----------*/
#define ResetToISP   0x60    /* MCU 软复位至ISP程序区*/
#define AllowFlash   0x80    /*允许ISP/IAP操作*/
#define StartAtISP   0x40  
#define OnReset      0x20


/*产品参数处于Data Flash的首地址*/
#define STEPBLOCK_ORIGIN	0x2800   //0x2C000x9400

bit MotorDir;
bit Runflag,Stopflag;

word stepsave,Degreesave;
byte np;

const byte forward[]=
{0xB8,0xFA,0x72,0xF6,0xB4,0xF5,0x71,0xF9};

const byte backward[]=
{0xF9,0x71,0xF5,0xB4,0xF6,0x72,0xFA,0xB8};

const word code Default_Degree=400;
const word code Default_RunSpeed=30;
const word code Default_StepNum=300;
const word code Default_StopSpeed=1;
const word code Default_RunStep=0;	
const word code Default_Diretion=1;
const word code Default_Market=0x88;
const word code Default_EndFlag=1;				//已归位
/*
data struct
{
	word Degree;				//角度
	word Diretion;			//方向
	word StepNum;				//总步数
	word RunStep;				//未运行步数
	word RunSpeed;			//运行时间
	word StopSpeed;			//转换方向间隔时间
	word Market;				//标志位
  word EndFlag;
}Stepblock;
*/
xdata struct
{
	word Diretion;			//方向
	word RunStep;				//未运行步数
	word Market;				//标志位
	word EndFlag;
}Stepblock;

xdata step_cnt1;


void StepRun(byte StepDir,word Speednum);



void Initial(void)
{
	//AUXR=AUXR & 0x7F;  				//T0x12=0; 系统时钟12分频,即 T=12/6=2us
	AUXR=0x00;
	
  TMOD=0x01;						//C/T1作定时用,16位模式	

	TH0=0xFF;
	TL0=0x38;
	ET0=1;
	TR0=1;


	P1M0=0;		//P1M0=0,P1M1=0,P1口为准双向口
	P1M1=0;
	P3M0=0;
	P3M1=0;
	EA=1;
}

void InitialUART(void)
{
    SCON = 0X50;     
    TMOD = 0X21;        
	  TH1 = 0xF3;			//Baudrate:4800
    //TH1=0xFA;				//9600
	  TR1 = 1 ;         
    TI=1;
}


//1ms*N 延时
void Delay1MS(word delay1ms)
{
	word cnt;
	byte cnt1; 
	

	for(cnt=0;cnt<delay1ms;cnt++)
	{
		for(cnt1=0;cnt1<200;cnt1++)
		//for(cnt1=0;cnt1<2;cnt1++)
		_nop_();
	}
}



//---------------------EEPROM --------------------------------
/*------------------
打开ISP/IAP功能
--------------------*/
void ISP_IAP_Enable(void)
{
	EA	=	0;	/* 关中断 */
	ISP_CONTR	=	ISP_CONTR & 0x18;       /* 0001,1000 */
	ISP_CONTR	=	ISP_CONTR | Wait_Time;
	ISP_CONTR	=	ISP_CONTR | 0x80;       /* 1000,0000 */	
}


/*------------------
关闭ISP/IAP功能
--------------------*/
void ISP_IAP_Disable(void)
{
	ISP_CONTR	=	ISP_CONTR & 0x7f;	/* 0111,1111 */
	ISP_TRIG	=	0x00;
	EA			=   1;                	/* 开中断 */
}

/*------------------
字节读
输入: 16位地址
返回: 一个字节数据
--------------------*/
byte Byte_Read(word byte_addr)
{
	ISP_ADDRH=(byte)(byte_addr >> 8);
	ISP_ADDRL=(byte)(byte_addr & 0x00ff);

	ISP_CMD	=ISP_CMD&0xf8;        // 1111,1000  等待模式
	ISP_CMD	=ISP_CMD|READ_Data_Memory_Command;   //0000,0001 读数据 
	ISP_IAP_Enable();
	ISP_TRIG=0x46;
	ISP_TRIG=0xb9;
	_nop_();
	_nop_();

	ISP_IAP_Disable();
	return (ISP_DATA);	
}


void flash_Block_Read(byte *dest, word src, word count)
{
	word idata i;
	
	for(i = 0; i < count; i++)
	{
		*(dest + i) = Byte_Read(src+i);
	}
}


/*------------------
扇区擦除
输入: 16位地址
返回:=1  Erase success
--------------------*/
byte Sector_erase(word sector_addr)
{
	word idata get_sector_addr	=	0;
	get_sector_addr			=	(sector_addr & 0xfe00); // 1111,1110,0000,0000; 取扇区地址
	ISP_ADDRH        		=	(byte)(get_sector_addr >> 8);
	ISP_ADDRL		        =	0x00;
	ISP_CMD	=	ISP_CMD	&	0xf8;	// 1111,1000 
	ISP_CMD	=	ISP_CMD	| SECTOR_ERASE_Data_Memory_Command;	// 0000,0011 
	ISP_IAP_Enable();
	ISP_TRIG	=	0x46;        // 触发ISP_IAP命令
	ISP_TRIG	=	0xb9;        // 触发ISP_IAP命令 
	_nop_();
	_nop_();
	
	ISP_IAP_Disable();
	return OK;	
}



/*------------------
写数据进 数据Flash存储器, 只在同一个扇区内写,不保留原有数据
begin_addr,被写数据Flash开始地址;counter,连续写多少个字节; array[],数据来源
--------------------*/
byte Sequential_write_flash_in_one_sector(word begin_addr, byte *array, word counter)
{
	word	idata	i	=	0;
	word	idata	in_sector_begin_addr	=	0;
	word	idata sector_addr	=	0;

	// 判是否是有效范围,此函数不允许跨扇区操作 

	if(counter > In_One_Sector)
		return	Error;
	in_sector_begin_addr = begin_addr & 0x01ff;         // 0000,0001,1111,1111 
	if((in_sector_begin_addr + counter) > In_One_Sector)
		return Error;

    //擦除 要修改/写入 的扇区 
	sector_addr	=	(begin_addr & 0xfe00);	// 1111,1110,0000,0000; 取扇区地址 
	ISP_ADDRH	=	(byte)(sector_addr >> 8);
	ISP_ADDRL	=	0x00;
	ISP_CMD		=	ISP_CMD	&	0xf8;		// 1111,1000 
	ISP_CMD		=	ISP_CMD	|	SECTOR_ERASE_Data_Memory_Command;	// 0000,0011 
	ISP_IAP_Enable();
	ISP_TRIG	=	0x46;        //触发ISP_IAP命令
	ISP_TRIG	=	0xb9;        // 触发ISP_IAP命令 
	_nop_();
	_nop_();

	for(i = 0; i< counter; i++)
	{
		//写一个字节
		ISP_ADDRH	=	(byte)(begin_addr >> 8);
		ISP_ADDRL	=	(byte)(begin_addr & 0x00ff);
		ISP_DATA	=	*array;
		ISP_CMD		=	ISP_CMD	&	0xf8;	//1111,1000
		ISP_CMD		=	ISP_CMD	|	PROGRAM_Data_Memory_Command;		//0000,0010
		ISP_TRIG	=	0x46;	// 触发ISP_IAP命令 
		ISP_TRIG	=	0xb9;	// 触发ISP_IAP命令 
    _nop_();
		_nop_();                   // 读回来

		ISP_DATA	=	0x00;
		ISP_CMD		=	ISP_CMD	&	0xf8;	// 1111,1000 
		ISP_CMD     =	ISP_CMD	|	READ_Data_Memory_Command;	// 0000,0001
		ISP_TRIG	=	0x46;	// 触发ISP_IAP命令 
		ISP_TRIG	=	0xb9;	// 触发ISP_IAP命令 
		_nop_();
		_nop_();		

		//  比较对错 if(ISP_DATA != *array)
		if(ISP_DATA != *array)
		{
			ISP_IAP_Disable();
			return Error;
		
		}
        begin_addr++;
				array++;
	}
	ISP_IAP_Disable();
	return	OK;	
}


void UploadBlock(void)
{
	flash_Block_Read((byte *)&Stepblock, STEPBLOCK_ORIGIN, sizeof(Stepblock)); 
}

byte UpdateBlock(void)
{
	Sector_erase(STEPBLOCK_ORIGIN);
	return(Sequential_write_flash_in_one_sector(STEPBLOCK_ORIGIN,(byte *)&Stepblock,sizeof(Stepblock)));
}


byte ResetBlock(void)
{	
//	Stepblock.Degree=Default_Degree;
	Stepblock.Diretion=Default_Diretion;
//	Stepblock.StepNum=Default_StepNum;
	Stepblock.RunStep=Default_RunStep;     //...
//	Stepblock.RunSpeed=Default_RunSpeed;
//	Stepblock.StopSpeed=Default_StopSpeed;
	Stepblock.Market=Default_Market;
	Stepblock.EndFlag=Default_EndFlag;  
	return(UpdateBlock());
}

byte ReturnSet(void)
{	
	Stepblock.Diretion=FordRun;
	Stepblock.RunStep=0;     
	Stepblock.Market=Default_Market;
	Stepblock.EndFlag=1;  
	return(UpdateBlock());
}


void ReadBlock(void)
{	
	word stepcnt;
	word step1;

	step1=RunDegree/0.9;
	step1=step1-Stepblock.RunStep;


	UploadBlock();
/*	if(Stepblock.Market!=Default_Market)
	{	
		printf("Stepblock.Market!=Default_Market\n");
		ResetBlock();
	}
	else*/
	if(Stepblock.Market!=Default_Market)
	{
		Stepblock.Diretion=0x01;
		Stepblock.RunStep=10;
		Stepblock.EndFlag=0x00;

		printf("Stepblock.Market=Default_Market\n");
		if((!Stepblock.EndFlag) && Stepblock.RunStep)				//未归位
		{
		
				if(Stepblock.Diretion==0x01)   //正转
				{
					//for(stepcnt=0;stepcnt<Stepblock.RunStep;stepcnt++)
					for(stepcnt=0;stepcnt<130;stepcnt++)
  				{
						StepRun(BackRun,10);				//反转归位					
					}
				}
				else if(Stepblock.Diretion==0x00)   //反转
				{
					for(stepcnt=0;stepcnt<300;stepcnt++)
					{
						StepRun(BackRun,10);				//反转归位					
					}

				}			
				ResetBlock();	
		}
		
	}
}


void MotorRst(void)
{
	Step_EN1=1;
	Step_EN2=1;
	Out_A0=0;
	Out_A1=0;
	Out_B0=0;
	Out_B1=0;
}

void MotorSet(void)
{
	P1=0xB8;
	Delay1MS(1);
}


void StepRun(byte StepDir,word Speednum)		// One step run
{

	if(StepDir & 0x01)
	{	 
		MotorDir=1;
		if(np==0)
			np=7;
		else 
			np--;
		P1=forward[np];
		Delay1MS(Speednum);	
	}
	else
	{
		MotorDir=0;
		if(np==0)
			np=7;
		else 
			np--;
		P1=backward[np];
		Delay1MS(Speednum);	
	}		
}

void RunNumRecord(word runnum)
{
		Stepblock.RunStep=runnum;  
		UpdateBlock();	
}




void MotorTurn(byte StepDir,word Speednum,word Degree)	//方向,速度,度数
{
	word degreecnt;
	word stepcnt;

	degreecnt=Degree/0.9;
	Degreesave=degreecnt;	
	
	for(stepcnt=0;stepcnt<degreecnt;stepcnt++)
	{
		StepRun(StepDir,Speednum);
		
		//if(!Stop_Mode)
		//{
		step_cnt1=stepcnt;
		RunNumRecord(stepcnt);
	//	UploadBlock();
	//	printf("RunStep:%d\n",Stepblock.RunStep);	
	//	}
	}
}


void MotorReturn(byte StepDir,word Speednum)
{
	word stepcnt;
	word savecnt;

	savecnt=Degreesave-stepsave;

	for(stepcnt=0;stepcnt<savecnt;stepcnt++)
	{
		StepRun(StepDir,Speednum);
	}
}


main()
{
	xdata word cnt;

	Initial();
	InitialUART();
	ReadBlock();


  Run_Mode=1;
	Stop_Mode=1;
	Speed_Mode=1;
  
  stepsave=0;
  Degreesave=0;

  printf("Program beginning.....\n");
	printf("Diretion:%d\n",Stepblock.Diretion);
	printf("RunStep:%d\n",Stepblock.RunStep);
	printf("Market:%d\n",Stepblock.Market);
	printf("EndFlag:%d\n",Stepblock.EndFlag);
	cnt=Stepblock.RunStep;

	while(1)
	{	
		if(!Run_Mode)
		{
			Runflag=1;
			if(!Speed_Mode)
			{
				Stepblock.Diretion=FordRun;
				MotorTurn(FordRun,LowSpeed,RunDegree);		//正转
				Delay1MS(200);
				Stepblock.Diretion=BackRun;
				MotorTurn(BackRun,LowSpeed,RunDegree);		//反转
				MotorRst();
				ReturnSet();
			}
			else
			{
				Stepblock.Diretion=FordRun;
				MotorTurn(FordRun,HighSpeed,RunDegree);		//正转
				Delay1MS(200);
				Stepblock.Diretion=BackRun;
				MotorTurn(BackRun,HighSpeed,RunDegree);		//反转
				MotorRst();
				ReturnSet();
			}
		}
		else
		{
			MotorSet();
		}
	}
}

void Timer0(void) reentrant  interrupt 1
{
		TH0=Timer_H;
		TL0=Timer_L;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -