我感觉迪文屏幕分两大类吧,指令屏和OS屏,指令屏幕只能通过UART指令交互和DWIN GUI交互;
OS屏幕,则可以通过在屏幕上二次开发,来实现我们的功能,当然了,OS屏幕也支持UART指令和
DWIN GUI交互,像指令屏那样开发。目前OS支持两到类开发:汇编开发和C语言开发。
一、DWIN GUI交互串口2
首先明确下串口电平,这个要看硬件手册,串口2是DWIN GUI的DEBUG口,RS232电平,剩下的口
有的是TTL电平、有的是RS232电平(PS:电平不对,会把串口烧坏),有的屏幕还带RS485,这个
就要看具体的屏幕数据手册(PS:找淘宝客服或者迪文官方QQ要,说句实话服务人员的态度还是不错
的,给他们点赞。但是有的问题他们也不懂,毕竟不是技术人员。顺便吐槽迪文的资料写的太烂、太烂
、太烂,无力吐槽。还有建议迪文开放技术交流渠道,有些问题资料不写,根本解决不了。)
PS:串口2是DWIN GUI的DEBUG口,用户不得使用(也用不了,没有开放接口)。
首先来看波特率:
通过以上就可以访问DWIN GUI的寄存器和数据,具体的指令地址请看手册。
通过以上,我们就可以和GUI进行交互了。
二、基于OS的串口使用
如果我们要进行二次开发,把一部分功能放到屏幕上,那么我们可以通过其他串口进行私有协议开发。
由于对用的开发有汇编和C,他们有不同的接口,这里仅仅讲解C语言开发。
首先来看支持的波特率:
PS:串口3仅仅不支持9600波特率。
C语言接口:
使用:
配置串口:com_config(3,0,115200); //串口设置,串口3配置115200波特率,N81格式。
下面来说下UART使用发送和就收架构:
UART的接收流程:
UART接收是按着数据流接收的,它并不知道什么是“完”,由于程序量小,协议不复杂,我才用Timer Out方法,即接收超时概念
来使用串口接收。手册上给了UARTX_TTL_State,0x00表示接收超时,但是我测试了下,不行,我根本查不到0x00这个状态
,此路明显不同,于是我采用了如下方法:
当接收缓存不为空时候,我就隔一段时间去查询现在的接收数据长度,如果本地接收数据长度和上次接收数据长度一致,
则认为接收完成,就去解析数据了,代码如下:
接收说完了,现在来说发送:
发送之前要先判断串口是否忙,否则有可能造成发上帧送数据帧发送了一部分,导致后面一部分没有发送,或者有retry机制,导致retry时候数据被清掉。基于以上两点原因,我自己做了个很简陋的发送架构如下(PS:UARTX_TX_LEN这个寄存器,我不知道如何使用,因此我就没用):
static void uart_tx_process(void)
{
static enum{
FSM_UART_TX_PROCESS_STATE_START = 0,
FSM_UART_TX_PROCESS_STATE_WAIT_TX,
FSM_UART_TX_PROCESS_STATE_WAIT_ACK,
}s_tState = FSM_UART_TX_PROCESS_STATE_START;
static unsigned char s_chRetrySend = 0;
#define RESET_FSM_UART_TX_PROCESS() {s_tState = FSM_UART_TX_PROCESS_STATE_START;}
switch(s_tState){
case FSM_UART_TX_PROCESS_STATE_START:
s_chRetrySend = 0;
s_tState = FSM_UART_TX_PROCESS_STATE_WAIT_TX;
//break;
case FSM_UART_TX_PROCESS_STATE_WAIT_TX:
if(get_systick()%5){
return;
}
if(!s_hwUartTXCnt){
return;
}
// if(app_read_register(22)){//等待发送缓存区空
// return;
// }
FLAG_ACK_CLEAR();
send_data_com(USER_APP_UART_NUM,s_chUartTxBuffer,s_hwUartTXCnt);
if(UART_GET_WAIT_ACK()){
s_hwUartWaitTimer = 600;
s_tState = FSM_UART_TX_PROCESS_STATE_WAIT_ACK;
}else{
s_hwUartTXCnt = 0;
UART_CLEAR_BUSY();
RESET_FSM_UART_TX_PROCESS();
}
break;
case FSM_UART_TX_PROCESS_STATE_WAIT_ACK:
if(!s_hwUartWaitTimer){
if(s_chRetrySend >= 2){
s_hwUartTXCnt = 0;
UART_CLEAR_BUSY();
//UART_CLEAR_WAIT_ACK();
RESET_FSM_UART_TX_PROCESS();
return;
}else{
s_tState = FSM_UART_TX_PROCESS_STATE_WAIT_TX;
}
s_chRetrySend++;
}
if(FLAG_ACK_GET()){
s_hwUartTXCnt = 0;
UART_CLEAR_BUSY();
//UART_CLEAR_WAIT_ACK();
RESET_FSM_UART_TX_PROCESS();
return;
}
break;
default:
while(1);
}
#undef RESET_FSM_UART_TX_PROCESS
}
每隔5ms看看TXbuffer(这个是用户定义的)是否非空,如果非空,则发送数据;发送后,判定是否等待ACK应道,如果是,则等待ACK,同时查看超时标示(我设置的1.2S),如果1.2S超时标志到了,ACK标志未到,则启动重发机制,重发3次;如果ACK,则本次发送结束;如果不需要等待ACK,则本次发送也结束;清除buffer占用标志。来看用户接口:
static fsm_rt_t app_send_cmd(unsigned char chCMD,unsigned char chIsWaitACK)
{
//unsigned short hwTemp = 0;
if(UART_GET_BUSY()){
return fsm_rt_on_going;
}
s_chUartTxBuffer[0] = 0x68;
s_chUartTxBuffer[1] = 0x00;
s_chUartTxBuffer[2] = 0x00;
s_chUartTxBuffer[3] = 0x01;
s_chUartTxBuffer[4] = 0x00;
s_chUartTxBuffer[5] = chCMD;
switch(chCMD){
case 4:
s_chUartTxBuffer[6] = 0xB8;
s_chUartTxBuffer[7] = 0x66;
break;
case 5:
s_chUartTxBuffer[6] = 0x99;
s_chUartTxBuffer[7] = 0x76;
break;
case 6:
s_chUartTxBuffer[6] = 0xFA;
s_chUartTxBuffer[7] = 0x46;
break;
case 7:
s_chUartTxBuffer[6] = 0xDB;
s_chUartTxBuffer[7] = 0x56;
break;
case 8:
s_chUartTxBuffer[6] = 0x34;
s_chUartTxBuffer[7] = 0xA7;
break;
case 18:
s_chUartTxBuffer[6] = 0x4F;
s_chUartTxBuffer[7] = 0x14;
break;
default:
break;
}
// hwTemp = CRC16_plc(s_chUartTxBuffer+1,5);
// s_chUartTxBuffer[6] = hwTemp >> 8;
// s_chUartTxBuffer[7] = hwTemp;
s_chUartTxBuffer[8] = 0x16;
UART_SET_BUSY();
s_hwUartTXCnt = 9;
UART_SET_WAIT_ACK(chIsWaitACK);
return fsm_rt_cpl;
}
很简单,查看缓存是否可用,然后把数据写到缓存里面,同时置忙标志位。
PS:函数嵌套不能太深,最好不要超过4级,可能会导致意向不到的结果;我开始用的嵌套了6级,导致发送出来的数据全是乱码,通过检查临时变量和函数嵌套深度,解决。
三、TIMER使用
来看C接口:
这个接口是数据手册给的,是错误的,不要使用,用下面的接口:
寄存器号:
使用: