|
|
楼主 |
发表于 2026-8-24 17:04:53
|
显示全部楼层
我让ai 助手 又重新写了一个。 目前来看还是不够准确。
我要用 p3.6 p3.7 能正常收,能正常发 就可以
AI
您需要使用串口1在P3.6/P3.7引脚上正常收发数据。让我确认一下官方的示例程序和寄存器配置方式。
根据手册 「19 2组USART-LIN/SPI,同步/异步串口通信,硬件奇偶校验」 章节中官方给出的串口1使用定时器1做波特率发生器的示例程序,结合 「6 功能脚切换」 章节的P_SW1配置,以及 「14 I/O口」 章节中对P3.6/P3.7引脚模式的设置要求,我来为您整理一个可以正常收发的完整示例代码。
串口1使用 P3.6/P3.7 正常收发代码
根据手册要求,切换到P3.6/P3.7引脚需要:
设置 P_SW1 的 S1_S[1:0]=01(对应RxD=P3.6, TxD=P3.7)
配置 P3M0/P3M1 设置P3.6/P3.7的I/O模式(除P3.0/P3.1外,其他引脚上电默认高阻输入,必须设置I/O模式)
//=========================================================
// 串口1 使用 P3.6(RxD) / P3.7(TxD) 正常收发示例
// 适用芯片:Ai8051U系列
// 编译环境:Keil C251
// 系统时钟:11.0592MHz,波特率:115200
// 波特率发生器:定时器1(16位自动重载,1T模式)
//=========================================================
#include "Ai8051U.H"
#include "intrins.h"
#define FOSC 11059200UL
#define BRT (65536 - (FOSC / 115200 + 2) / 4)
void UartInit()
{
// 1. 串口1功能脚切换到 P3.6(P33.8... 实际是 P3.6 RxD) / P3.7(TxD)
P_SW1 |= 0x40; // S1_S[1:0]=01, 选择P3.6/P3.7作为串口1引脚
// 2. 设置P3.6/P3.7的I/O模式(必须!除P3.0/P3.1外上电默认高阻输入)
// P3.6 作为 RxD 输入,设为准双向口
// P3.7 作为 TxD 输出,设为推挽输出或准双向口
P3M0 &= ~0xC0; // P3.6/P3.7 M0位清零
P3M1 &= ~0xC0; // P3.6/P3.7 M1位清零 -> 准双向口模式
// 3. 串口控制寄存器配置
SCON = 0x50; // SM0=0, SM1=1(模式1), REN=1(允许接收), SM2=0
// 4. 定时器1作为波特率发生器
S1BRT = 0; // 串口1选择定时器1为波特率发生器
TMOD &= ~0xF0; // 定时器1模式0(16位自动重载)
TMOD |= 0x00;
TL1 = BRT; // 波特率重载值低8位
TH1 = BRT >> 8; // 波特率重载值高8位
T1x12 = 1; // 定时器1时钟1T模式
TR1 = 1; // 启动定时器1
}
void main()
{
// 32位模式下允许访问扩展寄存器
EAXFR = 1;
UartInit();
// 允许串口1中断
ES = 1;
EA = 1;
SBUF = 'A'; // 发送测试数据
while (TI == 0); // 等待发送完成
TI = 0; // 清除发送标志
while (1)
{
if (RI) // 收到数据
{
RI = 0; // 清除接收标志
SBUF = SBUF; // 回显收到的数据(示例)
while (TI == 0);
TI = 0;
}
}
}
📋
关键点说明:
配置项 值 作用
P_SW1 |= 0x40 S1_S[1:0]=01 串口1切换到 P3.6/P3.7
P3M0 &= ~0xC0 P3.6/P3.7 M0=0 设置准双向口
P3M1 &= ~0xC0 P3.6/P3.7 M1=0 设置准双向口
SCON = 0x50 模式1, REN=1 允许收发
S1BRT = 0 选定时器1 波特率发生器
T1x12 = 1 定时器1 1T模式 提高波特率
如果您想要中断接收的更完整示例(避免轮询阻塞),也可以参考以下方式:
#include "Ai8051U.H"
#include "intrins.h"
#define FOSC 11059200UL
#define BRT (65536 - (FOSC / 115200 + 2) / 4)
bit busy;
char wptr;
char rptr;
char buffer[16];
void UartIsr() interrupt 4
{
if (TI)
{
TI = 0;
busy = 0;
}
if (RI)
{
RI = 0;
buffer[wptr++] = SBUF;
wptr &= 0x0f;
}
}
void UartInit()
{
P_SW1 |= 0x40; // 串口1切换到P3.6/P3.7
P3M0 &= ~0xC0; // P3.6/P3.7设为准双向口
P3M1 &= ~0xC0;
SCON = 0x50; // 模式1, REN=1
S1BRT = 0; // 选定时器1做波特率发生器
TMOD &= ~0xF0;
TL1 = BRT;
TH1 = BRT >> 8;
T1x12 = 1;
TR1 = 1;
wptr = 0;
rptr = 0;
busy = 0;
}
void UartSend(char dat)
{
while (busy);
busy = 1;
SBUF = dat;
}
void UartSendStr(char *p)
{
while (*p)
{
UartSend(*p++);
}
}
void main()
{
EAXFR = 1; // 允许访问扩展寄存器(32位模式)
UartInit();
ES = 1; // 允许串口1中断
EA = 1; // 打开总中断
UartSendStr("Uart Test !\r\n");
while (1)
{
if (rptr != wptr) // 有数据待处理
{
UartSend(buffer[rptr++]);
rptr &= 0x0f;
}
}
}
----------------------------------------
最后一次借助 ai 助手,
下一步 准备 自己 重新 从头到尾 写一个试试。
|
|