|
#include <reg52.h>
/********IO引腳定義***********************************************************/
sbit SW1=P1^0; //四個獨立按鍵定義
sbit SW2=P1^1;
sbit SW3=P1^2;
sbit SW4=P1^3;
sbit SMG1 = P1^4; //數碼管第一位定義
sbit SMG2 = P1^5; //數碼管第二位定義
sbit SMG3 = P1^6; //數碼管第三位定義
sbit SMG4 = P1^7; //數碼管第四位定義
int table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x40}; //共陰極數碼管段值
unsigned char flag; //right(lhj[i+1],lhj[i+2]); //正轉,兩個參數代表步進量和轉速
/********數據定義***********************************************************/
// 512個脈沖 90度
unsigned char dataout[8]={0xf1,0xf2,0xf4,0xf8};
//這里我們定義4組數,分別對應四拍:A-B-C-D 從板上設計來分配,選擇P2口的低四位輸出
//P2。0為A相,P2。1為B相,P2。2為C相,P2。3為D相,將高四位都置1,也就是F。
//我們用索引的方式輸出,比如正轉,元素由0到3這樣的循環,反轉則由3到0的循環
//程序中我們保存索引號,比如上次轉在第2元素停下,則下次的正轉由3開始向后計數,反轉則由1開始向前計數
//這樣,電機的轉角度就會很精確
unsigned char datac=0; //存放索引號(元素號)
unsigned int gStep = 0;
unsigned long gMainchong = 0;
unsigned int gJd = 0;
unsigned int gKey_flag = 0;
unsigned int b1,b2,b3; //臨時變量
void delayms(xms);
void Timer0_Init();
void Display();
void rightAll();
void leftAll();
void stepAll();
void Ang();
void KeyScan();
/********函數聲明*************************************************************/
void right(unsigned int Speed,unsigned int road); //正轉
void left(unsigned int Speed,unsigned int road); //反轉
void mDelay(unsigned int DelayTime); //延時函數
/***********主函數開始********************************************************/
void main()
{
unsigned char i=0;
P2&=0XF0; //因ULN2003A直接驅動,為高電平輸出,初始時為低電平,這里一定不能少了
mDelay(100);
Timer0_Init();
while(1)
{
KeyScan();
Ang();
}
}
void Timer0_Init()
{
TMOD=0x01; //定時器方式一
TH0=(65536-500)/256; //定義高字節
TL0=(65536-500)%256; //定義低字節
ET0=1; //計數器中斷
EA=1; //開總中斷
// TR0 = 1;
}.
void Display()
{ //以下把num值區分開 以便數碼管顯示
b1=gJd%1000/100; //百位
b2=gJd%1000%100/10; //十位
b3=gJd%1000%100%10; //個位
P0=0x40;
SMG1=0; //顯示"-"
delayms(3);
SMG1=1;
P0=table[b1];
SMG2=0; //顯示百位
delayms(3);
SMG2=1;
P0=table[b2];
SMG3=0; //顯示十位
delayms(3);
SMG3=1;
P0=table[b3];
SMG4=0;
delayms(3); //顯示個位
SMG4=1;
}
/***********左轉,兩個參數代表步進量和轉速*************************************/
void right(unsigned int Speed,unsigned int road)
{
//步進節拍:A-B-C-D
do{
if(datac==3) //索引號超出3回到0
datac=0;
else
datac++;
P2=dataout[datac]; //這里就在P2口輸出我們定義好的相序步進,P2。0為A相,P2。1為B相,P2。2為C相,P2。3為D相
//這里我們不考慮P2的高四位,直接賦值
mDelay(road); //這里的延時就可控制轉速
Speed--;
}
while(Speed);
P2&=0XF0; //將四個腳復位0
}
/***********右轉,兩個參數代表步進量和轉速*************************************/
void rightAll()
{
if(gStep == 3)
gStep = 0;
else
gStep++;
P2=dataout[gStep];
if(gMainchong == 2048)
gMainchong = 0;
else
gMainchong++;
}
/***********整體左轉*************************************/
void leftAll()
{
if(gStep == 0)
gStep = 3;
else
gStep--;
P2=dataout[gStep];
if(gMainchong == 0)
// gMainchong = 4096;
gMainchong = 2048;
else
gMainchong--;
}
/***********固定動作*************************************/
void stepAll()
{
right(512, 50);
left(1024, 50);
right(215, 50);
}
/***********計算并顯示角度*************************************/
void Ang() // 計算角度
{
unsigned int i;
// gJd = gMainchong*5.625/32.0;
gJd = gMainchong*11.25/64.0;
b1=gJd%1000/100; //將得到的數據拆分,以便數碼管顯示 百位
b2=gJd%1000%100/10; //十位4
b3=gJd%1000%100%10; //個位
for(i=0;i<20;i++) Display(); //顯示20遍,防止顯示數據抖動,變化太快
}
/***********反轉,兩個參數代表步進量和轉速*************************************/
void left(unsigned int Speed,unsigned int road)
{
//步進節拍A-D-C-B
do{
if(datac==0) //索引號超出0回到3
datac=3;
else
datac--;
P2=dataout[datac]; //這里就在P2口輸出我們定義好的相序步進,P2。0為A相,P2。1為B相,P2。2為C相,P2。3為D相
//這里我們不考虛P2的低四位,直接賦值
mDelay(road); //這里的延時就可控制轉速
Speed--;
}
while(Speed);
P2&=0XF0; //將四個腳復位0
}
/***********延時函數*******************************************************/
void mDelay(unsigned int DelayTime) // 10ms
{
unsigned char j=0;
while(DelayTime--)
{
for(j=0;j<10;j++){}
}
}
// 延時函數
void delayms(xms)
{
unsigned int x,y;
for(x=xms;x>0;x--)
for(y=110;y>0;y--)
;
}
/***********按鍵掃描函數*************************************/
void KeyScan()
{
if(SW1 == 0)
{
delayms(10);
if(SW1 == 0) // 正傳
{
TR0 = 0;
gKey_flag = 1; //
Timer0_Init();
TR0 = 1;
}
}
if(SW2 == 0)
{
delayms(10);
if(SW2 == 0) // 反傳
{
TR0 = 0;
gKey_flag = 2;
Timer0_Init();
TR0 = 1;
}
}
if(SW3 == 0)
{
delayms(10);
if(SW3 == 0) // 自定義動作
{
TR0 = 0;
gKey_flag = 3;
Timer0_Init();
TR0 = 1;
}
}
if(SW4 == 0)
{
delayms(10);
if(SW4 == 0) // 停止
{
TR0 = 0;
gKey_flag = 0;
Timer0_Init();
TR0 = 1;
}
}
}
void T0_int() interrupt 1
{
// flag=1; //標志位之一
TR0 = 0;
switch(gKey_flag)
{
case 0x00:
P2&=0XF0;
break;
case 0x01:
rightAll();
TH0=(65536-10000)/256; //定義高字節
TL0=(65536-10000)%256; //定義低字節
TR0 = 1;
break;
case 0x02:
leftAll();
TH0=(65536-10000)/256; //定義高字節
TL0=(65536-10000)%256; //定義低字節
TR0 = 1;
break;
case 0x03:
stepAll();
break;
default:
break;
}
}
|
|