菜鸟开贴,学习STM32F4

2019-07-20 21:19发布

本帖最后由 mingjie2015 于 2016-6-29 07:29 编辑

学习板 探索者STM32F4
起始时间:2016年06月29日更新时间:尽量做到每天更新目标:完成开发板大部分内容(时间因情况而定)
相关参考:(1)正点原子STM32F4相关资料(2)安福莱V5开发板相关资料(3)网友龙之谷 《菜鸟开帖,持续更新90天,顺序学习开发板大部分实验,以此帖作为一个坚持的动力》
谨以此贴作为学习STM32F4的资料,方面自己以后查找。




友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
12条回答
mingjie2015
2019-07-21 08:43
本帖最后由 mingjie2015 于 2016-7-14 15:18 编辑

2016年07月12日 lcd液晶显示(一)在开发过程中使用液晶或者串口来显示调试信息比较直观的显示需要显示的信息,lcd采用的芯片为ILI9341,3.2寸液晶屏分辨率为320*240
一.引脚定义
[mw_shl_code=c,true](1)16根数据线:
PD0/FSMC_D2
PD1/FSMC_D3
PD8/FSMC_D13
PD9/FSMC_D14
PD10/FSMC_D15
PD14/FSMC_D0
PD15/FSMC_D1

PE7/FSMC_D4
PE8/FSMC_D5
PE9/FSMC_D6
PE10/FSMC_D7
PE11/FSMC_D8
PE12/FSMC_D9
PE13/FSMC_D10
PE14/FSMC_D11
PE15/FSMC_D12
(2)1根地址线:
PF12/FSMC_ A6
(3)控制线:
PD4/FSMC_NOE               
PD5/FSMC_NWE        
PG12/FSMC_NE4               
PB15/LCD_BL
RESET   直接连接在单片机RESET脚上二.IO口初始化
static void LCD_CtrlLinesConfig(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;

        /* 使能FSMC时钟 */
        RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);

        /* 使能 GPIO时钟 */
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOG, ENABLE);

        /* 设置 PD.00(D2), PD.01(D3), PD.08(D13), PD.09(D14),
         PD.10(D15), PD.14(D0), PD.15(D1), PD.04(NOE), PD.05(NWE), 为复用推挽输出 */

        GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FSMC);

        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_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOD, &GPIO_InitStructure);

        /* 设置 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) 为复用推挽输出 */

        GPIO_PinAFConfig(GPIOE, GPIO_PinSource7 , GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOE, GPIO_PinSource8 , GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOE, GPIO_PinSource9 , GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOE, GPIO_PinSource10 , GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOE, GPIO_PinSource11 , GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOE, GPIO_PinSource12 , GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOE, GPIO_PinSource13 , GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOE, GPIO_PinSource14 , GPIO_AF_FSMC);
        GPIO_PinAFConfig(GPIOE, GPIO_PinSource15 , GPIO_AF_FSMC);

        GPIO_InitStructure.GPIO_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;
        GPIO_Init(GPIOE, &GPIO_InitStructure);

        /* 设置 PF.12(A6 (RS))  为复用推挽输出 */
        GPIO_PinAFConfig(GPIOF, GPIO_PinSource6, GPIO_AF_FSMC);

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
        GPIO_Init(GPIOF, &GPIO_InitStructure);

        /* 设置 PG12 (LCD/CS)) 为复用推挽输出 */
        GPIO_PinAFConfig(GPIOG, GPIO_PinSource12, GPIO_AF_FSMC);

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
        GPIO_Init(GPIOG, &GPIO_InitStructure);
}
static void LCD_FSMCConfig(void)
{
        FSMC_NORSRAMInitTypeDef  init;
        FSMC_NORSRAMTimingInitTypeDef  timingWrite;
        FSMC_NORSRAMTimingInitTypeDef  timingRead;

        /*-- FSMC Configuration ------------------------------------------------------*/
        /*----------------------- SRAM Bank 4 ----------------------------------------*/
        /* FSMC_Bank1_NORSRAM4 configuration */
        
        timingRead.FSMC_AddressSetupTime = 0XF;         //地址建立时间(ADDSET)为16个HCLK 1/168M=6ns*16=96ns        
        timingRead.FSMC_AddressHoldTime = 0x00;         //地址保持时间(ADDHLD)模式A未用到        
        timingRead.FSMC_DataSetupTime = 60;                        //数据保存时间为60个HCLK        =6*60=360ns
        timingRead.FSMC_BusTurnAroundDuration = 0x00;
        timingRead.FSMC_CLKDivision = 0x00;
        timingRead.FSMC_DataLatency = 0x00;
        timingRead.FSMC_AccessMode = FSMC_AccessMode_A;         //模式A


        timingWrite.FSMC_AddressSetupTime =9;              //地址建立时间(ADDSET)为9个HCLK =54ns
        timingWrite.FSMC_AddressHoldTime = 0x00;         //地址保持时间(A               
        timingWrite.FSMC_DataSetupTime = 8;                 //数据保存时间为6ns*9个HCLK=54ns
        timingWrite.FSMC_BusTurnAroundDuration = 0x00;
        timingWrite.FSMC_CLKDivision = 0x00;
        timingWrite.FSMC_DataLatency = 0x00;
        timingWrite.FSMC_AccessMode = FSMC_AccessMode_A;         //模式A

        /*
         LCD configured as follow:
            - Data/Address MUX = Disable
            - Memory Type = SRAM
            - Data Width = 16bit
            - Write Operation = Enable
            - Extended Mode = Enable
            - Asynchronous Wait = Disable
        */
                                                                                                                                /* - BANK 1 (of NOR/SRAM Bank 1~4) is enabled */
        FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);
        
        init.FSMC_Bank = FSMC_Bank1_NORSRAM4;                                                /* 这里我们使用NE4 ,也就对应BTCR[6],[7] */
        init.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;         /* 不复用数据地址 */
        init.FSMC_MemoryType =FSMC_MemoryType_SRAM;                                  /* FSMC_MemoryType_SRAM;SRAM */  
        init.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;                /* 存储器数据宽度为16bit */
        init.FSMC_BurstAccessMode =FSMC_BurstAccessMode_Disable;        /*  FSMC_BurstAccessMode_Disable; */
        init.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
        init.FSMC_AsynchronousWait=FSMC_AsynchronousWait_Disable;
        init.FSMC_WrapMode = FSMC_WrapMode_Disable;   
        init.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;  
        init.FSMC_WriteOperation = FSMC_WriteOperation_Enable;                /* 存储器写使能 */  
        init.FSMC_WaitSignal = FSMC_WaitSignal_Disable;   
        init.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable;                         /* 读写使用不同的时序 */
        init.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
        init.FSMC_ReadWriteTimingStruct = &timingRead;                 /* 读写时序 */
        init.FSMC_WriteTimingStruct = &timingWrite;                                  /* 写时序 */

        FSMC_NORSRAMInit(&init);                                                                          /* 初始化FSMC配置 */

        FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);                                /* 使能BANK1 */
}
因RESER引脚直接连接在单片机引脚上,故不需要配置RESET管脚读芯片ID
uint16_t ILI9341_ReadID(void)
{                        
        uint8_t buf[4];

        ILI9341_REG = 0xD3;
        buf[0] = ILI9341_RAM;
        buf[1] = ILI9341_RAM;
        buf[2] = ILI9341_RAM;
        buf[3] = ILI9341_RAM;

        return (buf[1] << 16) + (buf[2] << 8) + buf[3];
}驱动ILI9341
void Init_ILI9341(void)
{
                ILI9341_WriteCmd(0xCF);  
                ILI9341_WriteParam(0x00);
                ILI9341_WriteParam(0xC1);
                ILI9341_WriteParam(0X30);
        
                ILI9341_WriteCmd(0xED);  
                ILI9341_WriteParam(0x64);
                ILI9341_WriteParam(0x03);
                ILI9341_WriteParam(0X12);
                ILI9341_WriteParam(0X81);
        
                ILI9341_WriteCmd(0xE8);  
                ILI9341_WriteParam(0x85);
                ILI9341_WriteParam(0x10);
                ILI9341_WriteParam(0x7A);
                ILI9341_WriteCmd(0xCB);  
                ILI9341_WriteParam(0x39);
                ILI9341_WriteParam(0x2C);
                ILI9341_WriteParam(0x00);
                ILI9341_WriteParam(0x34);
                ILI9341_WriteParam(0x02);
                ILI9341_WriteCmd(0xF7);  
                ILI9341_WriteParam(0x20);
                ILI9341_WriteCmd(0xEA);  
                ILI9341_WriteParam(0x00);
                ILI9341_WriteParam(0x00);
                ILI9341_WriteCmd(0xC0);    //Power control
                ILI9341_WriteParam(0x1B);   //VRH[5:0]
                ILI9341_WriteCmd(0xC1);    //Power control
                ILI9341_WriteParam(0x01);   //SAP[2:0];BT[3:0]
                ILI9341_WriteCmd(0xC5);    //VCM control
                ILI9341_WriteParam(0x30);          //3F
                ILI9341_WriteParam(0x30);          //3C
                ILI9341_WriteCmd(0xC7);    //VCM control2
                ILI9341_WriteParam(0XB7);
                ILI9341_WriteCmd(0x36);    // Memory Access Control
                ILI9341_WriteParam(0x48);
                ILI9341_WriteCmd(0x3A);   
                ILI9341_WriteParam(0x55);
                ILI9341_WriteCmd(0xB1);   
                ILI9341_WriteParam(0x00);   
                ILI9341_WriteParam(0x1A);
                ILI9341_WriteCmd(0xB6);    // Display Function Control
                ILI9341_WriteParam(0x0A);
                ILI9341_WriteParam(0xA2);
                ILI9341_WriteCmd(0xF2);    // 3Gamma Function Disable
                ILI9341_WriteParam(0x00);
                ILI9341_WriteCmd(0x26);    //Gamma curve selected
                ILI9341_WriteParam(0x01);
                ILI9341_WriteCmd(0xE0);    //Set Gamma
                ILI9341_WriteParam(0x0F);
                ILI9341_WriteParam(0x2A);
                ILI9341_WriteParam(0x28);
                ILI9341_WriteParam(0x08);
                ILI9341_WriteParam(0x0E);
                ILI9341_WriteParam(0x08);
                ILI9341_WriteParam(0x54);
                ILI9341_WriteParam(0XA9);
                ILI9341_WriteParam(0x43);
                ILI9341_WriteParam(0x0A);
                ILI9341_WriteParam(0x0F);
                ILI9341_WriteParam(0x00);
                ILI9341_WriteParam(0x00);
                ILI9341_WriteParam(0x00);
                ILI9341_WriteParam(0x00);                  
                ILI9341_WriteCmd(0XE1);    //Set Gamma
                ILI9341_WriteParam(0x00);
                ILI9341_WriteParam(0x15);
                ILI9341_WriteParam(0x17);
                ILI9341_WriteParam(0x07);
                ILI9341_WriteParam(0x11);
                ILI9341_WriteParam(0x06);
                ILI9341_WriteParam(0x2B);
                ILI9341_WriteParam(0x56);
                ILI9341_WriteParam(0x3C);
                ILI9341_WriteParam(0x05);
                ILI9341_WriteParam(0x10);
                ILI9341_WriteParam(0x0F);
                ILI9341_WriteParam(0x3F);
                ILI9341_WriteParam(0x3F);
                ILI9341_WriteParam(0x0F);
                ILI9341_WriteCmd(0x2B);
                ILI9341_WriteParam(0x00);
                ILI9341_WriteParam(0x00);
                ILI9341_WriteParam(0x01);
                ILI9341_WriteParam(0x3f);
                ILI9341_WriteCmd(0x2A);
                ILI9341_WriteParam(0x00);
                ILI9341_WriteParam(0x00);
                ILI9341_WriteParam(0x00);
                ILI9341_WriteParam(0xef);         
                ILI9341_WriteCmd(0x11); //Exit Sleep
                bsp_DelayMS(120);
                ILI9341_WriteCmd(0x29); //display on        
                ILI9341_SetDirection(0);                         //默认为竖屏
                bsp_LedOff(1);                                //点亮背光
}
void ILI9341_SetDirection(uint8_t _ucDir)
{
        ILI9341_WriteCmd(0x36);
        /* 0 表示竖屏(排线在下),1表示竖屏(排线在上), 2表示横屏(排线在左边)  3表示横屏 (排线在右边) */
        if (_ucDir == 0)
        {
                ILI9341_WriteParam(0xA8);        /* 横屏(排线在左边) */
                g_LcdHeight = 240;
                g_LcdWidth = 320;
        }
        else if (_ucDir == 1)
        {
                ILI9341_WriteParam(0x68);        /* 横屏 (排线在右边) */
                g_LcdHeight = 240;
                g_LcdWidth = 320;
        }
        else if (_ucDir == 2)
        {
                ILI9341_WriteParam(0xC8);        /* 竖屏(排线在上) */
                g_LcdHeight = 240;
                g_LcdWidth = 320;
        }
        else if (_ucDir == 3)
        {
                ILI9341_WriteParam(0x08);        /* 竖屏(排线在下) */
                g_LcdHeight = 240;
                g_LcdWidth = 320;
        }
}

static void ILI9341_SetDispWin(uint16_t _usX, uint16_t _usY, uint16_t _usHeight, uint16_t _usWidth)
{
        ILI9341_WriteCmd(0X2A);                 /* 设置X坐标 */
        ILI9341_WriteParam(_usX >> 8);        /* 起始点 */
        ILI9341_WriteParam(_usX);
        ILI9341_WriteParam((_usX + _usWidth - 1) >> 8);        /* 结束点 */
        ILI9341_WriteParam(_usX + _usWidth - 1);

        ILI9341_WriteCmd(0X2B);                                   /* 设置Y坐标*/
        ILI9341_WriteParam(_usY >> 8);   /* 起始点 */
        ILI9341_WriteParam(_usY);
        ILI9341_WriteParam((_usY + _usHeight - 1) >>8);                /* 结束点 */
        ILI9341_WriteParam((_usY + _usHeight - 1));
}
void ILI9341_ClrScr(uint16_t _usColor)
{
        uint32_t i;
        uint32_t n;

        ILI9341_SetDispWin(0, 0, g_LcdHeight, g_LcdWidth);

        ILI9341_REG = 0x2C;                         /* 准备读写显存 */
        n = g_LcdHeight * g_LcdWidth;
        for (i = 0; i < n; i++)
        {
                ILI9341_RAM = _usColor;
        }

}
[/mw_shl_code]
基本上可以驱动ILI9341 3.2寸液晶屏了
这里有个关于液晶模块的例子看着不错 针对不同液晶   同样针对其他模块也可以按照这种方式处理,增加代码的兼容性,便于扩展有兴趣的可以参考一下
http://www.openedv.com/forum.php ... D%B5%E3%D4%AD%D7%D3








一周热门 更多>