题目温度采集分析系统设计学生姓名学号专业电子信息工程指导教师时间 2018.1.1摘要:本课题设计基于TMS320F28335型号DSP的高速度、宽范围、高精度的温度采集系统方案。
系统以TMS320F28335为控制核心,通过测温电路采集温度数据,经AD转换后给DSP 控制器,通过FIR滤波器计算出温度值,DSP通过RS232接口上传温度值到电脑上位机显示温度,通过LCD12864显示温度及时间,重点介绍AD转换接口电路以及系统控制软件的设计过程。
一、功能设计要求设计一个电池供电野外温度采集分析系统,功能包括:1.每小时采集环境温度10次,进行FIR滤波2.每天通过串口发送单天平均气温3.有三个按键:K1切换温度/时间显示。
K2、K3修改时间,K2=time+,K3=time-4.当电池电压低于安全值时,发送报警信息二、硬件设计1.系统方案:该系统包括温度采集电路模块、TMS320F28335芯片、A/D转换部分和LCD液晶显示,首先要初始化A/D转换模块,然后等待中断,当产生中断后对采集到的模拟信号进行处理,并通过低频率的FIR滤波后得到一天的温度输出,为确保转换精度要进行多次取值求平均,转换结果放在结果寄存器的高12位上,通过编程将处理后的温度值送到LCD上进行显示。
设计采用热敏电阻PT100组成的温度采集电路,利用热敏电阻输出电压值与温度间的函数关系式,检测温度的变化;然后将采集的温度送入TMS320F28335的片上A/D,将电压转换为数字信号,并通过低频率的FIR滤波后得到一天的温度输出;最后通过LCD12864显示结果。
图1 系统方案2.主控方案:TMS320F28335主控芯片控制芯片32位TMS320F28335芯片,该DSP芯片专门用于控制领域,最高可在150 MHz主频下工作,可进行双16 ×16乘加和32 ×32乘加操作,运算与控制速度快,并带有18 K×16位片上SRAM和128 K×16位片上FLASH;并带有两个事件管理模块,可以同时产生多路PWM信号; 16路12位片上ADC,可以同时进行16路转换。
另外,该器件还有3个独立的32位CPU定时器以及多达56个独立编程的GP I O引脚和19根外部扩展地址总线。
TMS320F28335采用哈佛总线结构,具有密码保护机制,保护程序和数据不被盗取。
因此,该芯片片上资源丰富,功能多、性价比高,利于简化软硬件设计,非常适用于温度采集与显示系统化的设计。
在设计的初期,把它分成了五个模块。
其中复位采用电源复位的方式,由引脚PCRESET引起。
为了可靠复位,其中低电平的有效时间至少6个CPU时钟周期。
3.电源模块:采用TPS731HD301电源芯片。
TPS73系列电源芯片为线性稳压芯片,输入电压5V,输出电压有两组,一组为3.3V,另一组随芯片型号不同而不同。
在该采用电路中,输出电压为3.3V和1.6V。
TPS731HD301芯片为模数转换提供基准电压,且输入端接+5V电源后再并联一个去噪声的电容,利用热敏电阻进行温度采集,采集后的输出电压(不得大于3.3v)与DSP的P2端口23引脚相连。
4.A/D转换:当模/数转换完成后,读取结果寄存器前,最好先读取模/数转换控制寄存器ADCRL2的ADCFIF01或ADCFIF02,以确定当前结果寄存器的状态,保证读取的结果是正确。
另外,要注意12位的转换结果放在结果寄存器中的高12位上,该12位数据与外部模拟输入电压的关系为:12位数字结果=4095*(输入电压/基准电压)数模转换部分采TMS320F28335内部的PWM功能结合外部滤波电路完成转换。
TMS320F28335将内部计算的控制信号转换成占空比可变PWM信号输出,为保证TMS320F28335不受后级返回来的信号干扰,故经光电隔离,送入RC组成的滤波网络变换成平滑电压信号再送往后级信号转换电路,将信号转换成4~20 mA标准信号输出。
5.温度采集电路:当模/数转换完成后,读取结果寄存器前,最好先读取模/数转换控制寄存器ADCRL2的ADCFIF01或ADCFIF02,以确定当前结果寄存器的状态,保证读取的结果是正确。
另外,要注意12位的转换结果放在结果寄存器中的高12位上,该12位数据与外部模拟输入电压的关系为:12位数字结果=4095*(输入电压/基准电压)数模转换部分采用TMS320F28335内部的PWM功能结合外部滤波电路完成转换,电路如图5所示。
TMS320F28335将内部计算的控制信号转换成占空比可变PWM信号输出,为保证TMS320F28335不受后级返回来的信号干扰,故经光电隔离,送入RC组成的滤波网络变换成平滑电压信号再送往后级信号转换电路,将信号转换成4~20 mA标准信号输出。
6.显示模块:此系统中显示器采用液晶显示方式,一款基于LCD12864控制器的图形液晶显示模块。
LCD12864内含7602个简体中文字型。
LCD12864有较强功能的I/0 缓冲器,可以随时准备接收TMS320F28335 的访问,并可在内部时序下及时地把TMS320F28335发来的指令和数据传输到位。
TMS320F28335与LCD12864的连接方式如图4示, LCD12864芯片的XA13: 18 及XZCS0 /1 经过译码确定LCM3202401 的片选信号, 其地址范围为0x003A00 ~0x003AFF,数据端口地址为: 0x002A00,命令端口地址为:0x002A01,这些地址映射被到TMS320F28335的外部区域0中,1D I R与读信号线连接用于控制数据的传输方向,通过调节电位器可以调整液晶的显示对比度。
7.按键电路:设计中还有3个按键,并通过这几个按键经外部中断将处理器唤醒,进行显示等任务,其他时间为节省功耗,处理器进入休眠状态。
8.电池选取:考虑到电池的充放电的便捷性与成熟性以及电池所需容量应该较大等因素,决定选择锂电池作为供电电池,工作电压3.7v-4.2v。
处理器功耗约0.18w,显示屏功耗0.06w,加上其他外部器件,工作时功耗按0.4w计,电流约0.4/3.7=108.11mA。
每天工作时长约1h,按30天计,所需容量需108.11*1*30=3243.2mA。
在考虑上冗余设计,最终选取电池容量为5000mA.三、软件设计1.设计思路:为满足低功耗的设计要求,处理器在上电进行了一系列初始化工作后便进入休眠状态。
同时定时器中断每隔6分钟将处理器唤醒进行温度采集任务,若外部有相应的按键中断发生,也进入相应的外部中断服务。
该程序主要包括主程序、延时、A/D转换,液晶屏相应汉字显示、温度计算与显示等子程序实现温度采集与显示的功能M1403芯片作为模数转换提供基准电压,利用热敏电阻进行采集,采集后的输出电压与DSP的P2口23引脚相连。
将采集到的电压送入A/D转换模块,编写程序实现A/D转换,转换结果放在结果寄存器的高12位上,编写函数获取A/D转换结果,将处理的温度值的各个对应显示到LCD上。
2. 2.程序流程图:MC1403 芯片Vin 端输入一个+5V的模拟电压值;在输入端接一个电容滤除其它频率分量;在Vout 端输出了一个稳定的电压值;GND端直接接模拟地;给试验箱供电,打开Setup CCS2(‘C2000), 在弹出的对话框中选择ICETEK-5100 USB Emulator for TMS320F28335 导入,进行配置设置然后进入CCS2(‘C2000),打开工程文件进行编译生成.out 文件下载到硬盘中然后调试,观察液晶显示屏,第一行显示“温度显示”,第二行显示“温度值℃”,当用手触摸时,温度显示不断变化,实现了温度的采集与现实。
四、总结此次的课程设计我做的设计是—温度采集与显示,在此次设计过程中我遇到的第一个比较难的问题就是编程序,因为之前没学的好,很多指令都不熟悉,通过几天的努力,从网上下载的资料和同学的帮助下还是完成了,设计的一开始我就着手准备设计资料,上网、图书馆查阅资料,我安排明确,因此工作进行得有条不紊。
在这次课程设计硬件设计我采用的是TMS320F28335芯片作为控制芯片,虽然老师在上实验课的时候已经简单的介绍过该芯片的特性与使用,但是在用它就出现了很多问题,在这里我遇到了很大的困难,虽然有书籍和网络上查找的辅导资料,但是由于硬件设计是灵活的东西,它不仅需要有过硬的理论知识,还必须有灵活的应用,因此在这方面的调试时花费了大量的时间。
首先,我们把系统想的过于简单,以为只是把每个模块的电路设计成功便可以,却忽视了模块与模块之间的相关性和衔接性,因此总出现错误。
其次,与组员沟通不够,硬件设计的参数与组员编程所用的不相符,导致出现硬件测试没问题,软件调试没问题,两者导入,就不行的状况,更由于各执己见坚持自己是对的一直没有发现问题所在,最后通过请教老师才得以解决。
附录:原理图:主程序:#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File#include "DSP2833x_Examples.h" // DSP2833x Examples Include File// Prototype statements for functions found within this file.interrupt void adc_isr(void);// Global variables used in this example:#define LCDDELAY 1#define LCDCMDTURNON 0x3f#define LCDCMDTURNOFF 0x3e#define LCDCMDSTARTLINE 0xc0#define LCDCMDPAGE 0xb8#define LCDCMDVERADDRESS 0x40#define ADC_usDELAY 8000L#define ADC_usDELAY2 20LUint16 ZhengshuT,XiaoshuT,Zhongjian1,Zhongjian2;float temp1=0;unsigned char lcdkey[5][32];unsigned char ledkey[12][8];Uint16 LoopCount;Uint16 ConversionCount;float temp;Uint16 i,j;Uint16 Voltage1[1024];Uint16 Voltage2[1024];void Delay(int nDelay);void TurnOnLCD();void LCDCLS();void LCDWrite(unsigned int x,unsigned int y,unsigned int LR,unsigned int n);void WriteNb(unsigned int x,unsigned int y,unsigned char *No,unsigned f,unsigned int LR); void Wendu(float c);void delay_loop();void delay_loop1();void error(void);//数字模块unsigned char ledkey[12][8]= //半角{{0x00,0x00,0x7C,0x82,0x82,0x82,0x7C,0x00}, //0{0x00,0x00,0x00,0x84,0xFE,0x80,0x00,0x00}, //1{0x00,0x00,0x84,0xC2,0xA2,0x92,0x8C,0x00}, //2{0x00,0x00,0x44,0x92,0x92,0x92,0x6C,0x00}, //3{0x00,0x00,0x30,0x28,0x24,0xFE,0x20,0x00}, //4{0x00,0x00,0x4E,0x92,0x92,0x92,0x62,0x00}, //5{0x00,0x00,0x7C,0x92,0x92,0x92,0x64,0x00}, //6{0x00,0x00,0x02,0xC2,0x32,0x0A,0x06,0x00}, //7{0x00,0x00,0x6C,0x92,0x92,0x92,0x6C,0x00}, //8{0x00,0x00,0x4C,0x92,0x92,0x92,0x7C,0x00}, //9{0x00,0x00,0x00,0x66,0x66,0x00,0x00,0x00}, //:{0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00}, //.};void main(void){InitSysCtrl();EALLOW;GpioMuxRegs.GPFMUX.all=0x0000; //I/O:0 特殊功能:1GpioMuxRegs.GPFDIR.all=0x000f; // outputEDIS;DINT;InitPieCtrl();IER = 0x0000; //CPU中断允许寄存器IFR = 0x0000;//CPU中断标志寄存器InitPieVectTable();EALLOW;SysCtrlRegs.HISPCP.all = 0x3; // HSPCLK = SYSCLKOUT/6给AD转换时钟提供一个6分频EDIS;EALLOW; // This is needed to write to EALLOW protected registerPieVectTable.ADCINT = &adc_isr;EDIS; // This is needed to disable write to EALLOW protected registersInitAdc(); // 初始化ADPieCtrlRegs.PIEIER1.bit.INTx6 = 1;IER |= M_INT1; // Enable CPU Interrupt 1EINT; // Enable Global interrupt INTMERTM; // Enable Global realtime interrupt DBGMLoopCount = 0;ConversionCount = 0;// Configure ADCAdcRegs.ADCMAXCONV.all = 0x0001; // Setup 2 conv's on SEQ1AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; // Setup ADCINA3 as 1st SEQ1 conv.AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; // Setup ADCINA2 as 2nd SEQ1 conv.AdcRegs.ADCTRL2.bit.EVA_SOC_SEQ1 = 1; // Enable EVASOC to start SEQ1AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS) // Configure EVA// Assumes EVA Clock is already enabled in InitSysCtrl();EvaRegs.T1CMPR = 0x0080; // Setup T1 compare valueEvaRegs.T1PR = 0x0fff; // Setup period registerEvaRegs.GPTCONA.bit.T1TOADC = 1; // Enable EVASOC in EVAEvaRegs.T1CON.all = 0x1042; // Enable timer 1 compare (up TurnOnLCD(); //打开显示LCDCLS(); //清除显示内存*(int *)0x108000=0x80; // 初始化ICETEK-CTRDelay(LCDDELAY);*(int *)0x108000=0x0;Delay(LCDDELAY);*(int *)0x108000=0x80;Delay(LCDDELAY);*(int *)0x108001=LCDCMDSTARTLINE; // 设置显示起始行Delay(LCDDELAY);*(int *)0x108002=0;Delay(LCDDELAY);for(;;){Wendu(temp);LCDWrite(2,0,0,0);LCDWrite(2,16,0,1);LCDWrite(2,32,1,2);LCDWrite(2,48,1,3);LCDWrite(6,48,1,4);//在液晶屏上显示相应的汉字及符号WriteNb(6,6,ledkey[ZhengshuT&0x000f],0,0);WriteNb(6,5,ledkey[(ZhengshuT&0x00f0)>>4],0,0);WriteNb(6,2,ledkey[XiaoshuT&0x000f],0,1);WriteNb(6,1,ledkey[(XiaoshuT&0x00f0)>>4],0,1);WriteNb(6,7,ledkey[11],0,0);//在液晶屏上显示温度值}}interrupt void adc_isr(void){Voltage1[ConversionCount] = AdcRegs.ADCRESULT0 >>4;Voltage2[ConversionCount] = AdcRegs.ADCRESULT1 >>4;if(ConversionCount == 1023){ConversionCount = 0;}else ConversionCount++;if(ConversionCount==0){ temp=0;for(i=0;i<200;i++)temp=temp+Voltage1[i];temp=temp/200.0;//求平均值temp=temp*3.0/4095.0;}// Reinitialize for next ADC sequenceAdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE return;}//延时子程序void Delay( int nDelay){int ii,jj,kk=0;for ( ii=0;ii<nDelay;ii++ ){for ( jj=0;jj<1024;jj++ ){kk++;}}}//打开显示子程序void TurnOnLCD(){*(int *)0x108001=LCDCMDTURNON;Delay(LCDDELAY);*(int *)0x108002=0;Delay(2048);*(int *)0x108001=LCDCMDSTARTLINE;Delay(LCDDELAY);*(int *)0x108002=0;Delay(LCDDELAY);}//清屏程序void LCDCLS(){int i,j;*(int *)0x108001=LCDCMDSTARTLINE;Delay(LCDDELAY);*(int *)0x108002=0;Delay(LCDDELAY);for ( i=0;i<8;i++ ){*(int *)0x108001=LCDCMDPAGE+i;Delay(LCDDELAY);*(int *)0x108002=0;Delay(LCDDELAY);*(int *)0x108001=LCDCMDVERADDRESS;Delay(LCDDELAY);*(int *)0x108002=0;Delay(LCDDELAY);for ( j=0;j<64;j++ ){*(int *)0x108003=0;Delay(LCDDELAY);*(int *)0x108002=0;Delay(LCDDELAY);}*(int *)0x108001=LCDCMDPAGE+i;Delay(LCDDELAY);*(int *)0x108002=0;Delay(LCDDELAY);*(int *)0x108001=LCDCMDVERADDRESS;Delay(LCDDELAY);*(int *)0x108002=0;Delay(LCDDELAY);for ( j=0;j<64;j++ ){*(int *)0x108004=0;Delay(LCDDELAY);*(int *)0x108002=0;Delay(LCDDELAY);}}}void LCDWrite(unsigned int x,unsigned int y,unsigned int LR,unsigned int n){unsigned char lcdkey[5][32]={{0x10,0x21,0x86,0x70,0x00,0x7E,0x4A,0x4A,0x4A,0x4A,0x4A,0x7E,0x00,0x00,0x00,0x00,0x02,0xFE,0x01,0x40,0x7F,0x41,0x41,0x7F,0x41,0x41,0x7F,0x41,0x41,0x7F,0x40,0x00},//温{0x00,0x00,0xFC,0x04,0x24,0x24,0xFC,0xA5,0xA6,0xA4,0xFC,0x24,0x24,0x24,0x04,0x00,0x80,0x60,0x1F,0x80,0x80,0x42,0x46,0x2A,0x12,0x12,0x2A,0x26,0x42,0xC0,0x40,0x00},//度{0x00,0x00,0x00,0x3E,0x2A,0xEA,0x2A,0x2A,0x2A,0xEA,0x2A,0x3E,0X00,0X00,0X00,0X00, 0x20,0x21,0x22,0x2C,0x20,0x3F,0x20,0x20,0x20,0x3F,0x28,0x24,0x23,0x20,0x20,0x00},//显{0x00,0x20,0x20,0x22,0x22,0x22,0x22,0xE2,0x22,0x22,0x22,0x22,0x22,0x20,0x20,0x00,0x10,0x08,0x04,0x03,0x00,0x40,0x80,0x7F,0x00,0x00,0x01,0x02,0x0C,0x18,0x00,0x00},//示{0x00,0x02,0x05,0xE2,0x18,0x04,0x02,0x02,0x02,0x02,0x02,0x02,0x04,0x1E,0x00,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x18,0x00,0x00},//℃};if(LR==0)int j;int k=n;*(int *)0x108001=LCDCMDPAGE+x; Delay(1);*(int *)0x108002=0;Delay(1);*(int *)0x108001=LCDCMDVERADDRESS+y; Delay(1);*(int *)0x108002=0;Delay(1);for(j=0;j<16;j++){*(int *)0x108003=lcdkey[k][j];Delay(10);*(int *)0x108002=0;Delay(10);}x++;*(int *)0x108001=LCDCMDPAGE+x;Delay(1);*(int *)0x108002=0;Delay(1);*(int *)0x108001=LCDCMDVERADDRESS+y; Delay(1);*(int *)0x108002=0;Delay(1);for(j=16;j<32;j++){*(int *)0x108003=lcdkey[k][j];Delay(100);*(int *)0x108002=0;Delay(100);}}{int j;int k=n;*(int *)0x108001=LCDCMDPAGE+x; Delay(1);*(int *)0x108002=0;Delay(1);*(int *)0x108001=LCDCMDVERADDRESS+y; Delay(1);*(int *)0x108002=0;Delay(1);for(j=0;j<16;j++){*(int *)0x108004=lcdkey[k][j];Delay(100);*(int *)0x108002=0;Delay(100);}x++;*(int *)0x108001=LCDCMDPAGE+x;Delay(1);*(int *)0x108002=0;Delay(1);*(int *)0x108001=LCDCMDVERADDRESS+y; Delay(1);*(int *)0x108002=0;Delay(1);for(j=16;j<32;j++){*(int *)0x108004=lcdkey[k][j];Delay(100);*(int *)0x108002=0;Delay(100);}}void WriteNb(unsigned int x,unsigned int y,unsigned char *No,unsigned f,unsigned int LR) {int i;y*=8;*(int *)0x108001=LCDCMDPAGE+x; // 设置操作页=1Delay(LCDDELAY);*(int *)0x108002=0;Delay(LCDDELAY);*(int *)0x108001=LCDCMDVERADDRESS+y; // 起始列=8Delay(LCDDELAY);*(int *)0x108002=0;Delay(LCDDELAY);if(LR==1)for(i=0;i<8;i++){if(f==1)*(int*)0x108004=~No[i];else*(int*)0x108004=No[i];Delay(LCDDELAY);*(int*)0x108002=0;Delay(LCDDELAY);}elsefor(i=0;i<8;i++){if(f==1)*(int*)0x108003=~No[i];else*(int*)0x108003=No[i];Delay(LCDDELAY);*(int*)0x108002=0;Delay(LCDDELAY);}}//温度计算子程序void Wendu(float c){temp1=52-30*c;ZhengshuT=(int)temp1;XiaoshuT=(int)((temp1-ZhengshuT)*100); Zhongjian1=ZhengshuT/10;Zhongjian2=ZhengshuT%10; ZhengshuT=(Zhongjian1<<4)|Zhongjian2;Zhongjian1=XiaoshuT/10;Zhongjian2=XiaoshuT%10;XiaoshuT=(Zhongjian1<<4)|Zhongjian2; }。