datasheet

RS232接口规范及编程资料(下)

2016-09-22来源: eefocus关键字:RS232  接口规范  编程资料
    上篇我们详细介绍了PC机的串行通讯硬件环境,以下将分别给出使用查询及中断驱动的方法编写的串行口驱动程序。这些程序仅使用RXD/TXD,无需硬件握手信号。

(2)使用查询方法的串行通讯程序设计:

 

#include
#include
#include
#define PortBase 0x2F8

void com_putch(unsigned char);
int com_chkch(void);

main()
{
 int c;
 unsigned char ch;

 outportb(PortBase + 1 , 0); /* Turn off interrupts - Port1 */

 /* Set COM1: 9600,8,N,1*/
 outportb(PortBase + 3 , 0x80);
 outportb(PortBase + 0 , 0x0C);
 outportb(PortBase + 1 , 0x00);
 outportb(PortBase + 3 , 0x03);

 clrscr();

 while(1) {

  c = com_chkch();
   if(c!=-1) {
   c &= 0xff; putch(c);
   if(c=='\n') putch('\r');
  }
 

  if(kbhit()) {
   ch = getch(); com_putch(ch);
  }
 }

}


void com_putch(unsigned char ch) {
 unsigned char status;

 while(1) {
  status = inportb(PortBase+5);
  if(status&0x01) inportb(PortBase+0); else break;
 }

 outportb(PortBase,ch);
}

int com_chkch(void) {
 unsigned char status;

 status = inportb(PortBase+5);
 status &= 0x01;
 if(status) return((int)inportb(PortBase+0)); else return(-1);

}

    使用查询方式的通讯程序适合9600bps以下的应用。

(3)使用中断的串行通讯程序设计:

    该程序由两部分组成,serial.c及sercom.c,sercom.c为通讯的底层驱动,使用中断的串行通讯程序可以工作到115.2Kbps.

 

#include
#include
#include
#include
#include
#include "llio.c"

COM *c;

main()
{
 unsigned char ch;

 c = ser_init( PORT_B,BAUD_9600,_COM_CHR8,_COM_NOPARITY,4096,4096 );

 while(1) {

  if( serhit(c)) {
   ch = getser(c);
   putchar(ch);
  }

  if(kbhit()) {
   ch = getch();
   putser(ch,c);
  }

 }
}

 

#include
#include
#include
#include

#define     CR 0x0d
#define     TRUE 0xff
#define     FALSE 0

#define     PORT_A     0 /* COM1 */
#define     PORT_B     1 /* COM2 */
#define     BAUD_9600  _COM_9600
#define     BAUD_4800  _COM_4800
#define     BAUD_2400  _COM_2400
#define     BAUD_1200  _COM_1200
#define     BAUD_600   _COM_600
#define     BAUD_300   _COM_300
#define     BAUD_110   _COM_110


typedef struct {
 char ready;             /* TRUE when ready */
 unsigned com_base;      /* 8250 Base Address */
 char irq_mask;          /* IRQ Enable Mask */
 char irq_eoi;           /* EOI reply for this port */
 char int_number;        /* Interrupt # used */
 void (_interrupt _far *old)( void );     /* Old Interrupt */

 /* Buffers for I/O */

 char *in_buf;             /* Input buffer */
 int in_tail;              /* Input buffer TAIL ptr */
 int in_head;              /* Input buffer HEAD ptr */
 int in_size;              /* Input buffer size */
 int in_crcnt;             /* Input count */
 char in_mt;               /* Input buffer FLAG */

 char *out_buf;            /* Output buffer */
 int out_tail;             /* Output buffer TAIL ptr */
 int out_head;             /* Output buffer HEAD ptr */
 int out_size;             /* Output buffer size */
 char out_full;            /* Output buffer FLAG */
 char out_mt;              /* Output buffer MT */
} COM;


COM     *ser_init( int port,int baud,int bit,int parity,int isize,int osize );
void     ser_close( COM *c );


int getsers( COM *c,int len,char *str );
int putsers( char *str, COM *c );
char serline( COM *c );
int getser( COM *c );
char serhit(COM *c);
char putser(char outch,COM *c);
void cntl_rts(int flag,COM *c);
void cntl_dtr(int flag,COM *c);
void clean_ser( COM *c );


#define     COM1_BASE         0x03F8
#define     COM1_IRQ_MASK     0xEF     /*11101111B IRQ 4 For COM1 */
#define     COM1_IRQ_EOI      0x64     /* IRQ 4 Spec EOI */
#define     COM1_INT_NUM      0x0C     /* Int # for IRQ4 */

#define     COM2_BASE         0x02F8
#define     COM2_IRQ_MASK     0xF7     /*11110111B IRQ 3 For COM2 */
#define     COM2_IRQ_EOI      0x63     /* IRQ 3 Spec EOI */
#define     COM2_INT_NUM      0x0B     /* Int # for IRQ3 */

/* 8250 ACE register defs */

#define     THR     0     /* Offset to Xmit hld reg (write) */
#define     RBR     0     /* Receiver holding buffer (read) */
#define     IER     1     /* Interrupt enable register */
#define     IIR     2     /* Interrupt identification reg */
#define     LCR     3     /* Line control register */
#define     MCR     4     /* Modem control register */
#define     LSR     5     /* Line status register */
#define     MSR     6     /* Modem status register */

#define     SREG(x)     ((unsigned)((unsigned)x + c->com_base))

/* 8259 Int controller registers */

#define     INTC_MASK     0x21     /* Interrupt controller MASK reg */
#define     INTC_EOI      0x20     /* Interrupt controller EOI reg */


#define     MAX_PORTS     2        /* # I/O ports (DOS limit) */
static int  count = 0;
static COM  com_list[MAX_PORTS];   /* I/O data structure */

static COM  *com1;                 /* Pointers for interrupt actions */
static COM  *com2;
static COM  *com_xfer;             /* Transfer interrupt data structure */

COM     *ser_init0(int port,char *ibuf,int isize, char *obuf,int osize);
void    ser_close0( COM *c );


void (_interrupt _far int_ser1)( void );    /* Int rtn for serial I/O COM 1 */
void (_interrupt _far int_ser2)( void );    /* Int rtn for serial I/O COM 2 */
void (_interrupt _far int_ser_sup)( void ); /* Support int actions */

COM     *ser_init( int port,int baud,int bit,int parity,int isize,int osize )
{
 unsigned status;
 char ch;
 COM *c;
 char *in_buf,*out_buf;

 status = _bios_serialcom(_COM_INIT,port,(bit | parity | _COM_STOP2| baud ));


 in_buf = malloc( isize );
 if( in_buf == NULL ) return( NULL );

 out_buf = malloc( osize );
 if( out_buf == NULL ) return( NULL );

 c = ser_init0(port,in_buf,isize,out_buf,osize );

 clean_ser(c);

 return( c );
}


void     ser_close(COM *c)
{
 int i;


 if( !c->ready ) return;

 ser_close0(c);

 free( c->in_buf );
 free( c->out_buf );

}


char     serline( COM *c )
{

 if( !c->ready ) return(FALSE);

 if( c->in_crcnt > 0 ) return( TRUE );
  else return( FALSE );
}

int     getsers( COM *c,int len,char *str )
{
 char ch;
 int i;

 i = 0;
 while( i   while( !serhit(c) ) {
   if(kbhit()) return( -1 );
  }

  ch = 0x7f & getser(c);
  switch( ch ) {

   case 0x0d: str[i++] = '\0';
   return( i );

   case 0x00:
   case 0x0a: break;

   default: str[i++] = ch;
   break;
  }
 }


 str[i] = '\0';
 return( len );
}


int     putsers( char *str, COM *c )
{
 int n,i,j;

 n = strlen( str );

 for( i=0; i   while( !putser( str[i],c ) );
 }

 return( n );
}

char     putser( char outch, COM *c )
{
 char val;

 if( !c->ready ) return(FALSE);

 while( !c->out_mt && (c->out_head == c->out_tail) );

 if( !c->out_full ) {
  c->out_buf[c->out_head++] = outch;
  if( c->out_head == c->out_size )
   c->out_head = 0;         /* Reset buffer circularly */
 }

 if( c->out_head == c->out_tail ) {
  c->out_full = TRUE;
  return( FALSE );
 } else c->out_full = FALSE;

 val = inp( SREG(LCR) );     /* Reset DLAB for IER access */
 val &= 0x7F;                /* Clear IER access bit */
 outp(SREG(LCR),val);

 val = inp( SREG(IER) );
 if( !(val & 0x02) )         /* Interrupt ON ? */
 {

  c->out_mt = FALSE;         /* Not MT now */
  _disable();                /* Interrupts OFF NOW */
  outp(SREG(IER),0x03);      /* RX & TX interrupts ON */
  _enable();                 /* Interrupts ON again */
 }

 return( TRUE );
}


char     serhit( COM *c )
{
 if( !c->ready ) return(FALSE);

 if( !c->in_mt ) return( TRUE );
  else return( FALSE );
}

int     getser( COM *c )
{
 int ch;

 if( !c->ready ) return(FALSE);

 if( !serhit(c) ) return( 0 );

 _disable();

 ch = 0xff & c->in_buf[c->in_tail++];
 if( c->in_tail == c->in_size ) c->in_tail = 0;

 if( c->in_tail == c->in_head ) c->in_mt = TRUE;

 if( ch == CR )             /* Keep track of CR's */
  c->in_crcnt--;

 _enable();


 return( ch );
}

void     clean_ser( COM *c )
{
 _disable();

 c->in_head = 0;
 c->in_tail = 0;
 c->in_mt = TRUE;
 c->in_crcnt = 0;

 _enable();
}


void     cntl_dtr( int flag,COM *c )
{
 char val;


 if( !c->ready ) return;

 val = inp(SREG(MCR));

 if( flag ) val |= 1;
  else val &= ~1;

 outp(SREG(MCR),val);
}


void     cntl_rts( int flag, COM *c )
{
 char val;

 if( !c->ready ) return;

 val = inp(SREG(MCR));

 if( flag ) val |= 2;
  else val &= ~2;

 outp(SREG(MCR),val);
}

COM     *ser_init0(int port,char *ibuf,int isize, char *obuf,int osize)
{
 int i;
 char val;
 COM *c;

 while( port >= MAX_PORTS )   /* Get port # in range */
 port--;
 for( i=0; i  {
  if( !com_list[i].ready ) {
   c = &(com_list[i]);
   break;
  }
 }
 

if( i == MAX_PORTS ) /* Not found */
 return( NULL );


 c->in_buf = ibuf;
 c->in_size = isize;
 c->in_mt = TRUE;
 c->in_head = 0;
 c->in_tail = 0;
 c->in_crcnt = 0;

 c->out_buf = obuf;
 c->out_size = osize;
 c->out_full = FALSE;
 c->out_mt = TRUE;
 c->out_head = 0;
 c->out_tail = 0;


 switch( port ) {

  case 0:         /* Here set up for COM1 */
   c->ready = TRUE;
   c->com_base = COM1_BASE;
   c->irq_mask = COM1_IRQ_MASK;
   c->irq_eoi = COM1_IRQ_EOI;
   c->int_number = COM1_INT_NUM;

   _disable();

   com1 = c;
   c->old = _dos_getvect( c->int_number );
   _dos_setvect(c->int_number,int_ser1);
  break;

 case 1:         /* Here set up for COM1 */
  c->ready = TRUE;
  c->com_base = COM2_BASE;
  c->irq_mask = COM2_IRQ_MASK;
  c->irq_eoi = COM2_IRQ_EOI;
  c->int_number = COM2_INT_NUM;

  _disable();

  com2 = c;
  c->old = _dos_getvect( c->int_number );
  _dos_setvect(c->int_number,int_ser2);
 break;

  default: return(NULL);     /* Bad port SKIP */
 }

 val = inp( INTC_MASK );
 val &= c->irq_mask;
 outp( INTC_MASK, val );

 val = inp( SREG(LSR) );     /* Read and discard STATUS */
 val = inp( SREG(RBR) );     /* Read and discard DATA */

 val = inp( SREG(LCR) );     /* Rst DLAB for IER access */
 val &= 0x7F;                /* 01111111B */
 outp( SREG(LCR),val );

 outp( SREG(IER),1);         /* Enable Data READY INT */

 outp( SREG(MCR),0xB );      /* Enable OUT2,RTS & DTR */

 _enable();

 return( c );

}

void     ser_close0( COM *c )
{
 char val;

 if( !c->ready ) return;

 _disable();

 val = inp(INTC_MASK);
 val |= ~c->irq_mask;
 outp(INTC_MASK,val);

 val = inp( SREG(LCR) );     /* Reset DLAB for IER access */
 val &= 0x7F;                /* Clear IER access bit */
 outp(SREG(LCR),val);

 val = inp( SREG(RBR) );
 val = inp( SREG(LSR));
 val = inp(SREG(IIR) );
 val = inp(SREG(IER) );
 outp(SREG(IER),0);         /* Disable 8250 Interrupts */

 outp(SREG(MCR),0);         /* Disable RTS,DTR and OUT2 */

 outp(SREG(MCR),0);         /* Disable OUT2 */

 _dos_setvect(c->int_number, c->old );

 _enable();

 c->ready = FALSE;

}

void     _interrupt _far int_ser1( void )
{

 com_xfer = com1;
 _chain_intr( int_ser_sup );
}


void     _interrupt _far int_ser2( void )
{

 com_xfer = com2;
 _chain_intr( int_ser_sup );
}


void     _interrupt _far int_ser_sup( void )
{
 char val;
 char ch;
 int ptr;
 COM *c;

 c = com_xfer;

 while( TRUE ) {
  val = inp( SREG(LSR) ); /* Read and discard STATUS */
  val = inp( SREG(IIR) ); /* Get interrupt status register */

  if( val & 0x04 ) /* Receive Interrupt */
  {

   ptr = c->in_head;
   ch = inp( SREG(RBR) );

   if( c->in_mt || ptr != c->in_tail ) {
    c->in_buf[ptr++] = ch;
    if( ptr == c->in_size ) ptr = 0;
    c->in_head = ptr;
    c->in_mt = FALSE;

    if( ch == CR )         /* Count lines */
    c->in_crcnt++;
   }
  } else {
   if( val & 0x02 ) /* Transmit Interrupt */
   {
    if( (!c->out_full) && (c->out_head == c->out_tail) ) {

     c->out_mt = TRUE;
     val = inp( SREG(LCR) );
     val &= 0x7F;
     outp(SREG(LCR),val);

     outp(SREG(IER),0x01);
/* RX interrupts ON */
    } else {

     outp(SREG(THR),
     c->out_buf[c->out_tail++]);
     if( c->out_tail == c->out_size ) c->out_tail = 0;
    }
   } else return;         /* No Interrupt */
  }

  outp(INTC_EOI,c->irq_eoi);
 }
}

(4)MCS-51串行通讯:    

    MCS-51的串行口使用起来非常简单,因为MCS-51单片机的串行口没有与MODEM控制相关的信号。这使得51的通讯口非常易于使用。使用查询方式时,仅需初始化有关的寄存器即可。演示程序如下:

#include
#include

void putch(unsigned char);
unsigned char getch(void);

main()
{
 unsigned char ch;

 SCON = 0x50; 
 TMOD |= 0x20; 
 TH1 = 0xfd; 
 TL1 = 0xfd;
 TR1 = 1; 
 TI = 1; 
 RI = 0; 
 
 while(1) {
  ch = getch(); putch(ch);

 }
}

void putch(unsigned char ch) {

 SBUF = ch;
 TI = 0;
 while(!TI);
}

unsigned char getch(void) {

 while(!RI);
 RI = 0;
 return(SBUF);

}

    使用中断驱动的程序比较复杂,下面为完整的MCS-51串行通讯底层驱动程序,由头文件serint.hJ及serint.c组成。

serint.h      

unsigned char RR_iHead;     /* receiver head index */
unsigned char RR_iTail;     /* receiver tail index */
unsigned char RR_cLev;      /* receiver buffer count */
unsigned char RR_cMax;      /* receiver buffer count */

unsigned char TR_iHead;     /* transmitter head index */
unsigned char TR_iTail;     /* transmitter tail index */
unsigned char TR_cLev;      /* transmitter buffer count */
unsigned char TR_cMax;      /* transmitter buffer count */

unsigned char UnGotCh;      /* saved char for ungetch() */

unsigned char SerFlags;     /* serial flag */

bit FlagTransIdle;          /* set when transmitter is finished */
bit FlagStripOutLF;         /* don't send linefeeds */
bit FlagCvtInCR;            /* convert incoming CR to LF */

unsigned char TestBits;

#define INRINGSIZE 128      /* must be <= 254 to avoid wraps */
#define OUTRINGSIZE 250     /* ditto */

#define T1RELOAD 253

#define CR 13
#define LF 10
#define ESC 27

#define EOF -1

unsigned char xdata RRing[INRINGSIZE];     /* receiver ring buffer */
unsigned char xdata TRing[OUTRINGSIZE];    /* receiver ring buffer */

int     putstr (const char *);
int     putch(int);
int     chkch();
int     getch();
void    SerWaitOutDone();
int     SerFlushIn();
int     putc(int TransChar);

 

serint.c     

/* CONSOLE.C -- serial I/O code */

/*---------------------------------------------------------------------------*/
/* Initialize serial port hardware and variables */

#include
#include "serint.h"

void     SerInitialize() {

 SerFlags = 0; 

 FlagTransIdle = 1;
 FlagCvtInCR = 1;         /* want to turn CRs into LFs */
 RR_iHead = RR_iTail = RR_cLev = RR_cMax = 0;
 TR_iHead = TR_iTail = TR_cLev = TR_cMax = 0;
 UnGotCh = -1;
 

/*--- set up Timer 1 to produce serial rate */

 TCON &= 0x3F;          /* clear run & interrupt flags */
 TMOD &= 0x0F;          /* flush existing Timer 1 setup */
 TMOD |= 0x20;          /* flush existing Timer 1 setup */

 SCON = 0x50;           /* flush existing Timer 1 setup */
 PCON |= 0x00; 
 TH1 = TL1 = T1RELOAD & 0x00FF;     /* flush existing Timer 1 setup */
 TR1 = 1;               /* start the timer */
 ES = 1;                /* enable serial interrupts */
}

/*---------------------------------------------------------------------------*/
/* Serial console interrupt handler */
/* If transmitter output is disabled, we fake trans interrupts until empty */

void     SerInt() interrupt 4
{

 if(RI) {                 /* receiver interrupt active? */
  if(RR_cLev    RRing[RR_iHead] = SBUF; /* pick up the character and stick in ring */
   RR_iHead++;             /* tick the index */
   RR_cLev++;              /* tick size counter */
   if(RR_iHead==INRINGSIZE) RR_iHead = 0;     /* hit end of array yet? */
  }
  RI = 0;                  /* indicate we have it */
 }

 if(TI) {                  /* transmitter interrupt active? */
  if(TR_cLev) {            /* anything to send? */
   SBUF = TRing[TR_iTail]; /* fetch next char and send it */
   TR_cLev--;              /* tick size counter */
   TR_iTail++;             /* tick the index */
   if(TR_iTail==OUTRINGSIZE) TR_iTail = 0;     /* hit end of array yet? */
  } else FlagTransIdle = 1;/* no, flag inactive */

  TI = 0;                  /* indicate done with it */
 }

}

/*---------------------------------------------------------------------------*/
/* Send character to console */
/* Can strip LFs, in which case you get CR instead of LF/CR */


int     putch(int TransChar)
{
 putc(TransChar);                 /* if not LF, handle normally */
 if(TransChar=='\n') putc('\r');  /* if LF, send a CR */
}

int     putc(int TransChar)
{

 while(TR_cLev>=OUTRINGSIZE);     /* wait for space in ring */
 ES = 0;
 TRing[TR_iHead] = TransChar;     /* point to char slot */
 TR_iHead++;                      /* tick counter & index */
 TR_cLev++;
 if(TR_iHead==OUTRINGSIZE) TR_iHead = 0;
 if(FlagTransIdle) {
  FlagTransIdle = 0;              /* kickstart transmitter if idle */
  TI = 1;
 }

 ES = 1;
 return(TransChar);
}

/*---------------------------------------------------------------------------*/
/* Decide if there are any pending chars */
/* Returns nonzero if there's a char */

int     chkch() {

 return(RR_cLev);                 /* tack on current level */
}

/*---------------------------------------------------------------------------*/
/* Wait for the serial transmitter to go idle */
/* If the transmitter is disabled, that's considered to be the same thing */

void     SerWaitOutDone() {

 while (TR_cLev);                 /* wait for ring empty */
 while(!FlagTransIdle);           /* wait for last char */


/*---------------------------------------------------------------------------*/
/* Flush the input buffer */
/* Returns number of chars flushed */


int     SerFlushIn() {

 ES = 0;                         /* turn off serial interrupts */
 RR_iTail = 0;                   /* reset ring variables */
 RR_iHead = 0;
 RR_cLev = 0;
 ES = 1;                         /* turn on serial interrupts */

}

/*---------------------------------------------------------------------------*/
/* Get character from console */
/* CRs turn into LFs unless we're not doing that... */


int     getch() {
 int RetVal;

 ES = 0;             /* avoid interruptions */

 if(RR_cLev) {       /* anything pending? */
  RetVal = RRing[RR_iTail];
  if(RetVal=='\r') RetVal = '\n';        /* use LF instead of CR */
  RR_iTail++;        /* tick size index & counter */
  RR_cLev--;
  if(RR_iTail==INRINGSIZE) RR_iTail = 0; /* hit end of array yet? */
 } else RetVal = -1;

 ES = 1;
 return(RetVal);
}

/*---------------------------------------------------------------------------*/
/* Send string to console */
/* putstr(char *pString); */
/* The ?putstr entry point has *pString in DPTR */

int     putstr (char *pstring)
{
 while(*pstring) {         /* fetch character if zero done */
  putch(*pstring);
  pstring++;               /* continue... */
 }
}

    使用查询的程序可以做到多高的波特率取决于主程序的工作量,使用中断方式的通讯驱动程序在使用11.0592MHz晶振时可以达到57.6Kbps的速率。

(5)关于RS485

    以上几个方面详细介绍了PC及MCS-51的RS-232C的串行通讯程序的设计方法,RS-485与RS-232C相类似,其区别在于使用双端平衡驱动及半双工模式,这些措施使RS-485传输距离更远,同时,RS-485还可以组网。在同一个RS-485网络中,可以多达32个模块,某些器件可以多达256个甚至更多。相应的,RS-485具有接收/发送控制端,RS-485的接收控制端可以在需要接收的时候打开或者一直打开以便无条件的接收线路上的数据。RS-485的发送控制端仅在需要发送时打开,平时应关端发送器,因为在同一RS-485网络中在同一时刻仅允许一个发送器工作。在数据发送完成后关闭发送器。这可以通过以下两种方法实现。

    一、在数据完全移出后,对于PC机为发送移位寄存器空,对于MCS-51为TI置位。这些调件既可使用查询的方法得到,也可以在中断程序中实现。

    二、将RS-485的接收器始终打开,这样一来,所有在RS-485上的数据均被接收回来,包括自己发送出去的数据。因此,当自己发送的数据完全被自己接收回来时即可关闭发送器。原则上说,这一方法无论是查询或中断方式都适用,但实际上,由于RS-485的数据通常打包后发送,因此,使用查询的方法并不理想。这一方法非常适合中断方式,尤其是以数据包传送的RS-485通讯。

关键字:RS232  接口规范  编程资料

编辑:什么鱼 引用地址:http://www.eeworld.com.cn/qrs/article_2016092230468.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:RS232接口规范及编程资料(上)
下一篇:自制USB接口和RS232串口的1-wire转接线

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

一加员工剧透一加7系列外放媲美华为Mate RS

还有几天就是一加7系列的国内新品发布会了,与该系列有关的信息也得了曝光,为了让消费者更好的了解一加系列,一加员工@酸数码透露了一些该系列的细节:1. 一加7系列外放媲美华为Mate RS,@酸数码称双扬声器外放效果未必好于单扬声器。因为单元差异和音腔体积和出音口尺寸和位置差异,经过测试发现一加7系列的外放媲美第一梯队的iPhone XS Max、Mate RS、S10+。2. 一加7系列拍照值得期待,@酸数码表示S10拍照好不是三星神优化,而是本身模组素质就是顶级的。带ram,光圈可变,镜头解析力高。暗示一加7系列在拍照方面采用的是三星的做法,拍照可期。3. 一加7系列会用上大内存,@酸数码说大内存正常使用时他估计很难体验出区别
发表于 2019-05-14
一加员工剧透一加7系列外放媲美华为Mate RS

PIC单片机-RS232串口通信

编写程序实现以下功能。在计算机上使用串口大师向开发板发每次发送1个字符。开发板每接收到一个数据,则交换该数据的高低4位,再发送回计算机。端口初始化时使能发送与接收,使用扫描方式接收数据,接收到数据后立即交换高低四位并发送,交换高低四位方式如下:i = ((RCREG & 0xff) << 4) | (RCREG >> 4)完整程序:/******************************************************************************** 标    题: 异步串口通讯* 功能描述: 在计算机上使用串口大师向开发板发每次发送1个字
发表于 2019-05-11

配置的雷达传感器功能强大 宝骏全新SUV RS-5将上市

宝骏全新SUV RS-5即将上市,自动驾驶辅助配置受到了很大的关注和好评。为了实现L2级别的自动驾驶辅助功能,宝骏RS-5采用了最新版本的博世ADAS自动驾驶辅助系统,在感应传感器方面,采用了77GHz毫米波雷达+多功能摄像头的融合方案,保障了智能驾驶的便利性和安全性。宝骏RS-5采用的77GHz中距毫米波雷达,相比同类型的其他雷达传感器体积更小,工艺要求更高、距离检测精度更高,其目标识别率是传统24G赫兹雷达传感器的3倍,开角达到90°,探测范围可达160m,具备全天候障碍物探测能力。通过77GHz中距毫米波雷达,宝骏RS-5主要实现了以下功能。一、ACC自适应巡航宝骏RS-5通过雷达和摄像头的配合,实现从0~130km/h之间
发表于 2019-03-05
配置的雷达传感器功能强大 宝骏全新SUV RS-5将上市

LPC2387 RS485通信

最近一款基于LPC2387方案的产品要用到RS485通信,查了下datasheet,LPC2387的Uart没有内置RS485功能,故只能采用电平转化了。最后选择了MAX485和英联的UM3085,两款芯片管脚兼容,都能进行TTL和RS485转化。因为采用半双工通信,所以用一个GPIO口同时控制DE和RE,某一刻只能是接收或发送。LPC2387的TXD1和RXD1分别和485的DI和RO连接。//RS-485收发控制示意代码,和普通串口通信相比多了485芯片的发送/接收使能设置 #define RS485_DE_RE (0x01<<9)  //GPIO P0.9控制DE,RE 
发表于 2019-02-15

技术文章—RS-232、RS-485与RS-422转换方案

工业现场应用中存在诸多总线应用情况,例如RS-232和RS-485转换且双向隔离、RS-485与RS-422接口共用,本文将为大家介绍这一类应用的方案,不仅简单方便,而且可以提高通信的可靠性。 一、高性能的RS-232与RS-485双向转换电路  图1 RS-232/RS-485双向转换模块 图1右侧所示为RS-232/RS-485总线双向转换模块,不仅体积大速度慢,而且RS-232和RS-485总线之间也没有实现隔离。图1左侧所示为MPM11T模块,通过如图2所示的简单连接即可实现RS-485与RS-232总线的自动切换。  图2 RS-232转RS
发表于 2019-02-14
技术文章—RS-232、RS-485与RS-422转换方案

stm32 RS485 SP3485

RS485 是半双工通信(2 线制) SP3485芯片的DE与RE短接在一起连接在STM32F1芯片的PG3上,通过PG3管脚就可以控制 SP3485的收发,当PG3=0时,为接收模式,当PG3=1时,为发送模式void USART2_IRQHandler(){    u8 r;    if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET)    {        r = USART_ReceiveData(USART2);       
发表于 2019-01-04
stm32 RS485 SP3485

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved