//*******************************************************
// 项目: 单线通讯程序
// 作者:
// 日期:2011年10月15日
// 功能:两单片机通过一个I/O口实现数据交换
// 备注:
//*******************************************************
#include "pic.h"
#include "pic16f887.h"
//*******************************************************
__CONFIG(HS&WDTDIS&PWRTEN&MCLREN&UNPROTECT&DUNPROTECT&BORDIS&IESODIS&FCMDIS&LVPDIS&DEBUGDIS&BORV21& WP1);
//*******************************************************
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long int
//*******************************************************
#define ID RB0 //定义单总线,即:数据输出引脚
#define K1 RB3
#define ID0 TRISB0
#define C CARRY
//*******************************************************
void MCU_init(void);
void delay(uint x);
void delay_1ms(uint z);
void delay_uS(uint z);
//*******************************************************
uchar a,b; //定义临时变量
uchar SBUF_M,TEMP; //定义要发送的或接收的8位数据
//*******************************************************
// 单总线 发送子程序
//*******************************************************
void danxian_fasong()
{
uchar i;
if(ID==1) //看是否空闲,
{
ID0=0; //
asm("NOP");
ID=0; //总线置0,锁定总线100ms,以便使接收方能扑捉到这个100ms的起始位,
delay_1ms(100); //起始位宽度选择原则是大于接收方大循环周期与中断函数运行时间的和;
ID=1; //再给一个上升沿,告诉接收方2毫秒后开始发送
delay_uS(1); //26uS
for(i=0;i<8;i++) //8次循环,将 SBUF_M 的8位数据全部送出
{
SBUF_M=SBUF_M<<1; //待发送的数据左移1位
ID=C; //待发送的数据赋给输出端
delay_uS(8); //109uS //每位数据保持109uS
}
ID=1; //待8位数据全部发送完毕后,务必释放总线为1
asm("NOP");
ID0=1;
}
else
{
return; //总线不空闲,跳出
}
}
//*********************************************
// 单总线 接收子程序
//*********************************************
void danxian_jieshou()
{
uchar i;
while(ID==0); //在此等待100ms剩余时间全部过去,26uS上升沿到来,则向下进行
delay_uS(1); //26uS
delay_uS(3); //50uS //延时50ms是为了扑捉数据位的中间位置
for(i=0;i<8;i++) //8次循环,将总线送来的8位数据全部接收,并赋给SBUF_M (模拟串口变量)
{
SBUF_M=SBUF_M<<1; //SBUF_M (模拟串口变量)左移1位
if(ID==1)
{
SBUF_M|=0X01;
}
else
{
SBUF_M&=0XFE;
}
delay_uS(8); //109uS接收时间必须与数据位保持时间同宽
}
a=SBUF_M; //待8位数据全部接收完毕后,将接收到的数据赋给 a ;
}
//******************主程序*******************************
void main()
{
MCU_init();
a=0;
b=0x01;
while(1)
{
//*****************发送部分******************************
if(K1==0)
{
while(K1==0);
SBUF_M=b;
danxian_fasong(); //调用发送子程序
b++;
}
//*****************接收部分******************************
if(ID==0)
{
danxian_jieshou(); //调用接收子函数
}
PORTD=a; //将a赋给PORTD显示出来
}
}
//*******************************************************
// 延时子函数(约1毫秒)
//*******************************************************
void delay_1ms(uint z) //延时子函数(约1毫秒)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
//******** 延时子函数************************************
//以下微秒级延时是在11.0592晶振下试验的:
//delay_uS(1);//26uS delay_uS(2);//38uS delay_uS(3);//50uS
//delay_uS(4);//61uS delay_uS(5);//74uS delay_uS(6);//86uS
//delay_uS(7);//98uS delay_uS(8);//109uS delay_uS(9);//122uS
//delay_uS(10);//133uS
//*******************************************************
void delay_uS(uint z) //延时子函数(微秒级)
{
uint x;
for(x=z;x>0;x--)
{
;
}
}
//*******************************************************
void delay(uint x)
{
uint a,b;
for(a=x;a>0;a--)
{
asm("clrwdt");
for(b=110;b>0;b--);
}
}
//*******************************************************
void MCU_init(void)
{
STATUS&=0x18;
OPTION=0x0F;
INTCON=0x00;
PIE1=0x00;
PIE2=0x00;
PIR1=0x00;
PIR2=0x00;
PCON=0x00;
//*******************************************************
// A口初始化
//*******************************************************
TRISA=0x03;
PORTA=0x00;
ANSEL=0X00;
ADON=0; //关闭AD功能 0:Timer1门控源为SYNCC2OUT 0:输出异步
PCON|=0x00;
OPTION&=0xDF;
SSPCON=0x09;
//*******************************************************
// B口初始化
//*******************************************************
TRISB=0x0F;
PORTB=0x00;
ANSELH=0X00;
CCP1CON=0x00;
CM2CON1=0x02;
IOCB=0x00; //禁止B口电平变化中断
INTCON&=0xEB;
OPTION&=0x7F;
WPUB=0xFF; //禁止B口弱上拉
//*******************************************************
// C口初始化
//*******************************************************
TRISC=0x01;
PORTC=0x00;
CCP1CON=0x00;
CCP2CON=0x00;
PSTRCON=0x00;
RCSTA=0x00;
SSPCON=0x09;
T1CON=0x00;
STATUS&=0x18; //0001 1000
OPTION=0x0F; //0000 1111
INTCON=0x00;
PIE1=0x00;
PIE2=0x00;
PIR1=0x00;
PIR2=0x00;
PCON=0x00;
//*******************************************************
// D口初始化
//*******************************************************
TRISD=0x00;
PORTD=0x00;
PSTRCON=0x00;
//*******************************************************
// E口初始化
//*******************************************************
TRISE=0x01;
PORTE=0x00;
ANSEL=0x00;
}