迪文屏幕学习笔记四:串口使用和定时器使用

我感觉迪文屏幕分两大类吧,指令屏和OS屏,指令屏幕只能通过UART指令交互和DWIN GUI交互;

OS屏幕,则可以通过在屏幕上二次开发,来实现我们的功能,当然了,OS屏幕也支持UART指令和

DWIN GUI交互,像指令屏那样开发。目前OS支持两到类开发:汇编开发和C语言开发。

迪文屏幕学习笔记四:串口使用和定时器使用_第1张图片

一、DWIN GUI交互串口2

首先明确下串口电平,这个要看硬件手册,串口2是DWIN GUI的DEBUG口,RS232电平,剩下的口

有的是TTL电平、有的是RS232电平(PS:电平不对,会把串口烧坏),有的屏幕还带RS485,这个

就要看具体的屏幕数据手册(PS:找淘宝客服或者迪文官方QQ要,说句实话服务人员的态度还是不错

的,给他们点赞。但是有的问题他们也不懂,毕竟不是技术人员。顺便吐槽迪文的资料写的太烂、太烂

、太烂,无力吐槽。还有建议迪文开放技术交流渠道,有些问题资料不写,根本解决不了。)

PS:串口2是DWIN GUI的DEBUG口,用户不得使用(也用不了,没有开放接口)。

首先来看波特率:

迪文屏幕学习笔记四:串口使用和定时器使用_第2张图片

 再看串口交互数据格式:
迪文屏幕学习笔记四:串口使用和定时器使用_第3张图片

迪文屏幕学习笔记四:串口使用和定时器使用_第4张图片 CRC16计算(PS:这个也可以通过配置文件关闭)

迪文屏幕学习笔记四:串口使用和定时器使用_第5张图片

 通过以上就可以访问DWIN GUI的寄存器和数据,具体的指令地址请看手册。

通过以上,我们就可以和GUI进行交互了。

二、基于OS的串口使用

如果我们要进行二次开发,把一部分功能放到屏幕上,那么我们可以通过其他串口进行私有协议开发。

由于对用的开发有汇编和C,他们有不同的接口,这里仅仅讲解C语言开发。

首先来看支持的波特率:

迪文屏幕学习笔记四:串口使用和定时器使用_第6张图片

PS:串口3仅仅不支持9600波特率。

C语言接口:

迪文屏幕学习笔记四:串口使用和定时器使用_第7张图片

迪文屏幕学习笔记四:串口使用和定时器使用_第8张图片

迪文屏幕学习笔记四:串口使用和定时器使用_第9张图片

使用:

配置串口:com_config(3,0,115200);        //串口设置,串口3配置115200波特率,N81格式。

下面来说下UART使用发送和就收架构:

UART的接收流程:

UART接收是按着数据流接收的,它并不知道什么是“完”,由于程序量小,协议不复杂,我才用Timer Out方法,即接收超时概念

来使用串口接收。手册上给了UARTX_TTL_State,0x00表示接收超时,但是我测试了下,不行,我根本查不到0x00这个状态

,此路明显不同,于是我采用了如下方法:

当接收缓存不为空时候,我就隔一段时间去查询现在的接收数据长度,如果本地接收数据长度和上次接收数据长度一致,

则认为接收完成,就去解析数据了,代码如下:

迪文屏幕学习笔记四:串口使用和定时器使用_第10张图片

 

接收说完了,现在来说发送:

发送之前要先判断串口是否忙,否则有可能造成发上帧送数据帧发送了一部分,导致后面一部分没有发送,或者有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接口:

 

这个接口是数据手册给的,是错误的,不要使用,用下面的接口:

迪文屏幕学习笔记四:串口使用和定时器使用_第11张图片

寄存器号:

迪文屏幕学习笔记四:串口使用和定时器使用_第12张图片

 

使用:

 迪文屏幕学习笔记四:串口使用和定时器使用_第13张图片

你可能感兴趣的:(触摸屏)