⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 k_modbus.c

📁 用于在线仪表的 modbus,仅供参考
💻 C
📖 第 1 页 / 共 2 页
字号:
/***********************
  Program name: modbus.c
***********************/
#include "sercom.h"
#include "mydef.h"
#include <alloc.h>
#include <dos.h>
#include <conio.h>
#include <fcntl.h>
#include <sys\stat.h>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int     port_ads;
static BYTE    inchr;
static BYTE    Picmask;
static int     comerror,picaddr;
BYTE mcont=MCONT_DTR|MCONT_OUT1|MCONT_OUT2;
static BYTE  lstat,mstat;
static BOOLEAN fifo_exist = FALSE;
static unsigned char ch[10]={0};
unsigned char outchar[1024]={0};
static char    max_send = 1;
static char *out_buf;
static char *in_buf;
static char *dataout_buf;
static char *datain_buf;
static RING    outring, inring,datain,dataout;
static BOOLEAN inxoff = FALSE;

void setbreak(long milliseconds);
void interrupt (*oldhand)(void);
void interrupt inthand(void);
BOOLEAN com_buffers(BOOLEAN create,int inbufsize,int outbufsize);
static BOOLEAN check_int(void);
void init_data();
long ReadTime(void);
void putbuf(RING *thering,unsigned char cc);
void putbuf1(RING *thering,unsigned int mm);
BOOLEAN getbuf(RING *thering,unsigned char *cc);
BOOLEAN getbuf1(RING *thering,unsigned int *mm);
extern struct peak_str peaka_bf[];
extern struct peak_str peakb_bf[];
extern struct peak_table peaka_tab[],peakb_tab[];
extern struct disp dsp;
extern struct control ctrl[];
extern unsigned short peak[];

void fifo_init(void);

BOOLEAN        was_enabled = FALSE;
int            irq_nbr;
unsigned int   send_num=0;
int            send_flag=FALSE;

extern struct com_param com_param;
extern struct modcom_param modcom_param;


void setfinish(void)
 {
   void baudset(void);
   void comparm(void);
   if(com_param.output==0) {
       irq_nbr = 4;     //make it global so that the ISR can read it
       port_ads=0x3f8;
      }
   if(com_param.output==1) {
       irq_nbr = 3;     //make it global so that the ISR can read it
       port_ads=0x2f8;
      }
   baudset();
   comparm();
   com_buffers(TRUE, BUFFER_SIZE, BUFFER_SIZE);
   intinit();
   asm sti;
 }
void baudset(void)
{
  unsigned int divisor;
  unsigned char lsb,msb;

  divisor = 115200/com_param.bandrate;
  lsb = divisor;
  msb = divisor >>8;              //TODO & 0xFF?

  outportb(REG_LCONT,LCONT_DLAB); //enable access to the divisor latches
			          //by setting the divisor latch access
				  //bit in the Line Control register
  outportb(port_ads,lsb);         //least significant byte of divisor
  outportb(port_ads + 1,msb);     //most significant byte of divisor
}

void comparm(void)
{
  BYTE Parmbyte;

  Parmbyte =com_param.charbits - 5;       //initial value:sets bits 0 and 1

  if (com_param.stopbits==2)
      Parmbyte |= LCONT_STOP;    // set bit 2

  if(com_param.parity != PARITY_NONE)
      Parmbyte |=LCONT_PARITY_ENABLE;   // set bit 3

  if(com_param.parity == PARITY_EVEN)
      Parmbyte |=LCONT_PARITY_SELECT;   // set bit 4

  outportb(REG_LCONT, Parmbyte);
}
/*initilize a Ring buffer*/
void initbuf(RING *thering,unsigned char * addr, int len)
{
   int i;
   thering->count = 0;
   thering->start = 0;
   thering->cnext = 0;
   thering->buffer = addr;
   thering->size = len;
   for(i=0;i<len;i++)
    thering->buffer[i]='\0';
}
/* Put a character into a RING buffer   */
void putbuf(RING *thering,unsigned char cc)
{
    thering->buffer[thering->cnext++] = cc;

  if (thering->count++>=thering->size)     //overflow?
    {
     thering->count--;
     if (thering->start++>=thering->size)
	 thering->start-=thering->size;   //move staring point
    }
   //Do we have to wrap around to the start of the buffer?
   if (thering->cnext>=thering->size)
       thering->cnext-=thering->size;
}
void putbuf1(RING *thering,unsigned int mm)
{
 unsigned char a[2]={0};
 int i;
  if(mm<=0xff) {
     a[0]=0x00;
     a[1]=(unsigned char)mm&0x00ff;
    }
  if(mm>0xff)  {
    a[0]=((unsigned char)(mm>>8)&0x00ff);
    a[1]=(unsigned char)(mm&0x00ff);
    }
  for(i=0;i<2;i++) {
    thering->buffer[thering->cnext++] = a[i];

  if (thering->count++>=thering->size)     //overflow?
    {
     thering->count--;
     if (thering->start++>=thering->size)
	 thering->start-=thering->size;   //move staring point
    }

   //Do we have to wrap around to the start of the buffer?
   if (thering->cnext>=thering->size)
       thering->cnext-=thering->size;
   }
}
/* Get a character from a RING buffer   */
BOOLEAN getbuf(RING *thering,unsigned char *cc)
{
  if (thering->count <= 0)  //nothing there
      return (FALSE);

    *cc=(unsigned char)thering->buffer[thering->start++];
    *cc=*cc&0x00ff;

    thering->count--;        //update count of retrievable chars

    if (thering->start >= thering->size)
	thering->start -= thering->size;

  return(TRUE);
}
BOOLEAN getbuf1(RING *thering,unsigned int *mm)
{
  unsigned char a[2];
  unsigned int aa;
  int i;
  if (thering->count <= 0)  //nothing there
      return (FALSE);

  for(i=0;i<2;i++) {
    a[i]=(unsigned char)thering->buffer[thering->start++];
    a[i]=a[i]&0x00ff;

    thering->count--;        //update count of retrievable chars

    if (thering->start >= thering->size)
	thering->start -= thering->size;
    }
   aa=(unsigned int)a[0];
   if(a[1]==' ') a[1]=0xff;
   *mm=(unsigned int)(((aa<<8)&0xff00)|a[1]);
  return(TRUE);
}
BOOLEAN com_buffers(BOOLEAN create,int inbufsize,int outbufsize)
{
static char Combuf_made = FALSE;

   if(create)
      {
      if(Combuf_made)
	 return(TRUE);
      out_buf = malloc(outbufsize);
      if(out_buf == NULL)
	 return(FALSE);
      in_buf =malloc(inbufsize);
      if (in_buf == NULL)
	 {
	 free(out_buf);
	 return(FALSE);
	 }
      dataout_buf=malloc(BUFFER_SIZE);
       if (dataout_buf == NULL)
	 {
	 free(out_buf);
	 free(in_buf);
	 return(FALSE);
	 }
      datain_buf=malloc(BUFFER_SIZE);
       if (datain_buf == NULL)
	 {
	 free(out_buf);
	 free(in_buf);
	 free(dataout_buf);
	 return(FALSE);
	 }
      initbuf(&outring, out_buf, outbufsize);
      initbuf(&inring, in_buf, inbufsize);
      initbuf(&dataout, dataout_buf, BUFFER_SIZE);
      initbuf(&datain,datain_buf,BUFFER_SIZE);
      Combuf_made = TRUE;
      return(TRUE);
      }

  else
    {         //destroy

      if(Combuf_made)
	{
	  free(in_buf);
	  free(out_buf);
	  free(dataout_buf);
	  free(datain_buf);
	  Combuf_made = FALSE;
	}
      return(TRUE);
    }
}

void interrupt inthand(void)
 {
    asm sti
    check_int();
    outportb(PIC1, EOI);  //end of interrupt to first PIC
 }

void fifo_init()
{
   fifo_exist = FALSE;
   max_send = 1;
   outportb(REG_FIFO, 0x0f);
  if(inportb(REG_INT_ID))
     return;
   fifo_exist = TRUE;
   max_send =15;
   outportb(REG_FIFO,1|2|4|8|64|128);    //14 byte trigger level or rcv
}

int intinit()
 {
    BYTE oldval;
    asm cli;
    outport(REG_INT_EN,0);
    oldhand = getvect(irq_nbr + 8); //record the address of current interrupt
    setvect(irq_nbr + 8, inthand);  //set the vector of myself ISR
    //Set MCONT_DTR,MCONT_RTS,MCONT_OUT1,MCONT_OUT2 on Modem Control register
    //outportb(REG_MCONT,MCONT_DTR|MCONT_RTS|MCONT_OUT1|MCONT_OUT2);
    outportb(REG_MCONT,mcont);
    //Calculate the bit that represent the irq within the PIC's
    //interrupt Enable register
    Picmask = 1<<(irq_nbr % 8);
    picaddr = (irq_nbr>7)?0xa1:0x21;
    asm cli                  //read the PIC interrupt Enable
    oldval = inportb(0x21);
    outportb(0x21, oldval &! Picmask);
    was_enabled = !(oldval & Picmask);
    outportb(REG_INT_EN, 0); //disable interrupt on the UART
    fifo_init();             //initialize FIFO buffer if any
    //Read the UART register in order to clear them
      asm cli;
      mstat = inportb(REG_MSTAT);
      lstat = inportb(REG_LSTAT);
      (void)inportb(REG_RX);           //read any character pending
      (void)inportb(REG_INT_ID);       //to clear theinterrup
				       //identification register
      //outportb(REG_INT_EN,ENABLE_ALL); //enable interrups on the UART
      outportb(REG_INT_EN,0x0d);
      outportb(0x20,0x20);             //reset the PIC
      inport(REG_INT_ID);
      inport(REG_RX);
      inxoff = FALSE;
     // asm sti;
      return(1);
}
static BOOLEAN check_int()
 {
  BYTE intreg;
  BYTE chr;
  int i;
  char a;
  unsigned int aa;
  intreg = inportb(REG_INT_ID);

//     if (intreg & 1)  //bit 0 has been set "1", nothing pending
//     return(FALSE);
  intreg=intreg&0xf;
   switch(intreg){
     case 0:          //modem status change
	 mstat = inportb(REG_MSTAT);
	 return(TRUE);
     case 2:          //Transmitter Holding register empty
	//lstat = inportb(REG_LSTAT);

	for(i=0;(i<max_send)&& outring.count; i++)
	  {
	   (void)getbuf(&outring, &inchr);
	    outportb(REG_TX, inchr);
	    send_num++;
	  }
	return(TRUE);
     case 4:          //rx data available
	while(inportb(REG_LSTAT)& LSTAT_DATA_READY)
	  {
	    chr = inportb(REG_RX);
	    putbuf(&inring, chr);
	  }
	return(TRUE);
     case 6:          //line staus change
	lstat = inportb(REG_LSTAT);

	while(inportb(REG_LSTAT) & LSTAT_DATA_READY)
	  {
	    chr = inportb(REG_RX);
	  }
       if(lstat & LSTAT_PARITY_ERROR)
	  comerror = PARITY_ERROR;
       else if (lstat & LSTAT_FRAME_ERROR)
	  comerror = FRAME_ERROR;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -