小熊熊 发表于 2025-5-9 17:40:24

大老们帮忙看一下这个单片机串口屏程序是否正常 用的是陶晶驰的串口

现在的问题是点击屏幕 单片机没有输出    #include "config.h"
#define U8 unsigned char
U8 rec_Dat;
U8 rec_num = 0;
void Uart1_Isr(void) interrupt 4
{
        if (TI)                                //检测串口1发送中断
        {
                TI = 0;                        //清除串口1发送中断请求位
        }
        if (RI)                                //检测串口1接收中断
        {
                RI = 0;                        //清除串口1接收中断请求位
        }
}

void Uart1_Init(void)        //9600bps@24.000MHz
{
    P_SW1 = (P_SW1 & ~0xc0) | 0x40;       
        SCON = 0x50;                //8位数据,可变波特率
        AUXR &= 0xBF;                //定时器时钟12T模式
        AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
        TMOD &= 0x0F;                //设置定时器模式
        TL1 = 0xCC;                        //设置定时初始值
        TH1 = 0xFF;                        //设置定时初始值
        ET1 = 0;                        //禁止定时器中断
        TR1 = 1;                        //定时器1开始计时
        ES = 1;                                //使能串口1中断
        rec_Dat=S2BUF;
       
}


// 处理接收到的数据
void usart1_RunTask(void)
{
    if (rec_num >= 6)
    {
      if ((rec_Dat == '\n') && (rec_Dat == '\r'))
      {
            if ((rec_Dat == 'O') && (rec_Dat == 'P') &&
                (rec_Dat == 'E') && (rec_Dat == 'N'))
            {
                P20 = 0; // 设置P0的值
            }
      }
      rec_num = 0; // 处理完数据后重置计数器
    }
}

国芯人工智能 发表于 2025-5-9 17:43:00

针对您提供的代码及故障现象分析,程序存在以下几处关键问题需要修正:

一、串口中断服务函数缺陷
原中断服务函数存在数据丢失风险:
c
void Uart1Isr(void) interrupt 4
{
    if (TI) { TI = 0; }//清除发送中断
    if (RI) { RI = 0; }//清除接收中断但未读取数据
}
问题分析:
在检测到接收中断标志RI=1时,未从SBUF寄存器中读取数据,导致接收数据丢失。
修正方案:
c
void Uart1Isr(void) interrupt 4
{
    if (RI) {
      RI = 0;
      recDat = SBUF;//保存接收数据
      if (recnum >= 60) recnum = 0; //防止溢出
    }
    if (TI) { TI = 0; }
}

二、UART1初始化函数错误
1. 错误的数据寄存器访问
代码中误用S2BUF(UART2缓冲区):
c
recDat=S2BUF;//错误:UART1应使用SBUF
修正方案:
删除该行代码。初始化函数仅需配置硬件,不应主动读取数据。

2. 波特率计算验证
根据代码注释//9600bps@24000MHz,实际晶振频率可能为24.000MHz。
计算定时器1重载值:
TH1 = 256 - (Fosc / 12 / 16 / Baudrate)
   = 256 - (24,000,000 / 12 / 16 / 9600)
   ≈ 256 - 13.02 ≈ 243 (0xF3)
当前配置TH1=0xFF会导致实际波特率偏低(约6250bps),建议修正为:
c
TL1 = 0xF3;//修正波特率参数
TH1 = 0xF3;

三、全局中断未启用
代码中未开启全局中断使能位EA,导致中断无法触发。
补充初始化代码:
c
void Uart1Init(void)
{
    //原有配置代码...
    EA = 1;//开启全局中断
}

四、数据协议处理逻辑优化
当前数据处理条件if (recnum >= 6)缺乏协议完整性校验:
1. 陶晶驰串口屏通常采用帧结构(如:AA CMDLEN CMD ... CKSUM 0F 0F)
2. 建议增加帧头、长度、校验和等检测逻辑
改进示例:
c
void usart1RunTask(void)
{
    if (recnum >= 4) {//假设最小帧长4字节
      if (recDat == 0xAA && recDat == 0x0F && recDat == 0x0F) {
            //校验通过后处理数据
            recnum = 0;//复位接收指针
      }
    }
}

五、硬件排查建议
1. 物理层验证
确认TXD(单片机)与RXD(屏幕)交叉连接
测量信号电平是否符合标准(3.3V/5V匹配)
使用示波器捕获波形,验证实际波特率

2. 陶晶驰配置检查
通过USART HMI工具确认控件事件是否绑定正确指令
检查屏幕工程中设置的波特率与代码是否一致

六、完整修正代码
c
include "config.h"
define UARTBUFLEN 60

volatile U8 recDat;
volatile U8 recnum = 0;

void Uart1Isr(void) interrupt 4
{
    if (RI) {
      RI = 0;
      recDat = SBUF;
      if (recnum >= UARTBUFLEN) recnum = 0; //循环缓冲
    }
    if (TI) TI = 0;
}

void Uart1Init(void) //9600bps@24.000MHz
{
    PSW1 = (PSW1 & ~0xC0) | 0x40; //切换UART1到P3.0/P3.1
    SCON = 0x50;    //8位数据+可变波特率
    AUXR &= ~0x40;//定时器1时钟12T模式
    TMOD &= 0x0F;   //定时器1模式设置
    TL1 = 0xF3;   //波特率重载值
    TH1 = 0xF3;
    TR1 = 1;      //启动定时器1
    ES = 1;         //使能串口中断
    EA = 1;         //开启全局中断
}

void ProcessTouchEvent(void)
{
    if (recnum >= 4) { //示例协议:AA CMD 0F 0F
      if (recDat==0xAA && recDat==0x0F && recDat==0x0F) {
            //TODO: 触发对应操作
            SBUF = 0x01; //示例:通过串口发送响应
            while(!TI);//等待发送完成
            TI = 0;
            recnum = 0; //清空缓冲区
      }
    }
}

七、调试建议
1. 最小系统验证
   通过短接单片机的TXD与RXD引脚,测试自发自收是否正常。

2. 指令监控
   使用USB转TTL工具连接屏幕串口,通过PC端串口助手确认屏幕实际输出数据。

3. LED辅助调试
   在中断服务函数中添加GPIO翻转代码,通过示波器观察中断触发频率。

以上修正可系统性解决通信异常问题。若仍存在故障,建议重点排查硬件链路阻抗匹配问题。

[本文内容由国芯人工智能辅助生成,仅供参考]

小熊熊 发表于 2025-5-9 18:33:27

还是不行 不知道哪里出了问题哦

小熊熊 发表于 2025-5-9 19:23:24

小熊熊 发表于 2025-5-9 18:33
还是不行 不知道哪里出了问题哦

我接的是1.61.7

jwd 发表于 2025-5-9 20:39:18

你可以先用串口助手和屏联调一下试试

ercircle 发表于 2025-5-9 20:51:55

代码不完整,且中断里没什么读写操作。建议用例程先测试

小熊熊 发表于 2025-5-9 22:15:51

感觉不对劲啊 多了好多符号

小熊熊 发表于 2025-5-10 20:21:20

ercircle 发表于 2025-5-9 20:51
代码不完整,且中断里没什么读写操作。建议用例程先测试

#define BAUDRATE      (9600)
#define T2_RELOAD       (65536 - (SYSCLK / BAUDRATE + 2) / 4)

    UART1_SwitchP1617();                //设置串口数据端口: RxD (P1.6), TxD (P1.7)

    UART1_Timer2BRT();                  //选择定时器2作为串口1波特率发生器
    TIMER2_TimerMode();               //设置定时器2为定时模式
    TIMER2_1TMode();                  //设置定时器2为1T模式
    TIMER2_SetPrescale(0);            //设置定时器2的8位预分频
    TIMER2_SetReload16(T2_RELOAD);      //设置定时器2的16位重载值
    TIMER2_Run();                     //定时器2开始运行

    UART1_EnableRx();                   //使能串口1接收数据
    UART1_Mode1();                      //设置串口1为模式1 (8位数据可变波特率)
    UART1_SetIntPriority(0);        //设置中断为最低优先级
       rec_num = 0;
    UART1_EnableInt();                  //使能串口1中断
    //<<AICUBE_USER_UART1_INITIAL_BEGIN>>
    // 在此添加用户初始化代码
    //<<AICUBE_USER_UART1_INITIAL_END>>
}
void usart1_RunTask(void)
{
        if(rec_num >= 6)
        {
      if((rec_Dat == 0x01) && (rec_Dat == 0x02))
                {
                        if((rec_Dat == 0x03) && (rec_Dat == 0x04) && (rec_Dat == 0x05) && (rec_Dat == 0x06))
            {
                P20 = 0; // 设置P0的值
            }
      }
      rec_num = 0; // 处理完数据后重置计数器
        }
}

小熊熊 发表于 2025-5-10 20:22:18

小熊熊 发表于 2025-5-10 20:21


这样子能接受到串口数据吗

小熊熊 发表于 2025-5-10 20:24:15

小熊熊 发表于 2025-5-10 20:21


void UART1_ISR(void) interrupt UART1_VECTOR
{
    //<<AICUBE_USER_UART1_ISR_CODE1_BEGIN>>
    // 在此添加中断函数用户代码
    if (UART1_CheckTxFlag())            //判断串口发送中断
    {
      UART1_ClearTxFlag();            //清除串口发送中断标志
    }

    if (UART1_CheckRxFlag())            //判断串口接收中断
    {
      UART1_ClearRxFlag();                 //清除串口接收中断标志
    }
                rec_Dat = SBUF;
    //<<AICUBE_USER_UART1_ISR_CODE1_END>>
}
页: [1] 2
查看完整版本: 大老们帮忙看一下这个单片机串口屏程序是否正常 用的是陶晶驰的串口