MC9S12DG128水温控制系统设计Word下载.docx
- 文档编号:17080313
- 上传时间:2022-11-28
- 格式:DOCX
- 页数:32
- 大小:273.12KB
MC9S12DG128水温控制系统设计Word下载.docx
《MC9S12DG128水温控制系统设计Word下载.docx》由会员分享,可在线阅读,更多相关《MC9S12DG128水温控制系统设计Word下载.docx(32页珍藏版)》请在冰豆网上搜索。
键盘模块
下图为键盘原理图
图3键盘原理图
此键盘为4*4的16键盘,其中0-9为数字键,A-F为功能键,其中A用来设定温度值,C用来设定P参数,D用来设定I参数,E用来设定D参数。
试验中采用扫描法获取键值,通过多次扫描来消除抖动产生的影响。
LED模块
图4LED原理图
8个led灯接在单片机PORTB口,它用来模拟加热强度,将DA输出平均分为8段,处于第一段时最低位灯亮处于第二段时,最低位两个小灯亮,处于第8段时所有小灯都亮。
其中向PTB端口对应位写低电平,对应的位的LED就点亮。
SCI通信模块:
图5SCI通信模块
其中MAX232为电平转换芯片。
只起到电平转换的作用,它将TTL电平和RS-232电平相互转换。
单片机发送过程时候,它将单片机发送的TTL电平转换为RS-232电平,通过串口连接到PC机。
单片机接受过程时候,串口过来的数据经过它转换为TTL电平,并送到单片机内部。
数码管显示模块:
图6数码管显示模块
由于每段灯亮需要大概10mA电流,当数码管每个段都点亮时候需要大概80mA电流,单片机单个引脚无法驱动如此大的电流,则通过加入三极管放大,用单片机控制三极管的导通,从而点亮数码管。
实际电路加热模块及采集模块:
1、通过PWM的占空比来控制过零SSR的导通时间。
其中T包含多个正弦波周期,为PWM周期,然后通过控制PWM的占空比来控制对应的导通正弦波数,即控制最后的加热持续时间。
图7过零固态继电器交流
交流过零型固态继电器,因有其电压过零时开启,负载电流过零时关断的特性。
它的最大接通、关断时间是半个电源周期,在负载上可得到一个完整的正弦波形。
也相应的减少了对负载的冲击。
而在相应的控制回路中产生的射频干扰也大大减少。
2、另一种可以通过将PWM的波形利用电容给平均化,变成比较平直的电压,通过这个电压来控制电阻丝的加热强度。
此系统设计就是利用此来实现的。
通过热电阻桥式电路,将温度信号的转换为电压信号,再经过信号调理电路输出0-5v的电压信号。
其中Pt100,测温范围为-200-850摄氏度
图8温度检测及信号调理电路
试验中,此处通过PWM的不同占空比波形,经过电容平均电压,再经放大。
图9PWM模块
然后将输出的不同电压值送给DG128的AD0通道中。
3、系统软件设计流程
1、主程序流程图
图9主程序流程图
2、系统控制框图
主程序中初始化后,通过键盘设定参数,然后系统根据这些参数执行,达到预期的闭环控制。
从而使最终的温度值保持在设定值附近。
其中需要设定的参数有温度以及PID的三个参数。
图10水温控制系统控制框图
3、部分模块函数的原理
其中数码管、AD转换、定时发送采用中断方式。
利用定时器设定一段时间,通过静态变量值计数,每来一次中断循环亮一个数码管,由于采用中断方式,与系统同时运行,不会导致数码管亮度不均。
通过计数时间到一定时间,给采样函数标记位写数,通过标记位执行相应的程序。
同样利用定时的时间到达标记相应的发送标记变量,从而执行相应的SCI发送命令。
4、调试过程及数据
在开始做这个设计的时候,先是把系统的每一部分都分成不同模块,每一个模块先单独作为一个工程建立,每一个模块调试成功之后才将各部分组合在一起,最终调试成为一个系统的。
系统的模块分为:
SCI串行口输入输出模块、LED数码管显示模块、KB键盘输入模块,AD转换输入模块,PWM模块。
模块的调试过程:
1.SCI串行口调试使用方法:
先将SCI的初始化,让接受程序,发送程序编译通过,然后在SCI的调试主程序中通过输入字符,并让其在电脑自带的超级终端上显示,如果超级终端成功显示我们在键盘上输入的字符,则说明SCI串行口模块可以调用,如果显示不成功则需要继续对程序进行修改和编译。
在串行口这里我遇到的问题及解决办法:
a.开始设置超级终端不正确,一直选择的是硬件,改为无以后正确
b.设置正确后仍不能发送字符,最后发现时没有连接串口
c.SCI控制字写的不对,开了中断,对发送过程产生影响
2.LED数码管调试使用方法:
分析数码管的共阴或者共阳,让后将LED编程初始化,然后编译数码管的段选函数,位选函数。
在数码管的测试主函数中编程保证数码管能够显示我们输入的静态数字。
比如我们在主函数中,让数码管显示“0123”,4位数码能够正常显示0123,则说明数码管模块中的函数可以被调用,否则需要继续对程序进行修改和编译。
在数码管这里我遇到的问题是:
a、数码管不显示。
原因及解决办法:
编写程序时候一直以为是共阴数码管,后来在同学的指导下才知道是共阳数码管。
后来在老师的指导下,发现本次实验用的数码管管脚和课本不一致,在修改管脚连线后,数码管才正常显示数字。
b.数码管亮度不均匀。
数码管亮度不均是因为在主程序的执行过程中,数码管循环点亮中间插入了其他程序,导致每个灯延时时间不同。
3.KB键盘输入模块
在理解了4*4矩阵键盘的编程原理后,自己结合课本成功编译通过键盘程序。
并联合之前做的数码管模块和串行口通讯模块,达到了让矩阵键盘按键,数码管显示数字,同时通过超级终端在电脑上显示矩阵键盘按键的数字。
在键盘这里我遇到的问题是:
a、开始写的是翻转键盘法,调试程序的时候,通过单步运行发现,每次按键获取的键值与理论的相差很远,要么是高四位全是1即检测不到按键按下,或者是获得的键码有多个0,理论是高四位一个0,第四位一个0。
而且只有三个键能用。
换了个键盘发现就能获得相应键值。
b、键盘输入PID参数值时候,用C、D、E分别完成P、I、D三个参数的输入,但是实际输入时候总是乱码,并且没法保存所设置的参数值,而且将exmple中的键值功能换为C、D时候,竟然也没法用。
解决办法:
通过将A、B键改为C、D时候发现没法设置,并换其他键盘时候也不能用,最后发现只有最后一行没法用。
将功能键用数字键替代时候就能完成设置。
通过对整体函数的查询,发现是PWM3通道和Y4公用一个引脚,将PWM初始化关掉,测试结果正确。
4.AD转换输入模块
在编译通过AD转换程序后,联系数码管显示模块,用一个可变电阻(电位器)的检测采样,用单片机的AD转换通道AN06输入采样信号,将其转化为0~100可变数字,用以模拟温度0~100度的变化,并在数码管上显示。
5、实验结果与心得
实验的最终结果:
达到了老师要求的键盘输入数码管及时显示,用PWM输出电压平均值大小模拟温度变化,数码管及时显示0到100的变化,并且数码管的最后一位为小数部分。
通过键盘A设定给定温度,C设置P参数,D设置I参数,E设置D参数,B完成整体的确定功能。
通过设定合适的PID参数后,用超级终端监控实时温度变化值和预期温度满足闭环系统的控制。
并用LED灯模拟不同的加温强度。
实验不足:
在PID算法上参照了example中的算法,PID只能设置整数值,并没有加入浮点运算。
实验心得:
通过本次的设计性实验,对嵌入式整个开发过程有所了解,同时也了解到编程调试程序的艰辛。
在系统设计之前自己完成了老师所给的最小系统原理图、串口发送的编写。
虽然程序逻辑没有错误但是在时间运行中还是出了很多错误,和自己理想差的很远,再一次明白了只有实践才能检验理论的正确性。
在整个过程中要学会有全局思维,将系统功能模块化,并将每个模块单独调试,为以后从事系统开发打下了一定的基础。
在单独调试模块时候,单独的功能都能实现,但是整体化后就出现了众多问题,例如开始用的反转法键盘最后也没有加进整体程序中,而是用的课本上的循环扫描键盘方式。
并且对自己的编程习惯有了一定的提升,要有良好的编程习惯,方便其他人读取。
进一步熟悉了模块化编程。
整个功能的模块化就为我们团队合作打了一定基础,此次实验中将和同学商量较多,在共同商讨与试验中解决了不少问题,并对水温系统不断的进行了完善。
这次实验,自己也深刻的感受到了自己在嵌入式系统设计和编程上的不足,对MC9S12DG128芯片的管脚和寄存器没有足够的了解,对单片机的各个功能仅限于皮毛,而且试验中很大部分都是参照别人的。
总之,在有限的时间内收获颇丰。
6、参考资料
学出实验过程中用到的参考资料,要求写出参考资料的来源,页码和参考内容
如
嵌入式系统——使用HCS12微控制器的设计与应用.王宜怀P119串行口处理函数
嵌入式系统——使用HCS12微控制器的设计与应用.王宜怀P134键盘处理函数
嵌入式系统——使用HCS12微控制器的设计与应用.王宜怀P140LED数码管函数
嵌入式系统——使用HCS12微控制器的设计与应用.王宜怀P202A/D转换函数
7、附录
实验程序
要求:
程序要求写出注释
程序按照如图顺序给出
#include<
hidef.h>
/*commondefinesandmacros*/
mc9s12dg128.h>
/*derivativeinformation*/
#pragmaLINK_INFODERIVATIVE"
mc9s12dg128b"
#defineINT8Uunsignedchar
#defineINT16Uunsignedint//dingyi
INT8UFlag_ADC;
//ad
INT16UAD_wData;
INT16UTemperature_Set,P_Set,I_Set,D_Set;
//温度设定值
INT8UFlag_Send,Flag_ADC;
//标志位
INT16UNUM;
INT8ULEDbuf[4]={'
0'
'
};
//数码管显示数组
constINT8UDtable[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
//led
constINT8UCStable[4]={0xf7,0xfb,0xfd,0xfe};
constINT8UKB_Table[33]=
{
0xee,'
1'
0xde,'
2'
0xbe,'
3'
0x7e,'
4'
0xed,'
5'
0xdd,'
6'
0xbd,'
7'
0x7d,'
8'
0xeb,'
9'
0xdb,'
0xbb,'
A'
0x7b,'
B'
0xe7,'
C'
0xd7,'
D'
0xb7,'
E'
0x77,'
F'
0x00
#defineKB_PPTP//jianpan
#defineKB_DDDRP
#defineKB_PEPERP
#defineKB_PSPPSP
#defineKB_IEPIEP
#defineKB_IFPIFP
#defineSCFBit7
#definekp100
#defineki1
#definekd100
#defineEnableSCIReIntSCI0CR2|=0x20
#defineDisableSCIReIntSCI0CR2&
=0xdf
#defineLEDdataPORTA
#defineLEDdata_DDDRA
#defineLEDcsPTT
#defineLEDcs_DDDRT
#defineReSendStatusRSCI0SR1//sci状态寄存器
#defineReTestBit5//接收缓冲区满标志位
#defineSendTestBit7//发送缓冲区满标志位
#defineReSendDataRSCI0DRL//数据寄存器
/*串口初始化函数
入口参数:
无
出口参数:
调用函数:
功能:
开SCI0,关SCI1,关串口中断,对串口初始化,默认为允许SCI,正常码输出
调试时间:
2012-6-6
作者:
孙文义
*/
voidSCIInit(void){
INT8Ut;
SCI0BD=0x0034;
SCI0CR1=0x00;
t=SCI0DRL;
t=SCI0DRH;
SCI0CR2=0x0c;
}
/*发送一个字节函数
串行发送一个字节
voidSCISend1(INT8Uo){
while
(1){
if((ReSendStatusR&
(1<
<
SendTestBit))!
=0){
ReSendDataR=o;
break;
}
}
待发送的字节数,存放待发送数据的地址
SCISend1
发送多个字节
voidSCISendN(INT8Un,INT8Uch[]){
INT8Ui;
for(i=0;
i<
n;
i++){
SCISend1(ch[i]);
/*接收一个字节函数
存放地址
接收到的数据(若接受失败。
返回0xff)
接收一个字节数据
INT8USCIRe1(INT8U*p){
INT16Uk;
for(k=0;
k<
0xfbbb;
k++){
i=ReSendDataR;
*p=0x00;
if(k>
=0xfbbb){
i=0xff;
*p=0x01;
returni;
/*串口接受多个字节函数
字节数及存放地址
SCIRe1(&
fp)
接收多个字节
INT8USCIReN(INT8Un,INT8Uch[]){
INT8Um;
INT8Ufp;
m=0;
while(m<
n){
ch[m]=SCIRe1(&
fp);
if(fp==1){
return1;
m++;
return0;
/*串口发送PC函数
SCISend1()
发送温度值
voidSendToSCI(void){
INT8Utemp[4],i;
if(Flag_Send==0xff){
if(LEDbuf[3]=='
+1){
temp[3]='
'
;
}else{
temp[3]=LEDbuf[3];
if(LEDbuf[2]=='
temp[2]='
temp[2]=LEDbuf[2];
temp[1]=LEDbuf[1];
temp[0]=LEDbuf[0];
SCISend1(temp[3]);
SCISend1(temp[2]);
SCISend1(temp[1]);
SCISend1('
.'
);
SCISend1(temp[0]);
Flag_Send=0;
/*数码管初始化函数
设置相应端口为输出
voidLEDInit(void){//
LEDdata_D=0xff;
LEDcs_D|=0x0f;
voidLEDShow1(INT8Ui,INT8Uc){
LEDcs=CStable[i];
if(i==2){
LEDdata=(~Dtable[c])&
0x7f;
LEDdata=~Dtable[c];
/*单个数码管显示函数
显示数据及第几个
LEDShow1(INT8Ui,INT8Uc)
显示第几个数码管
voidLEDShow(INT8U*Buf,INT8Ui){
INT8Uc;
//INT16Uj;
i<
=3;
i++){
c=Buf[i]-'
LEDShow1(3-i,c);
//for(j=0;
j<
=100;
j++){
//_FEED_COP();
//}
/*PWM初始化函数
设置PWM工作方式及占空比时钟源对其方式分频对齐方式极性
voidPwm_Init(void)//
PWME_PWME0=0;
PWMPRCLK=0X22;
//clockA=总线时钟/4
PWMSCLA=1;
//clockSA=clockA/(2*PWMSCLA)
PWMSCLB=1;
PWMCLK=0X04;
//通道0选用clockSA为时钟源
PWMPOL=0X04;
//通道0首先输出高电平
PWMCAE=0X00;
//输出左对齐
PWMCTL=0X00;
//非级联模式
PWMDTY0=255;
PWMPER0=255;
//通道0的周期寄存器
PWME_PWME0=1;
/*AD初始化函数
设置AD控制寄存器
voidAD_Init(void){//ad
ATD0TEST1=0b00000000;
//禁止特殊通道
ATD0CTL2=0b11000010;
//快速清除模式,完成中断允许
ATD0CTL3=0b00001000;
//队列长度为1
ATD0CTL4=0b01000011;
//ATDclock=1M
ATD0CTL5=0b10100110;
/*AD转换完成中断函数
利用中断将数据存入
__interrupt22Int_AD0(void){
AD_wData=ATD0DR0;
//ReadouttheResultRegister
//PORTB=ATD0DR6L;
/*数字PID函数
result反馈量
tmp偏差
实现比例积分微分的控制
bytePID(dwordresult){
staticsignedintek1,Pik1;
signedintek,Ppk,Pik,Pdk,Pk;
unsignedchartmp;
ek=(result-Temperature_Set);
Ppk=kp*ek;
Pik=ki*ek+Pik1;
Pdk=kd*(ek-ek1);
Pk=Ppk+Pik+Pdk;
ek1=ek;
Pik1=Pik;
if(Pk>
0){
25500){
tmp=255;
tmp=(byte)(Pk/100);
returntmp;
tmp=0;
/*采样控制函数
PID(result)
将要传送的数据转换到数组中,并控制PWM的占空比
voidSample(void){
bytege,shi,bai,point;
dwordresult;
if(Flag_ADC==0xff){
result=(dword)(AD_wData)*1000/1023;
bai=(byte)(result/1000+'
shi=(byte)((result%1000)/100+'
ge=(byte)((result%100)/10+'
point=(byte)(result%10+'
if(bai=='
){
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MC9S12DG128 水温 控制系统 设计