?? rainwipereeprom v20.c
字號:
/********************************
名稱:雨刷控制器
日期: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 + -