Aaron~ 发表于 2018-11-29 16:02:13

STM32-F103ZET6-与串口屏通信(附设备例程)

本帖最后由 Aaron~ 于 2018-11-30 10:48 编辑

1. 开发板使用说明
功能
MCU   STM32F103ZET6
I/O       1路I/O
IO检测检测闸刀的导通还是断开
ADC      3路AD
            CH1:电压采集
            CH2:电流采集
            CH16:MCU内部温度采集
LED       工作指示灯
按键      复位按键
电源      5V ~ 12V电源输入







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

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

2.评估板硬件和软件部分详细介绍
硬件接口定义功能                           对应STM32F103的IOLED                           PB0ADC1                        PC1ADC2                        PC2TXD2(触摸屏端子显示) PA10RXD2(触摸屏端子显示) PA9
硬件原理图
软件程序界面工程配置文件在“T5UIC1屏 配置文件与图片”文件夹中STM32程序请参照STM32F103源码
界面工程0 开机界面:0X1000 MCU程序0)数据结构体与宏定义// 指令数据发送宏操作#define SEND_DATA(P)    comSendChar(TRANS_COM, P)#define TX_8(P1)      SEND_DATA((P1)&0xFF) // send one byte#define TX_16(P1)       TX_8((P1)>>8);TX_8(P1) // send two byte#define TX_32(P1)       TX_16((P1)>>16);TX_16((P1)&0xFFFF) // send four byte#define BEGIN_CMD()   TX_8(FRAME_HRAD)#define END_CMD()       TX_32(FRAME_TAIL) // 系统结构体typedef struct{    us08 shake_ok;      // 握手成功标志位    char version;   // 系统程序版本号}SYSTEM_STR;extern SYSTEM_STR g_sys_str, *p_sys_str; // 软定时结构体typedef struct{      volatile us08      Mode;       /* 计数器模式,1次性 */      volatile us08      Flag;       /* 定时到达标志*/      volatile us32      Count;      /* 计数器 */      volatile us32      PreLoad;    /* 计数器预装值 */}SOFT_TMR; // 应答处理回调函数结构体typedef struct{void (*handle_shake)(void);   //应答处理}DWIN_HANDLE_STR; // 帧数据结构体typedef struct{    us08 len;                   // 参数长度    us08 cmd1;                  // 指令1    us08 cmd2;                  // 指令2(预留)    us08 data; // 指令参数 有效数据缓存区}DWIN_DATA_STR; // 队列结构体typedef struct{    DWIN_DATA_STR *Out;   //指向数据输出位置             DWIN_DATA_STR *In;      //指向数据输入位置                   DWIN_DATA_STR *End;   //指向Buf的结束位置    DWIN_DATA_STR *Buf;   //存储数据的空间           us16 NData;             //队列中数据个数                              us16 MaxData;                //队列中允许存储的数据个数}DWIN_QUEUE_STR; // 文本属性结构体typedef struct{    us08 mode;                              //      显示模式     us16 sx, sy;                        //      字符串显示的左上角坐标                             us16 f_color, b_color;      //字符显示颜色 && 字符背景显示颜色    us08 num_i;                              //         显示的整数位数,0x01-0x14     us08 num_f;                              //显示的小数位数,0x00-0x14,Num_I+Num_F 之和不能超过20    us08p_len;            //待发送的数据字节数    us08 *p_data;         //指向数据缓存区的指针}DWIN_TEXT_STR; 1)main():硬件初始化,ADC数据采集,IO状态采集,接收触摸屏数据处理int main(void){float temp_v = 9.8f; // 当前温度值float vol_v = 0.98f; // 当前采集的电压值float cur_v = 0.58f; // 当前采集的电流值   us08sw_v = 1;      // 闸刀状态值 // 清空系统结构体memset(&g_sys_str, 0, sizeof(SYSTEM_STR));p_sys_str = &g_sys_str; // 获取软件版本号date_formatting(p_sys_str->version); // 板级初始化(接口驱动初始化)init_bsp(); // 初始化迪文屏 主要是初始化使用到的应用函数init_dwin(); // 点亮LED灯 等待握手LED_ON;while(!p_sys_str->shake_ok){      // 处理迪文屏回应的数据      dwin_handle_porcess();} // 启动一个ID为0的软件定时器 时间间隔为3秒soft_timer_start_auto(0, 3000); // 获取模拟采集量 和 IO状态检测// 显示温度 电压 电流 闸刀状态temp_v = get_temp_value();vol_v= get_adc_value(ADC_CH_VOL)*3.3f/4096.0f;cur_v= get_adc_value(ADC_CH_CUR)*3.3f/4096.0f;sw_v   = get_io_status();show_temperature(temp_v, 1);show_voltage(vol_v, 2);show_currents(cur_v, 2);show_gate_switch(sw_v); // 启动一个ID为1的软件定时器 时间间隔为500mssoft_timer_start_auto(1, 200);while(ENABLE){      // 处理迪文屏回应的数据   dwin_handle_porcess();    // 判断软定时器0 时间是否到达   if(soft_timer_check(1)){       LED_TOGGLE;   }    // 判断软定时器0 时间是否到达   if(soft_timer_check(0)){        // 获取模拟采集量 和 IO状态检测       temp_v = get_temp_value();       vol_v= get_adc_value(ADC_CH_VOL)*3.3f/4096.0f;       cur_v= get_adc_value(ADC_CH_CUR)*3.3f/4096.0f;       sw_v   = get_io_status();        // 将获取到的数据量呈现到液晶屏       show_temperature(temp_v, 1);       show_voltage(vol_v, 2);       show_currents(cur_v, 2);       show_gate_switch(sw_v);   }} 2). dwin_frame_pack ():从接口缓存区获取数据并组包void dwin_frame_pack(void){      us08 recvData;    static us08 recvOffset = 0;    static us08 rStatus = STAUS_IDLE;        static DWIN_DATA_STR frameT;     if(comGetChar(TRANS_COM, &recvData)){      //my_printf("%02X ", recvData);          switch(rStatus){            case STAUS_IDLE:                if(recvData == FRAME_HRAD)                  rStatus = STAUS_CMD1;            break;             case STAUS_CMD1:                frameT.cmd1 = recvData;                frameT.cmd2 = 0x00;                frameT.len = 0;                recvOffset = 0;                rStatus = STAUS_START;            break;             case STAUS_CMD2:                frameT.cmd2 = recvData;                rStatus = STAUS_START;            break;             case STAUS_START:                frameT.data = recvData;                if(recvData == FRAME_TAIL1)                   rStatus = STAUS_O001;            break;             case STAUS_O001:                frameT.data = recvData;                if(recvData == FRAME_TAIL2)                   rStatus = STAUS_O002;                else                  rStatus = STAUS_START;            break;             case STAUS_O002:                frameT.data = recvData;                if(recvData == FRAME_TAIL3)                   rStatus = STAUS_O003;                else                  rStatus = STAUS_START;            break;             case STAUS_O003:                frameT.data = recvData;                if(recvData == FRAME_TAIL4)                   rStatus = STAUS_OVER;                else                  rStatus = STAUS_START;            break;      }    }     if(rStatus == STAUS_OVER){      #if 0 //for debug      my_printf("%02X %02X %02X ", FRAME_HH, FRAME_HL, DGUSRecvLen);      for(i = 0; i < DGUSRecvLen; i++)            my_printf("%02X ", DGUSRecvBuff);      my_printf("\r\n\r\n");      #endif          frameT.len = recvOffset-4;      queueAdd(&frameT);            rStatus = STAUS_IDLE;    }}3). dwin_handle_porcess ():处理迪文屏回应的数据void dwin_handle_porcess(void){         us08 i = 6;    DWIN_DATA_STR rFrame;    DWIN_DATA_STR *frame = &rFrame;     // 从迪文屏的串口缓存区中获取数据 并判断是否符合 迪文通信协议的帧结构    while(i--){      dwin_frame_pack();     }     // 从队列中获取数据帧    if(dwin_frame_read(&rFrame)){      return;    }     #if 0//SHOW_RECV_MSG    {      my_printf("\r\n");      my_printf("> Recv: \r\n");      my_printf("cmd_type(cmd1): %02X\r\n", frame->cmd1);      my_printf("ctr_type(cmd2): %02X\r\n", frame->cmd2);      my_printf("data_len(    ): %d\r\n", frame->len);      my_printf("data_msg(    ): ");      for(i = 0; i < frame->len; i++)            my_printf("%02X ", frame->data);      my_printf("\r\n");    }    #endif     if(this_hand_str == NULL) return;     // 解析数据帧并进行相应处理    switch(frame->cmd1){      case NOTIFY_SHAKE:      // 握手应答            if((frame->len != 2) && ((frame->data != 0x4F)&&(frame->data != 0x4B)))                return;                            if(this_hand_str->handle_shake != NULL)                this_hand_str->handle_shake();         break;    }}4). comSendBuf ():数据发送函数void comSendBuf(COM_PORT_E _ucPort, us08 *_ucaBuf, us16 _usLen){    UART_T *pUart;      pUart = ComToUart( _ucPort );      if( pUart == 0 ){                return;      }      if( pUart->SendBefor != 0 ){                pUart->SendBefor( ); /* 如果是RS485通信,可以在这个函数中将RS485设置为发送模式 */      }       UartSend( pUart, _ucaBuf, _usLen );}5). soft_timer_start_auto ():启动一个自动定时器,并设置定时周期void soft_timer_start_auto(uint8_t _id, uint32_t _period){    if( _id >= TMR_COUNT ){                /* 打印出错的源代码文件名、函数名称 */                //BSP_Printf( "Error: file %s, function %s()\r\n", __FILE__, __FUNCTION__ );                while( 1 ){                        ;                               /* 参数异常,死机等待看门狗复位 */                }      }       DISABLE_INT( );                         /* 关中断 */       s_tTmr.Count         = _period;       /* 实时计数器初值 */      s_tTmr.PreLoad         = _period;       /* 计数器自动重装值,仅自动模式起作用 */      s_tTmr.Flag         = 0;             /* 定时时间到标志 */      s_tTmr.Mode         = TMR_AUTO_MODE; /* 自动工作模式 */       ENABLE_INT( );                        /* 开中断 */}6). soft_timer_check ():检测定时器是否超时us08 soft_timer_check(uint8_t _id){    if( _id >= TMR_COUNT ){                return 0;      }       if( s_tTmr.Flag == 1 ){                s_tTmr.Flag = 0;                return 1;      }      else{                return 0;      }} 7). show_temperature ():显示温度数据,文本显示void show_temperature(float data, us08 num_f){    us32 value;    us08 text;    DWIN_TEXT_STR textStr;        switch(num_f){      case 1:             value = data*10;       break;            case 2:             value = data*100;       break;            case 3:             value = data*1000;       break;       default: return;    }    text = value>>24;    text = value>>16;;    text = value>>8;;    text = value;     textStr.sx = 130; textStr.sy = 50;    dwin_fill_rect(textStr.sx, textStr.sy, textStr.sx+80, textStr.sy+50, ASSEMBLE_RGB(31, 33, 33));     textStr.mode = 0;    textStr.mode = FONT1632|DISABLE_NUM_BCOLOR|ENABLE_SIGNED_NUM|DISABLE_NUM_ZERO|DISABLE_NUM_ZERO_S;    textStr.f_color = ASSEMBLE_RGB(0, 0, 255);    textStr.p_len = 4;          textStr.p_data = text;    textStr.num_i = 8;    textStr.num_f = num_f;        dwin_disp_num(&textStr);}8). show_gate_switch ():显示闸刀状态量,2D画图形式 void show_gate_switch(us08 sw){    us08 text1 = {0xBF, 0xAA};    us08 text0 = {0xB9, 0xD8};    DWIN_TEXT_STR textStr;        dwin_fill_rect(150, 199, 250, 231, ASSEMBLE_RGB(251, 146, 0));     dwin_fill_rect(151, 200, 249, 230, ASSEMBLE_RGB(31, 33, 33));    if(sw == 1){      dwin_fill_rect(199, 201, 248, 229, ASSEMBLE_RGB(0, 255, 0));            textStr.mode = 0;      textStr.mode = DISABLE_TEXT_RESIZE|DISABLE_TEXT_BCOLOR|FONT1224;      textStr.f_color = ASSEMBLE_RGB(0, 0, 0);      textStr.p_len = 2;      textStr.p_data = text1;      textStr.sx = 215; textStr.sy = 203;      dwin_disp_string(&textStr);    }    else{      dwin_fill_rect(152, 201, 200, 229, ASSEMBLE_RGB(255, 0, 0));       textStr.mode = 0;      textStr.mode = DISABLE_TEXT_RESIZE|DISABLE_TEXT_BCOLOR|FONT1224;      textStr.f_color = ASSEMBLE_RGB(0, 0, 0);      textStr.p_len = 2;      textStr.p_data = text0;      textStr.sx = 165; textStr.sy = 203;      dwin_disp_string(&textStr);    }    }











bzbs 发表于 2024-1-18 23:37:16

大佬有例程不

pengtaoABC 发表于 2024-1-22 11:04:29

d.程序:T5UIC1屏工程配置文件在“T5UIC1屏 配置文件与图片”文件夹中,通过SD卡下载DWIN_SET导入屏中即可。 STM32程序在“STM32F103xx 源码”文件夹。???
页: [1]
查看完整版本: STM32-F103ZET6-与串口屏通信(附设备例程)