《嵌入式系统设计性实验报告飞思卡尔单片机.doc》由会员分享,可在线阅读,更多相关《嵌入式系统设计性实验报告飞思卡尔单片机.doc(25页珍藏版)》请在三一办公上搜索。
1、嵌入式系统设计性实验报告 作者:苏显龙 班级:50806 学号 10摘要:该实验设计基于飞思卡尔MC9S12DG128开发板平台,根据实验的要求,完成了水温控制系统各个模块的设计,并对整个系统进行调试,并取得比较好的效果。MC9S12DG128是一个以16位中央处理器为核心的16位微控制器,并且集成了用于采集、控制与通信的多个模块。本次实验运用MC9S12DG128的AD转换模块采集时事的温度,用脉冲宽度调制(PWM)技术控制固体继电器导通与关断时间的长度完成加热。并通过串口(SCI)实时传送加热的状态。测温电路采用热电阻。关键字 温度控制 MC9S12DG128 固体继电器 热电偶 PID控
2、制任务描述1.制作一个水温自动控制系统,控制对象为1升净水,容器为搪瓷器皿。水温可以在一定范围内由人工设定,并能在环境温度降低时实现自动控制,以保持设定的温度基本不变。定的温度基本不变。2.要求(1)温度设定范围为 4090,最小区分度为1,标定温度1。(2)环境温度降低时(例如用电风扇降温)温度控制的静态误差1。(3)用十进制数码管显示水的实际温度保留一位小数。(4)采用适当的控制方法(如数字PID),当设定温度突变(由 40提高到60)时,减小系统的调节时间和超调量。(5)温度控制的静态误差0.2。(6)从串口输出水温随时间变化的数值。一、系统设计的功能图1 系统整体框图设计 0.1.MC
3、9S12DG128单片机是本次设计的控制核心。MC9S12DG128是一个以16位中央处理器为核心的16位微控制器,128K的字节的Flash EEPROM存储器,8K字节的RAM,2K字节的EEPROM,两个异步串行通信接口(SCI),两个串行外围接口(SPI),两个8通道模拟数字转换器(ADC),1个8通道脉宽调制模块,两个兼容CAN2.0A/B协议的控制器,1个Byteflight模块和内部集成电路总线。主要完成AD转换,PID控制算法的运算,并且输出PWM波控制固态继电器。0.2.键盘模块采用4*4矩阵式键盘,大大减少了I/O端口的使用量,并且功能强大。键盘模块主要完成预设温度的输入。
4、0.3.热电阻阻测温模块。热电阻是中低温区最常用的一种温度检测器。它的主要特点是测量精度高,性能稳定。本次实验采用铂热电阻的测量,精确度高,稳定性相当好。0.4.显示模块包括数码管显示和LED显示。数码管用来显示搪瓷内水的实时温度,LED发光二极管用来指示此时加热的强度。0.5.加热模块是通过单片机输出的PWM波,控制固态继电器导通与关断,从而控制加热器的导通与关断,PWM波是通过单片机经过PID计算得出的。PID算法在温度控制系统中有着广泛的应用,并且数字PID技术的成熟,大大减少了硬件的成本,微控制器的出现大大提高了控制精度和速度。二、硬件设计原理及内容2.1热电阻测温电路。 图2中的Rt
5、为铂热电阻,R1为10k,WR1为150的绕线电位器,用来保证电桥电路中当温度为0 C时电压输出Vt为0V。电桥的供电电压Va为5V,为保证电压精度,由一只5k的电位器WR2电源电桥电压,VH电压为VH=4V,电桥a点电位和b点电位分别为:=Rt+图2 热电阻测温电路考虑电桥初始平衡条件:R2*WR1=R1*Rt,R0为初始时刻电阻。Vt=Va-Vb=*R1*R0(at+b)/(2atR0+2bR0+R0+R2)(R1+WR1);图3中所示为精密放大电路,需将此电压用精密放大器放大后才能作为或转换的输入值WR3为调零点电位器,WR4为调放大倍数的电位器。究竟要放大多少倍,我们可以做一下定量分析
6、。在0100C的范围内,热电阻的线性度很好,满足以上的公式。图3 信号放大电路2.2.矩阵键盘。图4中为矩阵式键盘的接法。H0-H3作为输出,H4-H7作为输入,通过依次给H0-H3赋高电平,分别依次轮询H4-H7引脚电平的状态,从而确定哪一个按键按下。图4 矩阵键盘 2.3.数码管显示。本次实验使用的是共阴数码管,数码管所对应的数字符号的段选已经存储在单片机中,单片机通过计算,得出每个数码管应该显示的数字,通过位选赋给每一个数码管,中间家一定的延迟时间,利用人的视觉暂留现象,可以认为所有数码管同时点亮。图5 数码管显示2.4.串口通信。MC9S12DG128模块中集成两个串口通信模块:SCI
7、1和SCI0。.本次实验中使用了SCI0模块。通过异步串口通信可以将搪瓷中水的温度实时的反应到上位机上。在上位机上可以用曲线实时的监测搪瓷里水的温度变化。图6 串行口通信2.5.PWM控制固体继电器 MC9S12DG128飞思卡尔单片机中专门集成PWM8路输出通道。通过设置PWM寄存器的值可以设置PWM的周期和占空比以及输出地方式。图7 PWM控制继电器PWM的占空比是通过单片机的PID运算得出的,通过输出宽窄不一样的脉冲,可以控制固体继电器导通与关断时间的长短,从而控制加热器加热的时间。为了使导通与关断不影响电网,使导通和关断的时间尽量是工频电压周期的整数倍。固态继电器是由微电子电路,分立电
8、子器件,电力电子功率器件组成的无触点开关。用隔离器件实现了控制端与负载端的隔离。固态继电器的输入端用微小的控制信号,达到直接驱动大电流负载。加热部分可以采用加热棒,加热棒可以为小型的容器进行加热,成本低,操作简单,易于实现。当温差大于C时时,PWM占空比最大,全速加热。当温差在C时调节PWM的脉冲宽度,进行比较精确的加热。这样可以快速准确的对搪瓷中的水进型加热。通过调节PID的P,I,D参数可以实现最优的加热时间和消除稳态误差。PID参数可以通过临界比例度法进行设置,经过多次设置可以达到最理想的状态。 三 、系统软件设计流程四、调试过程及数据4.1 串口通讯调试调试过程中,通过串口发送当前温度
9、值,当经A/D转换后温度为50度时,串口向计算机发送数据,由于开始的时候温度值储存错误,导致发送 。再经过检查后,解决了这一问题,调试成功。4.2 LED调试调试LED过程中,犯了很多小的错误,比如,书中程序为共阳数码管,而实验板上为共阴数码管,需要在程序段选处加非,端口设置要正确等问题。这个调试过程稍长,先是基本的显示1,2,3,4。4.3 A/D转换调试调试A/D过程中,在写主程序时,忽略了10位A/D输出,定义中间变量的长度出现错误,导致最高温度在数码管上只显示到65。增加定义长度后,实现了0到100的温度调整。4.4 键盘调试键盘调试过程中,采用中断方式,耗费了大量时间,最后一次终于成
10、功,只是由于中断后发送键盘值到串口,导致数码管显示会产生中断,这是一个没有解决的地方。4.5 定时器调试在定时器调试过程中,最开始忽略了计数寄存器不能写数的错误,像里面写数,但是一直不好使,最后在书中发现了这句话,采用了1分频后,定时时间为8MS,然后利用标志实现各个模快所需要的时间。五、实验结果与心得刚开始看到实验题目与要求时,感觉这个设计对于目前自己的水平,好像是很难,心里有点没底,在接下来的几次实验中,虽然没有做出全部模块,但是也收获了许多。对于串行收发模块,A/D转换,数码管显示,键盘模块,定时模块都已经按要求完成。,老师也讲解了一些编写程序的规范,及编写程序中容易犯的一些常见的错误,
11、同时在调试过程中,学会了许多调试的方法,及了解了自己的不足之处,为自己以后的工作,学习,打下了一定的基础,遗憾的是没有完成题目的全部要求,以后会努力的,感觉这些才是这次课程设计最大的收获。六、参考资料嵌入式体统使用HCS12微控制器的设计与应用.王宜怀 P119 串行通信函数嵌入式体统使用HCS12微控制器的设计与应用.王宜怀 P134 键盘处理函数嵌入式体统使用HCS12微控制器的设计与应用.王宜怀 P141 数码显示函数嵌入式体统使用HCS12微控制器的设计与应用.王宜怀 P202 AD转换函数嵌入式体统使用HCS12微控制器的设计与应用.王宜怀 P224 定时器编程基础七、附录实验程序:
12、/1.包含通用头文件#include isr.h /中断处理函数头文件/2.包含面向硬件对象头文件#include SCI.h /串行通信头文件#include LED.h /LED驱动#include KB.h /键盘扫描识别头文件#include Timer.h #include PWM.h #include ADC.h #include Type.h /3. 定义全局变量/3.1. LED显示缓冲区INT8U LEDbuf4;/3.2. SCI接收缓冲区INT8U ReBuf4;/3.3. 正确接收标志位(0:接收并成功接收;1:没有接收或接收失败)INT8U SerialBuff1;
13、/存放接收数据的数组INT8U KB_DefValue4; /存放键盘数INT8U Flag_seg=0; /数码管扫描标志位INT8U Flag_send=0; /串口发送标志位INT8U Flag_ad=0;/A/D转换标志位INT8U Flag_key=0,q,j=0;INT8U ge,shi,bai,xiao,qian;/数码管各位INT32U ad=0; #pragma LINK_INFO DERIVATIVE mc9s12dj128b/SCI.h串行通信头文件-/串行通信需要用到的头文件#include /MCU映像寄存器名#include Type.h /类型别名定义/串行通信寄
14、存器及标志位定义#define ReSendStatusR SCI0SR1 /SCI状态寄存器#define ReTestBit 5 /接收缓冲区满标志位#define SendTestBit 7 /发送缓冲区空标志位#define ReSendDataR SCI0DRL /数据寄存器/串行通信相关函数声明void SCIInit(void); /串行口初始化函数声明void SCISend1(INT8U o); /串行发送1个字节void SCISendN(INT8U n,INT8U ch); /串行发送n个字节INT8U SCIRe1(INT8U *p); /串行接收1个字节INT8U S
15、CIReN(INT8U n,INT8U ch); /串行接收n个字节#include SCI.h /串行通信头文件void SCIInit(void) INT8U t; /定义波特率Bt=9600,SCI0BD=fBUS/(16*Bt) SCI0BDL = 0x80; /须先给低8位赋值 SCI0BDH = 0x00; /再给高8位赋值 SCI0CR1 = 0x00; /设置允许SCI,正常码输出,8位数据,无校验 t = SCI0DRL; /读数据寄存器(清0) t = SCI0SR1; /读状态寄存器(清0) SCI0CR2 = 0x0C; /允许SCI0接收和发送 查询方式/SCISen
16、d1:串行发送1个字节-*/功 能:串行发送1个字节 */参 数:o=要发送的数据 */返 回:无 /调试时间:2011-6-1/作 者:苏显龙 */-*void SCISend1(INT8U o) /判断ReStatusR的第SendTestBit位是否为1,是1可以发送 while (1) if (ReSendStatusR & (1SendTestBit) != 0) ReSendDataR = o; break; /SCISendN:串行发送N个字节-*/功 能:发送数组中的N个字节数据 */参 数:n=待发送的数据字节数,ch=存放待发送数据的数组首地址 */返 回:无 */内部调用
17、函数:SCISend1 /调试时间:2011-6-1/作 者:苏显龙 */-*void SCISendN(INT8U n,INT8U ch) INT8U i; for (i=0; in; i+) SCISend1(chi);/SCIRe1:串行收一个字节数据-*/功 能:从串行口接收1个字节的数据 */参 数:p=标志指针 */返 回:接收到的数据(若接收失败,返回0xff) */说 明:参数*p带回接收标志=0收到数据,=1未收到数据 /调试时间:2011-6-1/作 者:苏显龙 */-*INT8U SCIRe1(INT8U *p) INT16U k; INT8U i; /ReStatusR
18、第ReTestBit位为1表示可接收数据 for (k=0; k0xfbbb; k+) if (ReSendStatusR & (1= 0xfbbb) i=0xff; *p=0x01; return i; /返回接收到的数据/SCIReN:HC08串行接收N个字节-*/功 能:接收N个字节数据,并存放在ch数组中 */参 数:n=待接收的数据字节数,ch=存放待接收数据的数组首地址 */返 回:接收标志=0收到数据,=1未收到数据 */内部调用函数:SCIRe1 /调试时间:2011-6-1/作 者:苏显龙 */-*INT8U SCIReN(INT8U n,INT8U ch) INT8U m;
19、 INT8U fp; m = 0; /接收n个数据 while (mn) chm = SCIRe1(&fp); if (fp = 1) return 1; /只要有1个字节数据没接收到就返回报错 m+; return 0;/KB.h键盘扫描识别头文件-/说明:本文件与具体的芯片型号有关/键盘扫描识别需要用到的头文件#include /MCU映像寄存器名#include Type.h /类型别名定/键盘扫描识别寄存器及标志位定义#define KB_P PTH /键盘接在PTH口上#define KB_D DDRH /相应的方向寄存器#define KB_PE PERH /相应的上拉下拉电阻允许
20、寄存器#define KB_PS PPSH /相应的极性选择寄存器#define KB_IE PIEH /相应的中断允许寄存器#define KB_IF PIFH /相应的中断标志寄存器/键盘扫描识别函数声明void KB_Init(void); /键盘初始化INT8U KB_Scan1(void); /扫描读取键值INT8U KB_Def(INT8U KB_valve); /键值转为定义值INT8U KB_ScanN(INT8U KB_count); /多次扫描键盘/KB.c键盘扫描识别-*/本文件包含: */ (1)KB_Init:键盘初始化 */ (2)KB_Scan1:单次扫描读取键值
21、 */ (3)KB_Def:键值转为定义值 */ (4)KB_ScanN:多次扫描键盘消除抖动问题 */-*/头文件#include KB.h /键盘扫描识别头文件/KB_Init:键盘初始化函数-*/功 能:初始化键盘中断的引脚,但未开放键盘中断 */参 数:无 */返 回:无 /调试时间:2011-6-1/作 者:苏显龙 */-*void KB_Init(void) KB_P = 0x00; /复位KB_P KB_D = 0x0F; /定义7-4为输入,3-0为输出 KB_PE = 0xF0; /定义KB_P.7-4允许上拉或下拉 KB_PS = 0x00; /定义KB_P.7-4上拉电阻
22、,并且下降沿产生中断 KB_IE = 0x00; /定义KB_P.7-4输入引脚禁止中断 KB_IF = 0xFF; /清除键盘中断标志位(写1清)/KB_Scan1:扫描读取键值函数-*/功 能:扫描一次4*4键盘上的按键,读取键值-*p;若无按键,*p为0xff */参 数:无 */返 回:扫描到的键值 /调试时间:2011-6-1/作 者:苏显龙 */-*INT8U KB_Scan1(void) INT8U line,i,tmp; line=0xFE; /使第一根行线为0(低电平) for (i = 1; i = 4; i+) /最多将扫描4根行线 /当前扫描的一行,输出低电平 tmp
23、= KB_P; tmp |= 0X0F; KB_P = tmp & line; asm(NOP); asm(NOP); /读取键盘口数据寄存器 tmp = KB_P; /通过观察4根列线中是否出现低电平来判断当前行有无按键 tmp &= 0XF0; /仅保留列线的值 if (tmp != 0xF0) /当前行有键按下 tmp=KB_P; /读取扫描到的键值 break; /退出循环不再扫描 else /当前行无按键,准备扫描下一行 line = (line 1) | 0x01; if (i = 5) /无按键,以后将返回0xff tmp = 0xFF; return (tmp);/KB_Sca
24、nN:多次扫描键盘函数-*/功 能:多次扫描键盘,消除抖动 */参 数:KB_count=多次扫描键盘的的次数 */返 回:多次扫描键盘得到的键值: */ 正常按键-KB_value_now; 非正常按键(包括无按键)-0xFF */内部调用函数:KB_Scan1 /调试时间:2011-6-1/作 者:苏显龙 */-*INT8U KB_ScanN(INT8U KB_count) INT8U i,KB_value_last,KB_value_now; if (0 = KB_count | 1 = KB_count) return KB_Scan1(); /先扫描一次得到的键值,便于下面比较 KB
25、_value_now = KB_value_last = KB_Scan1(); /以下多次扫描消除误差 for (i=0; iKB_count-1; i+) KB_value_now = KB_Scan1(); if (KB_value_now = KB_value_last) return KB_value_now; /返回扫描的键值 else KB_value_last = KB_value_now; return 0xFF; /返回出错标志/KB_Def:键值转为定义值函数-*/功 能:键值转为定义值 */参 数:KB_valve=键值 */返 回:KeyPress=键定义值 /调试时
26、间:2011-6-1/作 者:苏显龙 */-*/键盘定义表const INT8U KB_Table= 0xEE,1,0xDE,2,0xBE,3,0x7E,A, 0xED,4,0xDD,5,0xBD,6,0x7D,B, 0xEB,7,0xDB,8,0xBB,9,0x7B,C, 0xE7,*,0xD7,0,0xB7,#,0x77,D, 0x00; INT8U KB_Def(INT8U KB_valve) INT8U KeyPress; INT8U i; INT8U j; i = 0; while (1) j = KB_Tablei; /与0(定义表结束标志)相比较 if (j = 0) /=0,即
27、表中无次定义值 KeyPress = 0xFF; /返回0xFF break; else /与键值相比较 if(j = KB_valve) /找到 KeyPress = KB_Tablei+1; /取键定义值 break; else i += 2; /指向下一个键值,继续判断 return KeyPress; /返回键定义值/LED.hLED驱动头文件-*/说明:本文件与具体的硬件连线方式和芯片型号有关 */-*/头文件#include /MCU映像寄存器名#include Type.h /类型别名定义/LED驱动相关寄存器宏定义#define LEDdata PORTB /LED数据口#de
28、fine LEDdata_D DDRB /数据口相应方向寄存器#define LEDcs PTH /LED位选口 #define LEDcs_D DDRH /位选口相应方向寄存器/外部函数声明void LEDInit(void); /4连排LED初始化void LEDShow(INT8U *Buf); /在4连排LED上显示4个十进制数/内部函数声明void LEDShow1(INT8U i, INT8U c); /在1个LED上显示数字/LED.cLED驱动-*/本文件包含: */ (1)LEDInit:4连排LED初始化 */ (2)LEDShow:在4连排LED上显示4个十进制数 */ (3)LEDShow1:在1个LED上显示数字 */硬件连接: */ (1)PTB 7-0 分别接LED的数据线 h g f e d c b a */ (2)PTH 7-4 分别接各LED的位选线(自右到左) /调试时间:2011-6-1/作 者:苏显龙 */-*#include LED.h /该头文件包含LED驱动相关寄存器宏定义/LED