打印

【MCU方案】+基于msp430f149实现楼宇对讲系统

[复制链接]
1245|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 uestc_zyd 于 2015-6-26 13:14 编辑

一、功能介绍
楼宇对讲系统应用于智能小区。整个系统由门口主机、楼层译码器和室内分机组成。门口主机接收用户输入数据、呼叫处理和控制电控锁。整个系统采用总线方式布线,门口主机到楼层译码器采用3总线方式,楼层译码器到室内分机采用无极性的2总线方式,保证即使用户线短路也不会影响整个系统。
主机发出编码信息(如房间号码),楼层译码器根据接收到的数据进行译码,若为本层的某个房间则将分机接通,主机检测到线路状态后就可以发送振铃信号,分机应答后可以进行通话,并给出开锁信号,即主机在收到分机的开锁信号后会打开电控锁。
二、方案描述
硬件系统包括3个部分:主机、楼层译码器、分机。软件系统主要包括显示模块、存储器操作模块、键盘输入模块、拨号处理模块、主处理模块。
系统构成如下图:

1、硬件主机设计
主机主要包括键盘输入电路、存储器电路、逻辑控制电路、比较器电路、驱动电路和音频处理电路。键盘输入电路主要用于接收用户输入的数据,如密码设置、振铃时间设置、房间号码设置等。存储器电路主要用于存储系统信息,如房间模式、密码。逻辑控制电路主要产生某些逻辑控制信号,如开锁信号、对话信号、振铃信号。比较器电路用于判断分机的状态,如摘机、挂机等。音频电路主要实现对讲功能。
2、楼层译码器设计
用来接收主机发出的编码数据,并对接收到的编码数据,并对接收到的编码数据进行处理,如果是本楼的分机则接通被呼叫的分机。楼层译码器选用HT12D芯片实现。主机发出的编码数据经过HT12D芯片译码,如果编码数据中的地址部分正好和该译码器的地址相同,那么HT12D芯片就在D8/D9/D10/D11中的某一个管脚输出高电平,通过这个高电平来接通分机。

3、软件部分在下节中介绍
三、软件部分
1、显示模块
显示程序是通过P1.2管脚模拟移位时钟信号,P1.0管脚在输出时钟的控制下一位一位地输出数据,P1.1管脚给出锁存信号将数据显示出来。整个显示程序主要由端口初始化、管脚高低电平产生、数据串行输出3个部分组成。

#include <msp430x14x.h>
#include "led.h"

void Init_Port(void)
{
//将P1口所有的管脚在初始化的时候设置为输入方式
P1DIR = 0;
//将P1口所有的管脚设置为一般I/O口
P1SEL = 0;

// 将P1.0 P1.1 P1.2 设置为输出方向
P1DIR |= BIT0;
P1DIR |= BIT1;
P1DIR |= BIT2;
// 将P1.3 P1.4 P1.5 设置为输出方向
P1DIR |= BIT3;
P1DIR |= BIT4;
P1DIR |= BIT5;

//将P2口所有的管脚在初始化的时候设置为输入方式
P2DIR = 0;
//将P2口所有的管脚设置为一般I/O口
P2SEL = 0;
//将中断寄存器清零
P2IE = 0;
P2IES = 0;
P2IFG = 0;
//管脚 P2.0 使能中断
P2IE |= BIT0;
//对应的管脚由低到高电平跳变使相应的标志置位
P2IES &= ~(BIT0);
return;
}
void SHCLK_Hi(void)
{
//P1.2管脚输出高电平
P1OUT |= BIT2;
return;
}
void SHCLK_Lo(void)
{
//P1.2管脚输出低电平
P1OUT &= ~(BIT2);
return;
}
void STCLK_Hi(void)
{
//P1.1管脚输出高电平
P1OUT |= BIT1;
return;
}
void STCLK_Lo(void)
{
//P1.1管脚输出低电平
P1OUT &= ~(BIT1);
return;
}
void DataOut(unsigned char nValue)
{
int i;
int j;
for(i = 0;i < 8;i++)
{
if ((nValue & 0x01) == 1)
{
P1OUT |= BIT0;//输出高电平
}
else
{
P1OUT &= ~(BIT0);//输出低电平
}
SHCLK_Hi();//时钟高电平,上升沿有效
for(j = 10; j > 0; j--) ;//延迟一点时间
SHCLK_Lo();//时钟低电平
for(j = 10; j > 0; j--) ;
nValue >>= 1;
}
return;
}


void Init_CLK(void)
{
unsigned int i;
//将寄存器的内容清零
//XT2震荡器开启
//LFTX1工作在低频模式
//ACLK的分频因子为1
BCSCTL1 = 0X00;

do
{
// 清除OSCFault标志
IFG1 &= ~OFIFG;
for (i = 0x20; i > 0; i--);
}
while ((IFG1 & OFIFG) == OFIFG); // 如果OSCFault =1

//将寄存器的内容清零
BCSCTL2 = 0X00;
//MCLK的时钟源为TX2CLK,分频因子为1
BCSCTL2 += SELM1;
//SMCLK的时钟源为TX2CLK,分频因子为1
BCSCTL2 += SELS;
}

2、I2C模块(存储器操作模块)
采用串行存储器24LC02B通过I2C实现与MSP430的连接。I2C的时序包括起始条件、数据传输、确认、停止条件。
#include "I2C.h"

void I2C_Initial( void )
{
P1DIR |= SCL; //将SCL管脚(P1.3)设置为输出管脚
I2C_Set_sck_low();
I2C_STOP();
Delay_ms(10);
return;
}
void I2C_Set_sda_high( void )
{
P1DIR |= SDA; //将SDA设置为输出模式
P1OUT |= SDA; //SDA管脚输出为高电平

_NOP();
_NOP();
return;
}
void I2C_Set_sda_low ( void )
{
P1DIR |= SDA; //将SDA设置为输出模式
P1OUT &= ~(SDA); //SDA管脚输出为低电平

_NOP();
_NOP();
return;
}
void I2C_Set_sck_high( void )
{
P1DIR |= SCL; //将SCL设置为输出模式
P1OUT |= SCL; //SCL管脚输出为高电平

_NOP();
_NOP();
return;
}
void I2C_Set_sck_low ( void )
{
P1DIR |= SCL; //将SCL设置为输出模式
P1OUT &= ~(SCL); //SCL管脚输出为低电平

_NOP();
_NOP();
return;
}
int I2C_GetACK(void)
{
int nTemp = 0;
int j;

_NOP();
_NOP();
I2C_Set_sck_low();
for(j = 30;j > 0;j--);
P1DIR &= ~(SDA); //将SDA设置为输入方向
//I2C_Set_sda_high();
I2C_Set_sck_high();

for(j = 30;j > 0;j--);
nTemp = (int)(P1IN & SDA); //获得数据

I2C_Set_sck_low();

return (nTemp & SDA);
}
void I2C_SetACK(void)
{
I2C_Set_sck_low();
I2C_Set_sda_low();
I2C_Set_sck_high();
I2C_Set_sck_low();
return;
}
void I2C_SetNAk(void)
{
I2C_Set_sck_low();
I2C_Set_sda_high();
I2C_Set_sck_high();
I2C_Set_sck_low();
return;
}
void I2C_START(void)
{
int i;

I2C_Set_sda_high();
for(i = 5;i > 0;i--);
I2C_Set_sck_high();
for(i = 5;i > 0;i--);
I2C_Set_sda_low();
for(i = 5;i > 0;i--);
I2C_Set_sck_low();
return;
}
void I2C_STOP(void)
{
int i;

I2C_Set_sda_low();
for(i = 5;i > 0;i--);
I2C_Set_sck_low();
for(i = 5;i > 0;i--);
I2C_Set_sck_high();
for(i = 5;i > 0;i--);
I2C_Set_sda_high();
for(i = 5;i > 0;i--);
I2C_Set_sck_low();
Delay_ms(10); //延迟一点时间

return;
}
void I2C_TxByte(int nValue)
{
int i;
int j;

for(i = 0;i < 8;i++)
{
if(nValue & 0x80)
I2C_Set_sda_high();
else
I2C_Set_sda_low();
for(j = 30;j > 0;j--);
I2C_Set_sck_high();
nValue <<= 1;
for(j = 30;j > 0;j--);
I2C_Set_sck_low();
}

return;
}
/////////////////////////////////////////////
// 接收是从 LSB 到 MSB 的顺序
int I2C_RxByte(void)
{
int nTemp = 0;
int i;
int j;

I2C_Set_sda_high();

P1DIR &= ~(SDA); //将SDA管脚设置为输入方向
_NOP();
_NOP();
_NOP();
_NOP();
for(i = 0;i < 8;i++)
{
I2C_Set_sck_high();

if(P1IN & SDA)
{
nTemp |= (0x01 << i);
}
for(j = 30;j > 0;j--);
I2C_Set_sck_low();
}

return nTemp;
}
void I2C_Write(char nAddr,char nValue)
{
int nTemp = 0xA0;//写命令
// 启动数据总线
I2C_START();
// 发送控制字节
I2C_TxByte(nTemp);
// 等待 ACK
nTemp = I2C_GetACK();

// 发送地址字节
I2C_TxByte(nAddr);
// 等待 ACK
nTemp = I2C_GetACK();

// 发送数据字节
I2C_TxByte(nValue);
// 等待 ACK
nTemp = I2C_GetACK();

// 停止总线
I2C_STOP();
return;
}
int PageWrite(char nAddr,char pBuf[])
{
int i;
int nTemp = 0xA0;//写命令
// 启动数据总线
I2C_START();
// 发送控制字节
I2C_TxByte(nTemp);
// 等待 ACK
nTemp = I2C_GetACK();
if(nTemp & BIT3) return 0;

// 发送地址字节
I2C_TxByte(nAddr);
// 等待 ACK
nTemp = I2C_GetACK();
if(nTemp & BIT3) return 0;

// 发送数据字节
for(i = 0; i < 8;i++)
{
I2C_TxByte(pBuf[0]);
// 等待 ACK
nTemp = I2C_GetACK();
if(nTemp & BIT3) return 0;
}

// 停止总线
I2C_STOP();
return (nTemp & SDA);
}
char I2C_Read(int nAddr)
{
int nRes = -1;
//写命令
int nTemp = 0xA0;
// 启动数据总线
I2C_START();
// 发送控制字节
I2C_TxByte(nTemp);
// 等待 ACK
nTemp = I2C_GetACK();

// 发送地址字节
I2C_TxByte(nAddr);
// 等待 ACK
nTemp = I2C_GetACK();

// 启动数据总线
I2C_START();
// 发送控制字节
nTemp = 0xA1;
I2C_TxByte(nTemp);
// 等待 ACK
nTemp = I2C_GetACK();

//读取数据
nRes = I2C_RxByte();

// 停止总线
I2C_STOP();
//成功返回
return nRes;
}
int ReadSeq(char nAddr, char nValue[], int nLen)
{
int i;
//写命令
int nTemp = 0xA0;
// 启动数据总线
I2C_START();
// 发送控制字节
I2C_TxByte(nTemp);
// 等待 ACK
nTemp = I2C_GetACK();
if(nTemp & BIT3) return 0;

// 发送地址字节
I2C_TxByte(nAddr);
// 等待 ACK
nTemp = I2C_GetACK();
if(nTemp & BIT3) return 0;

// 启动数据总线
I2C_START();
// 发送控制字节
nTemp = 0xA1;
I2C_TxByte(nTemp);
// 等待 ACK
nTemp = I2C_GetACK();
if(nTemp & BIT3) return 0;

//读取数据
for(i = 0; i < nLen; i++)
{
//读一个字节数据
nValue[i] = I2C_RxByte();
//发送ACK
I2C_SetACK();
}

// 停止总线
I2C_STOP();
//成功返回
return 1;
}
void Delay_ms(unsigned long nValue)//毫秒为单位,8MHz为主时钟
{
unsigned long nCount;
int i;
unsigned long j;
nCount = 2667;
for(i = nValue;i > 0;i--)
{
for(j = nCount;j > 0;j--);
}
return;
}
void Delay_us(unsigned long nValue)//微秒为单位,8MHz为主时钟
{
int nCount;
int i;
int j;
nCount = 3;
for(i = nValue;i > 0;i--)
{
for(j = nCount;j > 0;j--);
}
return;
}

3、键盘输入模块
矩阵键盘电路利用MSP430的一般I/O口来进行扩展设计,矩阵键盘有行、列线组成,通过扫描来获取键盘的输入,读取线的状态就可以判断哪个键被按下。
一般IO口方式的程序设计:
#include <msp430x14x.h>

void Delay(void);
int KeyScan(void);
int KeyProcess(void);
void Init_Port(void)
{
//将P1口所有的管脚在初始化的时候设置为输入方式
P1DIR = 0;

//将P1口所有的管脚设置为一般I/O口
P1SEL = 0;

// 将P1.4 P1.5 P1.6 P1.7设置为输出方向
P1DIR |= BIT4;
P1DIR |= BIT5;
P1DIR |= BIT6;
P1DIR |= BIT7;

//先输出低电平
P1OUT = 0x00;
return;
}
int KeyScan(void)
{
int nP10,nP11,nP12,nP13;
int nRes = 0;
for(;;)
{
//读取各个管脚的状态
nP10 = P1IN & BIT0;
nP11 = (P1IN & BIT1) >> 1;
nP12 = (P1IN & BIT2) >> 2;
nP13 = (P1IN & BIT3) >> 3;

//是否有键被按下
if(nP10 == 0 || nP11 == 0 || nP12 == 0 || nP13 == 0)
{
//有键被按下
break;
}

}
Delay(); //延时一点时间,消除抖动
//读取各个管脚的状态
nP10 = P1IN & BIT0;
nP11 = (P1IN & BIT1) >> 1;
nP12 = (P1IN & BIT2) >> 2;
nP13 = (P1IN & BIT3) >> 3;

//是否有键被按下
if(nP10 == 0 || nP11 == 0 || nP12 == 0 || nP13 == 0)
{
//有键被按下,进行键盘输入分析
nRes = KeyProcess();
}
else return -1;//没有输入,为干扰

return nRes;
}
void Delay(void)
{
int i;
for(i = 100;i--;i > 0) ;//延时一点时间
}
int KeyProcess(void)
{
int nRes = 0;
int nP10;
int nP11;
int nP12;
int nP13;
//P1.4输出低电平
P1OUT &= ~(BIT4);
nP10 = P1IN & BIT0;
if (nP10 == 0) nRes = 13;
nP11 = (P1IN & BIT1) >> 1;
if (nP11 == 0) nRes = 14;
nP12 = (P1IN & BIT2) >> 2;
if (nP12 == 0) nRes = 15;
nP13 = (P1IN & BIT3) >> 3;
if (nP13 == 0) nRes = 16;
//P1.5输出低电平
P1OUT &= ~(BIT4);
nP10 = P1IN & BIT0;
if (nP10 == 0) nRes = 9;
nP11 = (P1IN & BIT1) >> 1;
if (nP11 == 0) nRes = 10;
nP12 = (P1IN & BIT2) >> 2;
if (nP12 == 0) nRes = 11;
nP13 = (P1IN & BIT3) >> 3;
if (nP13 == 0) nRes = 12;
//P1.6输出低电平
P1OUT &= ~(BIT4);
nP10 = P1IN & BIT0;
if (nP10 == 0) nRes = 5;
nP11 = (P1IN & BIT1) >> 1;
if (nP11 == 0) nRes = 6;
nP12 = (P1IN & BIT2) >> 2;
if (nP12 == 0) nRes = 7;
nP13 = (P1IN & BIT3) >> 3;
if (nP13 == 0) nRes = 8;
//P1.7输出低电平
P1OUT &= ~(BIT4);
nP10 = P1IN & BIT0;
if (nP10 == 0) nRes = 1;
nP11 = (P1IN & BIT1) >> 1;
if (nP11 == 0) nRes = 2;
nP12 = (P1IN & BIT2) >> 2;
if (nP12 == 0) nRes = 3;
nP13 = (P1IN & BIT3) >> 3;
if (nP13 == 0) nRes = 4;

P1OUT = 0x00;//恢复以前值。

//读取各个管脚的状态
nP10 = P1IN & BIT0;
nP11 = (P1IN & BIT1) >> 1;
nP12 = (P1IN & BIT2) >> 2;
nP13 = (P1IN & BIT3) >> 3;
for(;;)
{
if(nP10 == 1 && nP11 == 1 && nP12 == 1 && nP13 == 1)
{
//等待松开按键
break;
}
}
return nRes;
}
void Init_CLK(void)
{
unsigned int i;
BCSCTL1 = 0X00; //将寄存器的内容清零
//XT2震荡器开启
//LFTX1工作在低频模式
//ACLK的分频因子为1

do
{
IFG1 &= ~OFIFG; // 清除OSCFault标志
for (i = 0x20; i > 0; i--);
}
while ((IFG1 & OFIFG) == OFIFG); // 如果OSCFault =1

BCSCTL2 = 0X00; //将寄存器的内容清零
BCSCTL2 += SELM1; //MCLK的时钟源为TX2CLK,分频因子为1
BCSCTL2 += SELS; //SMCLK的时钟源为TX2CLK,分频因子为1
}
中断功能方式的程序:
#include <msp430x14x.h>
void Init_Port(void)
{
//将P1口所有的管脚在初始化的时候设置为输入方式
P1DIR = 0;

//将P1口所有的管脚设置为一般I/O口
P1SEL = 0;

// 将P1.4 P1.5 P1.6 P1.7设置为输出方向
P1DIR |= BIT4;
P1DIR |= BIT5;
P1DIR |= BIT6;
P1DIR |= BIT7;

//先输出低电平
P1OUT = 0x00;

// 将中断寄存器清零
P1IE = 0;
P1IES = 0;
P1IFG = 0;
//打开管脚的中断功能
//对应的管脚由高到低电平跳变使相应的标志置位
P1IE |= BIT0;
P1IES |= BIT0;
P1IE |= BIT1;
P1IES |= BIT1;
P1IE |= BIT2;
P1IES |= BIT2;
P1IE |= BIT3;
P1IES |= BIT3;
_EINT();//打开中断
return;
}
void Delay(void)
{
int i;
for(i = 100;i--;i > 0) ;//延时一点时间
}
int KeyProcess(void)
{
int nP10,nP11,nP12,nP13;
int nRes = 0;
//P1.4输出低电平
P1OUT &= ~(BIT4);
nP10 = P1IN & BIT0;
if (nP10 == 0) nRes = 13;
nP11 = P1IN & BIT1;
if (nP11 == 0) nRes = 14;
nP12 = P1IN & BIT2;
if (nP12 == 0) nRes = 15;
nP13 = P1IN & BIT3;
if (nP13 == 0) nRes = 16;
//P1.5输出低电平
P1OUT &= ~(BIT4);
nP10 = P1IN & BIT0;
if (nP10 == 0) nRes = 9;
nP11 = P1IN & BIT1;
if (nP11 == 0) nRes = 10;
nP12 = P1IN & BIT2;
if (nP12 == 0) nRes = 11;
nP13 = P1IN & BIT3;
if (nP13 == 0) nRes = 12;
//P1.6输出低电平
P1OUT &= ~(BIT4);
nP10 = P1IN & BIT0;
if (nP10 == 0) nRes = 5;
nP11 = P1IN & BIT1;
if (nP11 == 0) nRes = 6;
nP12 = P1IN & BIT2;
if (nP12 == 0) nRes = 7;
nP13 = P1IN & BIT3;
if (nP13 == 0) nRes = 8;
//P1.7输出低电平
P1OUT &= ~(BIT4);
nP10 = P1IN & BIT0;
if (nP10 == 0) nRes = 1;
nP11 = P1IN & BIT1;
if (nP11 == 0) nRes = 2;
nP12 = P1IN & BIT2;
if (nP12 == 0) nRes = 3;
nP13 = P1IN & BIT3;
if (nP13 == 0) nRes = 4;

P1OUT = 0x00;//恢复以前值。

//读取各个管脚的状态
nP10 = P1IN & BIT0;
nP11 = P1IN & BIT1;
nP12 = P1IN & BIT2;
nP13 = P1IN & BIT3;
for(;;)
{
if(nP10 == 1 && nP11 == 1 && nP12 == 1 && nP13 == 1)
{
//等待松开按键
break;
}
}
return nRes;
}
// 处理来自端口 1 的中断
interrupt [PORT1_VECTOR] void PORT_ISR(void)
{
Delay();
KeyProcess();
if(P1IFG & BIT0)
{
P1IFG &= ~(BIT0);// 清除中断标志位
}
if(P1IFG & BIT1)
{
P1IFG &= ~(BIT1);// 清除中断标志位
}
if(P1IFG & BIT2)
{
P1IFG &= ~(BIT2);// 清除中断标志位
}
if(P1IFG & BIT3)
{
P1IFG &= ~(BIT3);// 清除中断标志位
}
}
void Init_CLK(void)
{
unsigned int i;
BCSCTL1 = 0X00; //将寄存器的内容清零
//XT2震荡器开启
//LFTX1工作在低频模式
//ACLK的分频因子为1

do
{
IFG1 &= ~OFIFG; // 清除OSCFault标志
for (i = 0x20; i > 0; i--);
}
while ((IFG1 & OFIFG) == OFIFG); // 如果OSCFault =1

BCSCTL2 = 0X00; //将寄存器的内容清零
BCSCTL2 += SELM1; //MCLK的时钟源为TX2CLK,分频因子为1
BCSCTL2 += SELS; //SMCLK的时钟源为TX2CLK,分频因子为1
}
4、发送编码数据处理
发送的编码数据总共有12位,前8位为地址数据,后4位为数据信息,首先要发送起始信息,然后再将编码数据一位一位地发送。
//发送编码数据
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;
}
}
5、拨号处理
拨号处理主要根据线路状态来判断分机状态,并根据分机的不同状态进行相应处理。线路状态的检测是通过比较器输入模块进行处理的。拨号处理的具体程序如下:
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))
{
//分机存在
//清除锁存信号
STCLK_Lo();
//输出1
DataOut(nLed[1]);
//给锁存信号,显示数据
STCLK_Hi();

//判断分机是否短路
nBit5 = (P1IN & BIT5) >> 5;
nBit6 = (P1IN & BIT6) >> 6;
if((nBit6 == 1) && (nBit5 == 1))
{
//分机短路
//提示音三次
Ring();
P4OUT &= ~(BIT2);
Delay_1s();
Ring();
P4OUT &= ~(BIT2);
Delay_1s();
Ring();
Delay_1s();
P4OUT &= ~(BIT2);
}//分机短路
else
{
//分机不短路
//发出振铃信号
//初始化摘机标志,为0代表没有摘机
ZhaijiFlag = 0;
//定时器中断允许
TBCTL |= TBCLR;
TBCCTL0 |= CCIE;
//在振铃时间30s内
while(RingFlag)
{
//发出振铃信号
Ring();
Delay_1s();
P4OUT &= ~(BIT2);
//判断分机是否摘机
nBit5 = (P1IN & BIT5) >> 5;
nBit6 = (P1IN & BIT6) >> 6;
if((nBit6 == 0) && (nBit5 == 0))
{
//分机摘机
//摘机标志为1,代表摘机
ZhaijiFlag = 1;
}//分机摘机
if(ZhaijiFlag == 1) break;
}//振铃时间内

//定时器中断禁止
TBCCTL0 &= ~(CCIE);

//假如分机摘机
if(ZhaijiFlag == 1)
{
//分机摘机
//对话
//定时器中断允许
TBCTL |= TBCLR;
TBCCTL0 |= CCIE;
P4OUT &= ~(BIT2);
DialogFlag = 1;
//在对话时间60s内
while( DialogFlag)
{
//打开对讲
P4OUT |= BIT0;
P4OUT |= BIT1;
P4OUT &= ~(BIT2);
P4OUT &= ~(BIT4);

//判断分机是否挂机
nBit5 = (P1IN & BIT5) >> 5;
nBit6 = (P1IN & BIT6) >> 6;
if((nBit6 == 0) && (nBit5 == 0))
{
//分机挂机
//关闭对讲
P4OUT &= ~(BIT0);
P4OUT &= ~(BIT3);
}//分机挂机,返回
else
{
//分机没有挂机
//判断是否开锁
nBit5 = (P1IN & BIT5) >> 5;
nBit6 = (P1IN & BIT6) >> 6;
if((nBit6 == 1) && (nBit5 == 1))
{
//分机开锁
for(i = 0;i < 10;i++)
{
//开电锁命令
P4OUT &= ~(BIT1);
}
break;
}//分机开锁
else//不开锁
{
;
}//不开锁
}//分机没有挂机
}//对话时间内

//定时器中断禁止
TBCCTL0 &= ~(CCIE);
}//分机摘机
}//分机不短路
}//分机存在
else //分机不存在
{
//清除锁存信号
STCLK_Lo();
//输出0
DataOut(nLed[0]);
//给锁存信号,显示数据
STCLK_Hi();

//提示音两次
Ring();
Delay_1s();
Ring();
}

nidle = 1; //重新开始扫描键盘
}


系统构成.JPG (38.18 KB )

系统构成.JPG

楼层译码器.JPG (205.3 KB )

楼层译码器.JPG

显示模块.JPG (141.82 KB )

显示模块.JPG

主机MSP430.JPG (218.5 KB )

主机MSP430.JPG

相关帖子

沙发
dirtwillfly| | 2015-6-26 13:36 | 只看该作者

使用特权

评论回复
板凳
JY-DX-JY| | 2015-6-26 17:34 | 只看该作者
顶一个。

使用特权

评论回复
地板
uestc_zyd|  楼主 | 2015-6-29 07:59 | 只看该作者

使用特权

评论回复
5
shenmu2012| | 2015-6-29 20:21 | 只看该作者
整个系统由门口主机、楼层译码器和室内分机组成。门口主机接收用户输入数据、呼叫处理和控制电控锁。整个系统采用总线方式布线,门口主机到楼层译码器采用3总线方式,楼层译码器到室内分机采用无极性的2总线方式,保证即使用户线短路也不会影响整个系统。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

64

帖子

1

粉丝