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

📄 rs232.c

📁 DSP56F807的CAN通讯程序,可用于多子板互连、也可作为开发的原型程序
💻 C
字号:
#include "dsp56f805_io.h"

#define RS_BUFFER_LNG 64
#define HALF_DUPLEX

/* done by Daniel Malik (daniel.malik@motorola.com) */

/* in case of HALF DUPLEX operation getchar() must be called periodically */
/* the portion needed to be called can be moved elsewhere (timer ISR etc) */
/* vesion 1.1 - internal variables changed to static */

static int rx_buffer[RS_BUFFER_LNG];
static int tx_buffer[RS_BUFFER_LNG];
static int *volatile tx_iptr,*volatile rx_iptr;
static int *tx_sptr,*rx_sptr; /* iptr belongs to ISR, sptr to SW */

asm void sci_tx_idle_isr(void) {
#ifdef HALF_DUPLEX
	/* put your code to switch the half duplex */
	/* line for reception here */
#endif
	bfclr	#0x0040,io.sci0.scicr	/* disable this irq */
	rti							/* these two lines could be in the ifdef..endif as well, but just in case... */
}

asm void sci_tx_empty_isr(void) {
	lea		(sp)+
	move	r0,x:(sp)+
	move	y0,x:(sp)
	move	tx_sptr,y0
	cmp		tx_iptr,y0
	beq		ste1					/* no data available */
#ifdef HALF_DUPLEX
	/* put your code to switch the half duplex */
	/* line for transmission here */
	bfset	#0x0040,io.sci0.scicr	/* enable tx_idle irq */
#endif
	move	tx_iptr,r0
	move	io.sci0.scisr,y0		/* read SR so irq flags are cleared */
	move	x:(r0)+,y0
	move	y0,io.sci0.scidr		/* transmit data */
	move	r0,y0
	cmp		#tx_buffer+RS_BUFFER_LNG,y0
	bne		ste2
	move	#tx_buffer,r0
	nop
ste2:		
	move	r0,tx_iptr				/* update pointer */
ste3:
	pop		y0
	pop		r0
	rti
ste1:
	bfclr	#0x0080,io.sci0.scicr	/* disable this interrupt */
	bra		ste3
}

asm void sci_rx_isr(void) {
	lea		(sp)+
	move	r0,x:(sp)+
	move	y0,x:(sp)
	move	io.sci0.scisr,y0	/* read SR so irq flag is cleared */
	move	rx_iptr,r0
	move	io.sci0.scidr,y0	/* read the data */
	move	y0,x:(r0)+
	move	r0,y0
	cmp		#rx_buffer+RS_BUFFER_LNG,y0
	bne		srx1
	move	#rx_buffer,r0
	nop
srx1:		
	move	r0,rx_iptr		/* update pointer */
	pop		y0
	pop		r0
	rti
}

char sci_getchar(void) {
	int c;
#ifdef HALF_DUPLEX
	if ((tx_iptr!=tx_sptr)&&(!(io.sci0.scisr&1))) io.sci0.scicr|=0x0080; /* enable tx_empty irq if no reception in progress */
	/* previous line must be called periodically to enable tx_empty irq in case there is data to be sent */
#endif
	if (rx_iptr==rx_sptr) return (-1); /* no data available */
	c=*(rx_sptr++);
	if (rx_sptr>=rx_buffer+RS_BUFFER_LNG) rx_sptr=rx_buffer;
	return(c);
}

void sci_putchar(char character) {
	int *newptr;
	newptr=tx_sptr+1;
	if (newptr>=(tx_buffer+RS_BUFFER_LNG)) newptr=tx_buffer;
	while(newptr==tx_iptr)	/* buffer is full, we have to wait */	
		if ((tx_iptr!=tx_sptr)&&(!(io.sci0.scisr&1))) io.sci0.scicr|=0x0080; /* enable tx_empty irq if no reception in progress */
	*tx_sptr=character;
	tx_sptr=newptr;
#ifdef HALF_DUPLEX
	if (!(io.sci0.scisr&1)) io.sci0.scicr|=0x0080; /* enable tx_empty irq if no reception in progress */
#else if
	sci0_scicr|=0x0080;		/* enable tx_empty irq */
#endif
}

asm void sci_init_hw(int baud_div) {
	move	y0,io.sci0.scibr
	move	#0x002c,io.sci0.scicr	/* enable Rx&Tx */
	bfset	#0x8000,cr.ipr			/* enable level 1 interrupts */
	bfset	#0x0100,sr				/* enable maskable interrupts */
	bfclr	#0x0200,sr
	bfset	#0x0010,io.ictn.gpr+13	/* assign IRQ 53 to group 1 */
	bfset	#0x1000,io.ictn.gpr+12	/* assign IRQ 51 to group 1 */
#ifdef HALF_DUPLEX
	bfset	#0x0100,io.ictn.gpr+12	/* assign IRQ 50 to group 1 */
#endif
	rts
}

void sci_send_string(char *string) {
	while (*string) sci_putchar(*(string++));
}

void sci_init(int baud_div) {
	tx_iptr=tx_sptr=tx_buffer;
	rx_iptr=rx_sptr=rx_buffer;
	sci_init_hw(baud_div);
}

⌨️ 快捷键说明

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