迪文屏幕T5L平台学习笔记七:RS485测试

文章描述了一位技术人员在将串口通信改为RS485通信后,遇到发送数据不成功的难题。通过检查数据手册和迪文论坛,发现需要手动切换TR5(P0.1)电平来控制发送,修改代码后成功实现收发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        由于串口通信距离近,且容易受到干扰,最近改为RS485通信方案,迪文屏幕DMG10600K070_03WTC正好也支持RS485通信,把调试过程记录下。

1、首先看下数据手册:

 串口5支持RS485通信。

2、查看《迪文T5L ASIC 应用开发指南》中UART5说明

 

IO口为专用IO口,无需配置:

3、驱动:

#define UART5_ENABLE_RX()           T5LIB_ATOM_CODE(SCON3R= SCON3R | 0x80;)
#define UART5_DISENABLE_RX()        T5LIB_ATOM_CODE(SCON3R= SCON3R & 0x7F;)
#define UART5_ENABLE_TX()           T5LIB_ATOM_CODE(SCON3T= SCON3T | 0x80;)
#define UART5_DISENABLE_TX()        T5LIB_ATOM_CODE(SCON3T= SCON3T & 0x7F;)
#define UART5_ENABLE_RX_INT()       T5LIB_ATOM_CODE(ES3R  = 0x01;)
#define UART5_DISENABLE_RX_INT()    T5LIB_ATOM_CODE(ES3R  = 0x00;)
#define UART5_ENABLE_TX_INT()       T5LIB_ATOM_CODE(ES3T  = 0x01;)
#define UART5_DISENABLE_TX_INT()    T5LIB_ATOM_CODE(ES3T  = 0x00;)
#define UART5_CLEAR_RX_FLAG()       T5LIB_ATOM_CODE(SCON3R= SCON3R & 0xFE;)
#define UART5_READ_RX_FLAG()        (SCON3R & 0xFE)
#define UART5_CLEAR_TX_FLAG()       T5LIB_ATOM_CODE(SCON3T= SCON3T & 0xFE;)
#define UART5_READ_TX_FLAG()        (SCON3T & 0xFE)

bool uart5_set_baudrate(uint32_t baudrate)
{
    union _union_uint32_t tTemp   = {0};
    bool     bResult = false;
 
    if(!baudrate){
        return false;
    }
 
    T5LIB_ATOM_CODE(
        
        SCON3T = SCON3T & 0xBF; //选择8位模式
        SCON3R = SCON3R & 0xBF; //选择8位模式
        tTemp.wTemp = (CPU_SYSCLK)/(baudrate*8l);
 
        BODE3_DIV_H = tTemp.chTemp[2];
        BODE3_DIV_L = tTemp.chTemp[3];
    )
 
    return true;
}

初始化:

static void uart5_init(void)
{
    UART5_DISENABLE_TX_INT();
    UART5_DISENABLE_RX_INT();
    UART5_DISENABLE_TX();
    UART5_DISENABLE_RX();
    UART5_CLEAR_TX_FLAG();
    UART5_CLEAR_RX_FLAG();
 
    uart5_set_baudrate(115200);
 
    UART5_ENABLE_RX();
    UART5_ENABLE_TX();
    UART5_ENABLE_RX_INT();
    //UART5_ENABLE_TX_INT();
}

中断:

static uint8_t xdata s_chBuffer[100] = {0};
static uint8_t       s_chSize = 0;


void uart5_rx_irq(void)
{
    UART5_CLEAR_RX_FLAG();
 
    if(s_chSize < sizeof(s_chBuffer)){
        s_chBuffer[s_chSize] = SBUF3_RX;
        s_chSize++;
    }
}
 
void uart5_tx_irq(void)
{
    static uint8_t i=1;
    UART5_CLEAR_TX_FLAG();
 
    if(i<s_chSize){
        SBUF3_TX = s_chBuffer[i];
        i++;
    }else{
        i=1;
        s_chSize = 0;
        UART5_DISENABLE_TX_INT();
    }
}
 
void uart5_tx_start(void)
{
    printf("uart5_tx_start\r\n");
    UART5_CLEAR_TX_FLAG();
    UART5_ENABLE_TX_INT();
    SBUF3_TX = s_chBuffer[0];
}
void UART5_T_ISR(void)	    interrupt 12
{
    SAFE_ATOM_CODE(
        extern void uart5_tx_irq(void);
        uart5_tx_irq();
    )
}

void UART5_R_ISR(void)	    interrupt 13
{
    SAFE_ATOM_CODE(
        extern void uart5_rx_irq(void);
        uart5_rx_irq();
    )
}

测试代码:

void test_uart5(void)
{
    static enum{
        FSM_UART5_STATE_START = 0,
        FSM_UART5_STATE_WAIT,
        FSM_UART5_STATE_SEND,
        FSM_UART5_STATE_CPL,
    }s_tUart5State = FSM_UART5_STATE_START;
 
    static  uint8_t s_chSizeOld = 0;
    static struct timer s_tUart5Timer = {0};
 
    switch(s_tUart5State){
        case FSM_UART5_STATE_START:
            //s_chSizeOld = 0;
            timer_set(&s_tUart5Timer,DELAY_TIMERS(20));
            s_tUart5State = FSM_UART5_STATE_WAIT;
            //break;
        case FSM_UART5_STATE_WAIT:
            if(!timer_expired(&s_tUart5Timer)){
                break;
            }
            if(s_chSizeOld != s_chSize){
                s_chSizeOld = s_chSize;
                s_tUart5State = FSM_UART5_STATE_START;
            }else{
                if(s_chSize){
//                    {
//                        int8_t    cData[10];
//                        int        i = 0;
//                        i = sprintf(cData,"%bd",s_chSize);
//                        write_dgusii_vp(0x500A,cData,10);
//                    }
                    {
                        uint8_t i=0;
                        for(i=0;i<s_chSize;i++){
                            printf("%bx ",s_chBuffer[i]);
                        }
                        printf("\r\n");
                    }
                    s_tUart5State = FSM_UART5_STATE_SEND;
                }else{
                    s_tUart5State = FSM_UART5_STATE_START;
                }
            }
            break;
        case FSM_UART5_STATE_SEND:
            uart5_tx_start();
            timer_set(&s_tUart5Timer,DELAY_TIMERS(3000));
            s_tUart5State = FSM_UART5_STATE_CPL;
            //break;
        case FSM_UART5_STATE_CPL:
            if(!s_chSize){
            //if(!s_chSize || timer_expired(&s_tUart5Timer)){
                s_tUart5State = FSM_UART5_STATE_START;
                printf("FSM_UART5_STATE_CPL\r\n");
            }
            break;
        default:
            FSM_DEFAULT_ACTION();
    }
}

测试发现:能接收,但是不能发送,分析log发现接收数据正确,发送流程正常,发送中断也进入了,但是上位机就是收不到任何数据,于是我把手册都看了一遍,没发现问题,于是去迪文论坛看看,搜到下面两篇帖子:

【提问】U5 串口485需要手动切换方向吗?

 请问芯片的TR4和TR5引脚用来做什么?

 

 

于是测试了下:我用的是UART5,那么就是TR5,也就是P0.1,高电平发送。

于是修改代码,测试下,收发正常了,到此我不知道各位是什么心情,我心里是有一万匹马过去了,屏幕手册没写,《迪文T5L ASIC 应用开发指南》没有写,《T5L DGUSII 应用开发指南20210507》没有写,《T5L_DGUS2应用指南_V55》也没有写,TMD!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值