📄 host.c
字号:
/*********************************************************/
/* */
/* 楼宇对讲系统主机程序 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 + -