日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

外设驱动库开发笔记35:迪文触摸屏驱动

發布時間:2024/7/23 编程问答 71 豆豆
生活随笔 收集整理的這篇文章主要介紹了 外设驱动库开发笔记35:迪文触摸屏驱动 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

??有些時候嵌入式系統也需要顯示更為復雜的圖形,需要更豐富的數據展示。為此,我們需要更大,色彩更豐富,帶觸屏的顯示屏,當然性價比更高就最好了。在我們的項目中遇到此類需求,我們有時會選擇DWIN觸摸屏。在本篇中,我們就來設計并實現DWIN觸摸屏的驅動。

1、功能概述

??我們這里所說的是迪文的串口屏,該屏有多種接口類型,有使用RS485接口的屏,也有可通過跳線實現TTL接口或RS232接口的屏。但不論什么接口均采用相同的通訊協議。迪文串口屏采用的通訊協議的完整指令結構如下圖所示:

??其中,CRC校驗不包括幀頭和數據長度,僅針對指令和數據進行校驗。CRC 校驗采用 ANSI CRC-16 (X16+X15+X2+1)格式。當啟用 CRC 幀校驗并開啟自動應答功能后(R2.4=1,RC.3=1),DGUS 屏會在 CRC 校驗完成后自動應答校驗情況,返回指令結構如下:

幀頭**+02+****(DGUS 屏接收的)指令+數據(0xFF 表示 CRC **校驗正確,0x00 表示 CRC **校驗錯誤)+CRC。**

??迪文的DGUS 把用戶圖形界面的每一個頁面分解成多個控件變量,即 DGUS 屏采用變量驅動模式工作,屏的工作模式和GUI的狀態完全由數據變量來控制。因此,串口指令也只需要對變量進行讀、寫即可,指令集非常簡單,一共只有5條指令。讀寫指令集如下圖所示:

??配置寄存器空間是用于存放指令狀態的,比如RTC(實時時間)、背光亮度等實時的狀態。了解寄存器的地址以及各寄存器的功能,就可以通過串口指令來實現上位機與DGUS屏信息傳輸及控制。寄存器地址0x00~0xFF,具體功能查看迪文寄存器功能說明。

2、驅動設計與實現

??已經了解了迪文屏的通訊協議,我們就可以據此編寫迪文屏的驅動程序。我們知道迪文屏的通訊協議有5個指令,我們的驅動就是通過這5個指令操作迪文屏。

2.1、對象定義

??我們們依然采用基于對象的操作方式來實現,所以首先我們依然是定義迪文屏的對象類型。具體定義如下:

/* 定義迪文串口屏對象類型 */ typedef struct DwinObject {DwinCheckCodeType checkMode; //校驗方式void (*SendData)(uint8_t *txData,uint16_t length); //發送數據void (*GetRegister)(struct DwinObject *dwin,uint8_t regAddress,uint8_t readByteLength);void (*SetRegister)(struct DwinObject *dwin,uint8_t regAddress,uint8_t *txData,uint16_t length); }DwinObjectType;

??迪文屏對象類型我們并沒有抽象出太多屬性,因為屏作為從設備并沒有返回太多信息,也沒有什么選擇特性。考慮到通訊信息的校驗可以選擇是否啟用,所以我們將其抽象為屬性以區別于不同的情況。

??在對象使用之前同樣需要對其初始化,所以我們需要對象初始化函數。初始化函數如下:

/* 初始化迪文串口屏對象 */ void DwinInitialization(DwinObjectType *dwin,DwinCheckCodeType checkMode,SendDataForDwinType SendData) {if((dwin==NULL)||(SendData==NULL)){return;}dwin->checkMode=checkMode;dwin->SendData=SendData;dwin->GetRegister=GetRegisterDataFromDwinLCD;dwin->SetRegister=SetRegisterDataToDwinLCD; }

2.2、對象操作

??定義并初始化過的對象就可以對其進行操作。我們已經說過,迪文屏通訊協議有5個操作碼。分別是:0x80、寫寄存器;0x81,讀寄存器;0x82,寫數據存儲器;0x83,讀數據存儲器;0x84,寫曲線緩沖區。我們對屏的操作就是實現對這5個操作碼的使用。

2.2.1、寫寄存器

??向指定的寄存器地址寫入數據,指令碼為0x80。該命令支持多個寄存器的連續寫操作,但最多只能寫入16個字節的數據。我們按照前面說的消息幀的格式編寫操作函數如下:

/*寫寄存器數據,一次最多允許寫16個字節,即length<=16*/ static void SetRegisterDataToDwinLCD(DwinObjectType *dwin,uint8_t regAddress,uint8_t *txData,uint16_t length) {/*命令的長度由幀頭(2個字節)+數據長度(1個字節)+指令(1個字節)+寄存器地址(1個字節)+寫的數據(最多16字節)+CRC校驗(2個字節)*/uint16_t cmd_Length=length+5;uint8_t cmd_Reg_Write[23];cmd_Reg_Write[0]=0x5A;cmd_Reg_Write[1]=0xA5;cmd_Reg_Write[2]=(uint8_t)(length+2);cmd_Reg_Write[3]= FC_REG_Write;cmd_Reg_Write[4]=regAddress;for(int dataIndex=0;dataIndex<length;dataIndex++){cmd_Reg_Write[dataIndex+5]=txData[dataIndex];}if(dwin->checkMode>DwinNone){uint16_t checkCode=CalcDwinCRC16(&cmd_Reg_Write[3],length+2);cmd_Reg_Write[length+5]=(uint8_t)checkCode;cmd_Reg_Write[length+6]=(uint8_t)(checkCode>>8);cmd_Length=cmd_Length+2;}dwin->SendData(cmd_Reg_Write,cmd_Length); }

2.2.2、讀寄存器

??從指定的寄存器地址開始讀取指定字節長度的數據,指令碼為0x81。一次讀取一到多個寄存器。由于寄存器地址是0x00到0xFF,所以理論上可以一次讀取全部寄存器。我們可以根據消息格式編寫操作函數如下:

/*讀寄存器數據*/ static void GetRegisterDataFromDwinLCD(DwinObjectType *dwin,uint8_t regAddress,uint8_t readByteLength) {/*命令的長度由幀頭(2個字節)+數據長度(1個字節)+指令(1個字節)+寄存器地址(1個字節)+讀取寄存器的字節長度(1個字節)+CRC校驗(2個字節)*/uint16_t cmd_Length=6;uint8_t cmd_Reg_Read[]={0x5A,0xA5,0x03,FC_REG_Read,0x00,0x00,0x00,0x00};//讀數據命令cmd_Reg_Read[4]=regAddress;cmd_Reg_Read[5]=readByteLength;if(dwin->checkMode>DwinNone){uint16_t checkCode=CalcDwinCRC16(&cmd_Reg_Read[3],3);cmd_Reg_Read[6]=(uint8_t)checkCode;cmd_Reg_Read[7]=(uint8_t)(checkCode>>8);cmd_Length=cmd_Length+2;}dwin->SendData(cmd_Reg_Read,cmd_Length); }

2.2.3、寫存儲器

??從指定的變量存儲器地址開始寫入數據串(字數據)到變量存儲區,指令碼為0x82。存儲區與寄存器不一樣,地址和數據都是16位的。理論上說一次可寫差不多100個字的數據,事實上通常不建議這種極限方式。所以我們將長度限制在100個字節以內。我們可以根據消息格式編寫操作函數如下:

/*寫數據變量存儲器,一次最多允許寫47個字,即length<=94*/ void WriteFlashDataToDwinLCD(DwinObjectType *dwin,uint16_t startAddress,uint8_t *txData,uint16_t length) {/*命令的長度由幀頭(2個字節)+數據長度(1個字節)+指令(1個字節)+起始地址(2個字節)+數據(長度為length)+CRC校驗(2個字節)*/uint16_t cmd_Length=length+6;uint8_t cmd_VAR_Write[102];cmd_VAR_Write[0]=0x5A;cmd_VAR_Write[1]=0xA5;cmd_VAR_Write[2]=(uint8_t)(length+3);cmd_VAR_Write[3]= FC_VAR_Write;cmd_VAR_Write[4]=(uint8_t)(startAddress>>8);//起始地址cmd_VAR_Write[5]=(uint8_t)startAddress;//起始地址for(int dataIndex=0;dataIndex<length;dataIndex++){cmd_VAR_Write[dataIndex+6]=txData[dataIndex];}if(dwin->checkMode>DwinNone){uint16_t checkCode=CalcDwinCRC16(&cmd_VAR_Write[3],length+2);cmd_VAR_Write[length+6]=(uint8_t)checkCode;cmd_VAR_Write[length+7]=(uint8_t)(checkCode>>8);cmd_Length=cmd_Length+2;}dwin->SendData(cmd_VAR_Write,cmd_Length); }

2.2.4、讀存儲器

??從變量存儲區指定地址開始讀取指定字長度的字數據,指令碼為0x83。讀取操作理論也可以讀取256個字節,其實顯示屏主要用于數據展示,主要是接收主機發來的數據。需要發送給主站的數據很有限。我們可以根據消息格式編寫操作函數如下:

/*讀變量存儲器數據*/ void ReadFlashDataFromDwinLCD(DwinObjectType *dwin,uint16_t startAddress,uint8_t readWordLength) {/*命令的長度由幀頭(2個字節)+數據長度(1個字節)+指令(1個字節)+起始地址(2個字節)+讀取的字長度(1個字節)+CRC校驗(2個字節)*/uint16_t cmd_Length=7;uint8_t cmd_VAR_Read[]={0x5A,0xA5,0x04,FC_VAR_Read,0x00,0x00,0x00,0x00,0x00};//讀數據命令cmd_VAR_Read[4]=(uint8_t)(startAddress>>8);//起始地址cmd_VAR_Read[5]=(uint8_t)startAddress;//起始地址cmd_VAR_Read[6]=readWordLength;//讀取長度if(dwin->checkMode>DwinNone){uint16_t checkCode=CalcDwinCRC16(&cmd_VAR_Read[3],4);cmd_VAR_Read[7]=(uint8_t)checkCode;cmd_VAR_Read[8]=(uint8_t)(checkCode>>8);cmd_Length=cmd_Length+2;}dwin->SendData(cmd_VAR_Read,cmd_Length); }

2.2.5、寫曲線緩沖區

??DGUS屏有一個16KB、可存儲8條曲線趨勢圖的曲線緩沖區,用于用戶簡單、快速顯示曲線。曲線緩沖區的數據都是16位無符號數。寫曲線緩沖區的指令碼為0x84。我們可以根據消息格式編寫操作函數如下:

/*寫曲線緩沖區,一次最多允許寫8個字,即length<=16*/ void WriteCurveToDwinLCD(DwinObjectType *dwin,uint8_t *txData,uint16_t length,uint8_t channelMode) {/*命令的長度由幀頭(2個字節)+數據長度(1個字節)+指令(1個字節)+通道模式(1個字節)+數據(length,最多8個字)+CRC校驗(2個字節)*/uint16_t cmd_Length=length+5;uint8_t cmd_Curve_Write[23];//寫曲線緩沖區命令cmd_Curve_Write[0]=0x5A;cmd_Curve_Write[1]=0xA5;cmd_Curve_Write[2]=(uint8_t)(length+2);cmd_Curve_Write[3]= FC_Curve_Write;cmd_Curve_Write[4]=channelMode;for(int dataIndex=0;dataIndex<length;dataIndex++){cmd_Curve_Write[dataIndex+5]=txData[dataIndex];}if(dwin->checkMode>DwinNone){uint16_t checkCode=CalcDwinCRC16(&cmd_Curve_Write[3],length+2);cmd_Curve_Write[length+5]=(uint8_t)checkCode;cmd_Curve_Write[length+6]=(uint8_t)(checkCode>>8);cmd_Length=cmd_Length+2;}dwin->SendData(cmd_Curve_Write,cmd_Length); }

3、驅動的使用

??我們已經實現了迪文觸摸屏的驅動,接下來我們就使用驅動開發應用。驅動的使用并不復雜,依然是定義對象,然后根據需要操作對象。

3.1、聲明并初始化對象

??首先我們需要使用DwinObjectType類型聲明一個迪文觸摸屏的對象變量。這就是一個具體的屏對象,具體如下:

??DwinObjectType lcd;

??當然這個對象還不能使用,因為器并未賦值。所以我們還要使用DwinInitialization函數初始化這個對象。在初始化之前我們必須定義一個形如void (*SendDataForDwinType)(uint8_t *txData,uint16_t length)的函數,具體如下:

//數據發送 void SendData(uint8_t *txData,uint16_t length) {uint16_t i;for(i=0;i<length;i++){//傳送寄存器不為空,等待傳送結束while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET){}// 寫一個字節到對應的串口傳送數據寄存器USART_SendData(USART3, txData[i]);} }

??并將函數指針傳遞作為參數傳遞給初始化函數。除了屏對象和發送數據函數指針外,初始化函數還有一個參數是校驗方式。這里我們選擇無校驗碼,所以初始化函數調用如下:

??DwinInitialization(&lcd,DwinNone,SendData);

??到這里對象的定義及初始化就完成了。

3.2、調用函數操作對象

??初始化之后的對象就可對其進行操作了。我們在前面已經針對5個操作碼實現了對對象的驅動。那么我們要操作對象時,就是調用這5個函數來實現的。

??向屏的數據存儲區寫數據時,需要調用WriteFlashDataToDwinLCD函數,如我們要向0x0000地址開始寫入8個字節的數據則:

??WriteFlashDataToDwinLCD(&lcd,0x0000,txData,8);

??從屏的數據存儲區讀取數據時,需要調用ReadFlashDataFromDwinLCD函數,如我們從0x000A地址開始讀取4個字長度的數據則:

??ReadFlashDataFromDwinLCD(&lcd,0x000A,4);

??向曲線緩沖區寫數據,總共有8個通道,一次最多允許寫8個字。通道模式用于選擇向哪些通道寫數據,每一位代表一個通道。所以我們在使用WriteCurveToDwinLCD函數寫曲線緩沖區時需要配置通道。比如我們要向8個通道寫8個字的數據則:

??WriteCurveToDwinLCD(&lcd,txData,16,0xFF);

??對于寄存器的讀寫操作,我們封裝了一些常用的,如讀取LCD系統時間、校準LCD系統時間等。

??讀取LCD系統時間:GetDateTimeFromDwinLCD(&lcd);

??校準LCD系統時間:CalibrationDateTimeForDwinLCD(&lcd,dateTime);

??音樂播放控制:HandleDwinLCDToPlayMusic(&l’c’d,playStart,playNum,volume);當playNum為0時表示停止播放。

??設置屏顯示畫面:SetDwinLCDDisplay(&lcd,picID);

??對于沒有封裝的寄存器操作,可以直接在對象中調用寄存器讀寫函數實現。如:

??lcd.GetRegister(&lcd, regAddress,readByteLength);

??lcd.SetRegister(&lcd,regAddress,txData,length);

4、應用總結

??我們通過實測,驅動迪文觸摸屏的操作結果與預期一致。我們讓MCU給顯示屏發送一些數據,并在屏上顯示出來:

??再來看看對傳感器做一下擾動時(用配氣儀和小型氣泵向傳感器管道送不同的氣)數據的變化,傳感器檢測對象變化是屏幕顯示也變化。

??再來改變一下氣體成分和氣泵的轉速看看數據的變化:

??經過以上實驗,迪文串口屏驅動已經達到預期。至于一些更復雜的操作方式也都可以以此為基礎實現之。

歡迎關注:

總結

以上是生活随笔為你收集整理的外设驱动库开发笔记35:迪文触摸屏驱动的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日本午夜一区二区三区 | 久久久久久九九九九九 | 狠狠干in | 欧美日韩色| 黄色免费网站观看 | 大学生av| 欧美色图五月天 | 免费在线播放毛片 | 老司机午夜在线 | 狠狠干天天 | 久操视频网站 | 精品国产欧美一区二区 | 天天夜夜骑| 久草中文在线视频 | av性天堂网 | 国产99久久久国产精品成人免费 | www狠狠| 日韩精品二区在线观看 | 黄免费在线观看 | 国产成人无码AA精品区 | 无码一区二区三区免费视频 | 不卡视频在线观看 | 男女啪啪免费网站 | 色爱av综合 | 精品乱子一区二区三区 | 热逼视频| 亚洲是色 | 中文资源在线观看 | av在线不卡免费看 | 一区二区高清在线 | 深夜福利在线播放 | 成人片黄网站久久久免费 | 国产探花在线精品一区二区 | 超碰997 | 国产精品无码一区二区三区在线看 | 国产深夜福利在线 | 97潮色 | 不卡av免费观看 | www.成人国产| 操操操操操操操操操操 | 久久社区视频 | 国产香蕉在线观看 | 91看片国产| 天堂视频一区二区 | 欧美劲爆第一页 | 国产av无码专区亚洲av毛片搜 | 国产香蕉视频在线播放 | 综合久久中文字幕 | 99在线免费 | 韩国妻子的朋友 | 91pao | 污污免费观看 | 在线观看欧美视频 | 在线观看麻豆视频 | 女人被男人操 | 国产精品成人电影在线观看 | 日本黄页网站 | 在线观看中文字幕一区二区 | 一个色综合网站 | 双性人妖互交localhost | 久久久久一区 | 国产一区=区 | 亚洲人成免费电影 | 天堂一级片 | 51精产品一区一区三区 | 一区二区视频在线观看 | 99久视频 | 在线免费观看国产精品 | 日日射日日干 | 亚洲码无人客一区二区三区 | 国产99久久久国产精品成人免费 | 黄色片99 | 探花国产精品一区二区 | av高清在线免费观看 | av黄色在线看 | 久久这里只有精品6 | 亚洲午夜久久久久久久国产 | 亚洲天堂一区二区三区四区 | 福利在线影院 | 日韩中文av | 欧美性猛交久久久久 | 欧美日韩一区二区三区免费 | 天天摸天天碰 | 美女一二三区 | 天堂а在线中文在线新版 | 我要看免费的毛片 | 性感美女在线观看 | 天天看毛片 | 亚洲欧洲日本一区二区三区 | www.天天色| 国产精品久久久久三级无码 | 免费精品无码AV片在线观看黄 | 男人操女人免费网站 | 久久久综合视频 | 国产一区综合 | 91精品国产综合久久久蜜臀九色 | 国产情侣一区 | 蜜桃精品久久久久久久免费影院 | 在线观看黄色免费网站 |