/*4相步進電機*/
/*程序:伍耀斌 13715528667 版本號:2010-1-9*
資源分配:p1.0~1.5用作顯示6位LED掃描
p2.0~2.7用作4*4鍵盤掃描
p0.0~0.7用作LED段顯示*/
#include<AT89X52.h>
//sbit LED=P3^7;
//sbit DD=P3^5;
//sbit SB=P3^4;
#define uchar unsigned char //定義為無符號字付 ~~typedef unsigned char uchar;
#define uint unsigned int //~~typedef unsigned int uint;
//typedef unsigned char uchar;
//typedef unsigned int uint;
// 定義說明:
//RAM區定義 全部大寫
//數值定義 全部小寫
//地址標號 首字母大寫,其余小寫
uchar code BitTab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf}; //11111110,11111101,11111011,11110111,11101111,11011111
uchar code DispTab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xFF};
//{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xFF}; 新板,段位沒有加2003
//{0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00}; 舊板,段位糜屑?003
//uchar DispBuf[4]; //四位掃描
unsigned char codes[8]={0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09};// 順時針
//{0x0b,0x09,0x0d,0x0c,0x0e,0x06,0x07,0x03}}; //9,18,36,45,54,63,72,81度 逆時針{0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09}
static uchar ONE; //存放個位數據
static uchar TWO; //存放十位數據
static uchar THREE; //存放百位數據
static uchar FOUR; //存放千位數據
static uchar FIVE;
static uchar SIX;
static uint TS; //定義為靜態變量 Ts=5msX200=1000ms=1S
//static uchar TS;
static uchar SEC; //秒變量
static uchar MIN; //分變量
static uchar HOUR; //小時變量
static uchar KEY; //放鍵值(做系這里的目的是為了以后可以隨時調用)
static uchar SET;
static uchar STEPtimer; //每一步的時間
static uchar FangShang; //正反轉控制 0正、1反
static uchar counts;
static uchar TSS;
static uchar StepSpeed;
static uchar Star; //首次開機標志,以低中檔啟動,3秒后轉為高檔
//static uchar ST;
//static uchar EOC;
//static uchar OE;
//uchar tem;
//============================================================
void Time (void); //時間處理
void Key4x4(void); //鍵掃描子程序
//void Timer (void); //定時子程序
void Motor (void); //電機控制程序
void OnStar(void);
//void SONG (void); //音樂子程序
//void Key (void); //一鍵多用子程序
//============================================================
void main(void)
{
TMOD=0x01; //定時器1用0模式,定時器0用1模式00000001
TH0=(65536-500)/256; //取整數
TL0=(65536-500)%256; //取余數
//TH0=(65536-500)/256; //取整數
//TL0=(65536-500)%256; //取余數
TH1=(8192-2000)/32;
TL1=(8192-2000)%32;
//IE=0x8A;
TR0=1; //開定時器
TR1=1;
EA=1; //開總中斷
ET0=1; //開定時器1中斷
ET1=1;
//--------付初值區-----------
TS=0;
SEC=0;
MIN=0;
HOUR=0;
STEPtimer=0;
FangShang=0;
counts=0;
StepSpeed=15;
Star=1; //開機標志
//---------------------------
while(1) //嚟度放以后要添加的服務子程序
{
Time (); //時間處理程序
Key4x4(); //鍵掃描子程序
//Timer(); //定時子程序
Motor(); //電機控制程序
OnStar(); //首次開機電機延時啟動
}
}
//=================================================================
/*內中斷0 用于計時*/
void Timer0(void) interrupt 1 //開定時器0中斷,工作于方式0,中斷號為1
{
TH0=(65536-500)/256; //5ms出中斷一次
TL0=(65536-500)%256;
//TH0=(65536-500)/256; //取整數
//TL0=(65536-500)%256; //取余數
TS++;
STEPtimer++;
}
//======================================================================
/*內中斷1 用于掃描顯示*/
void Timer1(void) interrupt 3 //2m掃描顯示程序。開定時器1中斷,工作于方式0 "void 函數名() interrupt 中斷號 using 工作組"
{//uchar tmp; // 中斷號命名:外中斷0為0、內部時鐘中斷0為1、外中斷1為2、內部時鐘中斷1為3
static uchar COUNT; //原為這個,現換下面的
TH1=(8192-2000)/32;
TL1=(8192-2000)%32;
switch(COUNT) //端口用位操作
{case 0: P0=DispTab[ONE],P1_0=0,P1_1=1,P1_2=1,P1_3=1,P1_4=1,P1_5=1; break;
case 1: P0=DispTab[TWO],P1_0=1,P1_1=0,P1_2=1,P1_3=1,P1_4=1,P1_5=1; break;
case 2: P0=DispTab[THREE],P1_0=1,P1_1=1,P1_2=0,P1_3=1,P1_4=1,P1_5=1; break;
case 3: P0=DispTab[FOUR], P1_0=1,P1_1=1,P1_2=1,P1_3=0,P1_4=1,P1_5=1; break;
case 4: P0=DispTab[FIVE],P1_0=1,P1_1=1,P1_2=1,P1_3=1,P1_4=0,P1_5=1; break;
case 5: P0=DispTab[SIX],P1_0=1,P1_1=1,P1_2=1,P1_3=1,P1_4=1,P1_5=0; break;
}
COUNT++;
if(COUNT==6)
{ COUNT=0;
}
}
//================================================================
/*時間處理子程序*/
void Time (void)
{if(TS==2000) //Ts=5msX200=1000ms=1S
{TS=0;
SEC++;
}
if(SEC==60)
{SEC=0;
MIN++;
}
if(MIN==60)
{MIN=1;
HOUR++;
}
if(HOUR==13)
{HOUR=1;
}
ONE=SEC%10;
TWO=SEC/10;
THREE=MIN%10;
FOUR=MIN/10;
FIVE=HOUR%10;
SIX=HOUR/10;
}
//========================================================================
//鍵掃描子程序 ///的為最新修改
void Key4x4(void)
{ static uchar TEM;
P2=0xff; //P2口: 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0
P2_0=0; // 1 1 1 1 1 1 1 0
TEM=P2; // 1 1 1 1 0 0 0 0
TEM=TEM&0xf0; // e0 1 1 1 0 0
if (TEM!=0xf0) // d0 1 1 0 1 0 0 0 0
{ // b0 1 0 1 1 0 0 0 0
//for(i=50;i>0;i--) // 70 0 1 1 1 0 0 0 0
//for(j=200;j>0;j--); //P2.0~p2.3為第一~四行,P2.4~P2.7為第一~四列
///if(Ts+0==Ts)
///{
TEM=P2;
TEM=TEM&0xf0;
if (TEM!=0xf0)
{
TEM=P2;
TEM=TEM & 0xf0;
switch(TEM)
{
case 0xe0: KEY=1; FangShang=0; break; //如果按鍵1按下,倒計時就立即停止,且顯示器顯示1
case 0xd0: KEY=2; FangShang=1; break;
case 0xb0: KEY=3; StepSpeed=2; break;
case 0x70: KEY=4; StepSpeed=3; break;
}
MIN=KEY;
}
///}
}
P2=0xff;
P2_1=0;
TEM=P2;
TEM=TEM&0xf0;
if (TEM!=0xf0)
{
//for(i=50;i>0;i--)
//for(j=200;j>0;j--);
///if(Ts+1==Ts)
///{
TEM=P2;
TEM=TEM&0xf0;
if (TEM!=0xf0)
{
TEM=P2;
TEM=TEM & 0xf0;
switch(TEM)
{
case 0xe0: KEY=5; StepSpeed=5; break;
case 0xd0: KEY=6; StepSpeed=10; break;
case 0xb0: KEY=7; StepSpeed=15; break;
case 0x70: KEY=8; StepSpeed=20; break;
}
MIN=KEY;
}
///}
}
P2=0xff;
P2_2=0;
TEM=P2;
TEM=TEM&0xf0;
if (TEM!=0xf0)
{
TEM=P2;
TEM=TEM&0xf0;
if (TEM!=0xf0)
{
TEM=P2;
TEM=TEM& 0xf0;
switch(TEM)
{
case 0xe0: KEY=9; StepSpeed=25; break;
case 0xd0: KEY=10; StepSpeed=30; break;
case 0xb0: KEY=11; break;
case 0x70: KEY=12; break;
}
MIN=KEY;
}
}
P2=0xff;
P2_3=0;
TEM=P2;
TEM=TEM&0xf0;
if (TEM!=0xf0)
{
TEM=P2;
TEM=TEM & 0xf0;
if (TEM!=0xf0)
{
TEM=P2;
TEM=TEM& 0xf0;
switch(TEM)
{
case 0xe0: KEY=13; break;
case 0xd0: KEY=14; break;
case 0xb0: KEY=15; break;
case 0x70: SEC=60; break;
}
MIN=KEY;
}
}
}
|