1) 可以直觀得看到到步進(jìn)電機(jī)的運(yùn)行軌跡,我們用了128×64LCD液晶顯示屏來(lái)直觀得顯示步進(jìn)電機(jī)的實(shí)際運(yùn)行軌跡。 (2) 能夠設(shè)定步進(jìn)電機(jī)的運(yùn)動(dòng)軌跡半徑大小。 (3) 利用單片機(jī)AT89S52的控制,通過(guò)按鍵來(lái)控制步進(jìn)電機(jī)的正反轉(zhuǎn),使其能夠順時(shí)針(圓)或者逆時(shí)針(圓)運(yùn)行。
(4) 隨時(shí)復(fù)位,同時(shí)做到在任意象限開始運(yùn)行。 我不會(huì)幫人弄的。有沒(méi)有大神會(huì)改或者寫這個(gè)源程序。求思路
單片機(jī)源程序如下:
- #include "LCD12864.H"
- #include <math.H>
- #include <intrins.h>
- #define STEP 1 //定義步進(jìn)值
- #define KEY_DATA P1 //P1口是按鍵
- #define KEY_NULL 0xff //默認(rèn)是高電平,按鍵按下是低電平
- sbit F1 = P2^0; //控制電機(jī)1I/O口定義
- sbit F2 = P2^1; sbit F3 = P2^2; sbit F4 = P2^3;
- sbit F5 = P3^0; //控制電機(jī)2I/O口定義
- sbit F6 = P3^1; sbit F7 = P3^5; sbit F8 = P3^6;
- bit flag1 ; bit flag2 ;
- unsigned char code FFW[8]={0xfe,0xfc,0xfd,0xf9,0xfb,0xf3,0xf7,0xf6}; //反轉(zhuǎn)
- unsigned char code FFZ[8]={0xf6,0xf7,0xf3,0xfb,0xf9,0xfd,0xfc,0xfe}; //正轉(zhuǎn)
- char y_start,y_end; //畫線的y坐標(biāo)起始和終點(diǎn)
- int x_start,x_end; //畫線的x坐標(biāo)起始和終點(diǎn)
- /********************************************************/
- void motor1_ffw() //電機(jī)驅(qū)動(dòng)反轉(zhuǎn)
- { unsigned char i;
- for (i=0; i<8; i++)
- { P2 = FFW[ i]&0x1f; //取數(shù)據(jù)
- delay(1000); }
- }
- void motor1_ffz() //電機(jī)驅(qū)動(dòng)正轉(zhuǎn)
- { unsigned char i;
- for (i=0; i<8; i++) //一個(gè)周期轉(zhuǎn)30度
- { P2 = FFZ[ i]&0x1f; //取數(shù)據(jù)
- delay(1000); }
- }
- void motor2_ffw() //電機(jī)驅(qū)動(dòng)反轉(zhuǎn)
- { F5=1;F6=1;F7=1;F8=0; delay(1000);
- F5=1;F6=1;F7=0;F8=0; delay(1000);
- F5=1;F6=1;F7=0;F8=1; delay(1000);
- F5=1;F6=0;F7=0;F8=1; delay(1000);
- F5=1;F6=0;F7=1;F8=1; delay(1000);
- F5=0;F6=0;F7=1;F8=1; delay(1000);
- F5=0;F6=1;F7=1;F8=1; delay(1000);
- F5=0;F6=1;F7=1;F8=0; delay(1000);
- }
- void motor2_ffz() //電機(jī)驅(qū)動(dòng)正轉(zhuǎn)
- { F5=0;F6=1;F7=1;F8=0; delay(1000);
- F5=0;F6=1;F7=1;F8=1; delay(1000);
- F5=0;F6=0;F7=1;F8=1; delay(1000);
- F5=1;F6=0;F7=1;F8=1; delay(1000);
- F5=1;F6=0;F7=0;F8=1; delay(1000);
- F5=1;F6=1;F7=0;F8=1; delay(1000);
- F5=1;F6=1;F7=0;F8=0; delay(1000);
- F5=1;F6=1;F7=1;F8=0; delay(1000);
- }
- void xiangxian1ni()
- { int x0,j,f, y0,y1; x0=20;y0=20 ; y1=0; j=x0+y0; f=0;
- y_start=32;y_end=y_start; x_start=43 ;x_end=x_start;
- do { x_start=x_end; y_start=y_end;
- if (f>=0)
- { motor1_ffw(); flag2=0; delay(10000);
- x_end=x_end+STEP; y_end=y_end;
- GUI_Line(x_start,y_start,x_end,y_end,1);
- f=f-2*x0+1; x0=x0-1; delay(10000); }
- else
- { motor2_ffz(); flag1=0; delay(10000);
- x_end=x_end; y_end=y_end+STEP;
- GUI_Line(x_start,y_start,x_end,y_end,1);
- f=f+2*y1+1; y1=y1+1; delay(10000); }
- j=j-1; }
- while (j!=0);
- }
- void xiangxian2ni()
- { int x0,x1, j,f, y1; x0=20;x1=0; y1=20; j=x0+y1; f=0;
- y_start=53;y_end=y_start; x_start=64;x_end=x_start;
- do { x_start=x_end; y_start=y_end; flag1=1; flag2=1;
- if (f>=0)
- { motor2_ffw(); flag1=0; delay(10000);
- x_end=x_end; y_end=y_end-STEP;
- GUI_Line(x_start,y_start,x_end,y_end,1);
- f=f-2*y1+1; y1=y1-1; delay(10000); }
- else { motor1_ffw(); flag2=0; delay(10000);
- x_end=x_end+STEP; y_end=y_end;
- GUI_Line(x_start,y_start,x_end,y_end,1);
- f=f+2*x1+1; x1=x1+1; delay(10000); }
- j=j-1; }
- while (j!=0);
- }
- void xiangxian3ni()
- { int x0,y0, j,f, y1; x0=20; y1=20;y0=0; j=x0+y1; f=0;
- y_start=32;y_end=y_start; x_start=85;x_end=x_start;
- do { x_start=x_end; y_start=y_end; flag1=1; flag2=1;
- if (f>=0)
- { motor1_ffz(); flag2=0; delay(10000);
- x_end=x_end-STEP; y_end=y_end;
- GUI_Line(x_start,y_start,x_end,y_end,1);
- f=f-2*x0+1; x0=x0-1; delay(10000); }
- else
- { motor2_ffw(); flag1=0; delay(10000);
- x_end=x_end; y_end=y_end-STEP;
- GUI_Line(x_start,y_start,x_end,y_end,1);
- f=f+2*y0+1; y0=y0+1; delay(10000); }
- j=j-1; }
- while (j!=0);
- }
- void xiangxian4ni()
- { int x0,x1, j,f, y1; x0=20;x1=0; y1=20; j=x0+y1; f=0;
- y_start=11;y_end=y_start; x_start=64;x_end=x_start;
- do { x_start=x_end; y_start=y_end; flag1=1; flag2=1;
- if (f>=0)
- { motor2_ffz(); flag1=0; delay(10000);
- x_end=x_end; y_end=y_end+STEP;
- GUI_Line(x_start,y_start,x_end,y_end,1);
- f=f-2*y1+1; y1=y1-1; delay(10000); }
- else
- { motor1_ffz(); flag2=0; delay(10000);
- x_end=x_end-STEP; y_end=y_end;
- GUI_Line(x_start,y_start,x_end,y_end,1);
- f=f+2*x1+1; x1=x1+1; delay(10000); }
- j=j-1; }
- while (j!=0);
- }
- void xiangxian1shun()
- { int x0,x1, j,f, y1; x0=20;x1=0; y1=20; j=x0+y1; f=0;
- y_start=53;y_end=y_start; x_start=64;x_end=x_start;
- do { x_start=x_end; y_start=y_end; flag1=1; flag2=1;
- if (f>=0)
- { motor2_ffw(); flag1=0; delay(10000);
- x_end=x_end; y_end=y_end-STEP;
- GUI_Line(x_start,y_start,x_end,y_end,1);
- f=f-2*y1+1; y1=y1-1; delay(10000); }
- else
- { motor1_ffz(); flag2=0; delay(10000);
- x_end=x_end-STEP; y_end=y_end;
- GUI_Line(x_start,y_start,x_end,y_end,1);
- f=f+2*x1+1; x1=x1+1; delay(10000); }
- j=j-1; }
- while (j!=0);
- }
- void xiangxian4shun()
- { int x0,j,f, y0,y1; x0=20;y0=20 ; y1=0; j=x0+y0; f=0;
- y_start=32;y_end=y_start; x_start=43 ;x_end=x_start;
- do { x_start=x_end; y_start=y_end; flag1=1; flag2=1;
- if (f>=0)
- { motor1_ffw(); flag2=0; delay(10000);
- x_end=x_end+STEP; y_end=y_end;
- GUI_Line(x_start,y_start,x_end,y_end,1);
- f=f-2*x0+1; x0=x0-1; delay(10000); }
- else
- { motor2_ffw();flag1=0; delay(10000);
- x_end=x_end; y_end=y_end-STEP;
- GUI_Line(x_start,y_start,x_end,y_end,1);
- f=f+2*y1+1; y1=y1+1; delay(10000); }
- j=j-1; }
- while (j!=0);
- }
- void xiangxian3shun()
- { int x0,x1, j,f, y1; x0=20;x1=0; y1=20; j=x0+y1; f=0;
- y_start=11;y_end=y_start; x_start=64;x_end=x_start;
- do { x_start=x_end; y_start=y_end; flag1=1; flag2=1;
- if (f>=0)
- { motor2_ffz(); flag1=0; delay(10000);
- x_end=x_end; y_end=y_end+STEP;
- GUI_Line(x_start,y_start,x_end,y_end,1);
- f=f-2*y1+1; y1=y1-1; delay(10000); }
- else
- { motor1_ffw(); flag2=0; delay(10000);
- x_end=x_end+STEP; y_end=y_end;
- GUI_Line(x_start,y_start,x_end,y_end,1);
- f=f+2*x1+1; x1=x1+1; delay(10000); }
- j=j-1; }
- while (j!=0);
- }
- void xiangxian2shun()
- { int x0,j,f, y0,y1; x0=20;y0=20 ; y1=0; j=x0+y0; f=0;
- y_start=32;y_end=y_start; x_start=85;x_end=x_start;
- do { x_start=x_end; y_start=y_end; flag1=1; flag2=1;
- if (f>=0)
- { motor1_ffz(); flag2=0; delay(10000);
- x_end=x_end-STEP; y_end=y_end;
- GUI_Line(x_start,y_start,x_end,y_end,1);
- f=f-2*x0+1; x0=x0-1; delay(10000); }
- else
- { motor2_ffz(); flag1=0; delay(10000);
- x_end=x_end; y_end=y_end+STEP;
- GUI_Line(x_start,y_start,x_end,y_end,1);
- f=f+2*y1+1; y1=y1+1; delay(10000); }
- j=j-1; }
- while (j!=0);
- }
- //*********************************************************************************************
- //說(shuō)明:程序主函數(shù)
- //*********************************************************************************************
- void main()
- {
- /***********************液晶初始化***************************/
- Display_Init();
- GUI_Fill_GDRAM(0x00);
- GUI_Line(0,32,127,32,1);
- GUI_Line(0,32,4,30,1);
- GUI_Line(0,32,4,34,1);
- GUI_Line(64,0,64,63,1);
- GUI_Line(62,60,64,63,1);
- GUI_Line(66,60,64,63,1);
- KEY_DATA=KEY_NULL;
- while(1)
- {
- delay(1000);
- switch(KEY_DATA)
- {
- case 0xfe:
- xiangxian1ni();
- KEY_DATA=0xff;
- break;
- case 0xfd:
- xiangxian2ni();
- KEY_DATA=0xff;
- break;
- case 0xfb:
- xiangxian3ni();
- KEY_DATA=0xff;
- break;
- case 0xf7:
- xiangxian4ni();
- KEY_DATA=0xff;
- break;
- case 0xef:
- xiangxian1shun();
- KEY_DATA=0xff;
- break;
- case 0xdf:
- xiangxian4shun();
- KEY_DATA=0xff;
- break;
- case 0xbf:
- xiangxian3shun();
- KEY_DATA=0xff;
- break;
- case 0x7f:
- xiangxian2shun();
- KEY_DATA=0xff;
- break;
- default:
- break; }
- }
- }
- 第二部分,調(diào)用LCD液晶屏程序部分:
- #include "LCD12864.h" //包含液晶端口定義的頭文件
- //********************************************************
- //延時(shí)函數(shù)
- //********************************************************
- void delay(unsigned int k)
- {
- unsigned int i; unsigned char j;
- for(i=0;i<k;i++)
- {
- for(j=0;j<10;j++);
- }
- }
- //********************************************************
- //延時(shí)1ms函數(shù)
- //********************************************************
- void delay_ms(unsigned int k) //延時(shí)0.994us,晶振12M
- {
- unsigned int x,y;
- for(x=k;x>0;x--)
- for(y=121;y>0;y--);
- }
- //********************************************************
- //寫命令函數(shù)
- //********************************************************
- void LcdWcom(unsigned char WCom)
- {
- delay(1);
- RS=0; //指明操作對(duì)象為指令寄存器
- RW=0; //指明為寫操作
- E=1;
- lcd_data=WCom; //將命令寫入總線
- E=0;
- }
- //********************************************************
- //寫數(shù)據(jù)函數(shù)
- //********************************************************
- void LcdWdata(unsigned char WData)
- {
- delay(1);
- RS=1; //指明操作對(duì)象為數(shù)據(jù)寄存器
- RW=0; //指明為寫操作
- E=1;
- lcd_data=WData; //將數(shù)據(jù)寫入總線
- E=0;
- }
- //********************************************************
- //顯示初始化函數(shù)
- //********************************************************
- void Display_Init(void)
- {
- delay_ms(45); //延時(shí)45ms
- RST=1;
- delay(1);
- RST=0;
- delay(1);
- RST=1;
- delay(1);
- LcdWcom(0x30); //設(shè)置為8位并行口,基本指令集
- delay(10);
- LcdWcom(0x30); //再次設(shè)置為8位并行口,基本指令集
- delay(5);
- LcdWcom(0x01);
- delay_ms(12); //延時(shí)12ms
- LcdWcom(0x06); //設(shè)置為游標(biāo)右移,DDRAM位地址加1,畫面不移動(dòng)
- delay(5);
- LcdWcom(0x0C); //開顯示
- }
- //********************************************************
- //讀數(shù)據(jù)函數(shù)
- //********************************************************
- unsigned char LcdRdata(void)
- {
- unsigned char LcdData;
- lcd_data=0xff; //釋放數(shù)據(jù)線
- RW=1; //指明為讀操作
- RS=1; //指明操作對(duì)象為數(shù)據(jù)寄存器
- E=1;
- delay(1);
- LcdData = lcd_data; //讀取數(shù)據(jù)線上的數(shù)據(jù)
- E=0;
- return (LcdData);
- }
- //********************************************************
- //填充GDRAM數(shù)據(jù):
- //參數(shù):dat為填充的數(shù)據(jù)
- //********************************************************
- void GUI_Fill_GDRAM(unsigned char dat)
- {
- unsigned char i; unsigned char j; unsigned char k;
- unsigned char bGDRAMAddrX = 0x80; //GDRAM水平地址
- unsigned char bGDRAMAddrY = 0x80; //GDRAM垂直地址
- for(i = 0; i < 2; i++)
- {
- for(j = 0; j < 32; j++)
- {
- for(k = 0; k < 8; k++)
- {
- LcdWcom(0x34); //設(shè)置為8位MPU接口,擴(kuò)充指令集,繪圖模式關(guān)
- LcdWcom(bGDRAMAddrY+j); //垂直地址Y
- LcdWcom(bGDRAMAddrX+k); //水平地址X
- LcdWdata(dat);
- LcdWdata(dat); }
- }
- bGDRAMAddrX = 0x88;
- }
- LcdWcom(0x36); //打開繪圖模式
- LcdWcom(0x30); //恢復(fù)基本指令集,關(guān)閉繪圖模式
- }
- //********************************************************
- //打點(diǎn)函數(shù)
- //參數(shù):color=1,該點(diǎn)填充1;color=0,該點(diǎn)填充白色0;
- //********************************************************
- void GUI_Point(unsigned char x,unsigned char y,unsigned char color)
- {
- unsigned char x_Dyte,x_byte; //定義列地址的字節(jié)位,及在字節(jié)中的哪1位
- unsigned char y_Dyte,y_byte; //定義為上下兩個(gè)屏(取值為0,1),行地址(取值為0~31)
- unsigned char GDRAM_hbit,GDRAM_lbit;
- LcdWcom(0x36); //擴(kuò)展指令命令
- x_Dyte=x/16; //計(jì)算在16個(gè)字節(jié)中的哪一個(gè)
- x_byte=x&0x0f; //計(jì)算在該字節(jié)中的哪一位
- y_Dyte=y/32; //0為上半屏,1為下半屏
- y_byte=y&0x1f; //計(jì)算在0~31當(dāng)中的哪一行
- LcdWcom(0x80+y_byte); //設(shè)定行地址(y坐標(biāo)),即是垂直地址
- LcdWcom(0x80+x_Dyte+8*y_Dyte); //設(shè)定列地址(x坐標(biāo)),并通過(guò)8*y_Dyte選定上下屏,即是水平地址
- LcdRdata(); //預(yù)讀取數(shù)據(jù)
- GDRAM_hbit=LcdRdata(); //讀取當(dāng)前顯示高8位數(shù)據(jù)
- GDRAM_lbit=LcdRdata(); //讀取當(dāng)前顯示低8位數(shù)據(jù)
- delay(1);
- LcdWcom(0x80+y_byte); //設(shè)定行地址(y坐標(biāo))
- LcdWcom(0x80+x_Dyte+8*y_Dyte); //設(shè)定列地址(x坐標(biāo)),并通過(guò)8*y_Dyte選定上下屏
- delay(1);
- if(x_byte<8) //判斷其在高8位,還是在低8位
- {
- if(color==1)
- {
- LcdWdata(GDRAM_hbit|(0x01<<(7-x_byte))); //置位GDRAM區(qū)高8位數(shù)據(jù)中相應(yīng)的點(diǎn)
- }
- else
- LcdWdata(GDRAM_hbit&(~(0x01<<(7-x_byte)))); //清除GDRAM區(qū)高8位數(shù)據(jù)中相應(yīng)的點(diǎn)
- LcdWdata(GDRAM_lbit); //顯示GDRAM區(qū)低8位數(shù)據(jù)
- }
- else
- {
- LcdWdata(GDRAM_hbit);
- if(color==1)
- LcdWdata(GDRAM_lbit|(0x01<<(15-x_byte))); //置位GDRAM區(qū)高8位數(shù)據(jù)中相應(yīng)的點(diǎn)
- else
- LcdWdata(GDRAM_lbit&(~(0x01<<(15-x_byte))));//清除GDRAM區(qū)高8位數(shù)據(jù)中相應(yīng)的點(diǎn)
- }
- LcdWcom(0x30); //恢復(fù)到基本指令集
- }
- //**************************************************************
- //畫水平線函數(shù)
- //參數(shù):color=1,填充1;color=0,填充0;
- // x0,x1為起始和終點(diǎn)的水平坐標(biāo)值,y為垂直坐標(biāo)值
- //**************************************************************
- void GUI_HLine(unsigned char x0, unsigned char x1, unsigned char y, unsigned char color)
- {
- unsigned char bak;
- if(x0>x1) // 對(duì)x0、x1大小進(jìn)行排列,以便畫圖
- {
- bak = x1;
- x1 = x0;
- x0 = bak;
- }
- do
- {
- GUI_Point(x0, y, color); // 從左到右逐點(diǎn)顯示,描出垂直線
- x0++;
- }while(x1>=x0);
- }
- //********************************************************
- //畫豎直線函數(shù)
- //參數(shù):color=1,填充黑色1;color=0,填充0;
- // x為起始和終點(diǎn)的水平坐標(biāo)值,y0,y1為垂直坐標(biāo)值
- //********************************************************
- void GUI_RLine(unsigned char x, unsigned char y0, unsigned char y1, unsigned char color)
- {
- unsigned char bak;
- if(y0>y1) // 對(duì)y0、y1大小進(jìn)行排列,以便畫圖
- {
- bak = y1;
- y1 = y0;
- y0 = bak;
- }
- do
- {
- GUI_Point(x, y0, color); // 從上到下逐點(diǎn)顯示,描出垂直線
- y0++;
- }while(y1>=y0);
- }
- //********************************************************
- //任意兩點(diǎn)畫直線函數(shù)
- //參數(shù):color=1,該線填充1;color=0,該線填充0;
- // x0:直線起點(diǎn)的x坐標(biāo)值,y0:直線起點(diǎn)的y坐標(biāo)值
- // x1:直線終點(diǎn)的x坐標(biāo)值,y1:直線終點(diǎn)的y坐標(biāo)值
- //********************************************************
- void GUI_Line(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char color)
- {
- char dx; // 直線x軸差值變量
- char dy; // 直線y軸差值變量
- char dx_sym; // x軸增長(zhǎng)方向,為-1時(shí)減值方向,為1時(shí)增值方向
- char dy_sym; // y軸增長(zhǎng)方向,為-1時(shí)減值方向,為1時(shí)增值方向
- char dx_x2; // dx*2值變量,用于加快運(yùn)算速度
- char dy_x2; // dy*2值變量,用于加快運(yùn)算速度
- char di; // 決策變量
- if(x0==x1) //判斷是否為垂直線
- {
- GUI_RLine(x0,y0,y1,color); //畫垂直線
- return;
- }
- if(y0==y1) //判斷是否為水平線
- {
- GUI_HLine(x0,x1,y0,color); //畫水平線
- return;
- }
- dx = x1-x0; // 求取兩點(diǎn)之間的差值
- dy = y1-y0;
- /* 判斷增長(zhǎng)方向,或是否為水平線、垂直線、點(diǎn) */
- if(dx>0) // 判斷x軸方向
- {
- dx_sym = 1; // dx>0,設(shè)置dx_sym=1
- }
- else
- {
- if(dx<0)
- {
- dx_sym = -1; // dx<0,設(shè)置dx_sym=-1
- }
- else
- {
- // dx==0,畫垂直線,或一點(diǎn)
- GUI_RLine(x0, y0, y1, color);
- return; }
- }
- if(dy>0) // 判斷y軸方向
- {
- dy_sym = 1; // dy>0,設(shè)置dy_sym=1
- }
- else
- {
- if(dy<0)
- { dy_sym = -1; // dy<0,設(shè)置dy_sym=-1 }
- else
- {
- // dy==0,畫水平線,或一點(diǎn)
- GUI_HLine(x0, y0, x1, color);
- return; }
- }
- /* 將dx、dy取絕對(duì)值 */
- dx = dx_sym * dx;
- dy = dy_sym * dy;
- /* 計(jì)算2倍的dx及dy值 */
- dx_x2 = dx*2;
- dy_x2 = dy*2;
- /* 使用Bresenham法進(jìn)行畫直線 */
- if(dx>=dy) // 對(duì)于dx>=dy,則使用x軸為基準(zhǔn)
- {
- di = dy_x2 - dx;
- while(x0!=x1)
- {
- GUI_Point(x0, y0, color);
- x0 += dx_sym;
- if(di<0)
- {
- di += dy_x2; // 計(jì)算出下一步的決策值 }
- else
- {
- di += dy_x2 - dx_x2; y0 += dy_sym; }
- }
- GUI_Point(x0, y0, color); // 顯示最后一點(diǎn)
- }
- else // 對(duì)于dx<dy,則使用y軸為基準(zhǔn)
- {
- di = dx_x2 - dy; while(y0!=y1)
- {
- GUI_Point(x0, y0, color);
- y0 += dy_sym;
- if(di<0)
- { di += dx_x2; }
- else
- { di += dx_x2 - dy_x2; x0 += dx_sym; }
- }
- GUI_Point(x0, y0, color); // 顯示最后一點(diǎn) }
- }
- unsigned char code DCB2HEX_TAB[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
復(fù)制代碼
|