串口收发
官方例程没有发现串口异步双工通信的例程,这里分享下异步双工通信(模式1,10位数据发送)的例程。
基本上不算全双工工作方式,因为发送时要禁用串口0中断(set_ES),会同时禁用收和发,也就是发送到发送完成这段时间没有串口接收中断。
初始化uart0时,TI(串口0发送中断标志位)必须要set,因为printf内部实现靠TI判断上一个字符发送完成。
#include <string.h>
void usr_InitialUART0_Timer1_Mode1(UINT32 u32Baudrate) //T1M = 1, SMOD = 1
{
P06_Quasi_Mode; //Setting UART pin as Quasi mode for transmit
P07_Quasi_Mode; //Setting UART pin as Quasi mode for transmit
SCON = 0x70; //UART0 Mode1, REN(Rx enable)=1, SM1(for mode1)=1, SM2(StopBit chk)=1
TMOD |= 0x20; //Timer1 Mode1
/* SMOD PCON.7 串口0波特率加倍使能.
串口0工作在模式2,或在模式1或3时,串口0用定时器1溢出作为波特率时钟源时,设置此位波特率加倍。 */
set_SMOD; //UART0 Double Rate Enable
set_T1M;
clr_BRCK; //Serial port 0 baud rate clock source = Timer1
#ifdef FOSC_160000
TH1 = 256 - (1000000/u32Baudrate+1); /*16 MHz */
#endif
#ifdef FOSC_166000
TH1 = 256 - (1037500/u32Baudrate); /*16.6 MHz */
#endif
set_TR1; // 定时器 1 启动控制
set_TI; //For printf function must setting TI = 1
}
void UART0_SendData(char dat)
{
/* send data to uart by polling, will disable uart isr */
clr_ES;
SBUF = dat;
while(TI!=1);
clr_TI;
set_ES;
}
void UART0_SendString(char *s)
{
while(*s)
{
UART0_SendData(*s++);
}
}
char putchar(char c)
{
UART0_SendData(c);
return c;
}
void SerialPort0_ISR(void) interrupt 4
{
if (RI)
{
/* stop bit */
/*if ((SCON & SET_BIT2) != SET_BIT2)
{
stat_rx_stop_bit_diff_cnt++;
}*/
//uart_process_rx(); // 处理串口输入
clr_RI;
}
if (TI)
{
/* No frame error report */
//if (FE )
// FE = 0;
clr_TI;
}
}
/* main初始化代码:
usr_InitialUART0_Timer1_Mode1(UART0_BAUD);
set_ES; //For interrupt enable
set_EA;
*/