📄 pic.c
字号:
********************************************************************************************************/
#include <pic.h>
//#include <pic12f6x.h>
/*****定义配置字*****/
__CONFIG(INTIO&WDTDIS&PWRTDIS&BOREN&PROTECT); //RC震荡,看门狗关,上电延时关,低电压复位允许,代码保护
#define CLI() GIE = 0 //清中断
#define SEI() GIE = 1 //开中断
#define EEROM_ADDR 1 //下位机地址在EErom中的地址
/*****定义管脚*****/
#define CALLKEY 1 //呼叫按键,高电平有效,与呼叫灯共用
#define CANCELKEY 3 //取消呼叫按键,低电平有效
#define TX 4 //数据发送管脚
#define RX 0 //数据接收管脚
#define POWERCONTR 5 //语音模块电源控制管脚,高电平有效
#define BELL 2 //响铃
#define BELL_DDR_OUT TRISIO &= ~(1<<BELL)
#define BELL_DDR_IN TRISIO |= (1<<BELL)
#define BELL_SET GPIO |= (1<<BELL)
#define BELL_CLR GPIO &= ~(1<<BELL)
#define BELL_H GPIO & (1<<BELL)
#define BELL_L !(GPIO & (1<<BELL))
#define POWERCONTR_DDR_OUT TRISIO &= ~(1<<POWERCONTR)
#define POWERCONTR_DDR_IN TRISIO |= (1<<POWERCONTR)
#define POWERCONTR_SET GPIO |= (1<<POWERCONTR)
#define POWERCONTR_CLR GPIO &= ~(1<<POWERCONTR)
#define POWERCONTR_H GPIO & (1<<POWERCONTR)
#define POWERCONTR_L !(GPIO & (1<<POWERCONTR))
#define CALLKEY_DDR_OUT TRISIO &= ~(1<<CALLKEY)
#define CALLKEY_DDR_IN TRISIO |= (1<<CALLKEY)
#define CALLKEY_SET GPIO |= (1<<CALLKEY)
#define CALLKEY_CLR GPIO &= ~(1<<CALLKEY)
#define CALLKEY_H GPIO & (1<<CALLKEY)
#define CALLKEY_L !(GPIO & (1<<CALLKEY))
#define CANCELKEY_DDR_OUT TRISIO &= ~(1<<CANCELKEY)
#define CANCELKEY_DDR_IN TRISIO |= (1<<CANCELKEY)
#define CANCELKEY_SET GPIO |= (1<<CANCELKEY)
#define CANCELKEY_CLR GPIO &= ~(1<<CANCELKEY)
#define CANCELKEY_H GPIO & (1<<CANCELKEY)
#define CANCELKEY_L !(GPIO & (1<<CANCELKEY))
#define RX_DDR_IN TRISIO |= (1<<RX) //接收管脚定义为输入
#define TX_DDR_OUT TRISIO &= ~(1<<TX) //发送管脚定义为输出
#define RX_PIN_H GPIO & (1<<RX) //接收管脚为高电平
#define RX_PIN_L !(RX_PIN_H) //接收管脚为低电平
#define TX_PORT_H GPIO |= (1<<TX) //发送管脚置高电平
#define TX_PORT_L GPIO &= ~(1<<TX) //发送管脚置低电平
/*****特定常量定义*****/
/*****操作码关键字*****/
#define INSPECTION 0b0101 //巡检
#define SETADRESS 0b0011 //设定地址
#define CONTROL 0b1010 //控制呼叫
#define RESET 0b0000 //复位
/*****状态码关键字*****/
#define CANCELCALL 0b110 //取消呼叫
#define STARTCALL 0b011 //开始呼叫
#define CANCELTALK 0b101 //取消通话
#define STARTTALK 0b010 //开始通话
#define NOTHINE 0 //待机状态
/*****声明结构体*****/
struct TXDataStruct //发送数据的结构体
{
unsigned char Adress ; //下位机地址 1 -- 125
unsigned char State ; //下位机状态
};
struct RXDataStruct //接收数据的结构体
{
unsigned char Operation ;
unsigned char Adress ;
unsigned char State ;
};
/*****声明变量*****/
unsigned char TXSign ; //发送数据繁忙标志 1:繁忙 0:空闲
unsigned char RXSign ; //是否有接收数据标志 1:有新数据 0:无新数据
struct TXDataStruct TXData ;
struct RXDataStruct RXData ;
unsigned char LocalAdress ; //本机地址
unsigned char LocalState ; //本机状态
/*********************************************************************************************************
** 函数名称: ConmuDelay
** 功能描述: 延时通讯频率的半个周期(10us)
** 输 入: A :
** B :
** C :
** 输 出: 返回此期间内总线状态
** 全局变量:
** 调用模块:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
unsigned char ConmuDelay (void)
{
//unsigned char i ;
unsigned char k ;
//for(i=3 ; i>0 ; i--) //i 与晶振有关
//{
if(RX_PIN_H) k = 0 ;
else k = 1 ;
//}
//if(k>0) k = 1 ;
return k ;
}
/*********************************************************************************************************
** 函数名称: ConmuTXBit
** 功能描述: 完成1bit的发送
** 输 入: A :
** B :BitData :要发送的数据1bit
** C :
** 输 出: 返回总线是否被占,1为被占用
** 全局变量:
** 调用模块:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
unsigned char ConmuTXBit ( unsigned char BitData )
{
unsigned char i ;
while ( RX_PIN_L ) ;
while ( RX_PIN_H ) ;
if (BitData) TX_PORT_H ;
else TX_PORT_L ;
ConmuDelay () ;
i = ConmuDelay () ;
TX_PORT_H ;
ConmuDelay () ;
if ( i!=BitData ) //检测总线是否被占
{
return 1 ;
}
else
{
return 0 ;
}
}
/*********************************************************************************************************
** 函数名称: ConmuRXBit
** 功能描述: 完成1bit的接收
** 输 入: A :
** B :
** C :
** 输 出: 接收到的数据1bit
** 全局变量:
** 调用模块:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
unsigned char ConmuRXBit ( void )
{
unsigned char i ;
while ( RX_PIN_L ) ;
while ( RX_PIN_H ) ;
i = ConmuDelay () ;
i &= ConmuDelay () ;
ConmuDelay () ;
return i ;
}
/*********************************************************************************************************
** 函数名称: DataCheck
** 功能描述: 进行数据效验
** 输 入: A :
** B :
** C :
** 输 出: 产生校验码4bits,放在低4位
** 全局变量:
** 调用模块:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
unsigned char DataCheck (unsigned char i,unsigned char j,unsigned char k)
{
unsigned char x ;
return x ;
}
/*********************************************************************************************************
** 函数名称: Conmunication
** 功能描述: 与下位机通讯模块
** 针结构 : 低电平 操作码 地址 状态 校验 应答(成功为0)
** 4bits 4bits 0+7bits 3bits 4bits 1bits
** 频率50KHZ,一针约用时24bits*40us=1060us
** 输 入: A :
** B :
** C :
** 输 出: 0 :
** 1 :
** 全局变量:
** 调用模块:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void Conmunication (void)
{
unsigned char ConmuSign ; //为1表示收数据,为0表示发数据
unsigned char ConmuCheck ; //做校验用
//unsigned char i ;
//起始位
if( RX_PIN_H ) return ;
ConmuDelay ();
ConmuDelay ();
ConmuDelay ();
if(RX_PIN_H) return ;
while ( RX_PIN_L );
//接收操作码
RXData.Operation = ( ConmuRXBit ()<<3 );
RXData.Operation |= ( ConmuRXBit ()<<2 );
RXData.Operation |= ( ConmuRXBit ()<<1 );
RXData.Operation |= ( ConmuRXBit ()<<0 );
/*RXData.Operation = 0 ;
i = 4 ;
do
{
i-- ;
RXData.Operation |= ( ConmuRXBit ()<<i );
}
while (i);*/
switch (RXData.Operation) //处理操作码
{
case INSPECTION : ConmuSign = 1 ; break ;
case SETADRESS : ConmuSign = 0 ; break ;
case CONTROL : ConmuSign = 0 ; break ;
case RESET : ConmuSign = 0 ; break ;
default : return ;
}
if( ConmuSign ) //发送数据
{
TXData.Adress = LocalAdress ;
TXData.State = LocalState ;
ConmuCheck = DataCheck (RXData.Operation,TXData.Adress,TXData.State) ; //校验
//发送地址
/*i = 8 ;
do
{
i-- ;
if ( ConmuTXBit ( (TXData.Adress>>i) & 1 ) )return;
}
while (i);*/
if ( ConmuTXBit ( (TXData.Adress>>7) & 1 ) )return;
if ( ConmuTXBit ( (TXData.Adress>>6) & 1 ) )return;
if ( ConmuTXBit ( (TXData.Adress>>5) & 1 ) )return;
if ( ConmuTXBit ( (TXData.Adress>>4) & 1 ) )return;
if ( ConmuTXBit ( (TXData.Adress>>3) & 1 ) )return;
if ( ConmuTXBit ( (TXData.Adress>>2) & 1 ) )return;
if ( ConmuTXBit ( (TXData.Adress>>1) & 1 ) )return;
if ( ConmuTXBit ( (TXData.Adress>>0) & 1 ) )return;
//发送状态
/*i = 3 ;
do
{
i-- ;
if ( ConmuTXBit ( (TXData.State>>i) & 1 ) )return;
}
while (i);*/
if ( ConmuTXBit ( (TXData.State>>2) & 1 ) )return;
if ( ConmuTXBit ( (TXData.State>>1) & 1 ) )return;
if ( ConmuTXBit ( (TXData.State>>0) & 1 ) )return;
//发送校验
/*i = 4 ;
do
{
i-- ;
if ( ConmuTXBit ( (ConmuCheck>>i) & 1 ) )return;
}
while (i);*/
if ( ConmuTXBit ( (ConmuCheck>>3) & 1 ) )return;
if ( ConmuTXBit ( (ConmuCheck>>2) & 1 ) )return;
if ( ConmuTXBit ( (ConmuCheck>>1) & 1 ) )return;
if ( ConmuTXBit ( (ConmuCheck>>0) & 1 ) )return;
//接收应答
if ( !ConmuRXBit () )TXSign = 0 ; //发送成功
}
else //接收数据
{
//接收地址
/*RXData.Adress = 0 ;
i = 8 ;
do
{
i-- ;
RXData.Adress = ( ConmuRXBit ()<<i ) ;
}
while (i);*/
RXData.Adress = ( ConmuRXBit ()<<7 ) ;
RXData.Adress |= ( ConmuRXBit ()<<6 ) ;
RXData.Adress |= ( ConmuRXBit ()<<5 ) ;
RXData.Adress |= ( ConmuRXBit ()<<4 ) ;
RXData.Adress |= ( ConmuRXBit ()<<3 ) ;
RXData.Adress |= ( ConmuRXBit ()<<2 ) ;
RXData.Adress |= ( ConmuRXBit ()<<1 ) ;
RXData.Adress |= ( ConmuRXBit ()<<0 ) ;
//接收状态
/*RXData.State = 0 ;
i = 3 ;
do
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -