📄 master.c
字号:
#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 + -