本帖最后由 芯圣电子官方QQ 于 2023-7-25 10:37 编辑
上一篇我使用了简单的方法使用printf,但是只能用UART1,为了治好我的强迫症,这一篇我来完善printf的使用,让它全部支持两个串口!
其实就是重定向putchar函数:
/**********************************************************************/
//*串口1初始化函数,对HC89S003的两个串口进行初始化和波特率设置
//*参数:baud-1200,2400,4800,9600,19200,57600
//*无返回值
/**********************************************************************/
void UART1_Init(u16 baud)
{
/**********************************UART配置初始化**************************************/
P2M0 = P2M0&0x0F|0x80; //P21设置为推挽输出
P0M1 = P0M1&0x0F|0x20; //P03设置为上拉输入
TXD_MAP = 0x21; //TXD映射P21
RXD_MAP = 0x03; //RXD映射P03
T4CON = 0x06; //T4工作模式:UART1波特率发生器
TH4 = (65536 - (1000000/baud))>>8;
TL4 = (65536 - (1000000/baud)); //波特率9600
SCON2 = 0x02; //8位UART,波特率可变
SCON = 0x10; //允许串行接收
IE |= 0X10; //使能串口中断
EA = 1;
TI = 1; //使用printf需要发送标志位TI=1;
}
void UART2_Init(u16 baud)
{
/**********************************UART配置初始化**************************************/
P2M0 = P2M0&0x0F|0x80; //P21设置为推挽输出
P0M1 = P0M1&0x0F|0x20; //P03设置为上拉输入
TXD2_MAP = 0x21; //TXD映射P21
RXD2_MAP = 0x03; //RXD映射P03
//波特率计算
//波特率 = 1/16 * (T5时钟源频率 / 定时器5预分频比) / (65536 - 0xFF98)
// = 1/16 * ((16000000 / 1) / 104)
// = 9615.38(误差0.16%)
//波特率9600
//反推初值 = (65536 - ((T5时钟源频率 / 定时器5预分频比) * (1 / 16)) / 波特率)
// = (65536 - (16000000 * (1 / 16) / 9600))
// = (65536 - 104.167)
// = FF98
RCAP5H = (65536 - (1000000/baud))>>8;
RCAP5L = (65536 - (1000000/baud));
T5CON = 0x06; //T5工作模式:UART2波特率发生器
S2CON2 = 0x00; //8位UART,波特率可变
S2CON = 0x10; //允许串行接收
IE |= 0x40; //使能串口中断
EA = 1;
}
void UART_Send(u8 UART,u8 buf)
{
if(UART==UART1)
{
SBUF = buf;
while(!TI);
TI=0;
}
if(UART==UART2)
{
S2BUF = buf;
while(!(S2CON&0x02));
S2CON&=~0x02;
}
}
void UART_Sends(u8 UART,u8 *buf)
{
while(*buf)
{
UART_Send(UART,*buf++);
}
}
//重定向putchar函数
char putchar(char c)
{
UART_Send(UART1,c);
return c;
}
对于波特率HC89S003的串口似乎和其他单片机不同,根据数据手册,波特率的设置如下
通过表格可以发现,如果使用默认的内部16M时钟是无法使用115200或者更高速率的,实测会乱码。
|