📄 zhukong.c
字号:
/**************************************************************************************/
/* 主控单片机 */
/* 功能1 :主控单片机与PC串口通信 */
/* 功能2 : 主控单片机与从机485总线通信 */
/* 功能3 : 主控单片机液晶显示 */
/* Author : 蒋铃锋 */
/* 日期 : 2005.10.27 */
/**************************************************************************************/
#include <W77C32.H>
#define uchar unsigned char
#define uint unsigned int
sbit RTS=P1^0;
bit TFF0=0;
///////////////////////////////////////////////////////////////////////////////
void init(void) ;
void IFready(void);
void send(void);
void delay1S(uchar time);
/////////////////////////////////////////////////////////////////////////////////
void F_data(unsigned char addr,unsigned char *buff);
void Time0(void);
void delay(unsigned int i);
void delay1(unsigned int i);
unsigned char buff[4]={0};
/////////////////////////////////////////////////////////////////////////////
uchar receive0=0xAA; //接收PC机的请求发送
uchar idata send0[3]={0xBB,0xBB,0xBB}; //发送给PC机的确认
uchar idata send1[3]={0xAB,0xAB,0xAB}; //数据的起始位
uchar idata send2[2]={0x00,0x00}; //数据的结束位
uchar xdata senddata[24][3];
uint sum=0; //所有数据位的和
uchar parity=0; //校验位
void main()
{
uchar i,j;
uchar MA_NUM; //机号0-23
uchar MA_ADDR; //从机硬件地址
uchar temp;
init();
for (i=0;i<24;i++) //初始化数据区
for (j=0;j<3;j++)
{senddata[i][j]=0;}
while(1)
{
for (MA_NUM=0;MA_NUM<24;MA_NUM++) //采集所有从机(24台)的数据
{ temp=MA_NUM<<3 ;
MA_ADDR=(temp|0x07) ; ////计算从机硬件地址 P2口为硬件地址
for(i=0;i<4;i++)
buff[i]=0; //初始化缓冲区
F_data(MA_ADDR,buff);
for(i=0;i<3;i++)
senddata[MA_NUM][i]=buff[i]; //采集第MA_NUM台从机数据 ,只需前3 个字节
//第4个字节为校验位,如果没收到数据,则为0
}
IFready();
send();
delay1S(1); //延时1秒
}
}
void init(void)
{
RCAP2H=0xff; RCAP2L=0xb2; //(RCAP2H,RCAP2L)=0xff64 4800波特 (RCAP2H,RCAP2L)=0xffB2 9600波特
TH2=0xff; TL2=0xb2; //T2波特率计算公式:晶振频率/(32*(65536-(RCAP2H,RCAP2L))
T2CON=0x30; //用定时器2做串口0的波特率发生器
TCLK=1; //T2发送时钟标志
RCLK=1; // T2接收时钟标志
TR2=1; // 打开T2中断
REN=1; //打开串口0接收功能
PCON=0x00; //SMOD=0;波特率不加倍
//SM0=0;
SM1=1; //模式1
//SM2=0;
//ES=1; //打开串行口0中断 ????? 如果用查询方式收,则=0 ?????
EA=1; //打开所有中断?????????????????????????????????????????
ET2=0; //关闭T2的中断
PMR|=0x01; //使用片上SRAM
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
TMOD=0x21; //定时器0,方式1 定时器2,方式2
TH1=0XFB;
TL1=0XFB;
//TH1=0Xe6;
//TL1=0Xe6;
TH0=-60000/256; //定时30MS
TL0=-(60000%256);
PCON=0X00;
TR1=1;
SCON1=0XD8; //TB8=1; sm2=0;
// EA=1;
ET0=1; //使能T0定时器中断
ET1=0; //关断T1中断
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
void IFready(void)
{ uchar i;
//uchar test;
do{
if(RI==0)
{for (i=0;i<3;i++)
{SBUF=send0[i];
while(TI==0);
TI=0; //是否发送完一个字节
}
delay1S(1);
}
//while(RI==0);
else
RI=0; //是否接收到一个字节
}while((SBUF^receive0)!=0); //PC 机未准备好
}
void send(void) //PC机准备好
{uchar i;
uchar j;
uchar temp=3;
// uchar xdata senddata[24][3];
for(i=0;i<3;i++) //发送起始位
{SBUF=send1[i];
while(TI==0);TI=0;
}
delay1S(1);
PMR|=0x01;
/*for(i=0;i<24;i++)
for(j=0;j<3;j++)
{
senddata[i][j]=temp;
temp++;
} */
for(i=0;i<24;i++) //发送数据位
for(j=0;j<3;j++)
{
SBUF=senddata[i][j];
sum+=senddata[i][j];
while(TI==0);TI=0;
}
parity=sum%256;
sum=0; //发送校验位
SBUF=parity;
while(TI==0);TI=0;
for(i=0;i<2;i++) //发送结束位
{SBUF=send2[i];
while(TI==0);TI=0;
}
}
void delay1S(uchar time) //time为所需延时的秒数
{
unsigned char num0;
unsigned char num1;
unsigned char num2;
unsigned char temp;
for(temp=0;temp<time;temp++)
for(num0=100;num0>0;num0--)
for(num1=147;num1>0;num1--)
for(num2=200;num2>0;num2--)
{}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
void F_data(unsigned char addr,unsigned char *buff)
{
int i,A_sign=0;
RTS=0; //主机抢总线,发送地址信息
delay(1); //延时1ms
SBUF1=addr;
while(TI_1!=1);
TI_1=0;
delay1(2); //延时2位波特率时间160微秒
RTS=1; //放总线
while(RI_1!=1) //2.接收从机发回的地址确认信号
{
TR0=1;
if(TFF0==1) //如果从机30MS不回发确认信息,强制退出,进入下一从机
{
RI_1=0;
TR0=0;
TFF0=0;
TH0=-60000/256;
TL0=-(60000%256);
return;
}
}
RI_1=0;
delay1(2);
TB8_1=0; //以下发送均为数据信息
TR0=0;
TH0=-60000/256;
TL0=-(60000%256);
if(SBUF1!=addr) //如果从机回复地址有误,主机强制该从机复位,进入下一从机
{
RTS=0; //主机抢总线,发送地址信息
delay(1); //延时1ms
SBUF1=0XFF;
while(TI_1!=1);
delay1(2);
TI_1=0;
TB8_1=1;
return; //////////////
}
else
{
RTS=0; //主机抢总线,发送地址信息
delay(1); //延时1ms
SBUF1=0x00;
while(TI_1!=1);
delay1(2);
TI_1=0;
}
RTS=1; //放总线
for(i=0;i<3;i++)
{
while(RI_1!=1) //2.接收从机发回数据
{
TR0=1;
if(TFF0==1) //如果从机30MS不回发确认信息,强制退出,进入下一从机
{
RI_1=0;
TR0=0;
TFF0=0;
TH0=-60000/256;
TL0=-(60000%256);
TB8_1=1; //置地址信息
return;
}
}
RI_1=0;
delay1(2);
TR0=0;
TH0=-60000/256;
TL0=-(60000%256);
*(buff+i)=SBUF1;
}
while(RI_1!=1) //接收从机发回校验信号
{
TR0=1;
if(TFF0==1) //如果从机30MS不回发确认信息,强制退出,进入下一从机
{
RI_1=0;
TR0=0;
TFF0=0;
TH0=-60000/256;
TL0=-(60000%256);
return;
}
}
RI_1=0;
delay1(2);
TR0=0;
TH0=-60000/256;
TL0=-(60000%256);
*(buff+3)=SBUF1;
if(*(buff+3)!=(*(buff+2)+*(buff+1)+*(buff))%0X100)
{
A_sign=1;
}
TB8_1=1; //置地址信息
return;
}
void Time0(void) interrupt 1 using 2 //定时器0中断程序
{
//tim++;
//if(tim%8==0)
TFF0=1;
}
void delay(unsigned int i) //延时ims
{
i=i*1000;
while(i--);
}
void delay1(unsigned int i) //延时i个波特率时间80微秒
{
i=i*260;
while(i--);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -