📄 serial_advanced.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 + -