迪文科技论坛

 找回密码
 立即注册
搜索
查看: 9158|回复: 9

【开源】STM32与迪文屏交互,实现常用功能 Arduino

[复制链接]

571

主题

168

回帖

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
12213
发表于 2019-5-22 09:11:42 | 显示全部楼层 |阅读模式
本文主要以迪文T5UIC1平台的指令屏作为试用对象,其他平台需进行改动后再使用。

一、开发板使用说明
1. 功能
序号
功能
描述
1
MCU
STM32F103ZET6
2
I/O
1路I/O


IO检测:检测闸刀的导通还是断开
3
ADC
3路AD


CH1:电压采集


CH2:电流采集


CH16:MCU内部温度采集
4
LED
工作指示灯
5
按键
复位按键
6
电源
5V ~ 12V电源输入

注:实现的功能:
a.上电后发送指令屏的握手指令给T5UIC1屏,T5UIC1屏收到指令后回返回应答信息,当MCU没有收到应答信息时,T5UIC1屏显示开机界面同时MCU的LED灯为常亮。
b. 当MCU收到T5UIC1屏的握手回应后,MCU通过页面转换指令进入“初始化系统”页面,显示倒计时5秒钟。
c. 当倒计时页面到达5秒后便进入主界面,此时MCU LED工作指示灯以200ms间隔闪烁以示工作正常状态,主界面显示当前MCU采集ADC通道的数据值,同时显示闸刀开关的状态。
d. MCU每3秒采用一次AD数据并更新到T5UIC1屏上。




2. 需使用的工具
a.硬件:硬石 STM32开发板(MCU为STM32F103ZET6,串口TTL电平)。
b. 软件: KEIL MDK5。
c.原理图:详见“硬件原理图”文件夹。
d.程序:T5UIC1屏工程配置文件在“T5UIC1屏 配置文件与图片”文件夹中,通过SD卡下载DWIN_SET导入屏中即可。 STM32程序在“STM32F103xx 源码”文件夹。

二、评估板硬件和软件部分详细介绍
1. 硬件原理图:详见“硬件原理图”文件夹
(1)硬件接口定义
功能
对应STM32F103的IO

LED
PB0

ADC1
PC1

ADC2
PC2

TXD2(触摸屏端子显示)
PA10

RXD2(触摸屏端子显示)
PA9


(2)硬件原理图


2. 软件程序
界面工程配置文件在“T5UIC1屏 配置文件与图片”文件夹中。
STM32程序在“STM32F103xx 源码”文件夹中。

(1)界面工程
0 开机界面:0X1000

(2)MCU程序
  1. [font=微软雅黑][size=3]<font size="4">0)数据结构体与宏定义
  2. // 指令数据发送宏操作
  3. #define SEND_DATA(P)    comSendChar(TRANS_COM, P)
  4. #define TX_8(P1)        SEND_DATA((P1)&0xFF) // send one byte
  5. #define TX_16(P1)       TX_8((P1)>>8);TX_8(P1) // send two byte
  6. #define TX_32(P1)       TX_16((P1)>>16);TX_16((P1)&0xFFFF) // send four byte
  7. #define BEGIN_CMD()     TX_8(FRAME_HRAD)
  8. #define END_CMD()       TX_32(FRAME_TAIL)


  9. // 系统结构体
  10. typedef struct{
  11.     us08 shake_ok;      // 握手成功标志位
  12.     char version[16];   // 系统程序版本号
  13. }SYSTEM_STR;
  14. extern SYSTEM_STR g_sys_str, *p_sys_str;

  15. // 软定时结构体
  16. typedef struct{
  17. volatile us08        Mode;       /* 计数器模式,1次性 */
  18. volatile us08        Flag;       /* 定时到达标志  */
  19. volatile us32        Count;      /* 计数器 */
  20. volatile us32        PreLoad;    /* 计数器预装值 */
  21. }SOFT_TMR;

  22. // 应答处理回调函数结构体
  23. typedef struct{
  24. void (*handle_shake)(void);   //应答处理
  25. }DWIN_HANDLE_STR;

  26. // 帧数据结构体  
  27. typedef struct{
  28.     us08 len;                   // 参数长度
  29.     us08 cmd1;                  // 指令1
  30.     us08 cmd2;                  // 指令2(预留)
  31.     us08 data[MAX_DWIN_RX_LEN]; // 指令参数 有效数据缓存区
  32. }DWIN_DATA_STR;

  33. // 队列结构体
  34. typedef struct{
  35.     DWIN_DATA_STR *Out;     //指向数据输出位置
  36.     DWIN_DATA_STR *In;      //指向数据输入位置
  37.     DWIN_DATA_STR *End;     //指向Buf的结束位置
  38.     DWIN_DATA_STR *Buf;     //存储数据的空间

  39.     us16 NData;             //队列中数据个数
  40. us16 MaxData;                //队列中允许存储的数据个数
  41. }DWIN_QUEUE_STR;

  42. // 文本属性结构体  
  43. typedef struct{
  44.     us08 mode;        //        显示模式
  45.     us16 sx, sy;        //        字符串显示的左上角坐标
  46.     us16 f_color, b_color;        //  字符显示颜色 && 字符背景显示颜色
  47.     us08 num_i;        // 显示的整数位数,0x01-0x14
  48.     us08 num_f;        //  显示的小数位数,0x00-0x14,Num_I+Num_F 之和不能超过20
  49.     us08  p_len;            //  待发送的数据字节数
  50.     us08 *p_data;           //  指向数据缓存区的指针
  51. }DWIN_TEXT_STR;

  52. 1)main():硬件初始化,ADC数据采集,IO状态采集,接收触摸屏数据处理
  53. int main(void)
  54. {
  55. float temp_v = 9.8f; // 当前温度值
  56. float vol_v = 0.98f; // 当前采集的电压值
  57. float cur_v = 0.58f; // 当前采集的电流值   
  58. us08  sw_v = 1;      // 闸刀状态值

  59. // 清空系统结构体
  60. memset(&g_sys_str, 0, sizeof(SYSTEM_STR));
  61. p_sys_str = &g_sys_str;

  62. // 获取软件版本号
  63. date_formatting(p_sys_str->version);

  64. // 板级初始化(接口驱动初始化)
  65. init_bsp();

  66. // 初始化迪文屏 主要是初始化使用到的应用函数
  67. init_dwin();

  68. // 点亮LED灯 等待握手
  69. LED_ON;
  70. while(!p_sys_str->shake_ok){
  71. // 处理迪文屏回应的数据
  72. dwin_handle_porcess();
  73. }

  74. // 启动一个ID为0的软件定时器 时间间隔为3秒
  75. soft_timer_start_auto(0, 3000);

  76. // 获取模拟采集量 和 IO状态检测
  77. // 显示温度 电压 电流 闸刀状态
  78. temp_v = get_temp_value();
  79. vol_v  = get_adc_value(ADC_CH_VOL)*3.3f/4096.0f;
  80. cur_v  = get_adc_value(ADC_CH_CUR)*3.3f/4096.0f;
  81. sw_v   = get_io_status();
  82. show_temperature(temp_v, 1);  
  83. show_voltage(vol_v, 2);  
  84. show_currents(cur_v, 2);  
  85. show_gate_switch(sw_v);

  86. // 启动一个ID为1的软件定时器 时间间隔为500ms
  87. soft_timer_start_auto(1, 200);
  88. while(ENABLE){
  89. // 处理迪文屏回应的数据
  90.    dwin_handle_porcess();

  91.    // 判断软定时器0 时间是否到达
  92.    if(soft_timer_check(1)){
  93.        LED_TOGGLE;
  94.    }

  95.    // 判断软定时器0 时间是否到达
  96.    if(soft_timer_check(0)){

  97.        // 获取模拟采集量 和 IO状态检测
  98.        temp_v = get_temp_value();
  99.        vol_v  = get_adc_value(ADC_CH_VOL)*3.3f/4096.0f;
  100.        cur_v  = get_adc_value(ADC_CH_CUR)*3.3f/4096.0f;
  101.        sw_v   = get_io_status();

  102.        // 将获取到的数据量呈现到液晶屏
  103.        show_temperature(temp_v, 1);  
  104.        show_voltage(vol_v, 2);  
  105.        show_currents(cur_v, 2);  
  106.        show_gate_switch(sw_v);
  107.    }
  108. }

  109. 2). dwin_frame_pack ():从接口缓存区获取数据并组包
  110. void dwin_frame_pack(void)
  111. {
  112. us08 recvData;
  113.     static us08 recvOffset = 0;
  114.     static us08 rStatus = STAUS_IDLE;
  115.    
  116.     static DWIN_DATA_STR frameT;

  117.     if(comGetChar(TRANS_COM, &recvData)){
  118.         //my_printf("%02X ", recvData);
  119.    
  120.         switch(rStatus){
  121.             case STAUS_IDLE:
  122.                 if(recvData == FRAME_HRAD)
  123.                     rStatus = STAUS_CMD1;
  124.             break;

  125.             case STAUS_CMD1:
  126.                 frameT.cmd1 = recvData;
  127.                 frameT.cmd2 = 0x00;
  128.                 frameT.len = 0;
  129.                 recvOffset = 0;
  130.                 rStatus = STAUS_START;  
  131.             break;

  132.             case STAUS_CMD2:
  133.                 frameT.cmd2 = recvData;
  134.                 rStatus = STAUS_START;
  135.             break;

  136.             case STAUS_START:
  137.                 frameT.data[recvOffset++] = recvData;
  138.                 if(recvData == FRAME_TAIL1)
  139.                     rStatus = STAUS_O001;
  140.             break;

  141.             case STAUS_O001:
  142.                 frameT.data[recvOffset++] = recvData;
  143.                 if(recvData == FRAME_TAIL2)
  144.                     rStatus = STAUS_O002;
  145.                 else
  146.                     rStatus = STAUS_START;
  147.             break;

  148.             case STAUS_O002:
  149.                 frameT.data[recvOffset++] = recvData;
  150.                 if(recvData == FRAME_TAIL3)
  151.                     rStatus = STAUS_O003;
  152.                 else
  153.                     rStatus = STAUS_START;
  154.             break;

  155.             case STAUS_O003:
  156.                 frameT.data[recvOffset++] = recvData;
  157.                 if(recvData == FRAME_TAIL4)
  158.                     rStatus = STAUS_OVER;
  159.                 else
  160.                     rStatus = STAUS_START;
  161.             break;
  162.         }
  163.     }

  164.     if(rStatus == STAUS_OVER){
  165.         #if 0 //for debug
  166.         my_printf("%02X %02X %02X ", FRAME_HH, FRAME_HL, DGUSRecvLen);
  167.         for(i = 0; i < DGUSRecvLen; i++)
  168.             my_printf("%02X ", DGUSRecvBuff[i]);
  169.         my_printf("\r\n\r\n");
  170.         #endif
  171.    
  172.         frameT.len = recvOffset-4;
  173.         queueAdd(&frameT);        
  174.         rStatus = STAUS_IDLE;
  175.     }
  176. }
  177. 3). dwin_handle_porcess ():处理迪文屏回应的数据
  178. void dwin_handle_porcess(void)
  179. {
  180.          us08 i = 6;
  181.     DWIN_DATA_STR rFrame;
  182.     DWIN_DATA_STR *frame = &rFrame;

  183.     // 从迪文屏的串口缓存区中获取数据 并判断是否符合 迪文通信协议的帧结构
  184.     while(i--){
  185.         dwin_frame_pack();
  186.     }

  187.     // 从队列中获取数据帧
  188.     if(dwin_frame_read(&rFrame)){
  189.         return;
  190.     }

  191.     #if 0//SHOW_RECV_MSG
  192.     {
  193.         my_printf("\r\n");
  194.         my_printf("> Recv: \r\n");
  195.         my_printf("  cmd_type(cmd1): %02X\r\n", frame->cmd1);
  196.         my_printf("  ctr_type(cmd2): %02X\r\n", frame->cmd2);
  197.         my_printf("  data_len(    ): %d\r\n", frame->len);
  198.         my_printf("  data_msg(    ): ");
  199.         for(i = 0; i < frame->len; i++)
  200.             my_printf("%02X ", frame->data[i]);
  201.         my_printf("\r\n");
  202.     }
  203.     #endif

  204.     if(this_hand_str == NULL) return;

  205.     // 解析数据帧并进行相应处理
  206.     switch(frame->cmd1){
  207.         case NOTIFY_SHAKE:      // 握手应答
  208.             if((frame->len != 2) && ((frame->data[0] != 0x4F)&&(frame->data[1] != 0x4B)))
  209.                 return;
  210.                
  211.             if(this_hand_str->handle_shake != NULL)
  212.                 this_hand_str->handle_shake();     
  213.         break;
  214.     }
  215. }
  216. 4). comSendBuf ():数据发送函数
  217. void comSendBuf(COM_PORT_E _ucPort, us08 *_ucaBuf, us16 _usLen){
  218.     UART_T *pUart;
  219. pUart = ComToUart( _ucPort );
  220. if( pUart == 0 ){
  221. return;
  222. }
  223. if( pUart->SendBefor != 0 ){
  224. pUart->SendBefor( ); /* 如果是RS485通信,可以在这个函数中将RS485设置为发送模式 */
  225. }

  226. UartSend( pUart, _ucaBuf, _usLen );
  227. }
  228. 5). soft_timer_start_auto ():启动一个自动定时器,并设置定时周期
  229. void soft_timer_start_auto(uint8_t _id, uint32_t _period){
  230.     if( _id >= TMR_COUNT ){
  231. /* 打印出错的源代码文件名、函数名称 */
  232. //BSP_Printf( "Error: file %s, function %s()\r\n", __FILE__, __FUNCTION__ );
  233. while( 1 ){
  234. ;                               /* 参数异常,死机等待看门狗复位 */
  235. }
  236. }

  237. DISABLE_INT( );                         /* 关中断 */

  238. s_tTmr[_id].Count           = _period;       /* 实时计数器初值 */
  239. s_tTmr[_id].PreLoad           = _period;       /* 计数器自动重装值,仅自动模式起作用 */
  240. s_tTmr[_id].Flag           = 0;             /* 定时时间到标志 */
  241. s_tTmr[_id].Mode           = TMR_AUTO_MODE; /* 自动工作模式 */

  242. ENABLE_INT( );                          /* 开中断 */
  243. }
  244. 6). soft_timer_check ():检测定时器是否超时
  245. us08 soft_timer_check(uint8_t _id){
  246.     if( _id >= TMR_COUNT ){
  247. return 0;
  248. }

  249. if( s_tTmr[_id].Flag == 1 ){
  250. s_tTmr[_id].Flag = 0;
  251. return 1;
  252. }
  253. else{
  254. return 0;
  255. }
  256. }


  257. 7). show_temperature ():显示温度数据,文本显示
  258. void show_temperature(float data, us08 num_f){
  259.     us32 value;
  260.     us08 text[4];
  261.     DWIN_TEXT_STR textStr;
  262.    
  263.     switch(num_f){
  264.         case 1:
  265.             value = data*10;
  266.         break;
  267.         
  268.         case 2:
  269.             value = data*100;
  270.         break;
  271.         
  272.         case 3:
  273.             value = data*1000;
  274.         break;

  275.         default: return;
  276.     }
  277.     text[0] = value>>24;
  278.     text[1] = value>>16;;
  279.     text[2] = value>>8;;
  280.     text[3] = value;

  281.     textStr.sx = 130; textStr.sy = 50;
  282.     dwin_fill_rect(textStr.sx, textStr.sy, textStr.sx+80, textStr.sy+50, ASSEMBLE_RGB(31, 33, 33));

  283.     textStr.mode = 0;
  284.     textStr.mode = FONT1632|DISABLE_NUM_BCOLOR|ENABLE_SIGNED_NUM|DISABLE_NUM_ZERO|DISABLE_NUM_ZERO_S;
  285.     textStr.f_color = ASSEMBLE_RGB(0, 0, 255);
  286.     textStr.p_len = 4;      
  287.     textStr.p_data = text;
  288.     textStr.num_i = 8;
  289.     textStr.num_f = num_f;
  290.    
  291.     dwin_disp_num(&textStr);
  292. }
  293. 8). show_gate_switch ():显示闸刀状态量,2D画图形式
  294. void show_gate_switch(us08 sw)
  295. {
  296.     us08 text1[2] = {0xBF, 0xAA};
  297.     us08 text0[2] = {0xB9, 0xD8};
  298.     DWIN_TEXT_STR textStr;
  299.    
  300.     dwin_fill_rect(150, 199, 250, 231, ASSEMBLE_RGB(251, 146, 0));
  301.     dwin_fill_rect(151, 200, 249, 230, ASSEMBLE_RGB(31, 33, 33));
  302.     if(sw == 1){
  303.         dwin_fill_rect(199, 201, 248, 229, ASSEMBLE_RGB(0, 255, 0));
  304.         
  305.         textStr.mode = 0;
  306.         textStr.mode = DISABLE_TEXT_RESIZE|DISABLE_TEXT_BCOLOR|FONT1224;
  307.         textStr.f_color = ASSEMBLE_RGB(0, 0, 0);
  308.         textStr.p_len = 2;
  309.         textStr.p_data = text1;
  310.         textStr.sx = 215; textStr.sy = 203;
  311.         dwin_disp_string(&textStr);
  312.     }
  313.     else{
  314.         dwin_fill_rect(152, 201, 200, 229, ASSEMBLE_RGB(255, 0, 0));

  315.         textStr.mode = 0;
  316.         textStr.mode = DISABLE_TEXT_RESIZE|DISABLE_TEXT_BCOLOR|FONT1224;
  317.         textStr.f_color = ASSEMBLE_RGB(0, 0, 0);
  318.         textStr.p_len = 2;
  319.         textStr.p_data = text0;
  320.         textStr.sx = 165; textStr.sy = 203;
  321.         dwin_disp_string(&textStr);
  322.     }
  323.    
  324. }</font>[/size][/font]
复制代码







回复

使用道具 举报

6

主题

14

回帖

157

积分

注册会员

Rank: 2

积分
157
发表于 2019-8-9 09:40:57 | 显示全部楼层
你好,请问在哪里下载贴纸所说的“硬件原理图”文件夹、“T5UIC1屏 配置文件与图片”文件夹、“STM32F103xx 源码”文件夹?
回复

使用道具 举报

0

主题

239

回帖

1792

积分

金牌会员

Rank: 6Rank: 6

积分
1792
发表于 2019-8-9 11:12:09 | 显示全部楼层
本帖最后由 qjhzh 于 2019-8-9 17:18 编辑

楼上请参考。T5UIC1的屏只要把应用指南那几十条指令弄熟了还是很容易的。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

6

主题

14

回帖

157

积分

注册会员

Rank: 2

积分
157
发表于 2019-8-14 09:23:07 | 显示全部楼层
qjhzh 发表于 2019-8-9 11:12
楼上请参考。T5UIC1的屏只要把应用指南那几十条指令弄熟了还是很容易的。

好的,非常感谢
回复

使用道具 举报

0

主题

2

回帖

81

积分

注册会员

Rank: 2

积分
81
发表于 2019-8-27 09:38:07 | 显示全部楼层
菜鸟学习,没有完整的工程,起步难,帮忙把DGUSII工程共享出来,参考一下,
回复

使用道具 举报

0

主题

52

回帖

422

积分

中级会员

Rank: 3Rank: 3

积分
422
发表于 2019-8-27 11:58:15 | 显示全部楼层
楼主,你好,

如下链接,请参考:http://inforum.dwin.com.cn:20080 ... mdisplay&fid=78
回复

使用道具 举报

0

主题

1

回帖

73

积分

注册会员

Rank: 2

积分
73
发表于 2022-1-20 18:09:38 | 显示全部楼层
Reset_W5200
回复

使用道具 举报

571

主题

168

回帖

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
12213
 楼主| 发表于 2022-3-1 14:20:18 | 显示全部楼层

型号:T5L EKT043B
主板:SMT32
实现功能:EKT043B做显控,SMT32做主控连接外设,二者通过串口实现交互。案例主要实现了EKT043B对STM32的IO口、PWM接口的控制。
附件包含DEMO(800*480)工程和C51源码。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

1

主题

12

回帖

120

积分

注册会员

Rank: 2

积分
120
发表于 2022-5-26 22:12:18 | 显示全部楼层
谢谢楼主,很实用
回复

使用道具 举报

571

主题

168

回帖

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
12213
 楼主| 发表于 2022-6-10 15:03:50 | 显示全部楼层

T5L+Arduino 408*272 DEMO和代码文件。




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|迪文科技论坛 ( 京ICP备05033781号-1 )

GMT+8, 2024-12-27 11:08 , Processed in 0.079869 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表