📄 m2.c
字号:
#include "reg51.h"
#include "absacc.h"
// uart 485
sbit RE_DE = P1^0;
#define TXD_485 1
#define RXD_485 0
// watch dog
sbit CLK = P1^1;
// double port SDRAM
#define DoublePort_W 0
#define DoublePort_R 1
sbit BUSY = P3^3;
#define COMMAND_SET 'S'
#define COMMAND_FIND 'T'
#define COMMEND_FIND 't'
#define COMMAND_GET 'G'
#define COMMAND_CLR 'C'
#define PC_SET 'V'
#define PC_GET 'G'
#define PC_FIND 'F'
#define PC_ERROR 'e'
#define ACK 'o'
#define SET_ACK 's'
#define GET_ACK 'g'
#define FIND_ACK 'f'
#define SET_OK 1
#define SET_ERROR 0
#define FIND_LEN 7
#define SET_LEN 7
#define GET_LEN 18
sbit test=P1^2;
sbit test1=P1^3;
#define RAM_order 0
#define RAM_set_addr 10
#define RAM_find_addr 20
#define RAM_get_addr 30
#define RAM_clr_addr 40
#define RAM_para_addr 50
#define RAM_data_addr 2000
#define WAIT_for_set 0xffff
#define WAIT_for_find 0x7fff
#define TRY_set 0x7000
#define TRY_find 0x7000
void UART_TXD(unsigned char uartdata);
bit UART_RXD(unsigned char *rxd_data);
void initialize(void);
void wait(unsigned short int x);
void DoublePortRAM( bit wr, // wr=0/1 -- write/read
unsigned char length, // data length
unsigned short int address, // RAM start address
unsigned char *buf); // data buffer
void find(unsigned char s_addr);
main()
{
unsigned char i;
unsigned char buffer[GET_LEN+1];
unsigned short int ustemp;
unsigned char address; // slave address
// initialize
CLK=0;CLK=1; // WatchDog
initialize();
address=0; // slave address
while(1)
{
for(i=0;i<GET_LEN+1;i++) buffer[i]=0; // clear buffer
DoublePortRAM(DoublePort_R,1,RAM_order,&i); // check DoublePortSDRAM order unit
CLK=0;CLK=1; // WatchDog
switch(i)
{
case COMMAND_CLR: // clear slave_parameter
DoublePortRAM(DoublePort_R,1,RAM_clr_addr,&buffer[0]); // get slave_address
RE_DE = TXD_485; // enable txd to 485
TB8=1; // ready to send slave_address
UART_TXD(buffer[0]); // send slave_address
RE_DE = RXD_485; // enable rxd from 485
if( (UART_RXD(&i))&&(i==ACK) ) // receive slave_ack? & slave_ack is right??
{ // have received slave_ack & slave_ack is right
RE_DE = TXD_485; // send setting_value to slave
TB8 = 0;
UART_TXD(COMMAND_CLR); // send order
for(i=1;i<SET_LEN;i++) // send slave setting_value
{
UART_TXD(0);
}
// del slave_old_parameter
ustemp = buffer[0]; // get slave_old_address
ustemp = ustemp*SET_LEN +1; // get the module_unit of slave_old_address
ustemp = ustemp + RAM_para_addr;
i = 0x7f; // setting module_value of slave_old_address
DoublePortRAM(DoublePort_W,1,ustemp,&i);
}
i = COMMEND_FIND; // finish find slave
DoublePortRAM(DoublePort_W,1,RAM_order,&i);
break;
case COMMAND_SET: // setting slave parameter
DoublePortRAM(DoublePort_R,SET_LEN,RAM_set_addr,buffer); // get setting_value from DoublePortSDRAM
RE_DE = TXD_485; // enable txd to 485
TB8=1; // ready to send slave_address
UART_TXD(buffer[0]); // send slave_address
RE_DE = RXD_485; // enable rxd from 485
if( (UART_RXD(&i))&&(i==ACK) ) // receive slave_ack? & slave_ack is right??
{ // have received slave_ack & slave_ack is right
RE_DE = TXD_485; // send setting_value to slave
TB8 = 0;
UART_TXD(COMMAND_SET); // send order
for(i=1;i<SET_LEN;i++) // send slave setting_value
{
UART_TXD(buffer[i]);
}
}
RE_DE=TXD_485;
i = COMMEND_FIND; // finish find slave
DoublePortRAM(DoublePort_W,1,RAM_order,&i);
break;
case COMMAND_FIND: // find slave
test1=!test1;
DoublePortRAM(DoublePort_R,1,RAM_find_addr,&buffer[1]); // get slave_address from DoublePortSDRAM
find(buffer[1]); // find slave parameter
i = COMMEND_FIND; // finish find slave
DoublePortRAM(DoublePort_W,1,RAM_order,&i);
default: // get slave_collect_data
test =!test;
ustemp = address;
ustemp = ustemp*FIND_LEN+1;
ustemp = ustemp+RAM_para_addr;
DoublePortRAM(DoublePort_R,1,ustemp,&i);
if(i&0x80) // slave enable
{
CLK=0;CLK=1; // WatchDog
RE_DE = TXD_485;
TB8 = 1;
UART_TXD(address);
RE_DE = RXD_485;
if( UART_RXD(&i)&&(i==ACK) ) // build uart
{
RE_DE = TXD_485;
TB8 = 0;
UART_TXD( COMMAND_GET ); // command-string
for(i=0;i<6;i++)
{
UART_TXD(0);
wait(10);
}
RE_DE = RXD_485;
for(i=0;i<GET_LEN+1;i++) UART_RXD(&buffer[i]); // collect slave data
buffer[2] = buffer[2]&0x7f;// have slave module
buffer[2] = buffer[2]+0x80;
}
}
else // slave disable
buffer[2] = 0;
buffer[1] = address; // save data to SDRAM
ustemp = address;
ustemp = ustemp*GET_LEN;
ustemp = ustemp+RAM_data_addr;
DoublePortRAM(DoublePort_W,GET_LEN,ustemp,&buffer[1]);
address++;
if(address>25) address=0; // test
break;
} // switch
CLK=0;CLK=1; // WatchDog
} // while
}
// ============================== function ===============================================
/*
向主机发送数据
参数:
uartdata — 将要发送的串行数据:unsigned char
执行方法:
令TB8=0(避免引起其他从机进行响应),开485(允许485发送),发送串口数据,开485(允许485接收)
*/
void UART_TXD(unsigned char uartdata)
{
EA=0; // close uart
SBUF=uartdata; // send data to serial
while(!TI) ;
TI=0;
EA=1; // open uart
}
bit UART_RXD(unsigned char *rxd_data)
{
#if 1
// can break loop
unsigned short int i;
//unsigned long int i;
for(i=0;i<0xa000;i++)
{
if(RI) break; // 0xf42400 ~= 16s
CLK=0;CLK=1;
}
if(i>=0xa000) return 0; // error
#else
// can't break loop
while(!RI) ;
#endif
RI = 0;
*rxd_data = SBUF;
return 1; // ok
}
/*
初始化本从机,使其开始正常工作
参数:
i,uctemp — 临时变量
执行:清双口RAM,清串口缓冲区,串口(9位,9,600波特/秒,开串口中断),清中断标志,清中断指针,发送初始化完成标志
*/
void initialize(void)
{
unsigned char i;
// WatchDog
CLK=0;CLK=1;
// wait for m1.c
wait(0xffff);
// initialize
TMOD=0x20; // 9600 band
TH1= 0xfd;
TL1=0xfd;
SCON=0xd0; //0xf0; // uart: format3, 9 bits
PCON = 0; // PCON=0x00/0x80; -- 9,6kBand/19.2kBand
TR1 = 1; // start to count time & offer 9,600 bit/s
RI = 0;
EA=0;
RE_DE = TXD_485;
}
/*
延时
参数:
x — 延时长度:unsigned short int
*/
void wait(unsigned short int x)
{
while(x--) ;
return;
}
/*
读写双口RAM
参数:
wr — write/read flag(0/1-write/read):bit
length — data length:unsigned char
address — SDRAM start address:unsigned short int
buf — data buffer:unsigned char *
执行:
若wr=0,则向双口RAM的address单元依次写入length个数据;若wr=1,则从双口RAM的address单元依次读出length个数据
*/
void DoublePortRAM( bit wr, // wr=0/1 -- write/read
unsigned char length, // data length
unsigned short int address, // RAM start address
unsigned char *buf) // data buffer
{
unsigned char i;
unsigned uctemp;
uctemp = (unsigned char) wr;
if(uctemp) // read from DoublePortRam
{
for(i=0;i<length;i++)
{
while(!BUSY) {CLK=0;CLK=1;} // DoublePortSDRAM is busy
buf[i]=XBYTE[address+i]; // read data from DoublePortSDRAM
}
}
else // write to DoublePortRAM
{
for(i=0;i<length;i++)
{
while(!BUSY) {CLK=0;CLK=1;} // DoublePortSDRAM is busy
XBYTE[address+i] = buf[i]; // write data to DoublePortSDRAM
}
}
}
/*
查找从机
参数:
s_addr — 被查找的从机地址
执行:
令TB8=1,表明为地址帧,发送该地址帧,收从机的应答信号。在预定的时间内若收到从机的应答信号,则要求从机返回从机参数;若未收到从机应答信号,则赋值未找到从机,并将查找结果写入双口RAM中,
*/
void find(unsigned char s_addr)
{
unsigned char buf[FIND_LEN+1];
unsigned char i;
unsigned short int ustemp;
for(i=0;i<FIND_LEN+1;i++) buf[i]=0; // initialize buf[]
RE_DE = TXD_485;
TB8=1;
UART_TXD(s_addr);// send slave address
RE_DE = RXD_485;
if( UART_RXD(&i)&&(i==ACK) ) // build uart
{
RE_DE = TXD_485;
TB8 = 0; // uart slave data
UART_TXD( COMMAND_FIND ); // command-string
for(i=0;i<6;i++)
{
UART_TXD(0);
// wait(10);
}
RE_DE = RXD_485;
CLK=0;CLK=1;
for(i=0;i<FIND_LEN+1;i++) UART_RXD(&buf[i]); // collect slave data
buf[2] = buf[2]&0x7f;// have slave module
buf[2] = buf[2]+0x80;
}
else /* 无从机应答 */
buf[2]=0x7f;
buf[1] = s_addr;
/* 查找结果存入双口RAM */
ustemp = s_addr;
ustemp = ustemp*FIND_LEN;
ustemp = ustemp + RAM_para_addr;
DoublePortRAM(DoublePort_W, FIND_LEN, ustemp , &buf[1]);
CLK=0;CLK=1; // watch dog
return ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -