📄 modbus.c
字号:
/*
实际用12MHZ晶振 BAUDRATE 4800
*/
/*TMOD=0x21; /T1 use COM T0 count */
TR1=1;
SCON=0xf0;
TH1=0xf3; // *f3 smod=1; for 4800 baud at 12Mhz C book pager 125 */
/*TH1=0xfd; for 9600 baud at 11.059 C book pager 125 */
PCON=0x80; /*4800 pcon=0x80 pc set as 18h */
TB8=1;
SM2=0;
SBUF=0;
/*r_in=SBUF;*/
REN=1;
RI=0;
ES=1;
EA=1;
}
/*---------------------------------------------------------*/
/*********************************************************/
void t0int(void) interrupt 1 using 1
{
/*TH0=0X3C; TL0=0XB6; 50ms */
/*TH0=0xfc; TL0=0x1e;*/ /*1ms*/
/*TH0=0x3c; TL0=0xa6;*/
/*每次62.5MS=62500=F424H=(0BDCH)补码
每16次中断为1秒
*/
TH0=0x0b; TL0=0xe0; /*DC+4=E0H*/
/***********/
T_50ms++;T_key++;
ms_timing++;
if((T_50ms&0xf8)!=0){REN=1; r_ptr=0;}
if((ms_timing&0x10)!=0){
ms_timing=0;second++;
second1++; second2++; up_second++;
if(second>=60){
second=0;minute++;minuter++;
if(minute>=60){
minute=0;hour++;
}
}
}
}
/*********************************************************/
void t1int(void) interrupt 3 using 2
{
return;
}
/*********************************************************/
/*----------------------------------------------------*/
/*interrupt [0x23] void SCON_int (void); Serial Port */
/* Serial Port */
void SCON_int(void) interrupt 4 using 1
{
//uchar status;
if(RI){
chint=SBUF;
flag_com=1;
if(r_ptr==0){
if(chint!=NUM){ //不是叫我
T_50ms=0; REN=0; flag_232C=0;
}else{
r_buff[r_ptr]=chint; r_ptr++; //叫我
T_50ms=0; flag_232C=0;
}
}else{
r_buff[r_ptr]=chint; r_ptr++; //收指令,共8字节
}
if(r_ptr>=8){flag_232C=1;}
RI=0;
}
if(TI)TI=0;
}
/*----------------------------------------------------*/
/*---------------------------------------------------------*/
void delay(uchar n)
{
data uchar i,j,k;
for(i=0;i<n;i++){
for(j=0;j<250;j++){
for(k=0;k<25;k++){
rst_wdog();
}
}
}
}
/*---------------------------------------------------------*/
//应答上位机,并给上传数据
/***************************************/
void send_data(uchar *buff,uchar n)
{
uchar ch,i;
ch=0; i=0;
TI=1;
TI=1;
TI=1;
while(TI==0);
SBUF=0x41;
TI=0; /*发送文件头‘ A ’*/
t_count=0; //CRCT=0;
while(t_count<n){
ch=((char *)&COM_buff)[t_count++]; /*up_data[NUM][t_count++];*/
while(TI==0);
SBUF=ch; /*发送文件块*/
TI=0;
//CRCT+=ch; /*ch;*/
}
while(TI==0);
SBUF=buff[n]; //CRCT; /*发送校验码*/
TI=0;
while(TI==0);
SBUF=buff[n+1]; //CRCT; /*发送校验码*/
TI=0;
while(TI==0);
}
/***************************************/
/*---------------------------------------------------------*/
void itoa(int x,unsigned char *str)
{
data unsigned int n;
data unsigned char chn,*p,str1[5];
data unsigned char i,j;
if(x<0){
*str++='-';
x=-x;
}
n=x;
p=str1;
j=0;
while(n!=0){
chn=n%10;
n=n/10;
*p++=chn+'0';
j++;
}
if(j!=0){
p--;
for(i=0;i<j;i++)*str++=*p--;
}
else *str++='0';
*str=0;
return;
}
/*---------------------------------------------------------*/
/*---------------------------------------------------------*/
//与替代7219显示条兼容
/*---------------------------------------------------------*/
void dis_7219(uchar iw,uchar ix,uchar chl)
{
data uchar i,j,nc;
clk=0;
if(chl==0)load=0;else load2=0;
for(j=0;j<25;j++)nc=0;
ab=iw;
for(i=0;i<8;i++){
din=abit7;
ab<<=1;
/*abit0=dout; dout;*/
clk=1;
for(j=0;j<5;j++)nc=0;
clk=0; for(j=0;j<5;j++)nc=0;
}
ab=ix;
for(i=0;i<8;i++){
din=abit7;
ab<<=1;
/*abit0=dout;*/
clk=1;
for(j=0;j<5;j++)nc=0;
clk=0; for(j=0;j<5;j++)nc=0;
}
if(chl==0)load=1; else load2=1;
for(j=0;j<25;j++)nc=0;
}
/*---------------------------------------------------------*/
/*----------------------------------------------------*/
/*
chl=1,2,3 select display the LED view window
*/
void display(uint x,uchar chl)
{
data uchar str[5],*p,i;
code uchar wei[9]= {2,3,4, 5,1,2, 4,3,5};
code uchar NIC[9]={0,0,0, 0,1,1, 1,1,1};
data uchar b_ptr;
p=str; i=1;
if(chl>3) return;
b_ptr=3*(chl-1); /*b_ptr=0--8*/
itoa(x,str);
if(x>999){
for(i=0;i<3;i++)dis_7219(wei[b_ptr+i],*p++,NIC[b_ptr+i]); /*i!=0*/
}else{
if(x>99){
dis_7219(wei[b_ptr],*p++,NIC[b_ptr]);
dis_7219(wei[b_ptr+1],(*p++|0x80),NIC[b_ptr+1]);
dis_7219(wei[b_ptr+2],*p++,NIC[b_ptr+2]);
}else{
if(x>9){
dis_7219(wei[b_ptr],0xf,NIC[b_ptr]);
dis_7219(wei[b_ptr+1],(*p++|0x80),NIC[b_ptr+1]);
dis_7219(wei[b_ptr+2],*p,NIC[b_ptr+2]);
}else{
dis_7219(wei[b_ptr],0xf,NIC[b_ptr]);
dis_7219(wei[b_ptr+1],0x80,NIC[b_ptr+1]);
dis_7219(wei[b_ptr+2],*p,NIC[b_ptr+2]);
}
}
}
}
/*----------------------------------------------------*/
void main(void)
{
code char data1[]={0x1,1,0x01,0xfa,0,0x2,0x6f,0xf7,0x0b,0xb8,0x0b,0xb8,0,0,1,0x2d,0,0x3e,7,8,9,10};
int crc,count,crc1;
uchar i,ch,work;
bit onebit;
for(i=0;i<8;i++) r_buff[i]=data1[i];
crc=CRC16(r_buff,4); //形成的crc=低位在前,在int中刚好高低颠倒
onebit=1; //read_a_bit(3);
in_buff[0]=ex_buff[1]=0xff;
for(i=0;i<5;i++)in_value[i]=ex_value[i]=100+i;
/*
for(i=0;i<8;i++){
onebit=read_a_bit(in_buff,i+5);
write_a_bit(ex_buff,i,onebit);
}
ch=fun_code(COM_buff,0x11);
crc=CRC16(data1,6); //char *puchMsg, uchar usDataLen)
*/
crc=0; flag_232C=0; r_ptr=0;
initial(); NUM=1; count=0; //NUM为机器号
while(1){
while(work==second){
if(flag_232C){ //收到上位机来的指令
flag_232C=0; r_ptr=0;
crc=CRC16(r_buff,6); //收到的数据CRC校验
crc1=r_buff[7]+(r_buff[6]<<8); //对方的CRC码
if(crc==crc1) flag_r=1; else flag_r=0; //CRC是否相等
rst_wdog();
}
//getkey();
rst_wdog();
}
work=second;
if(flag_r){
receive=!receive; //接收到命令灯光指示
flag_r=0;
for(i=0;i<8;i++)COM_buff[i]=r_buff[i];
ch=fun_code(COM_buff,NUM);
}
lamp=!lamp; //主循环指示
display(in_buff[0],1); //in_buff[0],1);
display(in_value[0],2); //in_value[0],2);
//if(count>10) r_buff[6]=r_buff[7]=0;
count++; if(count>999)count=0;
display(count,3);
if(flag_com){flag_com=0; count=0;}
EA=1; ES=1; SM2=0; TB8=1; ET0=1; TR0=1;
rst_wdog();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -