STC8H8K64U 串口3、串口4问题
用STC8H8K64U 做项目,串口3、串口4均初始化,但串口3并未调用,只使用了串口4。 用USB转串口工具将串口3连接至电脑调试工具,发现串口3不断有00 00 00……输出。用示波器检查串口3的引脚TXD3和RXD3,发现IO口电平平稳,并未发生变化。在波特率>38400时,无论在那个波特率下,电脑接收到的数据始终时00 00 00……,请问为什么示波器检测TXD3和RXD3电平未发生变化的情况下,电脑端仍然能接收到00 00 信号,且串口4一旦停止数据发送,电脑端的数据接收也立刻停止。串口3通过USB转TTL工具连接至电脑,串口4连接至触摸屏
#include "stc8h.h" //包含STC8H的头文件
#include "intrins.h" //使用_nop_()函数所必须要包含的头文件,
//否则延时函数中调用的_nop_()函数没有被头文件引用过来,
//会导致编译器找不到这个而函数而报错。
unsigned char uart1_txflag = 0; //定义1个位变量,UART1事件位变量标志,记录UART1已产生发送中断
// 供主循环查询UART1是否已产生发送中断,在主循环中处理UART1的中断事件任务,不堵塞其他中断
unsigned char uart1_rxflag = 0; //定义1个位变量,UART1事件位变量标志,记录UART1已产生接收中断
// 供主循环查询UART1是否已产生接收中断,在主循环中处理UART1的中断事件任务,不堵塞其他中断
unsigned char uart2_txflag = 0; //定义1个位变量,UART2事件位变量标志,记录UART2已产生发送中断
// 供主循环查询UART2是否已产生发送中断,在主循环中处理UART2的中断事件任务,不堵塞其他中断
unsigned char uart2_rxflag = 0; //定义1个位变量,UART2事件位变量标志,记录UART2已产生接收中断
// 供主循环查询UART2是否已产生接收中断,在主循环中处理UART2的中断事件任务,不堵塞其他中断
unsigned char uart3_txflag = 0; //定义1个位变量,UART3事件位变量标志,记录UART3已产生发送中断
// 供主循环查询UART3是否已产生发送中断,在主循环中处理UART3的中断事件任务,不堵塞其他中断
unsigned char uart3_rxflag = 0; //定义1个位变量,UART3事件位变量标志,记录UART3已产生接收中断
// 供主循环查询UART3是否已产生接收中断,在主循环中处理UART3的中断事件任务,不堵塞其他中断
unsigned char uart4_txflag = 0; //定义1个位变量,UART4事件位变量标志,记录UART4已产生发送中断
// 供主循环查询UART4是否已产生发送中断,在主循环中处理UART1的中断事件任务,不堵塞其他中断
unsigned char uart4_rxflag = 0; //定义1个位变量,UART4事件位变量标志,记录UART4已产生接收中断
// 供主循环查询UART4是否已产生接收中断,在主循环中处理UART4的中断事件任务,不堵塞其他中断
void Uart1_Init(void) //115200bps@40.000MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器时钟1T模式
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设置定时器模式
TL1 = 0xA9; //设置定时初始值
TH1 = 0xFF; //设置定时初始值
ET1 = 0; //禁止定时器中断
TR1 = 1; //定时器1开始计时
ES = 1; //使能串口1中断
}
void Uart2_Init(void) //115200bps@40.000MHz
{
S2CON = 0x50; //8位数据,可变波特率
AUXR |= 0x04; //定时器时钟1T模式
T2L = 0xA9; //设置定时初始值
T2H = 0xFF; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
IE2 |= 0x01; //使能串口2中断
}
void Uart3_Init(void) //115200bps@40.000MHz
{
S3CON = 0x10; //8位数据,可变波特率
S3CON |= 0x40; //串口3选择定时器3为波特率发生器
T4T3M |= 0x02; //定时器时钟1T模式
T3L = 0xA9; //设置定时初始值
T3H = 0xFF; //设置定时初始值
T4T3M |= 0x08; //定时器3开始计时
IE2 |= 0x08; //使能串口3中断
}
void Uart4_Init(void) //115200bps@40.000MHz
{
S4CON = 0x10; //8位数据,可变波特率
S4CON |= 0x40; //串口4选择定时器4为波特率发生器
T4T3M |= 0x20; //定时器时钟1T模式
T4L = 0xA9; //设置定时初始值
T4H = 0xFF; //设置定时初始值
T4T3M |= 0x80; //定时器4开始计时
IE2 |= 0x10; //使能串口4中断
}
void main (void)
{
P_SW2 |= 0x80; //允许访问扩展的特殊寄存器,XFR
//32位8051需要使用下面3句进行初始化
// EAXFR = 1; //允许访问扩展的特殊寄存器,XFR
// WTST = 0; //设置取程序代码等待时间,赋值为0表示不等待,程序以最快速度运行
// CKCON = 0; //设置访问片内的xdata速度,赋值为0表示用最快速度访问,不增加额外的等待时间
P0M0 = 0x00; P0M1 = 0x00; //设置 P0 口为准双向口模式
P1M0 = 0x00; P1M1 = 0x00; //设置 P1 口为准双向口模式
P2M0 = 0x00; P2M1 = 0x00; //设置 P2 口为准双向口模式
P3M0 = 0x00; P3M1 = 0x00; //设置 P3 口为准双向口模式
P3M0 = 0x00; P3M1 = 0x0c; //P32、P33设置为高阻输入(需要同步开启上拉电阻)
P4M0 = 0x00; P4M1 = 0x00; //设置 P4 口为准双向口模式
P5M0 = 0x00; P5M1 = 0x00; //设置 P5 口为准双向口模式
P6M0 = 0x00; P6M1 = 0x00; //设置 P6 口为准双向口模式
P7M0 = 0x00; P7M1 = 0x00; //设置 P7 口为准双向口模式
uart1_txflag = 0; //初始化用户标志位
uart1_rxflag = 0; //初始化用户标志位
uart2_txflag = 0; //初始化用户标志位
uart2_rxflag = 0; //初始化用户标志位
uart3_txflag = 0; //初始化用户标志位
uart3_rxflag = 0; //初始化用户标志位
uart4_txflag = 0; //初始化用户标志位
uart4_rxflag = 0; //初始化用户标志位
Uart1_Init(); //调用UART1初始化函数
Uart2_Init(); //调用UART2初始化函数
Uart3_Init(); //调用UART3初始化函数
Uart4_Init(); //调用UART4初始化函数
EA = 1; //总中断允许位打开
while(1) //主循环中查询需要处理的各种事件
{
/*本演示程序中,主循环查询各中断有无需要继续处理的事件的次序,
依次是 UART/UART2/UART3/UART4, 用户可以自己根据实际情况,
调整查询各中断有无需要继续处理的事件的优先次序*/
if(uart1_txflag) //主循环中查询,UART1是否已产生发送中断,是否有需要处理的UART1发送事件
{
uart1_txflag = 0; //清0,UART1发送事件位变量标志
_nop_(); //用户在此添加需要处理的事件
_nop_();
}
if(uart1_rxflag) //主循环中查询,UART1是否已产生接收中断,是否有需要处理的UART1接收事件
{
uart1_rxflag = 0; //清0,UART1接收事件位变量标志
_nop_(); //用户在此添加需要处理的事件
_nop_();
}
if(uart2_txflag) //主循环中查询,UART2是否已产生发送中断,是否有需要处理的UART2发送事件
{
uart2_txflag = 0; //清0,UART2发送事件位变量标志
_nop_(); //用户在此添加需要处理的事件
_nop_();
}
if(uart2_rxflag) //主循环中查询,UART2是否已产生接收中断,是否有需要处理的UART2接收事件
{
uart2_rxflag = 0; //清0,UART2接收事件位变量标志
_nop_(); //用户在此添加需要处理的事件
_nop_();
}
if(uart3_txflag) //主循环中查询,UART3是否已产生发送中断,是否有需要处理的UART3发送事件
{
uart3_txflag = 0; //清0,UART3发送事件位变量标志
_nop_(); //用户在此添加需要处理的事件
_nop_();
}
if(uart3_rxflag) //主循环中查询,UART3是否已产生接收中断,是否有需要处理的UART3接收事件
{
uart3_rxflag = 0; //清0,UART3接收事件位变量标志
_nop_(); //用户在此添加需要处理的事件
_nop_();
}
if(uart4_txflag) //主循环中查询,UART4是否已产生发送中断,是否有需要处理的UART4发送事件
{
uart4_txflag = 0; //清0,UART4发送事件位变量标志
_nop_(); //用户在此添加需要处理的事件
_nop_();
}
if(uart4_rxflag) //主循环中查询,UART4是否已产生接收中断,是否有需要处理的UART4接收事件
{
uart4_rxflag = 0; //清0,UART4接收事件位变量标志
_nop_(); //用户在此添加需要处理的事件
_nop_();
}
}
}
void Uart1_Isr(void) interrupt UART1_VECTOR
{
if (TI) //检测串口1发送中断
{
TI = 0; //清除串口1发送中断请求位
_nop_(); //特急处理
//以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
//但时间不要太长,否则会影响其他中断事件的实时响应速度
uart1_txflag = 1; // uart1_txflag置1是通知主循环处理部分串口1发送中断事件不需要特急处理的任务
//置1,记录UART1已产生发送中断,供主循环查询判断有无需处理的UART1发送任务
}
if (RI) //检测串口1接收中断
{
RI = 0; //清除串口1接收中断请求位
_nop_(); //特急处理
//以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
//但时间不要太长,否则会影响其他中断事件的实时响应速度
uart1_rxflag = 1; // uart1_rxflag置1是通知主循环处理部分串口1接收中断事件不需要特急处理的任务
//置1,记录UART1已产生接收中断,供主循环查询判断有无需处理的UART1接收任务
}
}
//UART1中断服务程序,UART1_VECTOR在stc8h头文件中已宏定义为4
void Uart2_Isr(void) interrupt UART2_VECTOR
{
if (S2CON & 0x02) //检测串口2发送中断
{
S2CON &= ~0x02; //清除串口2发送中断请求位
_nop_(); //特急处理
//以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
//但时间不要太长,否则会影响其他中断事件的实时响应速度
uart2_txflag = 1; // uart2_txflag置1是通知主循环处理部分串口2发送中断事件不需要特急处理的任务
//置1,记录UART2已产生发送中断,供主循环查询判断有无需处理的UART2发送任务
}
if (S2CON & 0x01) //检测串口2接收中断
{
S2CON &= ~0x01; //清除串口2接收中断请求位
_nop_(); //特急处理
//以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
//但时间不要太长,否则会影响其他中断事件的实时响应速度
uart2_rxflag = 1; // uart2_rxflag置1是通知主循环处理部分串口2接收中断事件不需要特急处理的任务
//置1,记录UART2已产生接收中断,供主循环查询判断有无需处理的UART2接收任务
}
}
//UART2中断服务程序,UART2_VECTOR在stc8h头文件中已宏定义为8
void Uart3_Isr(void) interrupt UART3_VECTOR
{
if (S3CON & 0x02) //检测串口3发送中断
{
S3CON &= ~0x02; //清除串口3发送中断请求位
_nop_(); //特急处理
//以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
//但时间不要太长,否则会影响其他中断事件的实时响应速度
uart3_txflag = 1; // uart3_txflag置1是通知主循环处理部分串口3发送中断事件不需要特急处理的任务
//置1,记录UART3已产生发送中断,供主循环查询判断有无需处理的UART3发送任务
}
if (S3CON & 0x01) //检测串口3接收中断
{
S3CON &= ~0x01; //清除串口3接收中断请求位
_nop_(); //特急处理
//以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
//但时间不要太长,否则会影响其他中断事件的实时响应速度
uart3_rxflag = 1; // uart3_rxflag置1是通知主循环处理部分串口3接收中断事件不需要特急处理的任务
//置1,记录UART3已产生接收中断,供主循环查询判断有无需处理的UART3接收任务
}
}
//UART3中断服务程序,UART3_VECTOR在stc8h头文件中已宏定义为17
void Uart4_Isr(void) interrupt UART4_VECTOR
{
if (S4CON & 0x02) //检测串口4发送中断
{
S4CON &= ~0x02; //清除串口4发送中断请求位
_nop_(); //特急处理
//以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
//但时间不要太长,否则会影响其他中断事件的实时响应速度
uart4_txflag = 1; // uart4_txflag置1是通知主循环处理部分串口4发送中断事件不需要特急处理的任务
//置1,记录UART4已产生发送中断,供主循环查询判断有无需处理的UART4发送任务
}
if (S4CON & 0x01) //检测串口4接收中断
{
S4CON &= ~0x01; //清除串口4接收中断请求位
_nop_(); //特急处理
//以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
//但时间不要太长,否则会影响其他中断事件的实时响应速度
uart4_rxflag = 1; // uart4_rxflag置1是通知主循环处理部分串口4接收中断事件不需要特急处理的任务
//置1,记录UART4已产生接收中断,供主循环查询判断有无需处理的UART4接收任务
}
}
//UART4中断服务程序,UART4_VECTOR在stc8h头文件中已宏定义为18
这个问题是随着串口4的数据发送,串口3并未发送数据的情况下,端口电平也未发生变化,电脑端为什么能接收到数据? 搞错,检测到TXD3有低频率的3百多Hz的电平变化,不知什么原因
感觉是串口3和串口4挨得太近,串口4干扰到串口3了
确实是挨得太近了造成的,将串口3切换到P5.1P5.0,干扰小很多 上拉电阻打开 实在是太奇怪了,串口3一旦使能,受串口4影响,其TXD3就有脉冲输出;若不使能,TXD3就没有脉冲输出。用的是STC8H库函数,检查没发现问题。
从我们正确的程序出发
页:
[1]
2