1 系统方案设计
系统整体设计
电子智能补光器的设计思路:首先通过单片机判断特殊天气模式是否启用,如果启用则直接亮黄灯并在手机上显示出来。确定特殊天气模式没有启用时,通过季节模块判断当前月份对应的季节来确定补光模式。通过光照传感器将外界光照强度与对应季节设定光照阈值进行比较,当外界光照强度大于设定阈值时进行补光操作,并通过蓝牙连接在手机上显示当前补光模式以及光照强度。
1.2 设计任务
主要任务简述:以单片机为核心,设计电子智能补光器,以满足各种不同情境下对光照需求的差异。
要求简述:
(1)在外界光照强度大于所设定阈值时补光器保持不工作状态,光照强度小于设定阈值时开始补光;
(2)可选择春、夏、秋、冬四种模式,分别对应四种不同的阈值电压;
(3)设置特殊天气模式,开启特殊天气模式后亮起黄色雾灯;
(4)通过蓝牙连接手机,显示当前的模式和光照强度。
1.3 模块方案选型
1.3.1主控方案选型
STC89C52单片机是宏晶科技推出的高反应速度、低功率消耗、有着很强抵的挡外界干扰能力的单片机,而且该单片机的指令代码非常切合传统的8051单片机,并且与传统51单片机对比而言,该单片机速度更快,是传统51单片机的8~12倍。除此之外,该单片机还有6时钟周期和12时钟周期可以任意选择。
主要特性如下:
(1)新一代8051单片机,6时钟机器周期和12时钟机器周期可以任意选择,指令代码非常契合传统8051单片机。
(2)工作电压:5.5V~3.3V(5V单片机)。
(3)工作频率范围处于0~40MHz之间,相当于普通8051单片机工作频率的0~80MHz范围,而且新一代单片机的实际工作频率可达48MHz。
(4)一共具有3个16位定时器,也就是定时器T0、T1、T2。
(5)外部中断4路,低电平触发或下降沿中断电路,PowerDown模式可通过外部中断低电平触发中断的方式触发。
1.3.2光电转换器的选择
ADC0832是NS(National Semiconductor)公司生产的串行接口8位A/D转换器,通过三线接口与单片机连接,功耗低,性能价格比较高,合适使用在袖珍式的智能仪器仪表中。ADC0832为8位分辨率A/D转换芯片,其最高分辨可达256级,可以适应一般的模拟量转换要求。芯片具有双数据输出可作为数据校验,以减少数据误差,转换速度快且稳定性能强。独立的芯片使能输入,使多器件连接和处理器控制变得更加方便。通过DI 数据输入端,可以轻易的实现通道功能的选择。其主要特点如下:
(1)8位分辨率,其最高分辨可达256级;
(2)双通道A/D转换;
第3页 共50页
(3)电源供电时光电转换器的输入电压在0~5V之间;
选择该A/D转换芯片,不仅因为其体积小、功耗低,而且可以适应一般的模拟量转换要求,完全满足系统的要求。另外,其内部电源输入与参考电压的复用,使得转换芯片的模拟电压输入在0~5V之间,电源电路供电可以同时满足51单片机和该芯片的共同使用。除此之外该芯片的转换时间极短,仅为32μS,反应非常迅速,另外该芯片具有双数据输出可作为数据校验的工具,以此来减少实验数据误差,转换速度快并且稳定性能出色。单独工作的芯片的使能输入,可以更轻松地对多元件进行连接,同时也可以更加方便地控制处理器。通过DI 数据输入端,使得实现通道功能的选择变的易如反掌。除此之外,价格上的优势同样也是选择它的原因之一。
1.3.3显示器的选择
LCD1602液晶显示器是广泛使用的一种工业字符型液晶显示模块。由字符型液晶显示器(LCD)、控制驱动主电路HD44780及其扩展驱动电路HD44100,以及少量电阻、电容元件和结构件等装配在PCB板上而组成,能够同时显示16x02即32个字符。(16列2行)。但寄存器不止32个,有一些显示效果,如字符一个个显示、字符从左到右或从右到左显示等等,显示效果简单。当然也有其他更好的选择,例如12864液晶显示器,它的显示模块是128×64点阵的汉字图形型液晶显示模块,可显示汉字及图形,具有多种功能:光标显示、画面移位、睡眠模式等。
其实综合来说,二者编程方面的难度差不多,原理方面也差不多,甚至12864液晶显示器更胜一筹,因为该显示器显示更全面,字符也更多,需要进行更多操作的话自然是12864液晶显示器能够胜任。但是对比来说的话,1602液晶显示器也能实现设计的要求,而且相对来说更重要的原因就是1602液晶显示器比较廉价,网上购买也比较便宜,最低五六块钱左右。而12864液晶显示器网上购买最便宜的也要在二三十左右。所以从造价方面以及使用方面考虑,当然是价格低廉而且功能也不欠缺的优先。因此选择1602液晶显示器作为显示器件。
2 硬件设计
2.1 单片机模块
单片机的主要特点有:
(1)有出色的性能单价比,高效能、低电压,易于制作便携式产品。
(2)集成度高,体积小,有较高的稳定性。而且单片机把各功能零件组合在一块芯片上,内部结构使用的是总线结构,不仅减轻了各芯片彼此之间的连线,还大大增加了单片机的安全性和抗干扰能力。
(3)控制功能强。为求满足工业控制的要求,通常单片机的指令系统中均
第4页 共50页
有极多样的转移指令、I/O口的逻辑操作和位处理特性。单片机的逻辑控制功能及运转速度均远高于同一等级的微机。
(4)外部总线增加了I2C(Inter-Integrated Circuit)及SPI(Serial Peripheral Interface)等串行总线方式,逐步缩小了体积,精简了构造。单片机的系统扩展、系统配置较典型、规范,容易构成各种规模的应用系统。
PORT0(P0.0~P0.7):端口0是一个8位宽的开路汲极双向输出入端口,共有8个位,P0.0表示位0,P0.1表示位1,依此类推。其他三个I/O端口(P1、P2、P3)则不具有此电路组态,而是内部有一提升电路,P0在当做I/O用时可以推动8个LS的TTL负载。
PORT1(P1.0~P1.7):端口1也是具有内部提升电路的双向I/O端口,其输出缓冲器可以推动4个LSTTL负载,同样地若将端口1的输出设为高电平,便是由此端口来输入数据。
PORT2(P2.0~P2.7):端口2是具有内部提升电路的双向I/O端口,每一个引脚可以推动4个LS的TTL负载,若将端口2的输出设为高电平时,此端口便能当成输入端口来使用。P2除了当做一般I/O端口使用外,若是在STC89C52扩充外接程序存储器或数据存储器时,也提供地址总线的高字节A8~A15,这个时候P2便不能当做I/O来使用了。
PORT3(P3.0~P3.7):端口3也具有内部提升电路的双向I/O端口,其输出缓冲器可以推动4个TTL负载,同时还多工具有其他的额外特殊功能,包括串行通信、外部中断控制、计时计数控制及外部数据存储器内容的读取或写入控制等功能。单片机的引脚图如图3-1所示。
#include "51Lib_Configure.h"
#include "51Lib_Declaration.h"
#if _CONFIG_FUNC_LCD1602_ == CH_ENABLE
#define _NOP() _nop_()
#define DataPort P0
#define DataPIN P0
#define CLR_RS (lcd1602_RS=0)
#define SET_RS (lcd1602_RS=1)
#define CLR_RW (lcd1602_RW=0)
#define SET_RW (lcd1602_RW=1)
#define CLR_EN (lcd1602_EN=0)
#define SET_EN (lcd1602_EN=1)
/*
LcdReset(); //LCD1602初始化
DelayMs(10);
sprintf(temp,"1111111111111111");//更新显示
DispStr(0,0,(unsigned char *)temp);//打印显示
sprintf(temp,"1111111111111111");//更新显示
DispStr(0,1,(unsigned char *)temp);//打印显示
*/
/***********************************************
函数名称:DispNum
功 能:让液晶从某个位置起连续显示一个数值,前面不会补0
参 数:x--位置的列坐标
y--位置的行坐标
Dis_dat--需要显示的数
Dis_Len--需要显示的宽度
返回值 :无
***********************************************/
void DispNum(uchar x, uchar y, uint Dis_dat, uchar Dis_Len)
{
uchar i;
uint dat = 1;
Disp1Char(x+Dis_Len-1,y,Dis_dat%10+0x30);
if(Dis_Len == 1)
return;
for(i = 1;i < Dis_Len;i++)
dat*=10;
for(i = 1; i < Dis_Len ; i++)
{
//dat = pow(10, Dis_Len-i);
if(Dis_dat >= dat)
Disp1Char(x+i-1,y,Dis_dat/dat%10+0x30);
else
Disp1Char(x+i-1,y,' ');
dat/=10;
}
}
/***********************************************
函数名称:DispStr
功 能:让液晶从某个位置起连续显示一个字符串
参 数:x--位置的列坐标
y--位置的行坐标
ptr--指向字符串存放位置的指针
返回值 :无
***********************************************/
void DispStr(uchar x,uchar y,uchar *ptr)
{
uchar *temp;
uchar i,n = 0;
temp = ptr;
while(*ptr++ != '\0') n++; //计算字符串有效字符的个数
for (i=0;i { Disp1Char(x++,y,temp[i]); if (x == 0x10) { break; } } } /******************************************* 函数名称:DispNchar 功 能:让液晶从某个位置起连续显示N个字符 参 数:x--位置的列坐标 y--位置的行坐标 n--字符个数 ptr--指向字符存放位置的指针 返回值 :无 ******************************************* void DispNChar(uchar x,uchar y, uchar n,uchar *ptr) { uchar i; for (i=0;i { Disp1Char(x++,y,ptr[i]); if (x == 0x10) { x = 0; y ^= 1; } } } */ /******************************************* 函数名称:LocateXY 功 能:向液晶输入显示字符位置的坐标信息 参 数:x--位置的列坐标 y--位置的行坐标 返回值 :无 ********************************************/ void LocateXY(uchar x,uchar y) { uchar temp; temp = x&0x0f; y &= 0x01; if(y) temp |= 0x40; //如果在第2行 temp |= 0x80; LcdWriteCommand(temp,1); } /******************************************* 函数名称:Disp1Char 功 能:在某个位置显示一个字符 参 数:x--位置的列坐标 y--位置的行坐标 data--显示的字符数据 返回值 :无 ********************************************/ void Disp1Char(uchar x,uchar y,uchar data1) { LocateXY( x, y ); LcdWriteData( data1 ); } /******************************************* 函数名称:LcdReset 功 能:对1602液晶模块进行复位操作 参 数:无 返回值 :无 ********************************************/ void LcdReset(void) { // DataDir = 0xFF; //数据端口设为输出状态 LcdWriteCommand(0x38, 0); //规定的复位操作 DelayMs(5); LcdWriteCommand(0x38, 0); DelayMs(5); LcdWriteCommand(0x38, 0); DelayMs(5); LcdWriteCommand(0x38, 1); //显示模式设置 LcdWriteCommand(0x08, 1); //显示关闭 LcdWriteCommand(0x01, 1); //显示清屏 LcdWriteCommand(0x06, 1); //写字符时整体不移动 LcdWriteCommand(0x0c, 1); //显示开,不开游标,不闪烁 } /*------------------------------------------------ 清屏函数 ------------------------------------------------*/ void LcdClear(void) { LcdWriteCommand(0x01,1); DelayMs(5); } /******************************************* 函数名称:LcdWriteCommand 功 能:向液晶模块写入命令 参 数:cmd--命令, chk--是否判忙的标志,1:判忙,0:不判 返回值 :无 ********************************************/ void LcdWriteCommand(uchar cmd,uchar chk) { if (chk) WaitForEnable(); // 检测忙信号? CLR_RS; CLR_RW; _NOP(); DataPort = cmd; //将命令字写入数据端口 _NOP(); SET_EN; //产生使能脉冲信号 _NOP(); _NOP(); CLR_EN; } /******************************************* 函数名称:LcdWriteData 功 能:向液晶显示的当前地址写入显示数据 参 数:data--显示字符数据 返回值 :无 ********************************************/ void LcdWriteData( uchar data1 ) { WaitForEnable(); //等待液晶不忙 SET_RS; CLR_RW; SET_EN; _NOP(); DataPort = data1; //将显示数据写入数据端口 _NOP(); //产生使能脉冲信号 _NOP(); _NOP(); CLR_EN; } /******************************************* 函数名称:WaitForEnable 功 能:等待1602液晶完成内部操作 参 数:无 返回值 :无 ********************************************/ void WaitForEnable(void) { unsigned int later=0; DataPort=0xff; CLR_RS; SET_RW; _NOP(); SET_EN; _NOP(); _NOP(); // while((DataPIN&Busy)!=0); while(((DataPIN&0x80)!=0)&&(later<1000)) //检测忙标志 { DelayUs2x(2); later++; } CLR_EN; // DataDir|=0xFF; //将P4口切换为输出状态 } #endif 相关文章
发表评论