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

Posted 无痕幽雨

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了迪文屏幕T5L平台学习笔记七:RS485测试相关的知识,希望对你有一定的参考价值。

由于串口通信距离近,且容易受到干扰,最近改为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();
    

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

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

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

 

 

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

于是修改代码,测试下,收发正常了,到此我不知道各位是什么心情,我心理是有一万匹马过去了,TMD!

以上是关于迪文屏幕T5L平台学习笔记七:RS485测试的主要内容,如果未能解决你的问题,请参考以下文章

迪文屏幕T5L平台学习笔记六:UART4的回环测试

迪文屏幕T5L平台学习笔记二:第一个C51C程序Demo

迪文屏幕T5L平台学习笔记四:C51使用printf或者sprintf注意事项

迪文屏幕T5L平台学习笔记四:C51使用printf或者sprintf注意事项

迪文屏幕T5L平台学习笔记一:开发环境搭建注意事项

迪文屏幕T5L平台学习笔记零:KEIL环境搭建