指导教师评定成绩:
审定成绩:
重 庆 邮 电 大 学 自 动 化 学 院
计算机控制技术课程设计报告
设计题目:光源随动系统
单位(二级学院):
学 生 姓 名: 专 业: 班 级: 学 号: 指 导 教 师:
设计时间: 2013 年 6 月 重庆邮电大学自动化学院制
实用文档
摘 要
本设计给出了一种基于单片机的点光源自动跟踪系统设计方案, 该设计使用TI公司的超低功耗的AT89C52单片机作为整个系统的控制核心,主要由电机驱动模块,点光源检测模块,电源转换模块等模块组成。利用8路光敏电阻来检测点光源的位置并将检测到的信号经过放大后进行AD转换,将转换的结果传给控制器AT89C52单片机,经过过单片机的运算和处理来确定点光源的运动趋势,并将运算的控制信号控制两台步进电机,使其跟随点光源运动。
本设计可以扩展为以后的太阳能发电的自动跟踪系统。该系统不仅能自动根据太阳光方向来调整太阳能电池板朝向, 结构简单、成本低, 而且在跟踪过程中能自动记忆和更正不同时间的坐标位置, 不必人工干预, 特别适合天气变化比较复杂和无人值守的情况, 有效地提高了太阳能的利用率, 有较好的推广应用价值。
关键词:AT89C52单片机、光源、自动跟踪、传感器
实用文档
目 录
摘要 .................................... 错误!未定义书签。 目录 ..................................................... 3 一 设计题目 .............................................. 4
1.1 基于单片机的光源自适应控制系统设计 ................ 4 1.2 设计要求 .......................................... 4 二 设计报告正文 .......................................... 5
2.1 设计方案总体方向的选择 ............................ 5 2.1.1 系统方案的拟定 .............................. 5 2.1.2 方案选择 ................................... 5
2.2 硬件电路的设计 .................................... 6
2.2.1 A/D转换模块 ................................. 6 2.2.2 步进电机模块 ................................ 9 2.2.3 电机驱动模块 .............................. 11
2.2.4 检测模块 ................................... 13 2.2.5 单片机模块 ................................. 14 2.3 系统软件设计 ..................................... 18 三 总体调试 ............................................. 19 3.1 总体调试 ........................................ 19
3.2 问题及解决方案 ................................... 19 3.2.1 通道比较阀值的设置 ......................... 19
实用文档
3.2.2 电机的防抖 ................................. 19 四 设计总结 ............................................ 20 五 参考文献 ............................................. 21 六 附录 ................................................. 22
实用文档
一、设计题目
1.1基于单片机的光源自适应控制系统设计
设计一控制系统,假设有一个太阳能电池板,为了使电池板最大限度的接受光照强度,通过控制器调节电池板的角度使电池板始终正对光线。采用步进电机作为角度调整装置,使系统能上下和左右旋转。
1.2设计要求
1.绘制原理图; 2.连接电路; 3.编写程序; 4.调试运行。
二、设计报告正文
2.1设计方案的选择
2.1.1系统方案的拟定 1.方案一
由检测电路、AT89C52单片机、时钟电路、A/D转换控制电路等主要模块组成。传感器部分采用光敏二极管,将光信号变换为电信号。经过A/D转换将其转化离散的数字信号。控制电路以单片机为核心,能够对采集的数字信号进行处理和判断,控制步进电机运转使传感器光板正对光线。 2.方案二
实用文档
以单片机低功耗LM3S1138微控制器作为核心控制单元,光强度检测模块,时钟模块,电机驱动,电源供电,步进电机控制电路模块等主要模块组成。传感器采用光敏电阻,LM3S1138微控制器自带8个10位A/D,能够识别模拟信号。控制电路以单片机为核心,能够对采集的模拟信号进行处理和判断对步进电机实现控制。 2.1.2方案选择
比较以上两方案可知,系统的工作原理是一致的,都是通过传感器感受光强变化并间接或直接将其转化成单片机能够识别的信号,通过单片机处理信号并进行判断,步进电机控制电路根据单片机传出的信号转动。不同的是选择的控制器,从单片机方面考虑,方案一所使用的传统的AT89C52单片机器件比方案二所使用的LM3S1138微控制器成本低,但是方案二集成8为A/D/处理模块,对于处理数模显得简单方便。经过试验,采用外接A/D模块的方案一,传感器采集数据电路处理较复杂,A/D模块后期程序编写遇到瓶颈,无法实现,于是改为选择采用LM3S1138微控制器的方案二,因为有经验借鉴,因此设计题目的要求得以方便实现。综合考虑,最后确定选择方案二。
系统组成及工作原理以单片机为控制核心,采用光强度检测电路测量,以光敏电阻传感器作为测量元件,构成光电测量模块。该系统可分为电源模块电路、光电测量电路、步进电机控制电路、单片机、A/D转换电路。选用的主要器件有:光敏电阻,LM3S1138微控制器,ULN2003步进电机驱动模块,步进电机等。
实用文档
图2-1 系统设计框图
2.2硬件电路的设计
2.2.1 步进电机模块 驱动方法及主要参数:
驱动方式(4-1-2相驱动)
导线颜色 5红 4橙 3黄 2粉 1蓝
主要技术参数
电机型号 28BYJ-48 2.步进电机的主要特性:
1) 步进电机必须加驱动才可以运转, 驱动信号必须为脉冲信号,没有脉冲的时候,步进电机静止, 如果加入适当的脉冲信号, 就会以一定的角度(称为步角)转动。转动的速度和脉冲的频率成正比。
2)28BYJ48是减速步进电机,减速比为1:64,步进角为5.625/64度。如果需要转动1圈,那么需要360/5.625*64=4096个脉冲信号。 3) 步进电机具有瞬间启动和急速停止的优越特性。 4)改变脉冲的顺序, 可以方便的改变转动的方向。
电压V 5 相数 4 步距角度 5.625/64 减速比 1:64 1 + - 2 + - - 3 + - 4 + - - 5 + - 6 + - - 7 + - 8 + -
实用文档
电机线圈由四相组成,即A、B、C、D四相,电机示意图和各线圈通电顺序图如下图所示:
步进电机原理图
相顺序从0到1称为一步,电机轴将转过5.625度,四相四拍为0-1-2-3则称为通电一周,若循环进行这种通电一周的操作,电机便连续的转动起来,而进行相反的通电顺序如3-2-1-0将使电机同速反转。同理四相八拍的通电顺序为
A-AB-B-BC-C-CD-D-DA-A(本设计用的是四相八拍)。通电一周的周期越短,即驱动频率越高,则电机转速越快,但步进电机的转速也不可能太快,因为它每走一步需要一定的时间,若信号频率过高,可能导致电机失步,甚至只在原步颤动。 2.2.3电机驱动模块
本设计采用LM3S1138微控制器(晶振频率为12MHZ)对该四线八相制步进电机进行控制。通过I/O口输出的具有时序的方波作为步进电机的控制信号,信号经过特定芯片驱动步进电机。本文选用ULN2003构成步进电机的驱动电路,ULN2003 是高耐压、大电流达林顿陈列,由七个硅NPN 达林顿管组成。
选择ULN2003A作为步进电机的驱动电路。其内部集成了一个消线圈反电动势的二极管,可用来驱动继电器。它是双列16脚封装,NPN晶体管矩阵,最大驱动电压=50V,电流=500mA,输入电压=5V,适用于TTL COMS,由达林顿管组成驱动电路。ULN是集成达林顿管IC,内部还集成了一个消线圈反电动势的二极管,它的输出端允许通过电流为200mA,饱和压降VCE约1V左右,耐压BVCEO约为36V。用户输出口的外接负载可根
实用文档
据以上参数估算。采用集电极开路输出,输出电流大,故可直接驱动继电器或固体继电器,也可直接驱动低压灯泡。通常单片机驱动ULN2003时,上拉2K的电阻较为合适,同时,COM引脚应该悬空或接电源。
图如图2-7所示。ULN2003和LM3S1138微控制器构成的驱动电路如图2-8所示。
图2-7 ULN2003内部方框图
该电路的特点如下:ULN2003 的每一对达林顿都串联一个2.7K 的基极电阻,在5V 的工作电压下它能与TTL 和CMOS 电路直接相连,可以直接处理原先需要标准逻辑缓冲器来处理的数据。ULN2003 工作电压高,工作电流大,灌电流可达500mA,并且能够在关态时承受50V 的电压,输出还可以在高负载电流并行运行。ULN2003 采用DIP—16 塑料封装。
实用文档
输入低电平输出高电平,输入高电平输出低电平。
ULN2003A的输出结构是集电极开路的,所以要在输出端接一个上拉电阻,在输入低电平的时候输出才是高电平 本次课程设计使用的5线4相步进电28BYJ-48有VCC线 故不需接上拉电阻。
图2-8 ULN2003和LM3S1138微控制器构成的驱动电路
2.2.4检测模块:
3 图2-9 光敏电阻分布图
1 2 4
实用文档
通过比较1、2和3、4两组电压的大小,实现竖直方向的转动,通过比较1、3和2、4两组电压的大小,实现水平方向的转动。
图2-10检测电路
2.2.5单片机模块
1.LM3S1138微控制器结构和引脚
单片机的选择主要考虑了单片机自带资源是否满足设计要求,如果能够选择合适的单片机,则可大为简化电路设计的复杂程度,从而提高系统的可靠性。本系统采用LM3S1138微控制器作为核心控制单元。LM3S1138微控制器具有的电池备用的休眠模块,可以有效地使LM3S1138掉电,在长时间的器件停止工作过程中让器件进入一个低功耗的状态,这非常适合要求最大限度降低功耗的应用。LM3S1138微控制器的优势还在于能够方便的运用多种ARM的开发工具和片上系统(SoC)的底层IP应用方案,以及广大的用户群体。另外,该微控制器使用了兼容ARM Thumb的Thumb2指令集来减少存储容量的需求,并以此达到降低成本的目的。最后,LM3S1138微控制器Stellaris系列的所有成员是代码兼容的,这为用户提供了灵活性,能够适应各种精确的需求。
LM3S1138微控制器的相关特性: 单输入和微分输入配置
实用文档
用作单终端输入的8个10位通道(输入) 灵活、可配置的模数转换
可以把输出配置为:驱动输出管脚、产生中断或者ADC采样序列
比较两个外部管脚输入或者将外部管脚输入与内部可编程参考电压相比较 片内低压差(LDO)稳压器,具有可编程的输出电压,用户可调节的范围为2.25V
到2.75V
因此采用LM3S1138微控制器可以最大程度提高本系统的准确度。
图2-11 LM3S1138芯片引脚图
2.3系统软件设计
实用文档
本设计中程序采用C语言进行设计。程序中主要有以下几个主要子程序:主程序,LM3S1138微控制器内部集成的A/D模块初始化、采集、转换数据程序,电机驱动控制程序。程序源代码见附录。
三、总体调试
3.1 软硬件调试
写完成后,在对整个系统调试的过程中,出现了电机不运转等问题。主要通过单独调试各个模块及检查相关硬件电路的焊接,找出问题所在,然后针对问题逐个击破,最后成功完成本设计。
四、设计总结
本系统是点光源随动系统,通过采用lm3s1138单片机作为核心部件,光敏三级管检测到的信号时通过AD转换为数字信号传输给单片机,将处理的结果以脉冲的形式输出给驱动电路uln2003,驱动步进电机运动。使其追踪到点光源的位置。通过老师同学的共同努力,大家相互配合,不断弥补知识的漏洞,基本可以实现点光源随动的功能
五、参考文献
[1]薛建国.基于单片机的太阳能电池自动跟踪系统的设计[J].长春师范学院学报:自然科学版,2005,24(3):26-30.
[2]张兴磊,杨丽丽.一种太阳自动跟踪系统的设计[J].青岛农业大学学报,2008,26(4):315—318.
[3]李敏,刘京城,刘俊,等.一种新型的太阳能自动跟踪装置[J].电子器件,2008,31(5):1702 1703,1708.
实用文档
[4]侯长来.一种太阳自动跟踪装置的设 JJ.现代机械,2005(1):66—68.
六、附录
1.系统整体电路图
实用文档
3.程序
#include \"systemInit.h\" #include \"uartGetPut.h\" #include #define ADCSequEnable ADCSequenceEnable #define ADCSequDisable ADCSequenceDisable #define ADCSequConfig ADCSequenceConfigure #define ADCSequStepConfig ADCSequenceStepConfigure #define ADCSequDataGet ADCSequenceDataGet tBoolean ADC_EndFlag = false; // 定义ADC转换结束的标志 // 定义KEY #define KEY_PERIPH SYSCTL_PERIPH_GPIOG #define KEY_PORT GPIO_PORTG_BASE #define KEY_PIN GPIO_PIN_5 unsigned char FFW[8]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09}; //四相八拍正转编码 unsigned char REV[8]={0x09,0x08,0x0c,0x04,0x06,0x02,0x03,0x01}; ////四相八拍反转编码 void motor_ffw() { unsigned char i; unsigned int j; 实用文档 for (j=0; j<1; j++) //转1*n圈 { for (i=0; i<8; i++) //一个周期转45度 { GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1| GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4| GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7, FFW[i]); // P1 = FFW[i]; //取数据 SysCtlDelay(1 * (TheSysClock / 3000)); } } } void motor_rev() { unsigned char i; unsigned int j; for (j=0; j<1; j++) //转1×n圈 { //退出此循环程序 for (i=0; i<8; i++) //一个周期转45度 { GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1| GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4| GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 , REV[i]); // P1 = REV[i]; //取数据 SysCtlDelay(1 * (TheSysClock / 3000)); } } } void motor_ffw1() { unsigned char i; unsigned int j; for (j=0; j<1; j++) //转1*n圈 { for (i=0; i<8; i++) //一个周期转45度 实用文档 { GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_0 | GPIO_PIN_1| GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4| GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7, FFW[i]); // P1 = FFW[i]; //取数据 SysCtlDelay(1 * (TheSysClock / 3000)); } } } void motor_rev1() { unsigned char i; unsigned int j; for (j=0; j<1; j++) //转1×n圈 { //退出此循环程序 for (i=0; i<8; i++) //一个周期转45度 { GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_0 | GPIO_PIN_1| GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4| GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 , REV[i]); // P1 = REV[i]; //取数据 SysCtlDelay(1 * (TheSysClock / 3000)); } } } // ADC初始化 void adcInit(void) { SysCtlPeriEnable(SYSCTL_PERIPH_GPIOB); SysCtlPeriEnable(SYSCTL_PERIPH_GPIOE); GPIOPinTypeOut(GPIO_PORTE_BASE,GPIO_PIN_0 | GPIO_PIN_1| GPIO_PIN_2 | GPIO_PIN_3); GPIOPinTypeOut(GPIO_PORTB_BASE,GPIO_PIN_0 | GPIO_PIN_1| GPIO_PIN_2 | GPIO_PIN_3); SysCtlPeriEnable(KEY_PERIPH); GPIOPinTypeIn(KEY_PORT, KEY_PIN); 实用文档 SysCtlPeriEnable(SYSCTL_PERIPH_ADC); // 使能ADC模块 SysCtlADCSpeedSet(SYSCTL_ADCSPEED_125KSPS); // 设置ADC采样率 ADCSequDisable(ADC_BASE, 0); // 配置前先禁止采样序列 // 采样序列配置:ADC基址,采样序列编号,触发事件,采样优先级 ADCSequConfig(ADC_BASE, 0, ADC_TRIGGER_PROCESSOR, 0); // ADC采样序列步进配置:ADC基址,采样序列0,步值,采样通道 ADCSequStepConfig(ADC_BASE, 0, 0, ADC_CTL_CH0); // 第0步:采样ADC0 ADCSequStepConfig(ADC_BASE, 0, 1, ADC_CTL_CH1); // 第1步:采样ADC1 ADCSequStepConfig(ADC_BASE, 0, 2, ADC_CTL_CH2); // 第2步:采样ADC2 ADCSequStepConfig(ADC_BASE, 0, 3, ADC_CTL_CH3); // 第3步:采样ADC3 ADC_CTL_END | // 结束,并 ADC_CTL_IE); // 申请中断 ADCIntEnable(ADC_BASE, 0); // 使能ADC中断 IntEnable(INT_ADC0); // 使能ADC采样序列中断 IntMasterEnable(); // 使能处理器中断 ADCSequEnable(ADC_BASE, 0); // 使能采样序列 } // ADC采样:*pulVal保存采样结果 void adcSample(unsigned long *pulVal) { ADCProcessorTrigger(ADC_BASE, 0); // 处理器触发采样序列 while (!ADC_EndFlag); // 等待采样结束 ADC_EndFlag = false; // 清除ADC采样结束标志 ADCSequDataGet(ADC_BASE, 0, pulVal); // 自动读取全部ADC结果 } int main(void) { unsigned char r,N=64; //N 步进电机运转圈数 实用文档 unsigned long ulVal[8],v[8]; int left,right,up,down,limit360l=0,limit180u=0,limit360r=0,limit180d=0; char s[40]; unsigned long i; jtagWait(); // 防止JTAG失效,重要! clockInit(); // 时钟初始化:PLL,20MHz uartInit(); // UART初始化 adcInit(); // ADC初始化 for (;;) { adcSample(ulVal); // ADC采样 for (i = 0; i < 8; i++) { v[i] = (ulVal[i] * 3) / 1024; // 转换成电压值 sprintf(s, \"ADC%d = %d(mV)\\r\\n\采样值格式化为电压值 uartPuts(s); // 通过UART输出电压值 } if( ((v[1]+v[2])-(v[0]+v[3])) > 3 ) left = 1; else left = 0; if( ((v[0]+v[3])-(v[2]+v[1])) > 3 ) right = 1; else right = 0; if( ((v[2]+v[3])-(v[1]+v[0])) > 3 ) up = 1; else up = 0; if( ((v[1]+v[0])-(v[2]+v[3])) > 3) down = 1; else 实用文档 down = 0; SysCtlDelay(15 * (TheSysClock / 3000)); // 延时约1500ms if (GPIOPinRead(KEY_PORT, KEY_PIN) == 0x00) // 如果按下KEY { // GPIOPinWrite(LED_PORT, LED_PIN, 0x00); // 点亮LED for(r=0;r } } if (right == 1 )//&& limit360r < 181) // 如果按下KEY { // GPIOPinWrite(LED_PORT, LED_PIN, 0x00); // 点亮LED for(r=0;r } right = 0; limit360r += 45; limit360l -= 45; } if (left == 1 )//&& limit360l < 181) // 如果按下KEY { // GPIOPinWrite(LED_PORT, LED_PIN, 0x00); // 点亮LED for(r=0;r } left = 0; limit360r -= 45; limit360l += 45; } if (up == 1 )//&& limit180u < 91) // 如果按下KEY 实用文档 { // GPIOPinWrite(LED_PORT, LED_PIN, 0x00); // 点亮LED for(r=0;r } up = 0; limit180u += 45; limit180d -= 45; } if (down == 1 )//&& limit180d < 91) // 如果按下KEY { // GPIOPinWrite(LED_PORT, LED_PIN, 0x00); // 点亮LED for(r=0;r } down = 0; limit180u -= 45; limit180d += 45; } } } // ADC采样序列0的中断 void ADC_Sequence_0_ISR(void) { unsigned long ulStatus; ulStatus = ADCIntStatus(ADC_BASE, 0, true); // 读取中断状态 ADCIntClear(ADC_BASE, 0); // 清除中断状态,重要 if (ulStatus != 0) // 如果中断状态有效 实用文档 { ADC_EndFlag = true; // 置位ADC采样结束标志 } } 4.实物图 实用文档 实用文档 实用文档 因篇幅问题不能全部显示,请点此查看更多更全内容