功能介绍:
0.本系统采用STC89C52作为单片机
1.支持手动/自动两种模式
2.自动模式下,系统实时监测当前各个方位的光强信息,并通过串口上报
3.自动模式下,通过判断各方位的光强,转动步进电机调节太阳能板,实现追光的效果
4.采用DC002作为电源接口可直接输入5V给整个系统供电
原理图:
PCB:
主程序:
#include <reg52.h>
#include <stdio.h>
#include "PCF8591.H"
#define uchar unsigned char
#define uint unsigned int
#define PCF8591 0x90 // PCF8591 地址
sbit KEY_MODE = P3^3;
sbit KEY_UP = P3^4;
sbit KEY_DOWN = P3^5;
sbit KEY_LEFT = P3^6;
sbit KEY_RIGHT = P3^7;
sbit LED1 = P1^0;
sbit LED2 = P1^1;
uchar Motor_Up[4]={0x08,0x04,0x02,0x01};
uchar Motor_Down[4]={0x01,0x02,0x04,0x08};
uchar Motor_Left[4] = {0x10, 0x20, 0x40, 0x80};
uchar Motor_Right[4] = {0x80, 0x40, 0x20, 0x10};
unsigned char AD_CHANNEL;
//延时函数
void Delay_ms(uint jj)
{
uint ii;
while (jj--)
for (ii = 0; ii < 125; ii++)
;
}
void UART_Init(void)
{
TMOD = 0x20; //定时器模式选择
PCON = 0x00;
SCON = 0x50;
TH1 = 0xFd; //设置波特率 9600
TL1 = 0xFd;
TR1 = 1; //启动定时器1
ES = 0; //开串口中断
EA = 1; //开总中断
}
/********************************************************************
* 名称 : PSend_Hex()
* 功能 : 发送字符串函数,可控制发送长度
* 变量 : 无
* 返回值 : 无
********************************************************************/
void Send_Hex(unsigned char *p, unsigned char num)
{
while (num--) //剩余发送的字符数
{
SBUF = *p; //将要发送的数据赋给串口缓冲寄存器
while (!TI)
; //等待发送结束
TI = 0; //软件清零
p++; //指针加一
}
}
void main() //函数功能:主函数
{
bit modeFlag = 0;
uchar AD_Up, AD_Down, AD_Left, AD_Right;
uchar i, j;
uchar Table[4];
Delay_ms(2000);
UART_Init();
while (1)
{
if (!KEY_MODE)
{
Delay_ms(20);
while (!KEY_MODE)
;
modeFlag = ~modeFlag; //模式切换
}
if (modeFlag == 0) //自动
{
LED1 = 1;
LED2 = 0;
for (i = 0; i < 8; i++)
{
switch (AD_CHANNEL)
{
case 0:
AD_Up = ReadADC(0) * 2; // ADC0 模数转换1
break;
case 1:
AD_Down = ReadADC(1) * 2; // ADC1 模数转换2
break;
case 2:
AD_Left = ReadADC(2) * 2; // ADC2 模数转换3
break;
case 3:
AD_Right = ReadADC(3) * 2; // ADC3 模数转换4
break;
}
Send_Hex(Table, 4);
if (++AD_CHANNEL > 3)
{
AD_CHANNEL = 0;
Table[0] = AD_Up;
Table[1] = AD_Down;
Table[2] = AD_Left;
Table[3] = AD_Right;
}
}
}
else //手动
{
LED1 = 0;
LED2 = 1;
AD_Up = 0; //上
AD_Down = 0; //下
AD_Left = 0; //左
AD_Right = 0; //右
}
///////////////////////////
if ((AD_Up > 220) || (AD_Down > 220) || (AD_Left > 220) || (AD_Right > 220))
{
AD_Up = 0; //上
AD_Down = 0; //下
AD_Left = 0; //左
AD_Right = 0; //右
}
if (((AD_Up < AD_Down) && (AD_Down - AD_Up > 10)) || (!KEY_UP)) //上转
{
for (i = 0; i < 10; i++)
{
for (j = 0; j < 4; j++)
{
P2 = Motor_Up[j];
Delay_ms(3);
}
}
P2 = 0X00;
}
//////////////////////////////////////
if (((AD_Up > AD_Down) && (AD_Up - AD_Down > 10)) || (!KEY_DOWN)) //下转
{
for (i = 0; i < 10; i++)
{
for (j = 0; j < 4; j++)
{
P2 = Motor_Down[j];
Delay_ms(3);
}
}
P2 = 0X00;
}
/////////////////////////////
if (((AD_Left < AD_Right) && (AD_Right - AD_Left > 10)) || (!KEY_LEFT)) //左转
{
for (i = 0; i < 10; i++)
{
for (j = 0; j < 4; j++)
{
P2 = Motor_Left[j];
Delay_ms(3);
}
}
P2 = 0X00;
}
//////////////////////////////////////
if (((AD_Left > AD_Right) && (AD_Left - AD_Right > 10)) || (!KEY_RIGHT)) //右转
{
for (i = 0; i < 10; i++)
{
for (j = 0; j < 4; j++)
{
P2 = Motor_Right[j];
Delay_ms(3);
}
}
P2 = 0X00;
}
////////////////////////////////////
Delay_ms(100); //延时,可适当修改
}
}