硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2313|回复: 5
收起左侧

[其它] 关于多个外设不同的初始化顺序,造成后初始化的外设不能正常工作原因说明

[复制链接]

14

主题

109

回帖

151

积分

初级会员

积分
151
发表于 2018-1-15 09:23:49 | 显示全部楼层 |阅读模式
本帖最后由 fswyt 于 2018-1-15 09:35 编辑

有时候我们会遇到在连续初始化多个外设时,有个外设工作不正常,但是和它前面的外设初始化调换下位置,就可以正常工作了。造成这个问题现象
的主要原因是外设初始化结构体是局部变量,放在栈里,另外这个外设初始化结构体里的一些值在我们初始化外设时没用到,想让它保持默认值,但
是我们没有给它默认值啊!!!这些没用到的参数值可不是确定的啊!!!可能是上一个局部变量留下的脏值!所以,我们在进行外设初始化时,要
对声明的局部变量进行初始化!

11.png
22.png

评分

参与人数 2金币 +40 收起 理由
byccc + 20
eric2013 + 20 赞一个!

查看全部评分

回复

使用道具 举报

14

主题

109

回帖

151

积分

初级会员

积分
151
 楼主| 发表于 2018-1-15 09:25:26 | 显示全部楼层
我之前也遇到过,同事也遇到过,所以建此贴,给大家提个醒。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107046
QQ
发表于 2018-1-15 09:41:54 | 显示全部楼层
非常感谢楼主分享
回复

使用道具 举报

36

主题

2040

回帖

2148

积分

至尊会员

积分
2148
发表于 2018-1-15 14:40:04 | 显示全部楼层
666,赞一个,感谢分享
Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better.
回复

使用道具 举报

1

主题

10

回帖

13

积分

新手上路

积分
13
发表于 2018-1-17 12:17:13 | 显示全部楼层
本帖最后由 小蜜蜂科技 于 2018-1-17 12:31 编辑

我测试了一下,对于我的程序来说还是没有作用,串口初始化放到液晶FSMC初始化前面还是不行.我在配置串口时已经按你的方法添加初始化结构体函数.程序都是死在读写LCD寄存器函数上
void bsp_Init(void)
{
        /*
                由于ST固件库的启动文件已经执行了CPU系统时钟的初始化,所以不必再次重复配置系统时钟。
                启动文件配置了CPU主时钟频率、内部Flash访问速度和可选的外部SRAM FSMC初始化。
                系统时钟缺省配置为72MHz,如果需要更改,可以修改 system_stm32f10x.c 文件
        */
        
        /* 使能CRC校验, 用于开启STemWin的使用 */
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);
        
        /* 优先级分组设置为4,可配置0-15级抢占式优先级,0级子优先级,即不存在子优先级。*/
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
        
        bsp_InitDWT();                                       /* 初始化数据观察点与跟踪(DWT)模块*/
        bsp_InitLed();                                                  /* 初始LED指示灯端口 */
        bsp_InitKey();                                                 /* 初始化按键 */
        BEEP_InitHard();                                        /* 初始化蜂鸣器硬件*/
        bsp_InitSPIBus();                                        /* 配置SPI总线 ,主要配置SPI2接口,这个接口是SPIflash与TSC2046共用的*/
        bsp_InitSFlash();                                        /* 初始化SPI flash(GBK字库)*/
//        SPI_FLASH_Test();                                        /* SPI FLASH读写测试试验*/
        bsp_InitUart();                                          /* 初始化串口 注意!!!要放在液晶屏初始化前面会死机*/
        LCD_InitHard();                                            /* 初始化显示器硬件*/        
//        bsp_InitUart();                                          /* 初始化串口 注意!!!要放在液晶屏初始化前面会死机*/
        bsp_InitSFRAM();                                        /* 初始化铁电存储器(保存参数)注意!!!要放在液晶屏初始化前面会死机*/
//        bsp_InitI2C();                                       /* 配置I2C总线 */
        TOUCH_InitHard();                                    /* 初始化触摸屏*/

        LCD_SetBackLight(BRIGHT_DEFAULT);        /* 打开液晶屏背光*/        
}

/////串口配置
static void InitHardUart(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
        
        //初始化结构体
        GPIO_StructInit(&GPIO_InitStructure);
        USART_StructInit(&USART_InitStructure);                                       

#if UART1_FIFO_EN == 1                /* 串口1 TX = PA9   RX = PA10 或 TX = PB6   RX = PB7*/

        /* 第1步:打开GPIO和USART部件的时钟 */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

        /* 第2步:将USART Tx的GPIO配置为推挽复用模式 */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);

        /* 第3步:将USART Rx的GPIO配置为浮空输入模式
                由于CPU复位后,GPIO缺省都是浮空输入模式,因此下面这个步骤不是必须的
                但是,我还是建议加上便于阅读,并且防止其它地方修改了这个口线的设置参数
        */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
        
        /* 第4步: 配置串口硬件参数 */
        USART_InitStructure.USART_BaudRate = UART1_BAUD;        /* 波特率 */
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        USART_InitStructure.USART_StopBits = USART_StopBits_1;
        USART_InitStructure.USART_Parity = USART_Parity_No ;
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
        USART_Init(USART1, &USART_InitStructure);

        USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);        /* 使能接收中断 */
        /*
                USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
                注意: 不要在此处打开发送中断
                发送中断使能在SendUart()函数打开
        */
        USART_Cmd(USART1, ENABLE);                /* 使能串口 */

        /* CPU的小缺陷:串口配置好,如果直接Send,则第1个字节发送不出去
                如下语句解决第1个字节无法正确发送出去的问题 */
        USART_ClearFlag(USART1, USART_FLAG_TC);     /* 清发送完成标志,Transmission Complete flag */
#endif

////液晶屏接口配置
/*
*********************************************************************************************************
*        函 数 名: LCD_CtrlLinesConfig
*        功能说明: 配置LCD控制口线,FSMC管脚设置为复用功能
*        形    参: 无
*        返 回 值: 无
*********************************************************************************************************
*/
static void LCD_CtrlLinesConfig(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        
        GPIO_StructInit(&GPIO_InitStructure);

        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);

        /* 使能 FSMC, GPIOD, GPIOE, GPIOF, GPIOG 和 AFIO 时钟 */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE |
                             RCC_APB2Periph_AFIO, ENABLE);

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


///////////////////////////////////////////////////
/*
*********************************************************************************************************
*        函 数 名: LCD_FSMCConfig
*        功能说明: 配置FSMC并口访问时序
*        形    参: 无
*        返 回 值: 无
*********************************************************************************************************
*/
static void LCD_FSMCConfig(void)
{
          FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
        FSMC_NORSRAMTimingInitTypeDef  p;        

   //如果这此添加初始化结构体函数,液晶屏反而不工作.
//FSMC_NORSRAMStructInit(&FSMC_NORSRAMInitStructure);                        //初始化结构体
        
        
///////////////////////////使用ILI9325时的设置//////////////////////////////////////        
/*-- FSMC Configuration ------------------------------------------------------*/
/*----------------------- SRAM Bank 1 ----------------------------------------*/
  p.FSMC_AddressSetupTime = 0;                                                        //地址建立时间 2
  p.FSMC_AddressHoldTime = 0;                                                        //地址保持时间 0
  p.FSMC_DataSetupTime = 2;                                                                //数据建立时间 5
  p.FSMC_BusTurnAroundDuration = 0;                                                /*总线转向时间*/
  p.FSMC_CLKDivision = 0;                                                                /*CLK时钟输出信号的HCLK周期数表示时间???*/
  p.FSMC_DataLatency = 0;                                                                /*指定在获得第一个数据前的时钟周期*/
  p.FSMC_AccessMode = FSMC_AccessMode_B;
///////////////////////////////////////////////////////////////
  /* Color LCD configuration ------------------------------------
     LCD configured as follow:
        - Data/Address MUX = Disable
        - Memory Type = SRAM
        - Data Width = 16bit
        - Write Operation = Enable
        - Extended Mode = Enable
        - Asynchronous Wait = Disable */
  FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;                                                          /*指定的FSMC块*/
/////////////////////液晶屏初始化/////////////////////////////////
void OTM8009A_InitHard(void)
{
        //OTM8009A_for_HSD5'_InitialCode_20120426.txt 480x854
        LCD_WriteReg(0xff00,0x80);
        LCD_WriteReg(0xff01,0x09);         // enable EXTC
        LCD_WriteReg(0xff02,0x01);
        LCD_WriteReg(0xff80,0x80);  // enable Orise mode
        LCD_WriteReg(0xff81,0x09); //
        LCD_WriteReg(0xff03,0x01);  // enable SPI+I2C cmd2 read


程序都是死在读写LCD寄存器这个函数上.LCD_WriteReg()

        #define OTM8009A_BASE                ((uint32_t)(0x60000000 | 0x00000000))
        #define OTM8009A_RAM                *(__IO uint16_t *)(OTM8009A_BASE +  (1 << (16 + 1)))        /* FSMC 16位总线模式下,FSMC_A17口线对应物理地址A16 */    //RS=1  (数据)
        #define OTM8009A_REG                *(__IO uint16_t *)(OTM8009A_BASE)        


void LCD_WriteReg(u16 LCD_Reg,u16 LCD_RegValue)
{
                OTM8009A_REG = LCD_Reg;                                        //写入要写的寄存器序号
                OTM8009A_RAM = LCD_RegValue;                //写入数据
}


回复

使用道具 举报

5

主题

109

回帖

124

积分

初级会员

积分
124
发表于 2018-1-28 17:26:47 | 显示全部楼层
收藏一下,谢谢楼主
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-15 13:03 , Processed in 0.293599 second(s), 32 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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