⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 master.c

📁 MSP430F149液位控制代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <msp430x14x.h>

#include "Master.H"
#include "Codes.H"

void main(void) {

	unsigned char itemp,jtemp;

	//关闭系统看门狗
	WDTCTL = WDTPW + WDTHOLD;

	//初始化系统时钟
	InitOsc();
	
	//初始化LCD显示
	LCD_Delayl(10);
	LCD_Initialization();
	LCD_Clear(0x00);
	LCD_DispMainMenu();
	
	//初始化LED显示
	InitLEDs();

	//打开P10~P14的按键中断
	InitKeyBroad();

	//初始化AD
	InitADC();

	//初始化继电器控制
	InitValve();

	//开总中断
	_BIS_SR(GIE);
	
	while(1){
		//"+""-"在主程序循环中查询按键
		//-----------------------------------------菜单--------------------------------------------
		//在"菜单中"执行"+""-"
		if(Sys_Work_Flag==0x00){
			if(((P1IN&BIT3)==BIT3)|((P1IN&BIT2)==BIT2)) {
				Sys_Menu_Flag ^= BIT0;
				LCD_DispMainMenu();
				LCD_Delayl(25);
			}
		}
		//-----------------------------------------单机--------------------------------------------
		//在"单机""系统"==>AD采集与显示过程
		if((Sys_Menu_Flag==0x00)&(Sys_Work_Flag==0x01)){
			//取得当前液面高度
			Sys_Height_Current=GetHeight();
			//显示当前液面高度
			ShutKeyBroad();
			LCD_DispNums(Sys_Height_Current,0,8,0);
			LCD_Delayl(5);
			InitKeyBroad();
			//报警,题目要求高于250mm或者低于0mm的时
			if((Sys_Height_Current>=250)|(Sys_Height_Current==0)) LEDGo(0xff);
			else LEDGo(0x00);
		}
		//在"单机""系统""不工作"==>使用"+""-"调整"设定高度"
		if((Sys_Menu_Flag==0x00)&(Sys_Work_Flag==0x01)&(Sys_Busy_Flag==0x00)){
			//修改系统中设定的液面高度+和-
			if((P1IN&BIT2)==BIT2){
				if(Sys_Height_Target==250){
					Sys_Height_Target=250;
					AlarmDelayl(1);
				}
				else Sys_Height_Target++;
				LCD_DispNums(Sys_Height_Target,4,72,1);
				LCD_Delayl(10);
			}
			if((P1IN&BIT3)==BIT3){
				if(Sys_Height_Target==0){
					Sys_Height_Target=0;
					AlarmDelayl(1);
				}
				else Sys_Height_Target--;
				LCD_DispNums(Sys_Height_Target,4,72,1);
				LCD_Delayl(10);
			}
		}
		//在"单机""系统""工作"==>电磁阀控制过程
		if((Sys_Menu_Flag==0x00)&(Sys_Work_Flag==0x01)&(Sys_Busy_Flag==0x01)){
			//放水过程
			if(Sys_Run_Directs==0x00) {
				if(Sys_Height_Current<=Sys_Height_Target) {
					itemp++;jtemp=0;
					if(itemp>3) {
						//完成放水过程
						itemp=0;
						//完成之后的工作
						Sys_Busy_Flag=0x00;
						//停止放水
						ValveB_Stop();
						AlarmDelayl(100);
					}
				} else {
					jtemp++;itemp=0;
					if(jtemp>3){
						//表示这次采集的数据比较准确
						jtemp=0;
					}
				}
			}
			//加水过程
			else {
				if(Sys_Height_Current>=Sys_Height_Target) {
					itemp++;jtemp=0;
					if(itemp>3) {
						//完成加水过程
						itemp=0;
						//完成之后的工作
						Sys_Busy_Flag=0x00;
						ValveA_Stop();
						AlarmDelayl(100);
					}
				} else {
					jtemp++;itemp=0;
					if(jtemp>3){
							jtemp=0;
						}
				}
			}
		}
		//-----------------------------------------联机--------------------------------------------
	}
}
//---------------------------------------------------------
void InitOsc(void) {
	
	unsigned char i,j;				//设置系统时钟
	BCSCTL1	= 0x00;				//启动XT2晶振,ACLK为XT1(32KHz)
	BCSCTL2	= 0x88;				//MCLK为XT2不分频;SMCLK为XT2,4MHz
	j=0;
	while(1) {
		IFG1 &= ~OFIFG;			//清OSCFault标志
		for (i=0xFF;i>0;--i);		//延时等待
		if ((IFG1 & OFIFG)!=0) {//若振荡器失效标志有效
			BCSCTL1 = 0x00;		//启动XT2晶振,ACLK为XT1(32KHz)
			BCSCTL2 = 0X88;		//MCLK为XT2不分频,SMCLK为XT2不分频
			j++;							//如果检测到振荡器失效,则计数
			if (j>10)					//如果计数值超过10次,则认为是硬件问题
				;							//OSCFault();
		} 
		else {
			for (i=0xFF;i>0;--i);	//等待振荡器达到足够的幅度
			IFG1 &= ~OFIFG;		//清OSCFault标志
			IE1 |= OFIE + ACCVIE;//中断允许(若振荡器故障,FLASH非法访问中断允许)
			break;
		}
	}  
}

void InitKeyBroad(void){
	//开键盘(P10~P14)中断
	P1DIR &= ~(BIT0+BIT1+BIT2+BIT3+BIT4);
	//下降沿中断
	P1IES |= (BIT0+BIT1+BIT4);
	//允许P1中断
	P1IE |= (BIT0+BIT1+BIT4);
}
void ShutKeyBroad(void){
	//关闭P1中断
	P1IE &= ~(BIT0+BIT1+BIT4);
}
#pragma vector=PORT1_VECTOR
__interrupt void PORT1_ISR (void) {

	ShutKeyBroad();

	LCD_Delayl(5);

	//在中断程序中处理 MENU.OK和NEXT
	//P1.4 as "MENU"
	if ((P1IFG&BIT4)==BIT4){
		//Refer to TableA in my notebook
		//any;01;any ==>> any;00;00
		if(Sys_Work_Flag==0x01){
			Sys_Work_Flag = 0x00;
			Sys_Busy_Flag = 0x00;			//Modified Flags
			ValveA_Stop();
			ValveB_Stop();						//Stop Working
			LCD_Delayl(5);
			LCD_DispMainMenu();				//Display StartMenu
		}
	}

	//P1.1 as "OK"
	if((P1IFG&BIT1)==BIT1){
		//00;00;any ==>> 00;01;any
		if((Sys_Menu_Flag==0x00)&(Sys_Work_Flag==0x00)){
			Sys_Work_Flag=0x01;
			LCD_DispSoloMode();
		}
		//00;01;00 ==>> 00;01;01
		else if((Sys_Menu_Flag==0x00)&(Sys_Work_Flag==0x01)) {
			Sys_Busy_Flag=0x01;//系统工作中,忙
			//确定当前系统的水位
			//Sys_Height_Current=GetHeight();
			Sys_Run_Directs=Sys_Height_Current>Sys_Height_Target?0:1;
			if(Sys_Run_Directs==0x00)ValveB_Run();
			else ValveA_Run();
		}
	}

	//P1.0 as "NEXT"
	if((P1IFG&BIT0)==BIT0){
	}

	//清除按键中断标志位
	P1IFG = 0x00;

	//打开P10~P14的按键中断
	InitKeyBroad();
}
void InitADC(void){

	P6DIR &= ~BIT6;
	P6SEL |= BIT6;

	ADC12CTL0 = ADC12ON + REFON + REF2_5V + SHT0_6;
	ADC12CTL1 = SHS_0 + SHP + CONSEQ_0;
}
void InitComm(void){

	P3DIR |= (BIT0+BIT4+BIT5);
	P3SEL |= (BIT4+BIT5);				//端口

	ME1 |= UTXE0 + URXE0;				//模块管理

	UCTL0 |=CHAR;							//字符长度
	UTCTL0 |= SSEL0 + SSEL1;		//SMCLK

	UBR00 = 0x9F;
	UBR10 = 0x01;							//4M/9600=416.66
	UMCTL0 = 0xB5;

	UCTL0 &= ~SWRST;
	IE1 |= URXIE0;
}

void CommStop(void) {
	UCTL0 &= ~SWRST;
	IE1 &= ~URXIE0;
}

#pragma vector=UART0RX_VECTOR
__interrupt void usart0_rx(void){

	unsigned char itemp;

	//接收数据
	itemp = RXBUF0;

	//首先判断数据是否正常
	//除结束字节之外,不应当有0xFF字节出现
	if((!(CommStat==0x02))&(itemp==0xFF)){
		//数据非法
		RX_data[0]=0;					//data buffer
		RX_data[1]=0;
		CommStat &= 0xF0;			//Low reseted
	}

	//根据CommStat决定当前的发送状态
	if((CommStat&0x0F)==0x00){
		//0x00之前没有收到数据
		//将接收到的数据储存在RX_data[0]
		RX_data[0]=itemp;
		//第一条接收完毕
		CommStat &= 0xF0;			//高4位保留
		CommStat |= 0x01;			//低4位修改
	}
	else if((CommStat&0x0F)==0x01){
		//0x01收取完第一字节
		//RX_data[1]存储数据
		RX_data[1]=itemp;
		//第二条接收完毕
		CommStat &= 0xF0;			//High reserved
		CommStat |= 0x02;			//Low modified
	}
	else if((CommStat&0x0F)==0x02){
		//0x02收取完第二字节
		//分析数据并作出相应的处理
		//主机能收到数据格式为定长的3字节:起始+数据(0~250)+结束位
		//起始位为ID(4)+0+CMD(3);结束位为0xFF
		if(itemp==0xFF){
			//结束位为0xFF,该数据有效
			CommStat &= 0xF0;		//High reserved
			CommStat |= 0x03;		//Low modified
			//数据完全接收,可以处理
		}
	}
}

void CommSend(){

	//判定是否有数据要发送
	if((CommStat&0xF0)==0x10) {
		
		P3OUT &= ~BIT0;					//switch to TX mode
		
		//发送的数据包也是定长3字节的
		while(!(IFG1&UTXIFG0));			//check and wait
		TXBUF0=TX_data[0];				//send data ID(4)+1+CMD(3)
		LCD_Delayt(4000);					//about 10ms
		
		while(!(IFG1&UTXIFG0));
		TXBUF0=TX_data[1];				//send data ID(4)+1+CMD(3)
		LCD_Delayt(4000);					//about 10ms
		
		while(!(IFG1&UTXIFG0));
		TXBUF0=0xFF;						//send data 0xFF as terminateflag
		LCD_Delayt(1000);					//about 2.5ms
		

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -