📄 m1.c
字号:
#include "reg51.h"
#include "absacc.h"
// double port SDRAM
#define DoublePort_W 0
#define DoublePort_R 1
sbit BUSY = P3^3; // DoublePortSDRAM busy signal
#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_ADD 'D'
#define PC_CLEAR 'C'
#define PC_ERROR 'e'
#define PC_ALL 'A'
#define SET_ACK 's'
#define GET_ACK 'g'
#define FIND_ACK 'f'
#define ADD_ACK 'd'
#define CLEAR_ACK 'c'
#define ALL_ACK 'a'
#define SET_OK 1
#define SET_ERROR 0
#define FIND_LEN 7
#define SET_LEN 7
#define GET_LEN 18
#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); // send data to serial
void initialize(void); // initialize slave
void wait(unsigned short int x); // wait for time
// write or read DoublePortSDRAM
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
// parameter
bit uart_flag; // interrupt flag
unsigned char pointer;// interrupt pointer
#define COUNT 8
unsigned char pc[COUNT]; // interrupt buffer
/*
串行中断服务程序:接收串口的数据,并将其存入中断缓冲区,供主程序调用
参数:
buffer[8] — 中断缓冲区:unsigned char
pointer — 中断缓冲区指针,用于指示中断缓冲区是否已满:unsigned char
uart_flag — 中断标志,供主机查询用:bit
执行方法:
直接接收PC机发送的数据桢(8个字节);收满后置位相应的标志位
*/
void uart(void) interrupt 4
{
RI = 0;
pc[pointer]=SBUF; // save data to interrupt buffer
pointer++; // adjust interrupt_pointer
if(pointer>=COUNT) // data_string end
{
pointer=0; // adjust interrupt_pointer to 0
uart_flag=1; // adjust uart_flag to 1
}
RI=0; // clear RI
}
/*
main1: 与PC机通讯,接收PC机命令(采用串口中断)并完成相应的处理过程
程序流程:
初始化:清除双口RAM单元内容,清串口缓冲区SBUF,初始化串口(9位,9,600波特/秒),开串行中断,开总中断,清除中断标志,清中断指针,发初始化完成标志'o'。
loop: 检查中断标志uart_flag(0/1-no/have),看是否有中断产生。若有,则取中断命令字pc[0],并根据该命令字执行相应的程序代码;若无,则进入下一轮循环。
命令处理程序:根据命令字pc[0]的内容进行相应的处理
{
pc[0]=PC_CLEAR:
取从机地址
将从机地址存入双口RAM的清除地址单元
向双口RAM的order单元写入'COMMAND_CLR',通知main2清除该从机参数
pc[0]=PC_ADD:
取从机地址
向双口RAM的相应单元添加从机
向主机发送添加应答信号'ADD_ACK'
pc[0]=PC_SET:
取设置值
将设置值存入双口RAM的设置单元
向双口RAM的order单元写入'COMMAND_SET',通知main2设置从机
延时,等待main2设置从机
向主机发送设置应答信号'SET_ACK'
pc[0]=PC_FIND:
取从机地址
将从机地址存入双口RAM的查找地址单元
向双口RAM的order单元写入'COMMAND_FIND',通知main2查找该从机
延时,等待main2查找从机
检查main2是否完成查找从机的命令(共试TRY_find次)
向主机发送查找应答信号'FIND_ACK'
向主机发送添加地址应答信号
pc[0]=PC_GET:
取从机地址
计算该从机的测量值在双口RAM中的存放地址
从双口RAM的相应地址中取出该从机的测量值
向主机发送取值应答信号'GET_ACK'
向主机发送从机的测量结果
pc[0]=其他值:
向主机发送报错应答信号'PC_ERROR'
}
清中断指针
清中断标志
清双口RAM的order单元
清数据缓冲区
*/
main()
{
unsigned char i;
unsigned short int ustemp;
unsigned char length;
unsigned char buffer[GET_LEN];
// initialize
initialize();
while(1)
{
i = (unsigned char) uart_flag;
if(!i) continue;
switch( pc[0] )
{
case PC_CLEAR: // clear slave_parameter
i=pc[1];
DoublePortRAM(DoublePort_W, 1, RAM_clr_addr , &i);
i = COMMAND_CLR; // ask MCS51_main2 to clear slave_parameter
DoublePortRAM(DoublePort_W,1,RAM_order,&i);
break;
case PC_ADD: // set slave_enable_flag
for(i=1;i<8;i++) buffer[i]=pc[i]; // save pc_buffer
for(i=1;i<8;i++) // save slave_enable_flag
{
ustemp=0;
ustemp=(unsigned short int) buffer[i];
ustemp=ustemp*FIND_LEN;
ustemp = ustemp+RAM_para_addr;
length=0x80;
DoublePortRAM(DoublePort_W, 1, ustemp , &buffer[i]); // save slave_address to DoublePortRAM
DoublePortRAM(DoublePort_W, 1, ustemp+1 , &length); // save slave_enable_flag to DoublePortRAM
}
UART_TXD(ADD_ACK); // send set_ack
break;
case PC_SET:
for(i=0;i<COUNT;i++) buffer[i] = pc[i]; // save setting_value
DoublePortRAM(DoublePort_W,SET_LEN,RAM_set_addr,&buffer[1]); // save setting_value to double_port_SDRAM
i = COMMAND_SET; // ask MCS51_main2 to set slave
DoublePortRAM(DoublePort_W,1,RAM_order,&i);
wait(WAIT_for_set); // wait for setting slave
wait(WAIT_for_set);
UART_TXD(SET_ACK); // send set_ack
break;
case PC_FIND:
length=pc[1]; // save slave address
DoublePortRAM(DoublePort_W,1,RAM_find_addr,&length); // ask MCS51_main2 to find slave
i = COMMAND_FIND;
DoublePortRAM(DoublePort_W,1,RAM_order,&i);
wait(WAIT_for_find); // wait for finding slave
for(ustemp=0;ustemp<TRY_find;ustemp++) // check: slave_setting finished? -- try 0xf000 times
{
DoublePortRAM(DoublePort_R,1,RAM_order,&i);
if(i==COMMEND_FIND) break;
wait(10);
}
// UART_TXD((unsigned char) (ustemp>>8)); // test
// UART_TXD( (unsigned char) ustemp); // test
if(ustemp<TRY_find) // find slave
{ // get slave_parameter_value
ustemp = length;
ustemp = ustemp*FIND_LEN;
ustemp = ustemp + RAM_para_addr;
// UART_TXD((unsigned char) (ustemp>>8)); // test
// UART_TXD( (unsigned char) ustemp); // test
DoublePortRAM(DoublePort_R, FIND_LEN, ustemp , buffer);
}
// send the result of finding_slave to PC
UART_TXD(FIND_ACK);
for(i=0;i<FIND_LEN;i++)
{
UART_TXD( buffer[i] );
}
break;
case PC_GET:
ustemp = pc[1]; // get slave collect data
ustemp = ustemp*GET_LEN;
ustemp = ustemp+RAM_data_addr;
DoublePortRAM(DoublePort_R,GET_LEN,ustemp,buffer);
// send the result of getting_slave_data to PC
UART_TXD(GET_ACK);
for(i=0;i<GET_LEN;i++)
{
UART_TXD(buffer[i]);
}
break;
default:
UART_TXD(PC_ERROR); // error command of PC
break;
}
pointer=0; // clear interrupt pointer
uart_flag=0; // clear uart flag
i = 0xff; // ask MCS51_main2 to set slave
DoublePortRAM(DoublePort_W,1,RAM_order,&i);
for(i=0;i<GET_LEN;i++) buffer[i]=0; // clear buffer
}
}
// ============================== function ===============================================
/*
向主机发送数据
参数:
uartdata — 将要发送的串行数据:unsigned char
执行方法:
令TB8=0(避免引起其他从机进行响应),开485(允许485发送),发送串口数据,开485(允许485接收)
*/
void UART_TXD(unsigned char uartdata)
{
TB8=0; /* 避免引起其他从机进行响应 */
SBUF=uartdata; // send data to serial
while(!TI) ;
TI=0; // clear TI
}
/*
初始化本从机,使其开始正常工作
参数:
i,uctemp — 临时变量
执行:清双口RAM,清串口缓冲区,串口(9位,9,600波特/秒,开串口中断),清中断标志,清中断指针,发送初始化完成标志
*/
void initialize(void)
{
unsigned char i;
unsigned char uctemp;
unsigned short int ustemp;
// clear DoublePortSDRAM 0~8000 unit
for(i=0,ustemp=0;ustemp<8000;ustemp++) DoublePortRAM(DoublePort_W,1,ustemp,&i);
// clear uart_rxd_buffer
for(i=0;i<5;i++) uctemp = SBUF;
// initialize uart
TMOD=0x20; // 9600 band
TH1= 0xfd;
TL1=0xfd;
SCON=0xd0; //0xf0; // uart: format3, 9 bits
PCON = 0x80; // PCON=0x00/0x80; -- 9,6kBand/19.2kBand
TR1 = 1; // start to count time & offer 9,600 bit/s
RI = 0;
ES = 1; // open serial interrupt
EA = 1; // open interrupt
uart_flag=0; // clear uart flag
pointer=0; // clear interrupt pointer
UART_TXD('o'); // m1 finished initialize
}
/*
延时
参数:
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); // DoublePortSDRAM is busy
buf[i]=XBYTE[address+i]; // read data from DoublePortSDRAM
}
}
else // write to DoublePortRAM
{
for(i=0;i<length;i++)
{
while(!BUSY) ; // DoublePortSDRAM is busy
XBYTE[address+i] = buf[i]; // write data to DoublePortSDRAM
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -