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

📄 host.c

📁 msp430实现的楼宇间通讯系统的原代码实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*********************************************************/
/* 							 */
/* 楼宇对讲系统主机程序 Version 1.0			 */
/*							 */
/*********************************************************/
#include <msp430x14x.h>
#include "led.h"
#include "I2C.h"

void Port_init(void);
void Send_Bit1(void);
void Send_Bit0(void);
void Send_Pre(void);
void Init_TimerB(void);
int KeyServe(void);
int Keyscan(void);
void Delay(void);
void Delay_1s(void);
//数据处理模块
void Ring(void);
int Process_Data(char nIn[],int nLen,char nRoom_Mode);
void DialAndProcess(void);
void Send_data(unsigned int numCode);
char Sub_Process(char nTemp,char nIn[],int nLen,char nRoom_Mode);
//void Send_code(unsigned int Room_mode,unsigned int numCode);
//特殊功能处理模块
char Administrator(char nTemp,char nIn[],int nLen,char nRoom_Mode);// 管理员设置用户密码和修改密码
char OpenDoorSelf(char nTemp,char nIn[],int nLen,char nRoom_Mode);// 密码开门
char SetRoomMode(char nTemp,char nIn[],int nLen);//管理员设置房号模式
char SetRingTime(char nTemp,char nIn[],int nLen);//管理员设置振铃时间
char SetDialogTime(char nTemp,char nIn[],int nLen);//管理员设置对话时间
char SetMasterPass(char nTemp,char nIn[],int nLen);//管理员设置密码
char AdministratorFlag;//进入管理员设置用户密码模式的标志
//G-U,#-P,*-L
unsigned char nLed[]={
 0x3f,0x06,0x5b,0x4f, /* 0 1 2 3*/
 0x66,0x6d,0x7d,0x07, /* 4 5 6 7 */
 0x7f,0x6f,0x77,0x7c, /* 8 9 A B */
 0x39,0x5e,0x79,0x71  /* C D E F */
};
int nRoom_Mode;	//房间模式
int nSecond;
char nidle;
unsigned int RingFlag,DialogFlag,ZhaijiFlag;
char Ring_time,Dialog_time;      //单位时间为S
int nRing;
int nDialog;
    
/*********************************************************/
/* 							 */
/* 主处理程序			 			 */
/*							 */
/*********************************************************/
int main(void)
{
    char nTemp;
    char nFlag;
    char nResult;

    char nCount;
    int nOther_Count;
    char nidle;
    char numRoom[8];     //房间键盘扫描值

	// 关闭看门狗
	WDTCTL = WDTPW + WDTHOLD;   
	//关闭中断
    _DINT();
	//初始化时钟
	Init_CLK();

    //所有初始化处理
    nRoom_Mode = 0;
    nSecond = 0;    
    nFlag = 0;

    nidle = 1;
    nCount = 0;
    RingFlag = 1;
    DialogFlag = 1;
    ZhaijiFlag = 0;
    Ring_time = 0;
    Dialog_time = 0;
    nOther_Count = 0;
    AdministratorFlag = 0;
	
    // 首先初始化系统
    Port_init();     //端口初始化
    Init_TimerB(); 
    
	I2C_Initial();

    //从I2C中读出配置信息
    nRoom_Mode = I2C_Read(513);
    Delay();
    Ring_time = I2C_Read(514);
    Delay();
    Dialog_time = I2C_Read(515);
    Delay();
    nFlag = 0x00;
	//打开中断
	_EINT(); 	
     //键盘扫描
    while(1)
    {
    	nTemp = 0x14;	
        P2OUT = 0x1F;
        
		if(nidle == 1) nTemp = Keyscan();   //扫描键盘
		switch(nTemp)
		{
            case 0:
			case 1:
			case 2:
			case 3:
			case 4:
			case 5:
			case 6:
			case 7:
			case 8:
			case 9:
			{
                switch(nFlag)
                {
                    case 0x00:
                    { 
                        switch(nCount)
	    				{
	    					case 0:
                            {
                    	        //清除锁存信号
	                            STCLK_Lo();
								DataOut(nLed[nTemp]);
                                break;
                            }
							case 1:
                            {
                                DataOut(nLed[nTemp]);
                                break;
                            }
		                    case 2:
                            {
                    	        DataOut(nLed[nTemp]);
                                break;
                            }
        	                case 3:
							{
                                DataOut(nLed[nTemp]);
                                break;
							}
						}//switch(nCount)
		                nResult = 0;
		                nResult = Sub_Process(nTemp,numRoom,nCount,nRoom_Mode);
		                nCount += 1;
		                if(nResult == 1) 
						{
							//给锁存信号,显示数据
	                        STCLK_Hi();
		                    Process_Data(numRoom,nCount - 1,nRoom_Mode);
		                    nCount = 0;
						}
                        break;
                    }//case 0x00:
                    case 0x0a:
                    {
                        nResult = 0;
                        nResult = SetRingTime(nTemp,numRoom,nCount);
                        nCount += 1;
                        if(nResult == 1)
                        {
                            nCount = 0;
                            nFlag = 0x00;
                        }
                        else if(nResult == 2)
                        {
							//清除锁存信号
							STCLK_Lo();
							//输出0
							DataOut(nLed[0]);
							//给锁存信号,显示数据
							STCLK_Hi(); 
                            nCount = 0;
                            nFlag = 0x00;
                        }
                
                        break;
                    }
                    case 0x0b:
                    {
                        nResult = 0;
                        nResult = SetDialogTime(nTemp,numRoom,nCount);
                        nCount += 1;
                        if(nResult ==1)
                        {
                            nCount = 0;
                            nFlag = 0x00;
                        }
                        else if(nResult == 2)
                        {
                            //清除锁存信号
							STCLK_Lo();
							//输出0
							DataOut(nLed[0]);
							//给锁存信号,显示数据
							STCLK_Hi(); 
                            nCount = 0;
                            nFlag = 0x00;
                        }
                
                        break;
                    }
                    case 0x0c:
                    {
                        nResult = 0;
                        nResult = SetMasterPass(nTemp,numRoom,nCount);
                        nCount += 1;
                        if(nResult == 1)
                        {
                            nCount = 0;
                            nFlag = 0x00;
                        }
                        else if(nResult == 2)
                        {
                            //清除锁存信号
							STCLK_Lo();
							//输出0
							DataOut(nLed[0]);
							//给锁存信号,显示数据
							STCLK_Hi(); 
                            nCount = 0;
                            nFlag = 0x00;
                        } 
                        break;
                    }
                    case 0x0d:
                    {
                        nResult = 0;
                        nResult = OpenDoorSelf(nTemp,numRoom,nCount,nRoom_Mode);
                        nCount += 1;
		                if(nResult == 1) 
						{
		                    nCount = 0;
                            nFlag = 0x00;
						}
                        break;
                    }
                    case 0x12:
                    {
                    	nResult = 0;
                    	if(AdministratorFlag == 1)
                    	{
                    	    nResult = Administrator(nTemp,numRoom,nCount,nRoom_Mode);
                            nCount += 1;
		                    if(nResult == 1) 
							{
		                        nCount = 0;
                                nFlag = 0x00;
                                AdministratorFlag = 0;
							}
						}
                        break;
                    }
                    case 0x13:
                    {
                        nResult = 0;
                        nResult = SetRoomMode(nTemp,numRoom,nCount);
                        nCount += 1;
                        if(nResult == 1)
                        {
                            nCount = 0;
                            nFlag = 0x00;
                        }
                        else if(nResult == 2)
                        {
                            //清除锁存信号
							STCLK_Lo();
							//输出0
							DataOut(nLed[0]);

							//给锁存信号,显示数据
							STCLK_Hi(); 
                            nCount = 0;
                            nFlag = 0x00;
                        }
                
                        break;
                    }                    
                    default:
                        break;
                }//switch(nFlag)
		        break;
			}
                        
			case 0x0A: // A 用来设置振铃时间
			{
	    		nFlag = 0x0a;
				break;
			}
			case 0x0B: // B 用来设置对话时间
			{
	    		nFlag = 0x0b;
				break;
			}
			case 0x0C: // C 管理员密码设置
			{
	    		nFlag = 0x0c;
	    		break;
			}
			case 0x0D: // D 自开锁
			{
	    		//Open_lock();       //密码开锁处理子程序
	    		nFlag = 0x0d;         //不显示密码
	    		break;
			}
			case 0x12: // #
       		{
	    		//Master_init();     //管理员对用户密码初始化处理子程序
	    		nFlag = 0x12;	    	
	    		break;
			}
			case 0x13: // *
			{
				//Password_change();     //设置房号模式
				nFlag = 0x13;
	    		break;
			}
			default:break;	
		} //键盘扫描结束   
    }         
    return 0;
}

/*********************************************************/
/* 														 */
/* 中断处理程序			 								 */
/*														 */
/*********************************************************/
//定时器B的中断处理
interrupt [TIMERB0_VECTOR] void TimerB_ISR(void)
{
	nRing += 1;
    nDialog += 1;
	if(nRing >= Ring_time)    //30s
	{
		nRing = 0;				
		RingFlag = 0;           //振铃30s中断标志
	}
	if(nDialog >= Dialog_time)   //60s
	{
		nDialog = 0;
		DialogFlag = 0;      //对话60s中断标志
	}
}	
//键盘扫描程序模块

/*********************************************************/
/* 														 */
/* 软件延时子程序							 			 */
/*														 */
/*********************************************************/
void Delay(void)
{
    int i;
    for(i = 6553;i > 0;i--) ;
}

//延迟1S
void Delay_1s(void)
{
    int i;
    for(i = 0;i < 100; i++)
	for(i = 0;i < 100; i++)
	    continue;
}
/*********************************************************/
/* 														 */
/* 键扫描子程序			 								 */
/*														 */
/*********************************************************/
int Keyscan(void)
{	
    int nTemp = 0x14;
	int nP30;
	int nP31;
	int nP32;
	int nP33;
    while(1)
    {
		nP30 = P3IN & BIT0;
		nP31 = (P3IN & BIT1) >> 1;
		nP32 = (P3IN & BIT1) >> 2;
		nP33 = (P3IN & BIT1) >> 3;
        if(nP30 == 1 || nP31 == 1 || nP32 == 1 || nP33 == 1) break;
    }           /*等待有键按下*/
    Delay();	/*软件延时*/
 
	nP30 = P3IN & BIT0;
	nP31 = (P3IN & BIT1) >> 1;
	nP32 = (P3IN & BIT1) >> 2;
	nP33 = (P3IN & BIT1) >> 3;
    if(nP30 == 1 || nP31 == 1 || nP32 == 1 || nP33 == 1)
	nTemp = KeyServe();      /*如果仍有键按下,则调用键服务子程序*/
    else
	nTemp = 0x14;	        /*如果为干扰,则令返回值为21*/
	
    return(nTemp);
}

/*********************************************************/
/* 														 */
/* 键服务子程序			 								 */
/*														 */
/*********************************************************/
int KeyServe(void)
{
    int nTemp = 0x14; 
	int nP30;
	int nP31;
	int nP32;
	int nP33;
 
    P2OUT |= BIT0;               /*行线RA0输出为高电平*/
	nP30 = P3IN & BIT0;
	nP31 = (P3IN & BIT1) >> 1;
	nP32 = (P3IN & BIT1) >> 2;
	nP33 = (P3IN & BIT1) >> 3;
    if(nP30 == 1)	nTemp = 0X13;       /*"*"键*/
    if(nP31 == 1)	nTemp = 0X00;       /*"0"键*/
    if(nP32 == 1)	nTemp = 0X12;       /*"#"键*/
    if(nP33 == 1)	nTemp = 0X0D;       /*"D"键*/
	
    P2OUT |= BIT1;               /*行线RA1输出为高电平*/
	nP30 = P3IN & BIT0;
	nP31 = (P3IN & BIT1) >> 1;
	nP32 = (P3IN & BIT1) >> 2;
	nP33 = (P3IN & BIT1) >> 3;
    if(nP30 == 1)	nTemp = 0X07;       /*"7"键*/
    if(nP31 == 1)	nTemp = 0X08;       /*"8"键*/
    if(nP32 == 1)	nTemp = 0X09;       /*"9"键*/
    if(nP33 == 1)	nTemp = 0X0C;       /*"C"键*/
	
    P2OUT |= BIT2;               /*行线RA2输出为高电平*/
	nP30 = P3IN & BIT0;
	nP31 = (P3IN & BIT1) >> 1;
	nP32 = (P3IN & BIT1) >> 2;
	nP33 = (P3IN & BIT1) >> 3;
    if(nP30 == 1)	nTemp = 0X04;       /*"4"键*/
    if(nP31 == 1)	nTemp = 0X05;       /*"5"键*/
    if(nP32 == 1)	nTemp = 0X06;       /*"6"键*/
    if(nP33 == 1)	nTemp = 0X0B;       /*"B"键*/
	
//    P2OUT |= BIT3;               /*行线RA3输出为高电平*/
//	nP30 = P3IN & BIT0;
//	nP31 = (P3IN & BIT1) >> 1;
//	nP32 = (P3IN & BIT1) >> 2;
//	nP33 = (P3IN & BIT1) >> 3;
//    if(nP30 == 1)	nTemp = 0X01;       /*"1"键*/
//    if(nP31 == 1)	nTemp = 0X02;       /*"2"键*/
//    if(nP32 == 1)	nTemp = 0X03;       /*"3"键*/
//    if(nP33 == 1)	nTemp = 0X0E;       /*"E"键*/
	
    P2OUT |= BIT4;                /*行线RA4输出为高电平*/
	nP30 = P3IN & BIT0;
	nP31 = (P3IN & BIT1) >> 1;
	nP32 = (P3IN & BIT1) >> 2;
	nP33 = (P3IN & BIT1) >> 3;
    if(nP30 == 1)	nTemp = 0X01;       /*"1"键*/
    if(nP31 == 1)	nTemp = 0X02;       /*"2"键*/
    if(nP32 == 1)	nTemp = 0X03;       /*"3"键*/
    if(nP33 == 1)	nTemp = 0X0A;       /*"A"键*/
	
    /*以上根据按下的键确定相应的键值*/
    
    while(1)
    {
		nP30 = P3IN & BIT0;
	    nP31 = (P3IN & BIT1) >> 1;
	    nP32 = (P3IN & BIT1) >> 2;
	    nP33 = (P3IN & BIT1) >> 3;
    	if((nP30 == 0) && (nP31 == 0) && (nP32 == 0) && (nP33 == 0)) 
			break;/*等待键盘松开*/
    }
    return(nTemp);
}


void Port_init(void)
{
	//将P2口所有的管脚设置为一般I/O口
    P2SEL = 0;
    //P2.0~P2.4为输出方向
	P2DIR = 0x00;
	P2DIR |= BIT0;
	P2DIR |= BIT1;
	P2DIR |= BIT2;
	P2DIR |= BIT3;
	P2DIR |= BIT4;
	//将P1口所有的管脚在初始化的时候设置为输入方式
    P1DIR = 0;
    //将P1口所有的管脚设置为一般I/O口
    P1SEL = 0;
    // 将P1.0 P1.1 P1.2 设置为输出方向
    P1DIR |= BIT0;
    P1DIR |= BIT1;
	P1DIR |= BIT2;
	//将P3口所有的管脚在初始化的时候设置为输入方式
    P3DIR = 0;
	//将P4口所有的管脚在初始化的时候设置为输入方式
    P4DIR = 0;
	//P4.0~P4.4为输出方向
	P4DIR = 0x00;
	P4DIR |= BIT0;
	P4DIR |= BIT1;
	P4DIR |= BIT2;
	P4DIR |= BIT3;
	P4DIR |= BIT4;
}

void Init_TimerB(void)
{
	// 选择ACLK,清除TAR
    TBCTL = TBSSEL0 + TBCLR;
	// TBCCR0 中断允许
    TBCCTL0 = CCIE;         
	// 时间间隔为 1 s
    TBCCR0 = 32768;			  
    // 增记数模式
    TBCTL |= MC0; 
	return;
}


void Send_Bit1(void)
{
    char i;
	P4OUT &= ~(BIT4);
    for(i = 55;i > 0;i--) ;
    for(i = 55;i > 0;i--) ;
	P4OUT |= BIT4;
    for(i = 55;i > 0;i--) ;
}
void Send_Bit0(void)
{
    char i;
    P4OUT &= ~(BIT4);
    for(i = 55;i > 0;i--) ;
    P4OUT |= BIT4;
    for(i = 55;i > 0;i--) ;
    for(i = 55;i > 0;i--) ;
}
void Send_Pre(void)
{
    char i,j;
    
    P4OUT &= ~(BIT4);
    for(j = 0;j < 36;j++)
        for(i = 0;i < 55;i++)
            ;
    P4OUT |= BIT4;
    for(i = 55; i > 0;i--) ;
}

//发送编码数据
void Send_data(unsigned int numCode)  //要发送的数据是numCode
{
    int CodeBit; 
    int SendBit;
    int nHigh;
    int nLow;
    int n;
    int i;
        
    nLow = numCode & 0x0f;
    nHigh = numCode >> 4;
        
    Send_Pre();
    for(i = 0;i < 8;i++)
    {
        SendBit = nHigh & 0x01;
        if(SendBit == 1)
            Send_Bit1();
        else
            Send_Bit0();                           
        nHigh >>= 1;
    }	
    for(i = 0;i < 4;i++)
    {
        SendBit = nLow & 0x01;
        if(SendBit == 1)
            Send_Bit1();
        else
            Send_Bit0();                          
        nLow >>= 1;
    }       
}

//振铃处理子程序模块
//RE1脚发出1/450Hz的脉冲
void Ring(void) 
{
    int i;
	P4OUT &= ~(BIT4);
	P4OUT &= ~(BIT0);
	
    P4OUT |= BIT2;
    for(i = 0; i < 200;i++) ;
    P4OUT &= ~(BIT2);
    for(i = 0; i < 200;i++);
}


//拨号处理子程序
void DialAndProcess(void)
{
    int i;
	int nBit5;
	int nBit6;
    //判断选通房间分机是否存在
    Delay();
    Delay();
    Delay();
	nBit5 = (P1IN & BIT5) >> 5;
	nBit6 = (P1IN & BIT6) >> 6;
    if((nBit6 == 1) && (nBit5 == 0))   
    {
		//分机存在

⌨️ 快捷键说明

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