單片機自動追光仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
45db7e1ff75b4f26961f56afd562c3c.png (93.35 KB, 下載次數: 35)
下載附件
2021-7-24 19:46 上傳
d865e44371ba51c2e2428c9525e0d09.png (100.16 KB, 下載次數: 52)
下載附件
2021-7-24 19:46 上傳
單片機源程序如下:
#include<reg52.h>
#include"AD0832.h"
sbit a=P0^0;
sbit b=P0^1;
sbit c=P0^2;
sbit d=P0^3;
sbit _74HC573_U2=P1^0;
sbit _74HC573_U5=P1^1;
#define Li P0
#define uint unsigned int
#define uchar unsigned char
uchar code turn[]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09};
/*返回角度數,角度數的范圍(角度數)*/
/*0°-360°
uint control_angle(int angle)
{
if (angle>360){angle=0;}
else if (angle<0) {angle=360;}
return angle;
}*/
/*返回值第幾拍數 控制轉動(角度數)*/
/*直接轉化度數取整(略微有誤差)不精確算法,*/
/*采用四舍五入的不精確算法*/
uint rsa_angle(uint angle)/*角度算法*/
{
uint x;
x=angle*10%9;//取余
angle=angle*10/9;//取整
if(x>=5) {angle+=1;}
return angle;
}
/*控制左右步進電機*/
uint left_right_control_turn(int a,int angle,uint ZhengFanZhuan)//a=此時的拍數,angle角度,ZhengFanZhuan正反轉控制碼
{
angle=rsa_angle(angle);/*角度算法*/
switch(ZhengFanZhuan)
{
case 1://表示順時針轉動
while(angle--)
{
a++;
if(a>7){a=0;}
Li=turn[a];
delay(50);
}
break;
case 2://表示逆時針轉動
while(angle--)
{
a--;
if(a<0){a=7;}
Li=turn[a];
delay(50);
}
break;
}
return a; //返回此時的拍數
}
/*控制上下步進電機*/
uint up_down_control_turn(int a,int angle,uint ZhengFanZhuan)//a=此時的拍數,angle角度,ZhengFanZhuan正反轉控制碼
{
uchar L;
angle=rsa_angle(angle);/*角度算法*/
switch(ZhengFanZhuan)
{
case 1://表示順時針轉動 //上
while(angle--)
{
a++;
if(a>7){a=0;}
L=turn[a];
Li=L<<4;
delay(50);
}
break;
case 2://表示逆時針轉動 //下
while(angle--)
{
a--;
if(a<0){a=7;}
L=turn[a];
Li=L<<4;
delay(50);
}
break;
}
return a; //返回此時的拍數
}
void main()
{
uint x=1,a,b;
uint left_right,up_down;
_74HC573_U5=1;//控制上下
_74HC573_U2=1; //控制左右
a=left_right_control_turn(0,4,1); //返回角度數,控制轉動(角度數)/*初始化,將步進電機歸零*/
b=up_down_control_turn(0,4,1); //返回角度數,控制轉動(角度數)/*初始化,將步進電機歸零*/
_74HC573_U5=0; //控制上下
_74HC573_U2=0;//控制左右
while(1)
{
while(1) //控制左右
{
left_right=left_right_V_compare(2);//范圍正負40mv
/*返回光線強代號(在40mv范圍內),比較左邊右邊電壓(光敏電阻光線越強阻值越小)*/
switch(left_right)
{
case 1:
{
_74HC573_U5=0;//開放
_74HC573_U2=1;//關閉
a=left_right_control_turn(a,3,1); //左//angle角度//角度數的范圍(角度數);
break;
}
case 2:
{
_74HC573_U5=0;//開放
_74HC573_U2=1;//關閉
a=left_right_control_turn(a,3,2); //右
break;
}
case 3:
{
break;
}
}
if(left_right==3)
{
_74HC573_U5=0;
_74HC573_U2=0;//關閉
break;}
}
while(1)//控制上下
{
up_down=up_down_V_compare(2);//范圍正負40mv
/*返回光線強代號(在50mv范圍內),比較上下電壓(光敏電阻光線越強阻值越小)*/
switch(up_down)
{
case 1:
{
_74HC573_U5=1; //開放
b=up_down_control_turn(b,1,1);//上 //angle角度//角度數的范圍(角度數);
break;
}
case 2:
{
_74HC573_U5=1;//開放
b=up_down_control_turn(b,1,2);//下
break;
}
case 3:
{
break;
}
}
if(up_down==3)
{
_74HC573_U5=0;//關閉
_74HC573_U2=0;//關閉
break;
}
}
}
}
/*----------------------------------------AD0832.c----------------------------------------*/
#include<reg52.h>
#include"AD0832.h"
/*
sbit up_down_cs=P2^0;
sbit up_down_Dl=P2^1;
sbit up_down_DO=P2^2;
sbit up_down_clk=P2^3;
sbit left_right_cs=P2^4;
sbit left_right_Dl=P2^5;
sbit left_right_DO=P2^6;
sbit left_right_clk=P2^7;*/
/*結合實際 AD0832有兩個
處理left_right代號為1;
處理up_down 代號為2;
void AD0832_Init(uint Code )*/
void delay(uint a)
{
uint b;
for(a;a>0;a--)
{
for(b=0;b<=110;b++)
{
;
}
}
}
/*初始化
處理left_right代號為1;
處理up_down 代號為2;
*/
void AD0832_Init()
{
up_down_cs=1;//關閉
left_right_cs=1;//關閉
delay(2);
}
/*返回處理left/up、right/down-AD數值, a為AD0832代號,b=1為處理left/up,b=2為處理right/down*/
/*AD數據處理,
結合實際AD0832有兩個
處理left_right代號為1;
處理up_down 代號為2;
uint AD_process(uint a) ) */
uchar AD_process(uint a,uint b)
{
uint i;
uchar AD;
AD0832_Init();
up_down_cs=1;//片選關閉
left_right_cs=1;//片選關閉
switch(a)//選擇left_right、up_down
{
case 1: //使用left_right
{
left_right_cs=0;//開放
left_right_Dl=1;//在第一個時鐘脈沖的下沉之前DI端必須是高電平,表示啟始信號
up_down_left_right_clk=0;//關閉 第一周期開始
up_down_left_right_clk=1;//第一個周期結束
delay(2);
left_right_Dl=1;//開始選擇通道功能
up_down_left_right_clk=0;//第二個周期開始
break;
}
case 2: //使用up_down
{
up_down_cs=0;//開放
up_down_Dl=1;//在第一個時鐘脈沖的下沉之前DI端必須是高電平,表示啟始信號
up_down_left_right_clk=0;//關閉 第一周期開始
up_down_left_right_clk=1;//第一個周期結束
up_down_Dl=1;//開始選擇通道功能
up_down_left_right_clk=0;//第二個周期開始
break;
}
}
switch(b)//選擇處理left/up、right/down-AD數值
{
case 1: //處理left/up_AD數據,根據left_right、up_down的電路圖可知left_right_left、up_down_up和CH0相連接
left_right_Dl=1; //配置位 1
up_down_Dl=1; //配置位 1
up_down_left_right_clk=1;//第二個周期結束
left_right_Dl=0; //配置位 0
up_down_Dl=0; //配置位 0
up_down_left_right_clk=0;//第三個周期開始
up_down_left_right_clk=1;//第三個周期結束
break;
case 2://處理right/down_AD數據,根據left_right、up_down的電路圖可知left_right_right、up_down_down和CH1相連接
left_right_Dl=1; //配置位 1
up_down_Dl=1; //配置位 1
up_down_left_right_clk=1;//第二個周期結束
left_right_Dl=1; //配置位 1
up_down_Dl=1; //配置位 1
up_down_left_right_clk=0;//第三個周期開始
up_down_left_right_clk=1;//第三個周期結束
break;
}
/*數據接收開始*/
for(i=0;i<8;i++) //高位在前
{
up_down_left_right_clk=1; //脈沖開始
up_down_left_right_clk=0; //脈沖結束
switch(a)
{
case 1:
AD|=(uchar)left_right_DO; //將下面儲存的低位數據向右移
AD<<=1; //將輸出數據DIO通過或運算儲存在dat最低位
break;
case 2:
AD|=(uchar)up_down_DO; //將下面儲存的低位數據向右移
AD<<=1; //將輸出數據DIO通過或運算儲存在dat最低位
break;
}
}
up_down_cs=1;//片選關閉
left_right_cs=1;//片選關閉
return AD; //將讀出的數據返回
}
/*返回光線強代號(在f范圍內相等(正常范圍)),比較左邊右邊電壓(光敏電阻光線越強阻值越小)*/
/*代號1表示左邊強,代號2表示右邊強,代號3表示在左邊右邊在相等(正常范圍)*/
uint left_right_V_compare(uint f)//500
{
uchar V_left,V_right;
uint a;
V_left=AD_process(1,1);
V_right=AD_process(1,2);
if ((V_left>V_right+f)&&(V_left-f>V_right)){a=1;}//左
else if ((V_left+f<V_right)&&(V_left<V_right-f)){a=2;}//右邊
else {a=3;}//符合范圍
return a;
}
/*返回光線強代號,比較上下電壓(光敏電阻光線越強阻值越小)*/
uint up_down_V_compare(uint f)
{
uchar V_up,V_down;
uint a;
V_up=AD_process(2,1);
V_down=AD_process(2,2);
if ((V_up>V_down+f)&&(V_up-f>V_down)){a=1;} //上
else if ((V_up+f<V_down)&&(V_up<V_down-f)){a=2;}//下
else {a=3;}//符合范圍
return a;
}
51hei.png (2.65 KB, 下載次數: 59)
下載附件
2021-7-25 04:49 上傳
仿真與代碼51hei附件下載:
自動.zip
(138.28 KB, 下載次數: 44)
2021-7-24 19:46 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|