标题:
51单片机四相双轴光源追踪装置源程序
[打印本页]
作者:
qq983511649
时间:
2019-5-3 17:42
标题:
51单片机四相双轴光源追踪装置源程序
实现功能;
光源追踪
装置图:
微信图片_20190404210146.jpg
(73.78 KB, 下载次数: 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 //更改数值,可调节灵敏度,以适应强弱光
#define Step 1 //调节步数 舵机转动的精度
#define DelayTime 8 //等待时间 舵机转动的速度
u32 data Result_ADC[5] = {0};
u8 PWM_DATA_X = 240;
u8 PWM_DATA_Y = 240;
u8 CheckStep = 0;
//*************************************************
//模块类型:内部函数声明
//功能描述:
//说 明:
//************************************************
void UartInit();
void InitADC();
void SendData(u8 dat);
u32 GetADCResult(u8 ch);
void Delay(u16 n);
void ShowResult(u8 ch);
//*************************************************
//函 数 名: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转换完成
ADC_CONTR &= ~ADC_FLAG; //Close ADC
buf = ADC_RES;
buf = (buf << 8) | ADC_RESL;
ADC_Voltage = (buf * 5.0) / 1024.0; //ADC转换结果计算
if((5.0 - ADC_Voltage) > 0)
{
ResValue = (ADC_Voltage * 10000) / (5.0 - ADC_Voltage); //计算光敏电阻阻值
}
return ResValue; //返回光敏电阻阻值
}
//*************************************************
//函 数 名:void InitADC(void)
//输 入:无
//输 出:无
//功能描述: ADC初始化
//*************************************************
void InitADC(void)
{
P1ASF = 0xf0; //设置P1口为AD口
CLK_DIV |= 0x20;
ADC_RES = 0; //清除结果寄存器
ADC_CONTR = ADC_POWER | ADC_SPEEDHH;
Delay(2); //ADC上电并延时
}
//*************************************************
//*************************************************
//函 数 名:void Write_ADC_Buf(void)
//输 入:无
//输 出:无
//功能描述: ADC结果存储
//*************************************************
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位数据,可变波特率
AUXR |= 0x40; //定时器1时钟为Fosc,即1T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设定定时器1为16位自动重装方式
TL1 = 0xE0; //设定定时初值
TH1 = 0xFE; //设定定时初值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
}
//*************************************************
//*************************************************
//函 数 名:void Delay(u16 n)
//输 入:延时值
//输 出:无
//功能描述: 延时函数
//*************************************************
void Delay(u16 n)
{
u16 x;
while (n--)
{
x = 5000;
while (x--);
}
}
//*************************************************
//函 数 名:void TIM0_Init(void)
//输 入:无
//输 出:无
//功能描述: 定时器0初始化 作为PWM基准
//*************************************************
void TIM0_Init(void) //78微秒的周期隌11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式,传统8051的12倍,1T就是指不分频,传统8051的始终是1T/12
TMOD &= 0xF0; //设置定时器模式,16位重载模式
TL0 = 0xA1; //设置定时初值
TH0 = 0xFC; //设置定时初值 差值64673
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
//*************************************************
//函 数 名:void PWM_Init(void)
//输 入:无
//输 出:无
//功能描述: PWM初始化
//*************************************************
void PWM_Init(void)
{
ACC = P_SW1;//即AUXR1
ACC &= ~(CCP_S0 | CCP_S1); //CCP_S0=0 CCP_S1=0//设置输出引脚
P_SW1 = ACC;
CCON = 0; //初始化PCA控制寄存器
CL = 0; //复位PCA16位寄存器
CH = 0;//高8位
CMOD = 0x04; //设置PCA时钟源为定时器0的溢出脉冲并且禁止PCA定时器cf位溢出中断
PCA_PWM0 = 0x00; //PCA模块0工作于8位PWM,PCA_PWM0是一个pwm寄存器
CCAP0H = CCAP0L = 245; //PWM0的占空比,0模块的比较的计数值
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工作与否
}
//*************************************************
//函 数 名:void SG90_Control(void)
//输 入:无
//输 出:无
//功能描述: SG90舵机控制
//*************************************************
void SG90_Control(void)
{
Write_ADC_Buf(); //读光敏电阻并做相应计算
switch(CheckStep)
{
//上下右旋转
case 0:
if((Result_ADC[1] > Result_ADC[3])&&PWM_DATA_Y !=249)
{
if((Result_ADC[1] - Result_ADC[3]) > SunValue)
{
CheckStep = 7;//上 左右转动
}
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://左右旋转
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;
}
}
//*************************************************
//函 数 名:void main(void)
//输 入:无
//输 出:无
//功能描述: 主函数
//*************************************************
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
谢谢分享 很好的创意
作者:
无敌多么寂寞
时间:
2021-2-22 10:14
请问下,这个有没有原理图啊
作者:
cqcgq
时间:
2022-9-21 15:33
提供一个原理图吧
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1