资源描述
沈阳理工大学课程设计专用纸
摘要
亮度是工业中非常关键的一项物理量,在农业,现代科学研究和各种高新技术的开发和研究中也是一个非常普遍和常用的测量参数。亮度自动控制的原理主要是:将随亮度变化而变化的物理参数,通过光传感器转变成电的或其他信号,传给处理电路,最后转换成亮度数值显示出来。目前最具发展前景的灯光调节是加入自动控制原理,通过自动控制系统,按照给定参数对对象的反馈信息进行调节,从而满足工农业生产的需求。本文介绍了以处理芯片STC1205A08S2为核心器件的亮度控制系统。STC1205A08S2 是宏晶以公司研制的51内核为主的系列单片机,这个芯片设计的时候就吸取其它51系列单片很容易被解密的教训,改进了加密机制。
关键词: 亮度控制;STC1205A08S2;自动控制系统。
目录
引言 1
1 课程设计概述 1
1.1 课程设计题目 1
1.2 课程设计要求 1
1.3 主要仪器设备 1
1.4 PWM控制说明 2
2 硬件设计 2
2.1 单片机部分 2
2.2 亮度反馈部分 4
2.3 按键电路部分 4
2.4 串口下载部分 5
2.5 LED执行部件 6
3 软件设计 6
3.1 按键的软件设计 6
3.2 一般串行下载介绍 7
3.3 LCD1062显示介绍 8
3.4 PWM控制具体过程 9
3.5 流程图设计 10
4 系统调试 10
4.1 LED执行部分调试 10
4.2串口下载部分调试 11
4.3 LED显示部分调试 11
4.4 按键部分调试 11
4.5系统调试 11
5 课设总结 11
参考文献 12
附 录 13
引言
调光灯亮度作为一项光工参数,在工业现场和过程控制中具有至关重要的作用。因而,各种以光敏作为传感器的光敏电阻和光敏二极管普遍使用。亮度是工业中非常关键的一项物理量,在农业,现代科学研究和各种高新技术的开发和研究中也是一个非常普遍和常用的测量参数。亮度自动控制的原理主要是:将随亮度变化而变化的物理参数,通过光传感器转变成电的或其他信号,传给处理电路,最后转换成亮度数值显示出来。目前最具发展前景的灯光调节是加入自动控制原理,通过自动控制系统,按照给定参数对对象的反馈信息进行调节,从而满足工农业生产的需求。
1 课程设计概述
1.1 课程设计题目
设计LED线性驱动电路和光敏管进行亮度测量电路,再用单片机设计控制器输出PWM,调节LED驱动功率,实现亮度的自动控制,通过键盘进行亮度设置,实际亮度可以实时显示。
1.2 课程设计要求
要求:1、实现亮度可调;
2、控制精度±1%(±50m);
3、实现亮度闭环反馈控制。
*附加要求:通过RS232或RS485接口可以与PC机通信,在PC机上能够进行参数显示和设置。
图1-2温度控制系统的基本组成
1.3 主要仪器设备
仪器设备名称
数量
示波器(YB4328D)
1台
直流稳压电源(DF1731SC3A)
1台
数字万用表
1块
PC机
1台
测光敏感元件
1个
1.4 PWM控制说明
PWM控制简介:脉冲宽度调制(PWM)是一种模拟控制方式,其根据相应载荷的变化来调制晶体管栅极或基极的偏置,来实现开关稳压电源输出晶体管或晶体管导通时间的改变,这种方式能使电源的输出电压在工作条件变化时保持恒定,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。PWM控制技术以其控制简单,灵活和动态响应好的优点而成为电力电子技术最广泛应用的控制方式,也是人们研究的热点。由于当今科学技术的发展已经没有了学科之间的界限,结合现代控制理论思想或实现无谐振软开关技术将会成为PWM控制技术发展的主要方向之一。
PWM基本原理:随着电子技术的发展,出现了多种PWM技术,其中包括:相电压控制PWM、脉宽PWM法、随机PWM、SPWM法、线电压控制PWM等,而在镍氢电池智能充电器中采用的脉宽PWM法,它是把每一脉冲宽度均相等的脉冲列作为PWM波形,通过改变脉冲列的周期可以调频,改变脉冲的宽度或占空比可以调压,采用适当控制方法即可使电压与频率协调变化。可以通过调整PWM的周期、PWM的占空比而达到控制充电电流的目的。
2 硬件设计
2.1 单片机部分
本设计选择的单片机芯片是STC1205A08S2,其原理图如2-1所示。该芯片的P2.0-3用作键盘数字量输入,为了防止干扰使键盘处于低电平,加入了上拉电阻时按键未按下时始终处于高电平状态;
芯片引脚功能:
P1.0作为光敏电阻反馈数据输入端口;
P0口显示数据输出到LCD1602显示;
P1.4作为PWM输出端口
图 2-1 STC控制系统原理图
AT89C51是一种带4K字节FLASH存储器(FPEROM—Flash Programmable and Erasable Read Only Memory)的低电压、高性能CMOS 8位微处理器,俗称单片机。AT89C2051是一种带2K字节闪存可编程可擦除只读存储器的单片机。单片机的可擦除只读存储器可以反复擦除1000次。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器,AT89C2051是它的一种精简版本。AT89C单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。
AT89C51主要接口介绍:
P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。当P0口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。
P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。
P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。
P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流这是由于上拉的缘故。
2.2 亮度反馈部分
如图2-2所示,图中RF为光敏电阻,它可更加接收到的LED灯光的亮度改变自身阻值。LED灯变亮,其阻值越小;反之,LED灯越亮,其阻值也越大。
图2-2 亮度反馈原理图
2.3 按键电路部分
键盘电路分类:
1、独立式键盘
独立式键盘是指直接用I/O口线构成的单个按键电路。每根I/O口线上按键的工作状态不会影响其他I/O口线的工作状态。微处理器通过向此I/O口发出读指令来得到当前按键的状态。键未按下时,此信号为1(高电平),键按下时,此信号为O(低电平)。因此,通过检测输入线的电平状态可以很容易判断哪个按键被按下了,一般独立式按键的接口,独立式键盘电路原理图:
2、矩形式键盘
独立式按键电路配置灵活,软件结构简单,但缺点是占用I/O口资源太多,在按键数量较多时,I/O口浪费大,矩阵式按键结构能够缓解这种矛盾。矩阵式键盘由行线、列线及位于行列线交叉点上的按键等部分组成。当应用系统需要的按键数量比较多时可采用矩阵式键盘。一般情况下,按键数等于矩阵行数和列数的乘积。矩形结构如图:
键盘电路选择:
根据实际需要,本次设计采用独立式键盘,如图2-3所示,通过按键可以增大、减小LED灯的给定值。给定值的不同,其亮度也不同。通过按键可把LED灯调节到合适的亮度。
图2-3 按键原理图
2.4 串口下载部分
通过下图2-4串口下载电路,可以将程序从PC机直接下载到板子上的STC中,比较方便。
图2-4 串口下载电路原理图
宏晶科技参考资料:
说明:STC89 系列单片机大部分具有在系统可编程(ISP)特性,ISP 的好处是:省去购买通用编程器,单片机在用户系统上即可下载/ 烧录用户程序,而无须将单片机从已生产好的产品上拆下,再用通用编程器将程序代码烧录进单片机内部。有些程序尚未定型的产品可以一边生产,一边完善,加快了产品进入市场的速度,减小了新产品由于软件缺陷带来的风险。由于可以将程序直接下载进单片机看运行结果故也可以不用仿真器。大部分STC89 系列单片机在销售给用户之前已在单片机内部固化有ISP 系统引导程序,配合PC 端的控制程序即可将用户的程序代码下载进单片机内部,故无须编程器(速度比通用编程器快)。不要用通用编程器编程,否则有可能将单片机内部已固化的ISP 系统引导程序擦除,造成无法使用STC 提供的ISP 软件下载用户的程序代码。
2.5 LED执行部件
如下图2-3所示,P1.4输出PWM输出控制信号。根据输出电压占空比不同,灯的亮度也不一样。占空比越大,说明输出电压越大,灯就越亮;反之,占空比越小,即说明输出电压越小,灯就越暗。
图 2-5 LED执行部件原理图
3 软件设计
3.1 按键的软件设计
键盘的监测方式:
1、查询方式:查询方式是指CPU不断的判断I/O口(按键接口)的状态,就像扫描一样,扫描哪个按键式是处于被按下状态,扫描到了就可以确定是哪个按键了。在查询方式下不管有没有按键,CPU都需要不断地进行查询操作,以判断是否有键按下,这不利于提高CPU的效率。在一些任务繁重或者低功耗应用场合,尤其不适合使用。如果采用中断方式,只有在每次有键按下,CPU才去响应键盘,这样能够大大减轻CPU的任务量。
2、中断方式:中断方式相比查询方式要好很多,当然它多占用了单片机的一个资源,当检测到有按键按下时,就进入到中断里面判断是哪个按键,换句话可以理解为在中断中扫描按键值。用中断方式恰恰就解决了查询方式中的问题。
键盘抖动原因:
由于按键多为机械弹性开关,它是利用了机械触点的合、断作用。所以按键开关在闭合和断开的瞬间均有一连串的抖动,抖动时间的长短由按键的机械特性决定,一般为5~10ms,这是一个很重要的参数。抖动过程引起电平信号的波动,有可能令CPU误解为多次按键操作,从而引起误处理。通常避免该问题是通过消抖来实现的,而消抖的方式也有两种,软件方式和硬件方式。
按键消抖方法:
1、硬件消抖方法:可以用电路来实现,如加RS触发器,使其产生单次手动脉冲;此外,也可以利用积分电路来吸收抖动带来的干扰脉冲,只要选择好适当的参数也能达到较好的效果。
2、软件消抖方法:多采用软件延时的方法:在第一次检测到有键按下时,执行一段延时10ms的子程序后,再确认电平是否仍保持闭合状态电平,如果保持闭合状态电平,则确认真正有键按下。释放一个键时,方法相同。这种消除抖动影响的软件措施是切实可行的。
3.2 一般串行下载介绍
ISP:在系统编程,一般目标芯片内包含了专用的接口电路,上位机发送编程命令码及编程控制信息后由芯片硬件自动完成编程。比如通过JTAG口升级就是其中的一种,现在推出的许多新的芯片比如ARM都采用此模式。ATMEL公司的AT89S5x系列的单片机的下载模式虽然不属于JTAG模式,但很类似,应该属于ISP类。
IAP:一般叫做在应用编程。MCS-51系列单片机中采用比较多的sst、stc两家公司的单片机就属于这种模式,与上面的模式是有区别的。
二者比较:
ISP编程属于纯硬件操作,只要FLASH的物理特性未损坏,就可以实现串口升级,但升级模式是固定的。
IAP模式属于属于软件操作,如果8K区并无物理损坏但软件有问题,就只能使用编程器来编程,无法实现串口升级。但正是由于这种可更改性,可以扩展多种升级方式,更灵活。其实物理损坏的可能性不大,所以我个人认为还是IAP更好些。
3.3 LCD1062显示介绍
1602LCD分为带背光和不带背光两种,基控制器大部分为HD44780,带背光的比不带背光的厚,是否带背光在应用中并无差别,两者尺寸差别如下图所示:
1602LCD的指令说明及时序:
序号
指令
RS
R/W
D7
D6
D5
D4
D3
D2
D1
D0
1
清显示
0
0
0
0
0
0
0
0
0
1
2
光标返回
0
0
0
0
0
0
0
0
1
*
3
置输入模式
0
0
0
0
0
0
0
1
I/D
S
4
显示开/关控制
0
0
0
0
0
0
1
D
C
B
5
光标或字符移位
0
0
0
0
0
1
S/C
R/L
*
*
6
置功能
0
0
0
0
1
DL
N
F
*
*
7
置字符发生存贮器地址
0
0
0
1
字符发生存贮器地址
8
置数据存贮器地址
0
0
1
显示数据存贮器地址
9
读忙标志或地址
0
1
BF
计数器地址
10
写数到CGRAM或DDRAM)
1
0
要写的数据内容
11
从CGRAM或DDRAM读数
1
1
读出的数据内容
LCD1064驱动软件代码在后面附录部分
3.4 PWM控制具体过程
脉冲宽度调制(PWM)是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。PWM信号仍然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有(ON),要么完全无(OFF)。电压或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去的。通的时候即是直流供电被加到负载上的时候,断的时候即是供电被断开的时候。只要带宽足够,任何模拟值都可以使用PWM进行编码。
许多微控制器内部都包含有PWM控制器。占空比是接通时间与周期之比;调制频率为周期的倒数。执行PWM操作之前,这种微处理器要求在软件中完成以下工作:
1、设置提供调制方波的片上定时器/计数器的周期
2、 在PWM控制寄存器中设置接通时间
3、设置PWM输出的方向,这个输出是一个通用I/O管脚
4、启动定时器
5、使能PWM控制器
目前几乎所有市售的单片机都有PWM模块功能,若没有,也可以利用定时器及GPIO口来实现。更为一般的PWM模块控制流程为:
1、使能相关的模块(PWM模块以及对应管教的GPIO模块)。
2、配置PWM模块的功能,具体有:
①设置PWM定时器周期,该参数决定PWM波形的频率。
②设置PWM定时器比较值,该参数决定PWM波形的占空比。
③设置死区(deadband),为避免桥臂的直通需要设置死区,一般较高档的单片机都有该功能。
④设置故障处理情况,一般为故障是封锁输出,防止过流损坏功率管,故障一般有比较器或ADC或GPIO检测。
⑤设定同步功能,该功能在多桥臂,即多PWM模块协调工作时尤为重要。
3、设置相应的中断,编写ISR,一般用于电压电流采样,计算下一个周期的占空比,更改占空比,这部分也会有PI控制的功能。
4、使能PWM波形发生。
3.5 流程图设计
控制现场主程序流程图设计如下:
开始
①
LCD初始化
AD初始化
延时
按键初始化
设第一行显示位置
LCD1062显示
单片机PWM控制
按键扫描
显示第一行内容
按键按下
设第二行显示位置
显示第二行内容
①
4 系统调试
4.1 LED执行部分调试
装好元件,接通电源,观察LED是否发光。若发光,说明LED部分连接正确;若不发光,则说明此部分线路连接有问题,应该用万用便检查STC第五脚,其电压应在0-5V;还要检查三极管三个脚是否连接正确。
4.2串口下载部分调试
把编好的程序通过次串口下载到STC,若可以下载,则说明此部分连线正确;若不能下载,则检查RS232各脚电压是否正常。
4.3 LED显示部分调试
将一个正确的显示程序下载到单片机,观察LCD是否按要求显示。若按要求显示,说明此部分可以正常工作;若不能显示,则先检查显示器的好坏,其次检查其各脚的连接是否正确。
4.4 按键部分调试
按下按键,观察LED灯亮度是否有变化,若按要求变化,说明此部分正常工作;若不按要求变化,则应先检查有关按键部分程序是否书写正确,其次检查按键与STC的线路连接情况是否正确。
4.5系统调试
各个部分的调试完成以后,还需要对整个系统进行调试。如发现问题及时纠正,直至能正常如期运行。
5 课设总结
本次课程设计是我们专业课程知识综合应用的实践训练,是我们迈向社会,从事职业工作前一个必不少的过程。在这个过程中本人更为深层次的了解了PI控制和PWM控制。根据课设需要在图书馆和网上积极寻找相关资料,不懂的地方询问老师和同学,极大的补充了自己所学的不足。仿真成功后需要做板子和写程序,课设工作量较大,要极大有耐心和恒心,当然也是锻炼我们耐心和恒心的机会。板子做好后,后面要注意的事情还很多。比如下载程序时板子没有反应,这时应检查板子上的焊点是否存在虚焊和漏焊,然后检查线路是否短路。调试程序时,为了方便快捷的调试程序需要将程序要分模块来调试,根据程序流程图把每个模块都调试好,最后各个模块一起调试一遍。通过此次课程设计,使我深深体会到,干任何事都必须耐心,细致,以后在以后的工作中任何一个小错误都有可能引发一个大的事故,我不禁时刻提示自己,一定要养成一种高度负责,认真对待的良好习惯。同时发现自己所掌握的知识量还不多,很多地方都需要学习,即便是掌握的知识,将其变成实物也很困难,而走向社会更多的是将理论变为实物,总之,即将走向社会的我们需要学习的地方还很多。
参考文献
[1] 谭浩强.C程序设计[M].北京:清华大学出版社,1991
[2] 高海生,杨文焕.单片机应用技术大全[M].西南交通大学出版社,1999-06.
[3] 徐爱钧,彭秀华.单片机高级C51应用程序设计[M].中国计量出版社,2001.
[4] 马盅梅.单片机的C语言应用程序设计[M].北京航空航天大学出版社,2003.
18
附 录
主要电路PCB:
电路原理图
电路原理
现场ADuC512程序
/*****************************************************************************/
#include "reg51.h"
#include "intrins.h"
#include "LCD1602.H"
#define FOSC 24058052L
#define BAUD 9600
sbit button1=P2^2; //按键-减小亮度
sbit button2=P2^1; //按键-增大亮度
sbit button3=P2^0 ; //按键-确认
typedef unsigned char BYTE;
typedef unsigned int WORD;
WORD exp=300;
BYTE REV=0;
/***************************************AD************************************/
/*Declare SFR associated with the ADC */
BYTE ch = 0; //ADC channel NO.
sfr ADC_CONTR = 0xBC; //ADC control register
sfr ADC_RES = 0xBD; //ADC hight 8-bit result register
sfr ADC_LOW2 = 0xBE; //ADC low 2-bit result register
sfr P1ASF = 0x9D; //P1 secondary function control register
/*Define ADC operation const for ADC_CONTR*/
#define ADC_POWER 0x80 //ADC power control bit
#define ADC_FLAG 0x10 //ADC complete flag
#define ADC_START 0x08 //ADC start control bit
#define ADC_SPEEDLL 0x00 //540 clocks
#define ADC_SPEEDL 0x20 //360 clocks
#define ADC_SPEEDH 0x40 //180 clocks
#define ADC_SPEEDHH 0x60 //90 clocks
/*------------------------------------------------------Get ADC result-----------------------------------------*/
WORD GetADCResult(BYTE ch)
{ WORD ADC_R;
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
_nop_(); //Must wait before inquiry
_nop_();
_nop_();
_nop_();
while (!(ADC_CONTR & ADC_FLAG)); //Wait complete flag
ADC_CONTR &= ~ADC_FLAG; //Close ADC
ADC_R=ADC_RES*4+ADC_LOW2; //Return ADC result
return ADC_R;}
/*********************************平均值**************************************/
WORD GetADCResult_P()
{ WORD ADC_RP=GetADCResult(0);
BYTE i;
for(i=0;i<10;i++)
ADC_RP=(ADC_RP+GetADCResult(0))/2;
ADC_RP=ADC_RP*0.48828;
return ADC_RP;}
/*-----------------------------------------------------Initial ADC sfr-------------------------------------------*/
void InitADC()
{ //P1ASF = 0xff;
ADC_RES = 0;
ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
Delay(2);}
/*---------------------------------------------------showADC()------------------------------------------------*/
void showADC(WORD j,BYTE x)
{ BYTE i,a[3],k=7;
for(i=0;i<3;i++)
{ a[i]=j%10;
j/=10;}
for(i=0;i<3;i++)
{ if(i==2)
{ gotoxy(x,k-i);
write_LCD_data('.');
k--;}
gotoxy(x,k-i);
display_LCD_number(a[i]);
}
}
/*-----------------------------------------------------PI调节---------------------------------------------------*/
void PI(BYTE i,BYTE ki) //i->模糊值
{ WORD r;
r=GetADCResult_P();
if(r<exp-i)
{ //CCAP0H=CCAP0H-(exp-r)/ki;
CCAP0H=CCAP0H-ki;
if(CCAP0H<0x2c)
CCAP0H=0x2c; }
if(r>exp+i)
{ //CCAP0H=CCAP0H+(r-exp)/ki;
CCAP0H=CCAP0H+ki;
if(CCAP0H>0xf4)
CCAP0H=0xf4; }
}
/*----------------------------------------------------Initial UART----------------------------------------------*/
void InitUart()
{ SCON = 0x5a;
PCON=0x80; //8 bit data ,no parity bit
TMOD = 0x20; //T1 as 8-bit auto reload
TH1 = TL1 = -13; //Set Uart baudrate
TR1 = 1; //T1 start running
}
/*--------------------Send one byte data to PC Input: dat (UART data) Output:- ------------------*/
void SendData(BYTE dat)
{ while (!TI); //Wait for the previous data is sen
TI = 0; //Clear TI flag
SBUF = dat; //Send current data
}
/*-----------------Send a string to UART Input: s (address of string) Output:None----------------*/
void SendString(char *s)
{ while (*s)
{ SendData(*s++);}
}
/*--------------------------------------------------------main()--------------------------------------------------*/
void main()
{ BYTE stp=5,ii,tab[3];
InitUart();
InitADC();
init_LCD();
gotoxy(1,0);
display_LCD_string(" exp: stp: ");
gotoxy(2,0);
display_LCD_string("act: ");
/***PWM控制***/
CCON = 0;
CL = 0; //复位PCA的计数器
CH = 0;
CMOD = 0x02;
CCAP0H = 0xf4;
CCAP0L = 0x00; //50
CCAPM0 = 0x42;
CR = 1;
showADC(exp,1);
gotoxy(1,14);
display_LCD_number(stp);
while (1)
{ if(!button1)
{ delay_50us(40000);
xp -=stp;
SendData(0xbb);
//SendData(0xbb); }
if(!button2)
{ delay_50us(40000);
exp +=stp;
SendData(ADC_RES);
SendData(ADC_LOW2); }
while(!button3)
{ if(!button2)
{ delay_50us(40000);
stp+=1;
gotoxy(1,14);
display_LCD_number(stp);
}
if(!button1)
{ delay_50us(40000);
stp -=1;
gotoxy(1,14);
display_LCD_number(stp); }
delay_50us(80000); }
if(RI)
{ RI=0;
REV=SBUF;
for (ii=0;ii<3;ii++)
{ tab[ii]=REV%10;;
REV/=10; }
for (ii=0;ii<3;ii++)
{ gotoxy(2,14-ii);
display_LCD_number(tab[ii]); }
}
showADC(exp,1);
showADC(GetADCResult_P(),2);
PI(3,1);
}
}
展开阅读全文