手头有一个红牛的stmf103开发版。以前用arduino 用它点灯跟使用串口。用起来很简答。上边的触摸屏是 ili9325.使用的是fsmc驱动 。16位接口。可以看到主频72M的开发版刷新屏幕非常的快。红牛开发版的例程都是基于标准库3.5的。
8.92 rEU:/ 红牛开发版自带的屏幕测试 https://v.douyin.com/jtbawFR/ 复制此链接,打开Dou音搜索,直接观看视频!
尝试把这个屏幕驱动移植到arduino上,这样就可以用arduino的api来捣鼓这个板子了。pio下载stm32库,还要下载arm的gcc编译器等。可能要等很久pio才能准备好。然后发现stm32的arduino库是基于hal库的一层包装。不能直接拿来用。
网上基本没有用fscm跑arduino的 。我只找到了这一个 零知实验室--技术资料 (lingzhilab.com) 它的豪华版开发版是STM32F407VET6 。可以下载到他的代码。找出它的fsmc相关代码
SRAM_HandleTypeDef hsram4; //SRAM句柄(用于控制LCD) void HAL_SRAM_MspInit(SRAM_HandleTypeDef *hsram) { GPIO_InitTypeDef GPIO_InitStructure; __HAL_RCC_FSMC_CLK_ENABLE(); //使能FSMC时钟 __HAL_RCC_GPIOD_CLK_ENABLE(); //使能GPIOD时钟 __HAL_RCC_GPIOE_CLK_ENABLE(); //使能GPIOE时钟 // //初始化PD0,1,4,5,8,9,10,14,15 // GPIO_Initure.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_8|\ // GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_7|GPIO_PIN_11; // GPIO_Initure.Mode=GPIO_MODE_AF_PP; //推挽复用 // GPIO_Initure.Pull=GPIO_PULLUP; //上拉 // GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速 // // GPIO_Initure.Alternate=GPIO_AF12_FSMC; //复用为FSMC F1系列没这个属性 // HAL_GPIO_Init(GPIOD,&GPIO_Initure); //初始化 // //初始化PE7,8,9,10,11,12,13,14,15 // GPIO_Initure.Pin=GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|\ // GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15; // HAL_GPIO_Init(GPIOE,&GPIO_Initure); /* Set PD.00(D2), PD.01(D3), PD.04(NOE), PD.05(NWE), PD.08(D13), PD.09(D14), PD.10(D15), PD.14(D0), PD.15(D1) as alternate function push pull */ GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15; GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; HAL_GPIO_Init(GPIOD, &GPIO_InitStructure); /* Set PE.07(D4), PE.08(D5), PE.09(D6), PE.10(D7), PE.11(D8), PE.12(D9), PE.13(D10), PE.14(D11), PE.15(D12) as alternate function push pull */ GPIO_InitStructure.Pin = GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15; HAL_GPIO_Init(GPIOE, &GPIO_InitStructure); /* Set PF.00(A0 (RS)) as alternate function push pull */ GPIO_InitStructure.Pin = GPIO_PIN_0; HAL_GPIO_Init(GPIOF, &GPIO_InitStructure); /* Set PG.12(NE4 (LCD/CS)) as alternate function push pull - CE3(LCD /CS) */ GPIO_InitStructure.Pin = GPIO_PIN_12; HAL_GPIO_Init(GPIOG, &GPIO_InitStructure); } FSMC_NORSRAM_TimingTypeDef FSMC_ReadWriteTim; FSMC_NORSRAM_TimingTypeDef FSMC_WriteTim; hsram4.Instance=FSMC_NORSRAM_DEVICE; hsram4.Extended=FSMC_NORSRAM_EXTENDED_DEVICE; hsram4.Init.NSBank = FSMC_NORSRAM_BANK4; //使用NE4! hsram4.Init.DataAddressMux=FSMC_DATA_ADDRESS_MUX_DISABLE; //地址/数据线不复用! hsram4.Init.MemoryType=FSMC_MEMORY_TYPE_SRAM; //SRAM! hsram4.Init.MemoryDataWidth=FSMC_NORSRAM_MEM_BUS_WIDTH_16; //16位数据宽度! hsram4.Init.BurstAccessMode=FSMC_BURST_ACCESS_MODE_DISABLE; //是否使能突发访问,仅对同步突发存储器有效,此处未用到! hsram4.Init.WaitSignalPolarity=FSMC_WAIT_SIGNAL_POLARITY_LOW;//等待信号的极性,仅在突发模式访问下有用! hsram4.Init.WaitSignalActive=FSMC_WAIT_TIMING_BEFORE_WS; //存储器是在等待周期之前的一个时钟周期还是等待周期期间使能NWAIT hsram4.Init.WriteOperation=FSMC_WRITE_OPERATION_ENABLE; //存储器写使能! hsram4.Init.WaitSignal=FSMC_WAIT_SIGNAL_DISABLE; //等待使能位,此处未用到! hsram4.Init.ExtendedMode=FSMC_EXTENDED_MODE_ENABLE; //读写使用不同的时序! hsram4.Init.AsynchronousWait=FSMC_ASYNCHRONOUS_WAIT_DISABLE;//是否使能同步传输模式下的等待信号,此处未用到 hsram4.Init.WriteBurst=FSMC_WRITE_BURST_DISABLE; //禁止突发写! // hsram4.Init.ContinuousClock=FSMC_CONTINUOUS_CLOCK_SYNC_ASYNC; //FMC读时序控制寄存器 FSMC_ReadWriteTim.AddressSetupTime=0x0F; //地址建立时间(ADDSET)为16个HCLK 1/168M=6ns*16=96ns FSMC_ReadWriteTim.AddressHoldTime=0; FSMC_ReadWriteTim.DataSetupTime=60; //数据保存时间为60个HCLK =6*60=360ns FSMC_ReadWriteTim.AccessMode=FSMC_ACCESS_MODE_D;//模式d //FMC写时序控制寄存器 FSMC_WriteTim.BusTurnAroundDuration=0; //总线周转阶段持续时间为0,此变量不赋值的话会莫名其妙的自动修改为4。导致程序运行正常 FSMC_WriteTim.AddressSetupTime=9; //地址建立时间(ADDSET)为9个HCLK =54ns FSMC_WriteTim.AddressHoldTime=0; FSMC_WriteTim.DataSetupTime=8; //数据保存时间为6ns*9个HCLK=54n FSMC_WriteTim.AccessMode=FSMC_ACCESS_MODE_D; //模式d HAL_SRAM_Init(&hsram4,&FSMC_ReadWriteTim,&FSMC_WriteTim);View Code
但是它的代码是基于f4的hal库,针脚也用的不一样。还是得改。只能从这获得思路
不得已搬出了STM32CubeMX 看看它会怎么自动生成代码 照猫画虎配置一同。然后观察它自动生成的代码
hsram4.Instance = FSMC_NORSRAM_DEVICE; hsram4.Extended = FSMC_NORSRAM_EXTENDED_DEVICE; /* hsram4.Init */ hsram4.Init.NSBank = FSMC_NORSRAM_BANK4; hsram4.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE; hsram4.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM; hsram4.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16; hsram4.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE; hsram4.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW; hsram4.Init.WrapMode = FSMC_WRAP_MODE_DISABLE; hsram4.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS; hsram4.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE; hsram4.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE; hsram4.Init.ExtendedMode = FSMC_EXTENDED_MODE_ENABLE; hsram4.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_ENABLE; hsram4.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE; /* Timing */ Timing.AddressSetupTime = 1; Timing.AddressHoldTime = 1; Timing.DataSetupTime = 1; Timing.BusTurnAroundDuration = 1; Timing.CLKDivision = 16; Timing.DataLatency = 17; Timing.AccessMode = FSMC_ACCESS_MODE_D; /* ExtTiming */ ExtTiming.AddressSetupTime = 1; ExtTiming.AddressHoldTime = 1; ExtTiming.DataSetupTime = 7; ExtTiming.BusTurnAroundDuration = 15; ExtTiming.CLKDivision = 16; ExtTiming.DataLatency = 17; ExtTiming.AccessMode = FSMC_ACCESS_MODE_D; if (HAL_SRAM_Init(&hsram4, &Timing, &ExtTiming) != HAL_OK) { Error_Handler( ); }
用这个魔改红牛的标准库程序,把标准库里跟fsmc有关的都换成hal调用
void LCD_IOConfig(void) { // GPIO_InitTypeDef GPIO_InitStructure; // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | // RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG | // RCC_APB2Periph_AFIO, ENABLE); // /* Set PD.00(D2), PD.01(D3), PD.04(NOE), PD.05(NWE), PD.08(D13), PD.09(D14), // PD.10(D15), PD.14(D0), PD.15(D1) as alternate // function push pull */ // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | // GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_14 | // GPIO_Pin_15; // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // GPIO_Init(GPIOD, &GPIO_InitStructure); // /* Set PE.07(D4), PE.08(D5), PE.09(D6), PE.10(D7), PE.11(D8), PE.12(D9), PE.13(D10), // PE.14(D11), PE.15(D12) as alternate function push pull */ // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | // GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | // GPIO_Pin_15; // GPIO_Init(GPIOE, &GPIO_InitStructure); // GPIO_WriteBit(GPIOE, GPIO_Pin_6, Bit_SET); // /* Set PF.00(A0 (RS)) as alternate function push pull */ // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // GPIO_Init(GPIOF, &GPIO_InitStructure); // /* Set PG.12(NE4 (LCD/CS)) as alternate function push pull - CE3(LCD /CS) */ // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; // GPIO_Init(GPIOG, &GPIO_InitStructure); GPIO_InitTypeDef GPIO_InitStructure; __HAL_RCC_FSMC_CLK_ENABLE(); //使能FSMC时钟 __HAL_RCC_GPIOD_CLK_ENABLE(); //使能GPIOD时钟 __HAL_RCC_GPIOE_CLK_ENABLE(); //使能GPIOE时钟 GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15; GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; HAL_GPIO_Init(GPIOD, &GPIO_InitStructure); /* Set PE.07(D4), PE.08(D5), PE.09(D6), PE.10(D7), PE.11(D8), PE.12(D9), PE.13(D10), PE.14(D11), PE.15(D12) as alternate function push pull */ GPIO_InitStructure.Pin = GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15; HAL_GPIO_Init(GPIOE, &GPIO_InitStructure); /* Set PF.00(A0 (RS)) as alternate function push pull */ GPIO_InitStructure.Pin = GPIO_PIN_0; HAL_GPIO_Init(GPIOF, &GPIO_InitStructure); /* Set PG.12(NE4 (LCD/CS)) as alternate function push pull - CE3(LCD /CS) */ GPIO_InitStructure.Pin = GPIO_PIN_12; HAL_GPIO_Init(GPIOG, &GPIO_InitStructure); } /********************************************************************************** ** Function name: void FSMC_LCDInit(void) ** Descriptions: FSMC时序配置 ** input parameters: 无 ** output parameters: 无 ** Returned value: 无 ************************************************************************************/ void FSMC_LCDInit(void) { // FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; //定义一个NOR初始化结构体 // FSMC_NORSRAMTimingInitTypeDef w,r; //定义一个NOR时序初始化结构体 // RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); //使能FSMC总线时钟 // w.FSMC_AddressSetupTime = 0x00; //地址建立时间:0x1 // w.FSMC_AddressHoldTime = 0x00; //地址保持时间:0x00 // w.FSMC_DataSetupTime = 0x01; //数据建立时间:0x2 // w.FSMC_BusTurnAroundDuration = 0x00; // w.FSMC_CLKDivision = 0x00; // w.FSMC_DataLatency = 0x00; // w.FSMC_AccessMode = FSMC_AccessMode_B; // r.FSMC_AddressSetupTime = 0x00; //地址建立时间:0x1 // r.FSMC_AddressHoldTime = 0x00; //地址保持时间:0x00 // r.FSMC_DataSetupTime = 0x07; //数据建立时间:0x2 // r.FSMC_BusTurnAroundDuration = 0x00; // r.FSMC_CLKDivision = 0x00; // r.FSMC_DataLatency = 0x0f; // r.FSMC_AccessMode = FSMC_AccessMode_B; // FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4; //扩展NOR BANK 的第1个子BANK // FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;//不使用总线复用 // FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;//扩展类型为NOR FLASH // FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;//扩展总线宽度为16位 // FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; // FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; // FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; // FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; // FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; // FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; // FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable; // FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; // FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &r; // FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &w; // FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); //根据指定参数初始化结构体 // FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE); //使能FSMC_Bank1_NORSRAM4 内存 FSMC_NORSRAM_TimingTypeDef FSMC_ReadWriteTim; FSMC_NORSRAM_TimingTypeDef FSMC_WriteTim; hsram4.Instance = FSMC_NORSRAM_DEVICE; hsram4.Extended = FSMC_NORSRAM_EXTENDED_DEVICE; hsram4.Init.NSBank = FSMC_NORSRAM_BANK4; //使用NE4! hsram4.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE; //地址/数据线不复用! hsram4.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM; // SRAM! hsram4.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16; // 16位数据宽度! hsram4.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE; //是否使能突发访问,仅对同步突发存储器有效,此处未用到! hsram4.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW; //等待信号的极性,仅在突发模式访问下有用! hsram4.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS; //存储器是在等待周期之前的一个时钟周期还是等待周期期间使能NWAIT hsram4.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE; //存储器写使能! hsram4.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE; //等待使能位,此处未用到! hsram4.Init.ExtendedMode = FSMC_EXTENDED_MODE_ENABLE; //读写使用不同的时序! hsram4.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE; //是否使能同步传输模式下的等待信号,此处未用到 hsram4.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE; //禁止突发写! // FMC读时序控制寄存器 FSMC_ReadWriteTim.AddressSetupTime = 0x1; //地址建立时间(ADDSET)为16个HCLK 1/168M=6ns*16=96ns FSMC_ReadWriteTim.AddressHoldTime = 0x01; FSMC_ReadWriteTim.DataSetupTime = 0x01; //数据保存时间为60个HCLK =6*60=360ns FSMC_ReadWriteTim.AccessMode = FSMC_ACCESS_MODE_D; //模式d // FMC写时序控制寄存器 FSMC_WriteTim.BusTurnAroundDuration = 10; //总线周转阶段持续时间为0,此变量不赋值的话会莫名其妙的自动修改为4。导致程序运行正常 FSMC_WriteTim.AddressSetupTime = 9; //地址建立时间(ADDSET)为9个HCLK =54ns FSMC_WriteTim.AddressHoldTime = 10; FSMC_WriteTim.DataSetupTime = 0x07; //数据保存时间为6ns*9个HCLK=54n FSMC_WriteTim.AccessMode = FSMC_ACCESS_MODE_D; //模式d HAL_SRAM_Init(&hsram4, &FSMC_ReadWriteTim, &FSMC_WriteTim); }
发现一个问题 无论怎么修改头文件的引用,HAL_SRAM_Init在pio里始终没有被编译。搞得我无比头大。最后我看了下cube生成的代码 里边除了gpio跟fsmc其他外设都关了。但是看pio里的hal库 默认所有功能都开着。再仔细看。源码里有个if define fsmc才会编译的句子 尝试在pio的配置文件platformio.ini里加上-d
[env:genericSTM32F103ZE] platform = ststm32 board = genericSTM32F103ZE framework = arduino build_flags = -D USBD_USE_CDC -D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC -D PIO_FRAMEWORK_ARDUINO_USB_FULLMODE -D USBCON -D HAL_SRAM_MODULE_ENABLED 这样终于不报错了。 但是读取的显示屏id始终不对是0000.目前没有找到办法。
。