本帖最后由 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; //重新开始扫描键盘
- }
复制代码
3qu
一周热门 更多>