• 项目(智慧教室)第一部分:cubemx配置,工程文件的移植,触摸屏的检测,项目bug说明


    第一章:需求与配置

    一。项目需求

            智能终端(应该是上位机)通过互联网发指令给中控主机,中控主机(stm32)接受到指令后再以无线形式对节点发出命令。

    1.利用Zigbee实现教室内,无线传感网络搭建,对接环境传感器,教室内风扇,空调,灯,报警等装置
    2.利用STM32实现Zigbee网关设计,运行触摸屏界面,嵌入式Web服务器

    二。实现外设控制

    注意:

            先配置引脚,再配置外设。否则会出现一些不可预料的问题

    1.时钟,串口,灯,蜂鸣器配置

    (1)RCC配置为外部时钟,修改时钟参数

    (2)SWD配置:为了不引脚冲突,使用

    (3)串口的使用(USART1,USART3)

    <1>USART1

    注意:大型项目串口使用中断,因为效率高

    <2>USART3

    串口3没有使用中断,观察原理图,使用串口母口与电脑通信。

    (4)GPIO配置

    1.GPIO灯的配置,设置为高电平(初始为灭)

    2.GPIO蜂鸣器配置,设置为低电平(初始不响)

    (5)LCD的FMSC配置

    FMSC的LCD2配置,这是显示页面

    (6)GPIO补充配置

    (7)SPI的配置

    PA5配置spi_sck

    配置PB5,PB4

    配置PH2为GPIO_OUTPUT

    spi配置全双工

    (8)Touch配置

    设置SPi2,注意:PG15为高电平

    设置SPI2

    三。Webserver开发

    1.SDIO配置

    (1)PC12设置为SDIO_CK时钟

    D0与D1配置

    D2与D3

    2.SDIO配置

    DMA配置

    3.ETH以太网接口

    (1)根据原理图配置引脚

    注意:有些引脚不需要配置,原因是采用RMII接口(需要看懂原理才可以自己配置)

    (2)配置外设

    时钟出现错误,修改

    四。Freertos配置

    1.调整时钟

    2.任务的创建

    (1)任务优先级的划分

    优先级划分:WebServer优先级最高,GUI优先级最低。判断方式,用户体验最佳。

    (2)堆栈大小划分

    在Freertos中配置堆大小时,需要把上述除以4(原因未知,且不一定除以4,可能就是单纯的分配问题,因为板子内存本来就不多)

    Touch

    Gui

    WebServer

    Zigbee

    3.其余优先级的配置

    五。LWIP配置

    (1)使能LWIP。关闭DHCP服务

    (2)使能LWIP。关闭展示全部参数

    (3)增大池大小

    (4)回调函数调用

    测试:使用上述回调函数,判断网络连接

    1. if(netif_is_link_up(netif)){
    2. printf("netif link is up\r\n");
    3. if(!netif_is_up(netif)){
    4. netif_set_up(netif);
    5. printf("netif is up\r\n");
    6. }
    7. }else{
    8. printf("netif link is down\r\n");
    9. }

    六。FatFs(文件管理)

    1.FatFs配置

    (1)配置SD卡(SDIO配置之后才可以配置这个)

    (2)设置HEAP堆空间大小

    (3)点击生成(会弹出警告,询问是否自动生成代码,点击确定)

    2.FatFs文件解释

    (1)配置FatFs之后会出现的文件。

    具体细节看下面这个图。上述三个文件对应下面的图。通用底层接口,链接机制,DSP驱动。

    补充实验1:读写SD卡的内容,使用了usb读写卡,通过他读写SD卡

    加入初始化代码,init在Freertos.c中的第一个任务中自动添加。

    1. uint8_t u8chr[] = "hello";
    2. uint32_t u32Wbytes;
    3. /* USER CODE END Variables */
    4. void MX_FATFS_Init(void)
    5. {
    6. /*## FatFS: Link the SD driver ###########################*/
    7. retSD = FATFS_LinkDriver(&SD_Driver, SDPath);
    8. /* USER CODE BEGIN Init */
    9. if(f_mount(&SDFatFS,SDPath,1) == FR_OK)
    10. {
    11. if(f_open(&SDFile,(const char*)"fatfs.txt",FA_CREATE_ALWAYS|FA_WRITE) == FR_OK)
    12. {
    13. if(f_write(&SDFile,u8chr,sizeof(u8chr),&u32Wbytes) == FR_OK)
    14. {
    15. f_close(&SDFile);
    16. }
    17. }
    18. }
    19. /* additional user code for init */
    20. /* USER CODE END Init */
    21. }

    运行之后,SD卡通过usb转接口连接电脑。里面有fatfs.txt文件,打开里面有Hello字符。

    注意:也可以fatfs.txt文件替换成scv文件,这是excel文件后缀名。

    3.FatFs函数的参考手册

    (1)进入c盘(cubemx的包目录下),找到第三方库存放地(Third_Party)

    (2)找到FatFs文件夹中的doc,点击html文件

    (3)打开html文件,函数解释都在这里,需要研究英文

    4.底层文件的简要介绍

    (1)FatFS底层实现

    (2)通用底层驱动API

    (3)我们应该研究什么东西

    这些都是在KEIL工程中

    //FatFS 提供的通用驱动文件的实现

    ff_gen_drv.c

    //针对SD底层驱动实现,封装成为通用的底层驱动API
    //如果使能freeRTOS,在read和Write里面,会用到操作系统的消息队列

    sd_diskio.c

    //HAL库的二次封装,把所有基于SD卡的操作都在bsp_driver_sd实现

    bsp_driver_sd.c

    七。emWin移植

    Cubemx配置

    (1)使能CRC

    (2)使能FSMC的写

    创建有警告,正常

    1.emWin的图形文件库的寻找,移植

    (1)在stm32的Cubemx的第三方目录的同层文件夹下,有个ST文件夹

    (2)ST文件夹下的STemWin就是图形文件库,移植就好(复制粘贴到Cubemx文件工程下面)

    (3)移植到keil的工程目录第三方文件夹下《这是keil项目文件夹中

    2.keil工程的创建工作组

    (1)创建工作组

    (2)对工作组进行管理

    (3)工作组路径与名称的设置

    3.添加库,主要包括下面文件

    (1)工作组添加存在的库文件

    (2)第三方的工程文件

    (3)添加emWin的os的GUI文件

    (4)GUIconf.c与GUIDRV_Template.c与LCD_Template.c

    (5)GUI_X_Touch_Analog.c

    这个是触控,自己定义,Ctrl+N创建工程,Ctrl+s保存,在第三方库文件夹下的emWin文件中创建src文件夹。

    在文件夹中保存文件

    (7)STemWin_CM4_OS_wc16_ot.a

    这个文件源码不开放,在Lib中,文件选择.a

    注意:Keil是无法识别.a这种文件的,所以需要手动配置

    选择library file

    4.把移植好的文件(.h)加入工程文件

    加入的是上述关联的文件夹

    八。对代码的修改

    为什么要对这些进行修改?

            我们使用的API接口是不统一的,一个是GUI驱动函数,一个是Lcd驱动函数,我们要同时使用他们,需要对双方进行连接,即代码相互调用。(一个驱动对硬件,一个驱动对液晶屏)

    1.SD卡的初始化设置

    1. #include "stdio.h"
    2. #include "string.h"
    3. uint8_t retSD; /* Return value for SD */
    4. char SDPath[4]; /* SD logical drive path */
    5. FATFS SDFatFS; /* File system object for SD logical drive */
    6. FIL SDFile; /* File object for SD */
    7. /* USER CODE BEGIN Variables */
    8. char u8chr[] = "hello";
    9. uint32_t u32Wbytes;
    10. char SensorBuff[100];
    11. /* USER CODE END Variables */
    12. void MX_FATFS_Init(void)
    13. {
    14. /*## FatFS: Link the SD driver ###########################*/
    15. retSD = FATFS_LinkDriver(&SD_Driver, SDPath);
    16. /* USER CODE BEGIN Init */
    17. if(f_mount(&SDFatFS,SDPath,1) == FR_OK)
    18. {
    19. if(f_open(&SDFile,(const char*)"fatfs.txt",FA_CREATE_ALWAYS|FA_WRITE) == FR_OK)
    20. {
    21. if(f_write(&SDFile,u8chr,sizeof(u8chr),&u32Wbytes) == FR_OK)
    22. {
    23. f_close(&SDFile);
    24. }
    25. }
    26. }
    27. //创建文件
    28. if(f_open(&SDFile,(const char*)"Sensor.csv",FA_CREATE_ALWAYS|FA_WRITE) == FR_OK){
    29. //格式化文件流
    30. //创建表头
    31. sprintf(SensorBuff, "序号,温度,湿度,光照\r\n");
    32. f_write(&SDFile,SensorBuff,strlen(SensorBuff),&u32Wbytes);
    33. //循环写入表项
    34. for(int i; i < 10; i++){
    35. sprintf(SensorBuff, "%d,%d,%d,%d\r\n",i + 1, i + 20, i + 30, i + 40);
    36. f_write(&SDFile,SensorBuff,strlen(SensorBuff),&u32Wbytes);
    37. //刷新到文件中
    38. // f_sync(&SDFile);
    39. }
    40. //关闭文件,缓存写入文件内
    41. f_close(&SDFile);
    42. }
    43. /* additional user code for init */
    44. /* USER CODE END Init */
    45. }

    2.对GUIconfig.c图形库的设置

    (1)对宏定义进行修改

    1. #define GUI_NUMBYTES (512*1024) //定义外部存储器大小
    2. #define GUI_BLOCKSUZE (0X80) //定义最小内存库操作大小
    3. #define SRAM_BANK_ADDR ((U32)0x68000000) //定义外部存储器首地址

    (2)对GUI_X_Config的修改

    1. void GUI_X_Config(void) {
    2. //
    3. // 32 bit aligned memory area
    4. //
    5. volatile U32* aMemory = (volatile U32*)(SRAM_BANK_ADDR);
    6. //
    7. // Assign memory to emWin
    8. //分配GUI存储器首地址及最小操作内存块大小
    9. GUI_ALLOC_AssignMemory((void *)aMemory, GUI_NUMBYTES);
    10. GUI_ALLOC_SetAvBlockSize(GUI_BLOCKSUZE);
    11. //
    12. // Set default font
    13. //
    14. GUI_SetDefaultFont(GUI_FONT_32_1);
    15. }

    3.对GUIDRV_Template.c进行修改

    通过这种方式,lcd的驱动与GUI的驱动就连接起来,可以相互配合

    (1)加入头文件,lcd.h,原因:GUI图形库与lcd连接,通过找到点   后向lcd拷贝即可

    (2)对set与get函数进行处理

    set来画点

    1. //添加lcd画点接口
    2. LCD_DrawPoint(x,y,PixelIndex);

    get来获取点位置

    1. //添加lcd读取点接口
    2. PixelIndex = lcd_read_gram(x,y);

    4.对LCDConf_FledColor_Templae.c进行修改

    (1)屏幕大小,屏幕上下左右的AD值,触摸屏的处理

    1. #define XSIZE_PHYS 480 // 屏幕X坐标长度
    2. #define YSIZE_PHYS 272 // 屏幕Y坐标长度
    3. #define GUI_TOUCH_AD_Y_TOP 170 // 屏幕X0点坐标AD值
    4. #define GUI_TOUCH_AD_Y_BOTTOM 1900 // 屏幕X480点坐标AD值
    5. #define GUI_TOUCH_AD_X_LEFT 100 // 屏幕Y0点坐标AD值
    6. #define GUI_TOUCH_AD_X_RIGHT 1930 // 屏幕Y272点坐标AD值

    (2)Config配置函数处理

    1. void LCD_X_Config(void) {
    2. //
    3. // Set display driver and color conversion
    4. //设置成自己的API接口
    5. GUI_DEVICE_CreateAndLink(&GUIDRV_Template_API, GUICC_M565, 0, 0);
    6. //
    7. // Display driver configuration, required for Lin-driver
    8. // 显示尺寸配置
    9. LCD_SetSizeEx (0, XSIZE_PHYS , YSIZE_PHYS);
    10. LCD_SetVSizeEx(0, VXSIZE_PHYS, VYSIZE_PHYS);
    11. //
    12. //触摸笔的校准
    13. GUI_TOUCH_Calibrate(GUI_COORD_X, 0, 480, GUI_TOUCH_AD_X_LEFT , GUI_TOUCH_AD_X_RIGHT);
    14. GUI_TOUCH_Calibrate(GUI_COORD_Y, 0, 272, GUI_TOUCH_AD_Y_TOP, GUI_TOUCH_AD_Y_BOTTOM);
    15. }

    (3)在驱动中写如lcd初始化

    加入#include "lcd.h",自写的文件可以直接写到最顶上

    5.GUI_X_Touch_Analog.c(这是自写的文件)

    1. #include "GUI.h"
    2. #include "Touch.h"
    3. void GUI_TOUCH_X_ActivateX(void)
    4. {
    5. }
    6. void GUI_TOUCH_X_ActivateY(void)
    7. {
    8. }
    9. //获取X坐标AD值
    10. int GUI_TOUCH_X_MeasureX(void)
    11. {
    12. return XPT_Read_XY(CMD_RDX);
    13. }
    14. //获取Y坐标AD值
    15. int GUI_TOUCH_X_MeasureY(void)
    16. {
    17. return XPT_Read_XY(CMD_RDY);
    18. }

    6.Freertos.c中

    #include "GUI.h"
    1. void Touch_Task(void const * argument)
    2. {
    3. /* init code for LWIP */
    4. MX_LWIP_Init();
    5. /* init code for FATFS */
    6. MX_FATFS_Init();
    7. GUI_Init();
    8. GUI_SetBkColor(GUI_BLUE);
    9. GUI_SetFont(GUI_FONT_32_1);
    10. GUI_SetColor(GUI_YELLOW);
    11. GUI_Clear();
    12. /* USER CODE BEGIN Touch_Task */
    13. GUI_PID_STATE State;
    14. printf("system is runing!\r\n");
    15. /* Infinite loop */
    16. for(;;)
    17. {
    18. //执行触摸笔检测
    19. GUI_TOUCH_Exec();
    20. //获取触摸笔状态值
    21. GUI_TOUCH_GetState(&State);
    22. //是否按下
    23. if(State.Pressed){
    24. //打印触摸笔坐标信息
    25. GUI_DispStringAt("X:",0,0);
    26. GUI_DispDecAt(State.x,32,0,4);
    27. GUI_DispStringAt("Y:",0,24);
    28. GUI_DispDecAt(State.y,32,24,4);
    29. }
    30. osDelay(10);
    31. }
    32. /* USER CODE END Touch_Task */
    33. }

    运行结果:

    下一节补充

    本人暂时遇到的BUG,stm32刷新速度很慢,非常慢。发现串口循环打印,暂用资源,ping命令ping不通。

  • 相关阅读:
    01_ue4进阶_PBR材质
    ES6 --》字符串与数值新增方法
    Android结构优化 - Java、Kotlin项目结构分包
    电容笔和触控笔有什么区别?平价好用的电容笔排行榜
    Abnova ACTN4纯化兔多克隆抗体说明书
    Docker逃逸---procfs文件挂载
    C#-抽象类与接口
    Docker 日志管理 - ELK
    数据库用户管理
    【信号去噪】基于麻雀算法优化VMD实现信号去噪附matlab代码
  • 原文地址:https://blog.csdn.net/m0_61659911/article/details/132595922