標題:
51單片機四相雙軸光源追蹤裝置源程序
[打印本頁]
作者:
qq983511649
時間:
2019-5-3 17:42
標題:
51單片機四相雙軸光源追蹤裝置源程序
實現(xiàn)功能;
光源追蹤
裝置圖:
微信圖片_20190404210146.jpg
(73.78 KB, 下載次數(shù): 63)
下載附件
2019-5-3 17:40 上傳
單片機源代碼如下:
//*************************************************
//模塊類型:包含外部文件
//功能描述:
//說 明:
//*************************************************
#include "stc15f2kxx.h"
#include "intrins.h"
#include "string.h"
#include "math.h"
//*************************************************
//模塊類型:自定義
//功能描述:
//說 明:
//************************************************
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long int u32;
#define CCP_S0 0x10 //P_SW1.4
#define CCP_S1 0x20 //P_SW1.5
#define ADC_POWER 0x80 //ADC電源控制位
#define ADC_FLAG 0x10 //ADC完成標志
#define ADC_START 0x08 //ADC起始控制位
#define ADC_SPEEDLL 0x00 //540個時鐘
#define ADC_SPEEDL 0x20 //360個時鐘
#define ADC_SPEEDH 0x40 //180個時鐘
#define ADC_SPEEDHH 0x60 //90個時鐘
//光敏電阻AD比較靈敏度
#define SunValue 1200 //更改數(shù)值,可調(diào)節(jié)靈敏度,以適應(yīng)強弱光
#define Step 1 //調(diào)節(jié)步數(shù) 舵機轉(zhuǎn)動的精度
#define DelayTime 8 //等待時間 舵機轉(zhuǎn)動的速度
u32 data Result_ADC[5] = {0};
u8 PWM_DATA_X = 240;
u8 PWM_DATA_Y = 240;
u8 CheckStep = 0;
//*************************************************
//模塊類型:內(nèi)部函數(shù)聲明
//功能描述:
//說 明:
//************************************************
void UartInit();
void InitADC();
void SendData(u8 dat);
u32 GetADCResult(u8 ch);
void Delay(u16 n);
void ShowResult(u8 ch);
//*************************************************
//函 數(shù) 名:u32 GetADCResult(u8 ch)
//輸 入:AD通道號
//輸 出:無
//功能描述: 讀取光敏電阻阻值
//*************************************************
u32 GetADCResult(u8 ch)
{
u16 buf;
float ADC_Voltage;
u32 ResValue;
ADC_CONTR = ADC_POWER | ADC_SPEEDL | ch | ADC_START;
_nop_(); //等待4個NOP
_nop_();
_nop_();
_nop_();
while (!(ADC_CONTR & ADC_FLAG)); //等待ADC轉(zhuǎn)換完成
ADC_CONTR &= ~ADC_FLAG; //Close ADC
buf = ADC_RES;
buf = (buf << 8) | ADC_RESL;
ADC_Voltage = (buf * 5.0) / 1024.0; //ADC轉(zhuǎn)換結(jié)果計算
if((5.0 - ADC_Voltage) > 0)
{
ResValue = (ADC_Voltage * 10000) / (5.0 - ADC_Voltage); //計算光敏電阻阻值
}
return ResValue; //返回光敏電阻阻值
}
//*************************************************
//函 數(shù) 名:void InitADC(void)
//輸 入:無
//輸 出:無
//功能描述: ADC初始化
//*************************************************
void InitADC(void)
{
P1ASF = 0xf0; //設(shè)置P1口為AD口
CLK_DIV |= 0x20;
ADC_RES = 0; //清除結(jié)果寄存器
ADC_CONTR = ADC_POWER | ADC_SPEEDHH;
Delay(2); //ADC上電并延時
}
//*************************************************
//*************************************************
//函 數(shù) 名:void Write_ADC_Buf(void)
//輸 入:無
//輸 出:無
//功能描述: ADC結(jié)果存儲
//*************************************************
void Write_ADC_Buf(void)
{
Result_ADC[1] = GetADCResult(4); //讀取四個光敏電阻阻值
Result_ADC[2] = GetADCResult(5);
Result_ADC[3] = GetADCResult(6);
Result_ADC[4] = GetADCResult(7);
}
//*************************************************
//*************************************************
void UartInit(void) //9600bps@11.0592MHz
{
SCON = 0x50; //8位數(shù)據(jù),可變波特率
AUXR |= 0x40; //定時器1時鐘為Fosc,即1T
AUXR &= 0xFE; //串口1選擇定時器1為波特率發(fā)生器
TMOD &= 0x0F; //設(shè)定定時器1為16位自動重裝方式
TL1 = 0xE0; //設(shè)定定時初值
TH1 = 0xFE; //設(shè)定定時初值
ET1 = 0; //禁止定時器1中斷
TR1 = 1; //啟動定時器1
}
//*************************************************
//*************************************************
//函 數(shù) 名:void Delay(u16 n)
//輸 入:延時值
//輸 出:無
//功能描述: 延時函數(shù)
//*************************************************
void Delay(u16 n)
{
u16 x;
while (n--)
{
x = 5000;
while (x--);
}
}
//*************************************************
//函 數(shù) 名:void TIM0_Init(void)
//輸 入:無
//輸 出:無
//功能描述: 定時器0初始化 作為PWM基準
//*************************************************
void TIM0_Init(void) //78微秒的周期隌11.0592MHz
{
AUXR |= 0x80; //定時器時鐘1T模式,傳統(tǒng)8051的12倍,1T就是指不分頻,傳統(tǒng)8051的始終是1T/12
TMOD &= 0xF0; //設(shè)置定時器模式,16位重載模式
TL0 = 0xA1; //設(shè)置定時初值
TH0 = 0xFC; //設(shè)置定時初值 差值64673
TF0 = 0; //清除TF0標志
TR0 = 1; //定時器0開始計時
}
//*************************************************
//函 數(shù) 名:void PWM_Init(void)
//輸 入:無
//輸 出:無
//功能描述: PWM初始化
//*************************************************
void PWM_Init(void)
{
ACC = P_SW1;//即AUXR1
ACC &= ~(CCP_S0 | CCP_S1); //CCP_S0=0 CCP_S1=0//設(shè)置輸出引腳
P_SW1 = ACC;
CCON = 0; //初始化PCA控制寄存器
CL = 0; //復位PCA16位寄存器
CH = 0;//高8位
CMOD = 0x04; //設(shè)置PCA時鐘源為定時器0的溢出脈沖并且禁止PCA定時器cf位溢出中斷
PCA_PWM0 = 0x00; //PCA模塊0工作于8位PWM,PCA_PWM0是一個pwm寄存器
CCAP0H = CCAP0L = 245; //PWM0的占空比,0模塊的比較的計數(shù)值
CCAPM0 = 0x42; //PCA模塊0為8位PWM模式,允許比較并允許輸出p1.1
PCA_PWM1 = 0x00; //PCA模塊1工作于8位PWM
CCAP1H = CCAP1L = 245; //PWM1的占空比
CCAPM1 = 0x42; //PCA模塊1為8位PWM模式 ,允許比較,允許輸出p1.0
CR = 1; //PCA定時器開始工作,位于CCON寄存器,控制pca工作與否
}
//*************************************************
//函 數(shù) 名:void SG90_Control(void)
//輸 入:無
//輸 出:無
//功能描述: SG90舵機控制
//*************************************************
void SG90_Control(void)
{
Write_ADC_Buf(); //讀光敏電阻并做相應(yīng)計算
switch(CheckStep)
{
//上下右旋轉(zhuǎn)
case 0:
if((Result_ADC[1] > Result_ADC[3])&&PWM_DATA_Y !=249)
{
if((Result_ADC[1] - Result_ADC[3]) > SunValue)
{
CheckStep = 7;//上 左右轉(zhuǎn)動
}
else
{
CheckStep = 1;//
}
}
else
{
CheckStep = 1;
}
break;
case 1:
if((Result_ADC[3] > Result_ADC[1])&&PWM_DATA_Y !=224)
{
if((Result_ADC[3] - Result_ADC[1]) > SunValue)
{
CheckStep = 6;//Y--
}
else
{
CheckStep = 2;
}
}
else
{
CheckStep = 2;
}
break;
case 2://左右旋轉(zhuǎn)
if((Result_ADC[2] > Result_ADC[4])&&PWM_DATA_X !=224)
{
if((Result_ADC[2] - Result_ADC[4]) > SunValue)
{
CheckStep = 4;//X--
}
else
{
CheckStep = 3;
}
}
else
{
CheckStep = 3;
}
break;
case 3:
if((Result_ADC[4] > Result_ADC[2])&&PWM_DATA_X !=249)
{
if((Result_ADC[4] - Result_ADC[2]) > SunValue)
{
CheckStep = 5;//X++
}
else
{
CheckStep = 0;
}
}
else
{
CheckStep = 0;
}
break;
case 4:
if(Result_ADC[1]-Result_ADC[3]>SunValue)
{
Delay(DelayTime);
PWM_DATA_Y += Step;
PWM_DATA_X -= Step;
if(PWM_DATA_X < 224)
{
PWM_DATA_X = 224;
}
if(PWM_DATA_Y > 249)
{
PWM_DATA_Y = 249;
}
CCAP1H = CCAP1L = PWM_DATA_Y;
CCAP0H = CCAP0L = PWM_DATA_X;
}
//**************
if(Result_ADC[3]-Result_ADC[1]>SunValue)
{
Delay(DelayTime);
PWM_DATA_Y -= Step;
PWM_DATA_X -= Step;
if(PWM_DATA_X < 224)
{
PWM_DATA_X = 224;
}
if(PWM_DATA_Y < 224)
{
PWM_DATA_Y = 224;
}
CCAP1H = CCAP1L = PWM_DATA_Y;
CCAP0H = CCAP0L = PWM_DATA_X;
}
if((labs(Result_ADC[1]-Result_ADC[3]))<=SunValue)
{
Delay(DelayTime);
PWM_DATA_X -= Step;
if(PWM_DATA_X < 224)
{
PWM_DATA_X = 224;
}
CCAP0H = CCAP0L = PWM_DATA_X;
}
CheckStep = 2;
break;
case 5:
if(Result_ADC[1]-Result_ADC[3]>SunValue)
{
Delay(DelayTime);
PWM_DATA_Y += Step;
PWM_DATA_X += Step;
if(PWM_DATA_X > 249)
{
PWM_DATA_X = 249;
}
if(PWM_DATA_Y > 249)
{
PWM_DATA_Y = 249;
}
CCAP1H = CCAP1L = PWM_DATA_Y;
CCAP0H = CCAP0L = PWM_DATA_X;
}
//**************
if(Result_ADC[3]-Result_ADC[1]>SunValue)
{
Delay(DelayTime);
PWM_DATA_Y -= Step;
PWM_DATA_X += Step;
if(PWM_DATA_X > 249)
{
PWM_DATA_X = 249;
}
if(PWM_DATA_Y < 224)
{
PWM_DATA_Y = 224;
}
CCAP1H = CCAP1L = PWM_DATA_Y;
CCAP0H = CCAP0L = PWM_DATA_X;
}//******************
if((labs(Result_ADC[1]-Result_ADC[3]))<=SunValue)
{
Delay(DelayTime);
PWM_DATA_X += Step;
if(PWM_DATA_X > 249)
{
PWM_DATA_X = 249;
}
CCAP0H = CCAP0L = PWM_DATA_X;
}
CheckStep = 3;
break;
case 6:
if(Result_ADC[2]>Result_ADC[4]>SunValue)
{
Delay(DelayTime);
PWM_DATA_Y -= Step;
PWM_DATA_X -= Step;
if(PWM_DATA_Y < 224)
{
PWM_DATA_Y = 224;
}
if(PWM_DATA_X < 224)
{
PWM_DATA_X = 224;
}
CCAP0H = CCAP0L = PWM_DATA_X;
CCAP1H = CCAP1L = PWM_DATA_Y;
}
//*************************
if(Result_ADC[4]-Result_ADC[2]>SunValue)
{
Delay(DelayTime);
PWM_DATA_Y -= Step;
PWM_DATA_X += Step;
if(PWM_DATA_X > 249)
{
PWM_DATA_X = 249;
}
if(PWM_DATA_Y < 224)
{
PWM_DATA_Y = 224;
}
CCAP1H = CCAP1L = PWM_DATA_Y;
CCAP0H = CCAP0L = PWM_DATA_X;
}
//******************
if((labs(Result_ADC[2]-Result_ADC[4]))<=SunValue)
{
Delay(DelayTime);
PWM_DATA_Y -= Step;
if(PWM_DATA_Y < 224)
{
PWM_DATA_Y = 224;
}
CCAP1H = CCAP1L = PWM_DATA_Y;
}
//*****************************
CheckStep = 1;
break;
case 7:
if(Result_ADC[2]-Result_ADC[4]>SunValue)
{
Delay(DelayTime);
PWM_DATA_Y += Step;
PWM_DATA_X -= Step;
if(PWM_DATA_Y >= 249)
{
PWM_DATA_Y = 249;
}
if(PWM_DATA_X <= 224)
{
PWM_DATA_X = 224;
}
CCAP0H = CCAP0L = PWM_DATA_X;
CCAP1H = CCAP1L = PWM_DATA_Y;
}
//**************
if(Result_ADC[4]-Result_ADC[2]>SunValue)
{
Delay(DelayTime);
PWM_DATA_Y += Step;
PWM_DATA_X += Step;
if(PWM_DATA_X > 249)
{
PWM_DATA_X = 249;
}
if(PWM_DATA_Y > 249)
{
PWM_DATA_Y = 249;
}
CCAP1H = CCAP1L = PWM_DATA_Y;
CCAP0H = CCAP0L = PWM_DATA_X;
}
//$
if((labs(Result_ADC[2]-Result_ADC[4]))<=SunValue)
{
Delay(DelayTime);
PWM_DATA_Y += Step;
if(PWM_DATA_Y > 249)
{
PWM_DATA_Y = 249;
}
CCAP1H = CCAP1L = PWM_DATA_Y;
}
//***************
CheckStep = 0;
break;
default:
break;
}
}
//*************************************************
//函 數(shù) 名:void main(void)
//輸 入:無
//輸 出:無
//功能描述: 主函數(shù)
//*************************************************
void main(void)
{
UartInit(); //初始化串口 用于測試,可刪除
InitADC(); //初始化ADC
TIM0_Init(); //初始化定時器0
PWM_Init(); //初始化PWM
while(1)
{
SG90_Control(); //舵機控制
}
}
***************************************************************************************
復制代碼
作者:
qinyuning
時間:
2019-5-6 01:23
有視頻嗎,看一下效果
作者:
mqq一米八八
時間:
2020-5-13 19:16
有沒有仿真圖
作者:
阿飛7812
時間:
2020-5-13 20:40
謝謝分享 很好的創(chuàng)意
作者:
無敵多么寂寞
時間:
2021-2-22 10:14
請問下,這個有沒有原理圖啊
作者:
cqcgq
時間:
2022-9-21 15:33
提供一個原理圖吧
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1