中国石油大学(华东)
专业综合实践报告
基于MSP430单片机的 智能仪表系统设计
学生姓名:贾梦之
学 号:07054208
专业班级:测控技术与仪器07-2班
20xx年3月
一、设计要求
以设计智能仪表为设计目的开展本次课程设计,要求先熟悉开发系统;学习MSP430F5438单片机的工作基本原理、各模块工作原理;熟悉C51编程;针对开发电路板上的资源对各个试验进一步学习验证;根据设计内容要求进行任务设计开发。
要求实际任务能达到运行的目的。
二、设计内容
在熟悉MSP430F5438单片机工作原理及内部各模块工作原理的基础上进行“芯片温度及工作电压智能监测仪表”开发,对该仪表的几点要求:
(1)采用ADC模块的内部采集通道采集芯片温度及工作电压,要求采用适当的数字滤波器进行采样数据处理,数据刷新显示周期应为2秒;
(2)采样结果转换成实际的工程参数,应按工程单位在LCD显示屏上显示,包括单位显示,要求把芯片温度和工作电压分页显示,采用按键切换或选择显示画面,应尽量做到操作清晰、界面美观;
(3)串口调试软件应该可以发送相应指令实现LCD显示内容的切换和相应数据上传,实际的芯片温度、工作电压应能通过UART接口上送至计算机相应的串口调试软件中。
三、硬件设计
(1)LCD显示部分
(2)按键部分
四、程序设计
#include <stdio.h>
#include <msp430x54x.h>
#include "lcdoperate.h"
void Init_Clk(void);
void systeminit(void);
void TA_init(void);
void Init_ADC();
void halUsbInit();
void UART_sd(char *pstr);
unsigned int tem[100]; // 转换值存取变量--温度 unsigned int vol[100]; // 转换值存取变量--电压 float temperature;
float voltage;
char show_tem[8];
char show_vol[8];
uint flagA,flagB;
/************************************************************************* ** 函数名称:main()
** 功能: 主函数
*************************************************************************/ void main()
{
systeminit(); //系统初始化
initLCDM();
TA_init();
ClearRAM(0,0,128,8); //清屏
_EINT();
while(1)
{
if(flagA)
{
if(!flagB)
{
ClearRAM(0,0,128,8);
WriteScreen(gImage1);
Display_String(2,2,"温度:");
flagB=1;
}
sprintf(show_tem,"%.1f℃",temperature);
Display_String(2,4,(uchar*)show_tem);
UART_sd("\nTemperature:");
UART_sd(show_tem);
}
else
{
if(!flagB)
{
ClearRAM(0,0,128,8);
WriteScreen(gImage2);
Display_String(2,2,"电压:");
flagB=1;
}
sprintf(show_vol,"%.2fV",voltage);
Display_String(7,2,(uchar*)show_vol);
UART_sd("\nVoltage:");
UART_sd(show_vol);
}
LPM0;
}
}
void TA_init(void)
{
TA1CTL = TASSEL__ACLK + TAIE + TACLR;
TA1CCR0 = 32768/50; TA1CTL |= MC__UP;
}
/************************************************************************* ** 函数名称:TA(void)
** 功能: Timer_A定时器中断服务程序
*************************************************************************/
#pragma vector=TIMER1_A1_VECTOR
__interrupt void TA(void)
{
static uint a;
uint ii;
TA1CTL &= ~TAIFG;
ADC12CTL0 |= ADC12SC; // 转换开始 if(++a > 99)
{
a = 0;
temperature=0;
voltage=0;
for(ii=0;ii<100;ii++)
{
temperature+=tem[ii];
voltage+=vol[ii];
}
temperature/=100.0;
voltage/=100.0;
temperature=2.5*temperature/4095;
temperature=(temperature-0.96)/0.00355;
voltage=2*2.5*voltage/4095;
LPM0_EXIT;
}
}
/************************************************************************* ** 函数名称:systeminit()
** 功能:系统初始化
** 相关文件:
** 修改日志:
*************************************************************************/ void systeminit()
{
WDTCTL = WDTPW+WDTHOLD; //停止看门狗
PADIR = 0xFFFF; //设置不用的IO口
PAOUT = 0;
PASEL = 0;
PBDIR = 0xFFFF;
PBOUT = 0;
PBSEL = 0;
PCDIR = 0xFFFF;
PCOUT = 0;
PCSEL = 0;
PDDIR = 0xFFFF;
PDOUT = 0;
PDSEL = 0;
PEDIR = 0xFFFF;
PEOUT = 0;
PESEL = 0;
P11DIR = 0xFF;
P11OUT = 0;
P11SEL = 0;
PJDIR = 0xFF;
PJOUT = 0;
P2DIR &= ~( BIT6 + BIT7); //P2.6 P2.7 设置为输入
P2REN |= BIT6 + BIT7; //上拉下拉电阻使能
P2OUT |= BIT6 + BIT7; //P2.6 P2.7 为上拉
P2IES |= BIT6 + BIT7; //P2.6 P2.7下降触发
P2IE |= BIT6 + BIT7; //P2.6 P2.7中断使能
P2IFG =0; //中断标志清除,防止配置过程中出现中断标志为1
Init_Clk();
Init_ADC();
halUsbInit();
}
/************************************************************************* ** 函数名称:Init_Clk(void)
** 功能:初始化时钟系统
*************************************************************************/ void Init_Clk(void)
{
P7SEL |= 0x03; //XT1起振
UCSCTL1 = DCORSEL_5; //选择DCO的范围
UCSCTL2 = 374; //设置DCO频率为16M
UCSCTL4 = SELM_3 + SELA_0 + SELS_3; //设置 MCLK = DCOC,MCLK =DCO,ACLK=XT1 while (SFRIFG1 & OFIFG) //清除 OFIFG,and XT1OFFG ,DCOFFG {
UCSCTL7 &= ~(XT1LFOFFG + DCOFFG);
SFRIFG1 &= ~OFIFG;
}
}
/************************************************************************* ** 函数名称:Init_ADC(void)
** 功能:初始化ADC
*************************************************************************/
void Init_ADC(void)
{
unsigned int i;
ADC12CTL2 = ADC12RES_2 + ADC12REFOUT; // AD基本配置
ADC12CTL0 = ADC12ON + ADC12MSC + ADC12SHT03 + ADC12REFON + ADC12REF2_5V; ADC12MCTL0 |= ADC12SREF_1 + ADC12INCH_10; // 采样温度
ADC12MCTL1 |= ADC12SREF_1 + ADC12INCH_11 + ADC12EOS; // 采样VACC/2
ADC12CTL1 = ADC12SHP + ADC12CONSEQ_1; // 选择转换模式 for (i=0;i<0xFFFF;i++); // 等待基准电压建立 UCSCTL8 |= MODOSCREQEN;
ADC12IE |= 0X02; // 使能通道1中断
ADC12CTL0 |= ADC12ENC; // 开启转换
}
/*************************************************************************
** 函数名称:串口初始化函数
** 工作环境: IAR 4.11B
** 功能:初始化串口
传输方式设置,主从设置,波特率设置
*************************************************************************/
void halUsbInit()
{
P5SEL |= BIT6 + BIT7; // 选择串口功能
UCA1CTL1 = UCSWRST; // 复位串口功能
UCA1CTL0 = UCMODE_0; // 选择串口功能
UCA1CTL0 &= ~UC7BIT; // 8位数据模式
UCA1CTL1 |= UCSSEL_1; // 时钟源选择
UCA1BR0 = 3; // 32768hz/3=9600
UCA1BR1 = 0;
UCA1MCTL = 06; // 波特率调整因子
UCA1CTL1 &= ~UCSWRST; // 使能串口功能
UCA1IE |= UCRXIE; // 使能接收中断
_BIS_SR(GIE);
}
/*************************************************************************
** 函数名称:AD转换中断函数
** 工作环境: IAR 4.11B
** 功能: 保存转换值
*************************************************************************/
#pragma vector = ADC12_VECTOR
__interrupt void ADC12ISR(void)
{
static uint ad_n=0;
tem[ad_n] = ADC12MEM0; // 保存第一通道值 vol[ad_n] = ADC12MEM1; // 保存第二通道值 ad_n++;
if(ad_n==100)ad_n=0;
}
/************************************************************************* ** 函数名称:端口中断程序
** 工作环境: IAR 4.11B
** 功能:按键处理
*************************************************************************/ #pragma vector = PORT2_VECTOR
__interrupt void port2(void)
{
switch(P2IV)
{
case 0x0e: flagA=0;flagB=0;LPM0_EXIT;break; //LED1 亮灭
case 0x10: flagA=1;flagB=0;LPM0_EXIT;break; //LED2 亮灭
default :break;
}
}
/************************************************************************* ** 函数名称:串口接收中断函数
** 工作环境: IAR 4.11B
** 功能:接收处理计算机命令
*************************************************************************/ #pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
{
if(UCA1RXBUF=='V')
{
flagA=0;
flagB=0;
}
else if(UCA1RXBUF=='T')
{
flagA=1;
flagB=0;
}
}
/************************************************************************* ** 函数名称:字符串发送函数
** 工作环境: IAR 4.11B
** 功能: 串口发送字符串
*************************************************************************/ void UART_sd(char *pstr)
{
uchar i = 0;
char *Buffer = pstr;
while(Buffer[i])
{
UCA1TXBUF =Buffer[i];
i++;
while (!(UCA1IFG & UCTXIFG));
}
}
五、显示界面
(1)温度显示界面:
(2)电压显示界面:
// 判断是否发送完毕