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

📄 serial_advanced.c

📁 使用picc开发的基于pic16f87x的与上位机进行串行通信的源程序
💻 C
字号:
/*

This is the advanced version of serial_setup(), in serial.c

For advanced users only.

I have found that its actually easier to just read the values of SPBRG and BRGH
out of the manual, and check the error rates by hand, rather than use macros to
work it out. It only takes a few seconds, and one doesnt change SPRBG or BRGH
that much.

Note that the baud rates generated by these mathematical equations are always
rounded down, so they can be out by +/-1 in very rare circumstances.  I have
noticed this for 10Mhz, 33600baud.  That is why the #assert statements are there
to double check everything.

I have tried floating point calculations to remove this limitation, with no
luck.  I dont think Hi-Tech C supports #if comparisons with floating point
statements.

*/

void serial_setup(void)
{
	/*
	 * Comms setup:
	 */

  //[user change - start]
  #define FOSC PIC_CLK      // <<< clock freq (ie: 4000000 Hz)
	#define BAUD 19200          // <<< in bits per second (ie: 19200bps)
	#define	BAUD_ERROR	4 	    // <<< set max. baud rate error (ie: 4%)
  //[user change - end]

  //[do not alter - start]
  //generate settings
	#if ((FOSC/(16UL * BAUD))-1UL) < 256UL
		#define SPBRG_SET (FOSC/(16UL * BAUD))-1
		#define BRGH_SET 1
	#else
		#define SPBRG_SET (FOSC/(64UL * BAUD))-1
		#define BRGH_SET 0
	#endif

  //check that error < N% (see manual for USART baud rates for async. mode)
  #define	BAUD_REAL (FOSC/((64UL-(BRGH_SET*48UL))*(SPBRG_SET+1)))
  #if BAUD_REAL > BAUD
		#if (((BAUD_REAL - BAUD)*100UL)/BAUD) > BAUD_ERROR
			#error	"baud rate error percentage is too high"
		#endif
	#else
		#if (((BAUD - BAUD_REAL)*100UL)/BAUD) > BAUD_ERROR
			#error	"baud rate error percentage is too high"
		#endif
	#endif
  //[do not alter - end]

	/* relates crystal freq to baud rate - see above and PIC16F87x data sheet under async 'USART'

	BRGH=1, Fosc=3.6864MHz		BRGH=1, Fosc=4MHz      BRGH=1, Fosc=8MHz    BRGH=1, Fosc=16MHz
	----------------------	  -----------------      -----------------    ------------------
	Baud		SPBRG             Baud		SPBRG          Baud		SPBRG         Baud		SPBRG
	1200		191               1200		207.3          1200		415.7         9600    103
	2400		95                2400		103.2          2400		207.3         19200		51
	4800		47                4800		51.1           4800		103.2         38400   25
	9600		23                9600		25.0           9600		51.1          57600   16
	19200		11                19200		12.0           19200	25.0          115200  8
	38400		5                 38400		5.5            38400	12.0
	57600		3                 57600		3.3            57600	7.7
	115200	1                 115200	1.2            115200	3.3

	*/

	//you can comment these #assert statements out if you dont want error checking
	#if FOSC==3686400 && BAUD==19200
		#assert SPBRG_SET==11
	#elif FOSC==4000000 && BAUD==19200
		#assert SPBRG_SET==12
	#elif FOSC==10000000 && BAUD==19200
		#if BRGH_SET==0
  		#assert SPBRG_SET==7
    #elif BRGH_SET==1
  		#assert SPBRG_SET==31
    #else
      #error
    #endif
	#elif FOSC==10000000 && BAUD==33600
		#if BRGH_SET==0
  		#assert SPBRG_SET==4
    #elif BRGH_SET==1
  		#assert SPBRG_SET==18 //NOTE: due to rounding, this should be 18, not 17! See manual.
    #else
      #error
    #endif
	#elif FOSC==16000000 && BAUD==19200
		#assert SPBRG_SET==51
	#elif FOSC==20000000 && BAUD==19200
		#assert SPBRG_SET==64
	#elif FOSC==20000000 && BAUD==57600
		#if BRGH_SET==0
  		#assert SPBRG_SET==4
    #elif BRGH_SET==1
  		#assert SPBRG_SET==20
    #else
      #error
    #endif
  #else
    #error could not #assert SPRBG and BRGH for specified crystal freq. and baud rate
	#endif

	SPBRG=SPBRG_SET;
	BRGH=BRGH_SET;	  //data rate for sending/receiving
	SYNC=0;						//asynchronous
	SPEN=1;						//enable serial port pins
	CREN=1;						//enable reception
	SREN=0;						//no effect
	TXIE=0;						//disable tx interrupts
	RCIE=0;						//disable rx interrupts
	TX9=0;						//8-bit transmission
	RX9=0;						//8-bit reception
	TXEN=0;						//reset transmitter
	TXEN=1;						//enable the transmitter
}

⌨️ 快捷键说明

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