📄 k_modbus.c
字号:
/***********************
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 + -