2557|5

6533

帖子

9

TA的资源

版主

楼主
 

【国民技术N32G430】06 综合调试,RTC,模拟IIC,串口 [复制链接]

  本帖最后由 秦天qintian0303 于 2022-10-25 10:58 编辑

前言:

        疫情真是一个烦人的事情,所有的计划都被无情的打断,转瞬就要到测评结束的时候了,得快马加鞭,于是就把实时时钟/传感器数据采集/串口部分都统一到这一篇章进行介绍。

准备工作:

        在此期间也是把N32G430的转接板做了回来,之前准备就用杜邦线连接进行测试着,不过发现使用杜邦线连接有几个弊端:

                一个是咱们的EVA板不好固定;

                还有就是移动过程中会出现接触不良的现象。

        所以还是做了转接板,由于手工测量的原因(N32G430C8L7_STB_V1.0.pcb并没有内容),实物还是存在一些偏差,简单调整了引脚角度还是可以装上的。

粗略尺寸图如下:

组装后实物图如下:

        引脚目前看没有什么问题,之前写的程序可以正常运行,且外设驱动正常。

        接下来就是N32G430测评页面操作分析:

        依次思维脑图进行进行一个整体测试系统的构造。

具体测试:

        接下来就进行剩余三个部分的具体测试内容。

一、RTC测试体验

        RTC的主要部分主要分开机检测、初始化、和RTC的获取和设置。

        每次开机通过备份寄存器存储的数据进行判断RTC是否在工作,备份寄存器是通过电池供电引脚供电,所以不会因为MCU的供电变化而停止工作,若是备份寄存器复位了就需要进行RTC的初始化了。

代码如下:

void port_RTC_init(void)
{
  /* Enable the PWR clock */
  RCC_APB1_Peripheral_Clock_Enable(RCC_APB1_PERIPH_PWR);
  /* Allow access to RTC */
  PWR_RTC_Backup_Access_Enable();
  
  /* check data from bpr dt register */
  if(RTC_Backup_Register_Read(RTC_BACKUP_REGISTER_1) != ERTC_BPR_DT1)
  {
    /* ertc configuration */
    ertc_config();
    /* write to ertc bpr data registers */
    RTC_Backup_Register_Write(RTC_BACKUP_REGISTER_1,ERTC_BPR_DT1);
  }

  
}

初始化代码:

/******************************************************************************/
//******************************************************************************
// 函数名称  : RTC_Date_And_Time_Default_Value
// 函数描述  : 时间参数初始值
// 输入参数  :
// 参数描述  : 无
// 输出参数  : 无
// 返回值    : 无
//******************************************************************************
void RTC_Date_And_Time_Default_Value(void)
{ 
  eRTC_set.week       = 2;
  eRTC_set.day        = 20;
  eRTC_set.month      = 9;
  eRTC_set.year       = 22;
  eRTC_set.hour       = 10;
  eRTC_set.min        = 0;
  eRTC_set.sec        = 0;
}


/**
*\*\name    RTC_CLKSource_Config.
*\*\fun     Configure the RTC peripheral by selecting the clock source.
*\*\param   ClkSrc    
*\*\            - RTC_CLK_HSE128    clock source select HSE/128
*\*\            - RTC_CLK_LSE       clock source select LSE
*\*\            - RTC_CLK_LSI       clock source select LSI
*\*\param   FirstLastCfg
*\*\            - RTC_CLK_FIRST_CONFIG
*\*\            - RTC_CLK_LAST_CONFIG
*\*\return  none
**/
//******************************************************************************
// 函数名称  : RTC_CLKSource_Config
// 函数描述  : RTC时钟配置,并获取分频参数
// 输入参数  : 
//      ClkSrc:
//            - RTC_CLK_HSE128    clock source select HSE/128
//            - RTC_CLK_LSE       clock source select LSE
//            - RTC_CLK_LSI       clock source select LSI
//param FirstLastCfg:
//            - RTC_CLK_FIRST_CONFIG
//            - RTC_CLK_LAST_CONFIG
// 参数描述  : 无
// 输出参数  : 无
// 返回值    : 无
//******************************************************************************
void RTC_CLKSource_Config(uint8_t ClkSrc, uint8_t FirstLastCfg)
{
  /* Enable the PWR clock */
  RCC_APB1_Peripheral_Clock_Enable(RCC_APB1_PERIPH_PWR);
  RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_AFIO);
  /* Allow access to RTC */
  PWR_RTC_Backup_Access_Enable();
  
  RCC_Backup_Reset();
  /* Disable RTC clock */
  RCC_RTC_Clock_Disable();
  if (ClkSrc == RTC_CLK_HSE128)
  {
    if (FirstLastCfg == RTC_CLK_FIRST_CONFIG)
    {
      /* Enable HSE */
      RCC_LSI_Disable();
      RCC_HSE_Config(RCC_HSE_ENABLE);
      while (RCC_HSE_Stable_Wait() == ERROR)
      {
      }
      RCC_RTC_Clock_Config(RCC_RTCCLK_SRC_HSE_DIV128);
    }
    else
    {
      RCC_LSI_Disable();
      RCC_RTC_Clock_Config(RCC_RTCCLK_SRC_HSE_DIV128);
      /* Enable HSE */
      RCC_HSE_Config(RCC_HSE_ENABLE);
      while (RCC_HSE_Stable_Wait() == ERROR)
      {
      }
    }
    SynchPrediv  = 0x1E8; // 8M/128 = 62.5KHz
    AsynchPrediv = 0x7F;  // value range: 0-7F
  }
  else if (ClkSrc == RTC_CLK_LSE)
  {
    if (FirstLastCfg == RTC_CLK_FIRST_CONFIG)
    {
      /* Enable the LSE OSC32_IN PC14 */
      RCC_LSI_Disable(); // LSI is turned off here to ensure that only one clock is turned on

#if (_LSE_BYPASS_)
      RCC_LSE_Config(RCC_LSE_BYPASS, 0x141);
#else
      RCC_LSE_Config(RCC_LSE_ENABLE, 0x141);
#endif
      while (RCC_Flag_Status_Get(RCC_FLAG_LSERD) == RESET)
      {
      }
      RCC_RTC_Clock_Config(RCC_RTCCLK_SRC_LSE);
    }
    else
    {
      /* Enable the LSE OSC32_IN PC14 */
      RCC_LSI_Disable();
      RCC_RTC_Clock_Config(RCC_RTCCLK_SRC_LSE);

#if (_LSE_BYPASS_)
      RCC_LSE_Config(RCC_LSE_BYPASS, 0x141);
#else
      RCC_LSE_Config(RCC_LSE_ENABLE, 0x141);
#endif
      while (RCC_Flag_Status_Get(RCC_FLAG_LSERD) == RESET)
      {
      }
    }
    SynchPrediv  = 0xFF; // 32.768KHz
    AsynchPrediv = 0x7F; // value range: 0-7F
  }
  else if (ClkSrc == RTC_CLK_LSI)
  {
    if (FirstLastCfg == RTC_CLK_FIRST_CONFIG)
    {
      /* Enable the LSI OSC */
      RCC_LSI_Enable();
      while (RCC_Flag_Status_Get(RCC_FLAG_LSIRD) == RESET)
      {
      }
      RCC_RTC_Clock_Config(RCC_RTCCLK_SRC_LSI);
    }
    else
    {
      RCC_RTC_Clock_Config(RCC_RTCCLK_SRC_LSI);
      /* Enable the LSI OSC */
      RCC_LSI_Enable();
      while (RCC_Flag_Status_Get(RCC_FLAG_LSIRD) == RESET)
      {
      }
    }
    SynchPrediv  = 0x13B; // 39.64928KHz
    AsynchPrediv = 0x7F;  // value range: 0-7F
  }
  else
  {  
  }
  /* Enable the RTC Clock */
  RCC_RTC_Clock_Enable();
  RTC_Wait_For_Synchronization();
}

/**
*\*\name    RTC_Prescaler_Config.
*\*\fun     RTC prescaler config.
*\*\param   RTC_InitStruct: pointer to a RTC_InitType structure. 
*\*\            - RTC_HourFormat
*\*\                - RTC_24HOUR_FORMAT
*\*\                - RTC_12HOUR_FORMAT
*\*\            - RTC_AsynchPrediv  the value in the 0-0x7F range
*\*\            - RTC_SynchPrediv   the value in the 0-0x7FFF range
*\*\return  none
**/
static void RTC_Prescaler_Config(RTC_InitType *RTC_InitStruct)
{
    /* Configure the RTC data register and RTC prescaler */
    RTC_InitStruct->RTC_AsynchPrediv = AsynchPrediv;
    RTC_InitStruct->RTC_SynchPrediv  = SynchPrediv;
    RTC_InitStruct->RTC_HourFormat   = RTC_24HOUR_FORMAT;
}

//******************************************************************************
// 函数名称  : ertc_config
// 函数描述  : ert初始化配置
// 输入参数  :
// 参数描述  : 无
// 输出参数  : 无
// 返回值    : 无
//******************************************************************************
void ertc_config(void)
{
  RTC_Date_And_Time_Default_Value();
  RTC_CLKSource_Config(RTC_CLK_LSE,RTC_CLK_FIRST_CONFIG);

  RTC_Prescaler_Config(&RTC_InitStructure);
  /* RTC calendar regulate */
  Set_Time();
}

//******************************************************************************
// 函数名称  : Set_Time
// 函数描述  : 设置时间
// 输入参数  :
// 参数描述  : 无
// 输出参数  : 无
// 返回值    : 无
//******************************************************************************
void Set_Time(void)
{
  
  // Date
  eDRTC_set.WeekDay = eRTC_set.week;
  eDRTC_set.Date    = eRTC_set.day;
  eDRTC_set.Month   = eRTC_set.month;
  eDRTC_set.Year    = eRTC_set.year;
  // Time
  eTRTC_set.H12     = RTC_AM_H12;
  eTRTC_set.Hours   = eRTC_set.hour;
  eTRTC_set.Minutes = eRTC_set.min;
  eTRTC_set.Seconds = eRTC_set.sec;
  
  RTC_CLKSource_Config(RTC_CLK_LSE,RTC_CLK_FIRST_CONFIG);
  RTC_Write_Protection_Disable();
  RTC_Prescaler_Config(&RTC_InitStructure);
  RTC_Calendar_Initializes(RTC_FORMAT_BIN,&RTC_InitStructure,&eDRTC_set,&eTRTC_set,DISABLE);
  RTC_Write_Protection_Enable();
}

RTC获取和设置代码:

//******************************************************************************
// 函数名称  : Get_Time
// 函数描述  : 获取时间
// 输入参数  :
// 参数描述  : 无
// 输出参数  : 无
// 返回值    : 无
//******************************************************************************
void Get_Time(void)
{  
  RTC_Time_Get(RTC_FORMAT_BIN,&eTRTC);
  RTC_Date_Get(RTC_FORMAT_BIN,&eDRTC);
  
  eRTC.week     = eDRTC.WeekDay;
  eRTC.day      = eDRTC.Date;
  eRTC.month    = eDRTC.Month;
  eRTC.year     = eDRTC.Year;

  eRTC.hour     = eTRTC.Hours;
  eRTC.min      = eTRTC.Minutes;
  eRTC.sec      = eTRTC.Seconds;
  
}

        这里需要注意,正常我们去除写保护就可以进行RTC寄存器的写操作了,不过N32G430还需要重新配置才能正常写,要不然就会出现RTC的随机数问题,有可能关闭写保护的操作会导致RTC复位?

二、IIC获取AHT20和SPL06数据

        AHT20是一个温湿度传感器,SPL06是一个温度、大气压力传感器,两者的IIC存在一点不同,就是AHT20发送完设备地址后不用再发送寄存器地址,而SPL06的寄存器比较多,需要对特定寄存器进行访问。

软件IIC各阶段代码:

#define IIC1_RCU_GPIO_clock     RCC_AHB_Peripheral_Clock_Enable(IIC1_MASTER_PERIPH_GPIO);
#define IIC1_SDA_INITOut        IIC1_SDA_GPIO_OutConfig()
#define IIC1_SDA_INITIn         IIC1_SDA_GPIO_InConfig()
#define IIC1_SDA_SET            GPIO_Pins_Set(IIC1_MASTER_GPIO,IIC1_MASTER_SDA_PIN)                  
#define IIC1_SDA_RESET          GPIO_Pins_Reset(IIC1_MASTER_GPIO,IIC1_MASTER_SDA_PIN)
#define IIC1_ReadSDA            GPIO_Input_Pin_Data_Get(IIC1_MASTER_GPIO, IIC1_MASTER_SDA_PIN)

#define IIC1_SCL_INITOut        IIC1_SCL_GPIO_OutConfig()
#define IIC1_SCL_SET            GPIO_Pins_Set(IIC1_MASTER_GPIO,IIC1_MASTER_CLK_PIN)                  
#define IIC1_SCL_RESET          GPIO_Pins_Reset(IIC1_MASTER_GPIO,IIC1_MASTER_CLK_PIN)
      
      
/*********************************全局变量**************************************/
      

/*********************************函数******************************************/      
void IIC1_IOInit(void);
void IIC1_SDA_GPIO_OutConfig(void);
void IIC1_SDA_GPIO_InConfig(void);
void IIC1_SCL_GPIO_OutConfig(void);
void IIC1_IIC_Init(void);
void IIC1_IIC_Start(void);
void IIC1_IIC_Stop(void);
void IIC1_SendACK(uint8_t ack);
uint8_t IIC1_RecvACK(void);
uint8_t IIC1_SendByte(uint8_t dat);
uint8_t IIC1_RecvByte(void);
void IIC1_SendBytes(uint8_t len,uint8_t* dat,uint8_t dev_addr);
void IIC1_RecvBytes(uint8_t len,uint8_t* dat,uint8_t dev_addr);
void IIC1_US_SendBytes(uint8_t len,uint8_t* dat,uint8_t dev_addr,uint8_t reg_addr);
void IIC1_US_RecvBytes(uint8_t len,uint8_t* dat,uint8_t dev_addr,uint8_t reg_addr);





//******************************************************************************
//* 函数名称  : SPI_IOInit()                                        
//* 函数描述  : SPI对应的IO口初始化                           
//* 输入参数  :                                                                 
//* 参数描述  :                                                                 
//* 输出参数  : 无                                                              
//* 返回值    : 无                                                               
//******************************************************************************      
void IIC1_IOInit(void)
{
  GPIO_InitType GPIO_InitStructure;
  IIC1_RCU_GPIO_clock;
  
  GPIO_Structure_Initialize(&GPIO_InitStructure);
  GPIO_InitStructure.Pin                = IIC1_MASTER_SDA_PIN|IIC1_MASTER_CLK_PIN;
  GPIO_InitStructure.GPIO_Mode          = GPIO_MODE_OUT_PP;
  GPIO_InitStructure.GPIO_Pull          = GPIO_PULL_UP;
  GPIO_Peripheral_Initialize(IIC1_MASTER_GPIO, &GPIO_InitStructure);
  
  IIC1_SDA_SET;
  IIC1_SCL_SET;

}

//******************************************************************************
//* 函数名称  : IIC1_SDA_GPIO_OutConfig()                                        
//* 函数描述  : IIC1SDA对应的IO口设置为输出模式                           
//* 输入参数  :                                                                 
//* 参数描述  :                                                                 
//* 输出参数  : 无                                                              
//* 返回值    : 无                                                               
//******************************************************************************      
void IIC1_SDA_GPIO_OutConfig(void)
{
  GPIO_InitType GPIO_InitStructure;
  IIC1_RCU_GPIO_clock;
  
  GPIO_Structure_Initialize(&GPIO_InitStructure);
  GPIO_InitStructure.Pin                = IIC1_MASTER_SDA_PIN;
  GPIO_InitStructure.GPIO_Mode          = GPIO_MODE_OUT_PP;
  GPIO_InitStructure.GPIO_Pull          = GPIO_PULL_UP;
  GPIO_Peripheral_Initialize(IIC1_MASTER_GPIO, &GPIO_InitStructure);
  
}
//******************************************************************************
//* 函数名称  : IIC1_SDA_GPIO_InConfig()                                        
//* 函数描述  : IIC1 SDA对应的IO口设置为输入模式                            
//* 输入参数  :                                                                 
//* 参数描述  :                                                                 
//* 输出参数  : 无                                                              
//* 返回值    : 无                                                               
//******************************************************************************      
void IIC1_SDA_GPIO_InConfig(void)
{
  GPIO_InitType GPIO_InitStructure;
  IIC1_RCU_GPIO_clock;
  
  GPIO_Structure_Initialize(&GPIO_InitStructure);
  GPIO_InitStructure.Pin                = IIC1_MASTER_SDA_PIN;
  GPIO_InitStructure.GPIO_Mode          = GPIO_MODE_INPUT;
  GPIO_InitStructure.GPIO_Pull          = GPIO_PULL_UP;
  GPIO_Peripheral_Initialize(IIC1_MASTER_GPIO, &GPIO_InitStructure);
  
}

//******************************************************************************
//* 函数名称  : IIC1_SCL_GPIO_OutConfig()                                        
//* 函数描述  : IIC1SCL对应的IO口设置为输出模式                           
//* 输入参数  :                                                                 
//* 参数描述  :                                                                 
//* 输出参数  : 无                                                              
//* 返回值    : 无                                                               
//******************************************************************************      
void IIC1_SCL_GPIO_OutConfig(void)
{
  GPIO_InitType GPIO_InitStructure;
  IIC1_RCU_GPIO_clock;
  
  GPIO_Structure_Initialize(&GPIO_InitStructure);
  GPIO_InitStructure.Pin                = IIC1_MASTER_CLK_PIN;
  GPIO_InitStructure.GPIO_Mode          = GPIO_MODE_INPUT;
  GPIO_InitStructure.GPIO_Pull          = GPIO_PULL_UP;
  GPIO_Peripheral_Initialize(IIC1_MASTER_GPIO, &GPIO_InitStructure);
}

//******************************************************************************
//* 函数名称  : IIC1_IIC_Init()                                                      
//* 函数描述  : IIC初始化                                                       
//* 输入参数  :                                                                  
//* 参数描述  :                                                                  
//* 输出参数  : 无                                                               
//* 返回值    : 无                                                               
//******************************************************************************     
void IIC1_IIC_Init(void)
{
  IIC1_SDA_INITOut;
//  IIC1_IIC_Stop();
  IIC1_SDA_RESET;
  IIC1_SCL_RESET;
}

//******************************************************************************
//* 函数名称  : IIC1_IIC_Start()                                                     
//* 函数描述  : I2C1开始信号                                                      
//* 输入参数  :                                                                  
//* 参数描述  :                                                                  
//* 输出参数  : 无                                                               
//* 返回值    : 无                                                             
//******************************************************************************     
void IIC1_IIC_Start(void)
{ 
  IIC1_SDA_SET;
  delay_us(8);
  IIC1_SCL_SET;
  delay_us(14);
  IIC1_SDA_RESET;
  delay_us(14);
  IIC1_SCL_RESET;
  delay_us(14);
}

//******************************************************************************
//* 函数名称  : IIC1_IIC_Stop(void)                                                 
//* 函数描述  : IIC停止信号                                                    
//* 输入参数  :                                                                  
//* 参数描述  :                                                                  
//* 输出参数  : 无                                                              
//* 返回值    : 无                                                              
//******************************************************************************     
void IIC1_IIC_Stop(void)
{
  IIC1_SDA_RESET;
  delay_us(14);
  IIC1_SCL_SET; 
  delay_us(8);
  IIC1_SDA_SET;
  delay_us(14);
}

//******************************************************************************
//* 函数名称  : IIC1_SendACK(uint8_t ack)                                    
//* 函数描述  : 发送应答信号                                                    
//* 输入参数  :ack (0:ACK 1:NAK)                                                
//* 参数描述  :                                                                 
//* 输出参数  : 无                                                               
//* 返回值    : 无                                                               
//******************************************************************************     
void IIC1_SendACK(uint8_t ack)  
{ 
  IIC1_SDA_INITOut;
  if(ack == 0)
  IIC1_SDA_RESET;                                                              //写应答信号 
  else
  IIC1_SDA_SET;  
  delay_us(14);
  IIC1_SCL_SET;                                                                //拉高时钟线  
  delay_us(14);                                                           //延时  
  IIC1_SCL_RESET;                                                              //拉低时钟线  
  delay_us(14);                                                           //延时    
} 

//******************************************************************************
//* 函数名称  : uint8_t IIC1_RecvACK(void)                                        
//* 函数描述  : 接收应答信号                                                   
//* 输入参数  :                                                                 
//* 参数描述  :                                                                  
//* 输出参数  : RecvACK                                                        
//* 返回值    : 无                                                              
//******************************************************************************  
uint8_t IIC1_RecvACK(void)  
{  
  
  uint8_t RecvACK;
    
  IIC1_SDA_INITIn;                                                    //SDA接口为输入
  delay_us(8);
  IIC1_SCL_SET;                                                                //拉高时钟线  
  delay_us(8);                                                           //延时  
  RecvACK = IIC1_ReadSDA;                                                      //读应答信号  
  IIC1_SCL_RESET;                                                              //拉低时钟线  
  delay_us(8);                                                           //延时 
  IIC1_SDA_INITOut;
    
  return RecvACK;
    
} 

//******************************************************************************
//* 函数名称  : void IIC1_SendByte(uint8_t dat)                                
//* 函数描述  : 向设备发送一个数据                                         
//* 输入参数  :                                                                  
//* 参数描述  :                                                                 
//* 输出参数  : 无                                                               
//* 返回值    : 无                                                               
//****************************************************************************** 
uint8_t IIC1_SendByte(uint8_t dat)  
{  
  uint8_t datsendbit;
  uint8_t RecvACK;
   
  for (uint8_t i=0; i<8; i++)                                                   //8位计数器  
  {  
    datsendbit = ((dat & 0x80) >> 7);
    dat <<= 1;                                                                  //移出数据的最高位 
    if(datsendbit == 1)
    {
      IIC1_SDA_SET;
    }
    if(datsendbit == 0)
    {
      IIC1_SDA_RESET;
    }                                                                           //送数据口 
    delay_us(8);
    IIC1_SCL_SET;                                                               //拉高时钟线  
    delay_us(8);                                                                //延时  
    IIC1_SCL_RESET;                                                             //拉低时钟线
    delay_us(8);  
  } 
  RecvACK = IIC1_RecvACK();
  return RecvACK;  
} 

//******************************************************************************
//* 函数名称  : IIC1_RecvByte()                                           
//* 函数描述  : IIC1接收一个数据                                                
//* 输入参数  :dat                                                               
//* 参数描述  :                                                                  
//* 输出参数  : 无                                                               
//* 返回值    : 无                                                               
//******************************************************************************
uint8_t IIC1_RecvByte(void)  
{    
  uint8_t RecvDat = 0;
  
  IIC1_SDA_INITIn; 
  for (uint8_t i=0; i<8; i++)                                                   //8位计数器  
  {  
    RecvDat <<= 1;
    IIC1_SCL_SET;                                                               //拉高时钟线  
    delay_us(10);                                                               //延时 
    RecvDat |= (IIC1_ReadSDA);
    IIC1_SCL_RESET;                                                             //拉低时钟线  
    delay_us(10);                                                               //延时   
  }
  IIC1_SDA_INITOut;
  return RecvDat; 
      
}

//******************************************************************************
//* 函数名称  : void IIC1_SendByte(uint8_t dat)                                
//* 函数描述  : IIC1向设备发送多个数据                                         
//* 输入参数  :                                                                  
//* 参数描述  :                                                                 
//* 输出参数  : 无                                                               
//* 返回值    : 无                                                               
//******************************************************************************
void IIC1_SendBytes(uint8_t len,uint8_t* dat,uint8_t dev_addr)  
{  
  uint8_t ack = 0;
  IIC1_IIC_Start();
  IIC1_SendByte(dev_addr<<1);
  
  for(uint8_t i = 0; i < len; i++) 
  {
    ack = IIC1_SendByte(*(dat+i));
  }
  IIC1_IIC_Stop();
}


//******************************************************************************
//* 函数名称  : IIC1_SendBytes                               
//* 函数描述  : IIC1从设备接收多个数据                                         
//* 输入参数  :                                                                  
//* 参数描述  :                                                                 
//* 输出参数  : 无                                                               
//* 返回值    : 无                                                               
//******************************************************************************  
void IIC1_RecvBytes(uint8_t len,uint8_t* dat,uint8_t dev_addr) 
{  
  IIC1_IIC_Start();
  IIC1_SendByte((dev_addr<<1)+1);
  
  for(uint8_t i = 0; i < len; i++) 
  {
    *(dat+i) = IIC1_RecvByte();
    
    if(i == (len - 1))
    {
      IIC1_SendACK(1);
    }
    else
    {
      IIC1_SendACK(0);
    }
  }
  IIC1_IIC_Stop();
}

//******************************************************************************
//* 函数名称  : void IIC1_US_SendBytes(uint8_t dat)                                
//* 函数描述  : IIC1向设备固定开始地址连续发送数据                                         
//* 输入参数  :                                                                  
//* 参数描述  :                                                                 
//* 输出参数  : 无                                                               
//* 返回值    : 无                                                               
//******************************************************************************
void IIC1_US_SendBytes(uint8_t len,uint8_t* dat,uint8_t dev_addr,uint8_t reg_addr)  
{  
  uint8_t ack = 0;
  IIC1_IIC_Start();
  IIC1_SendByte(dev_addr<<1);
  IIC1_SendByte(reg_addr);

  for(uint8_t i = 0; i < len; i++) 
  {
    ack = IIC1_SendByte(*(dat+i));
  }
  IIC1_IIC_Stop();
}


//******************************************************************************
//* 函数名称  : IIC1_US_RecvBytes                               
//* 函数描述  : IIC1从设备固定地址连续接收数据                                         
//* 输入参数  :                                                                  
//* 参数描述  :                                                                 
//* 输出参数  : 无                                                               
//* 返回值    : 无                                                               
//******************************************************************************  
void IIC1_US_RecvBytes(uint8_t len,uint8_t* dat,uint8_t dev_addr,uint8_t reg_addr) 
{  
  IIC1_IIC_Start();
  IIC1_SendByte(dev_addr<<1);
  IIC1_SendByte(reg_addr);
  
  IIC1_IIC_Start();
  IIC1_SendByte((dev_addr<<1)+1);
  for(uint8_t i = 0; i < len; i++) 
  {
    *(dat+i) = IIC1_RecvByte();
    
    if(i == (len - 1))
    {
      IIC1_SendACK(1);
    }
    else
    {
      IIC1_SendACK(0);
    }
  }
  IIC1_IIC_Stop();
}

        硬件IIC测试了一下,没有完全成功,能够读取到数据但是是错误的,这个比读出来都是FF进了一步,而且还需要分别设计这两种传感器的模式,和软件模拟的方式并没有明显的优势,,所以也就不纠结了,也洗完大家可以帮忙指针一下问题。

硬件IIC代码如下:

//******************************************************************************
//* 函数名称  : IIC1_IOInit                               
//* 函数描述  : IIC1初始化及IO口初始化                                         
//* 输入参数  :                                                                  
//* 参数描述  :                                                                 
//* 输出参数  : 无                                                               
//* 返回值    : 无                                                               
//******************************************************************************
void IIC1_IOInit(void)
{
  I2C_InitType i2c1_master;
  GPIO_InitType i2c1_gpio;
  RCC_APB1_Peripheral_Clock_Enable(RCC_APB1_PERIPH_I2C1);
  RCC_AHB_Peripheral_Clock_Enable(IIC1_MASTER_PERIPH_GPIO);

  GPIO_Structure_Initialize(&i2c1_gpio);
  /*PD13 -- SCL; PD12 -- SDA*/
  i2c1_gpio.Pin            = IIC1_MASTER_SDA_PIN | IIC1_MASTER_CLK_PIN;
  i2c1_gpio.GPIO_Slew_Rate = GPIO_SLEW_RATE_FAST; 
  i2c1_gpio.GPIO_Mode      = GPIO_MODE_AF_OD;
  i2c1_gpio.GPIO_Alternate = GPIO_AF7_I2C1;
  i2c1_gpio.GPIO_Pull      = GPIO_PULL_UP; 
  GPIO_Peripheral_Initialize(IIC1_MASTER_GPIO, &i2c1_gpio);

  I2C_Reset(I2C1);
  I2C_Initializes_Structure(&i2c1_master);
  i2c1_master.BusMode     = I2C_BUSMODE_I2C;
  i2c1_master.DutyCycle   = I2C_SMDUTYCYCLE_1; 
  i2c1_master.OwnAddr1    = 0x76;
  i2c1_master.AckEnable   = I2C_ACKEN;
  i2c1_master.AddrMode    = I2C_ADDR_MODE_7BIT;
  i2c1_master.ClkSpeed    = 100000; /* 100k */

  I2C_Initializes(I2C1, &i2c1_master);

  I2C_ON(I2C1);
}

//******************************************************************************
//* 函数名称  : IIC1_IIC_Init()                                                      
//* 函数描述  : IIC初始化                                                       
//* 输入参数  :                                                                  
//* 参数描述  :                                                                  
//* 输出参数  : 无                                                               
//* 返回值    : 无                                                               
//******************************************************************************     
void IIC1_IIC_Init(void)
{
  I2C_Generate_Stop_Enable(I2C1);
}

//******************************************************************************
//* 函数名称  : void IIC1_SendBytes(uint8_t dat)                                
//* 函数描述  : IIC1向设备固定开始地址连续发送数据                                         
//* 输入参数  :                                                                  
//* 参数描述  :                                                                 
//* 输出参数  : 无                                                               
//* 返回值    : 无                                                               
//******************************************************************************
void IIC1_SendBytes(uint8_t len,uint8_t* dat,uint8_t dev_addr)  
{  
  uint8_t* sendBufferPtr = dat;
  I2CTimeout = I2CT_LONG_TIMEOUT;
  while (I2C_Flag_Status_Get(I2C1, I2C_FLAG_BUSY))
  {
    if ((I2CTimeout--) == 0)
    {
      break;
    }
  }
  I2C_Generate_Start_Enable(I2C1);
  
  I2CTimeout = I2CT_LONG_TIMEOUT;
  while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_MODE_FLAG)) /* EV5 */
  {
    if ((I2CTimeout--) == 0)
    {
      break;
    }
  }
  
  I2C_7bit_Addr_Send(I2C1, dev_addr, I2C_DIRECTION_SEND);   
  I2CTimeout = I2CT_LONG_TIMEOUT;
  while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_TXMODE_FLAG)) /* EV6 */
  {
    if ((I2CTimeout--) == 0)
    {
      break;
    }
  }
  
//  I2C_Data_Send(I2C1,reg_addr);
//  I2CTimeout = I2CT_LONG_TIMEOUT;
//  while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_SENDING)) /* EV6 */
//  {
//    if ((I2CTimeout--) == 0)
//    {
//      break;
//    }
//  }

/* send data */
  while (len-- > 0)
  {
    I2C_Data_Send(I2C1, *sendBufferPtr++);
    I2CTimeout = I2CT_LONG_TIMEOUT;
    while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_SENDING)) /* EV8 */
    {
      if ((I2CTimeout--) == 0)
      {
        break;
      }
    }
  }

  I2CTimeout = I2CT_LONG_TIMEOUT;
  while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_SENDED)) /* EV8-2 */
  {
    if ((I2CTimeout--) == 0)
    {
      break;
    }
  }
  I2C_Generate_Stop_Enable(I2C1);
  
  while (I2C_Flag_Status_Get(I2C1, I2C_FLAG_BUSY))
  {
    if ((I2CTimeout--) == 0)
    {
      break;
    }
  }
}

//******************************************************************************
//* 函数名称  : IIC1_RecvBytes                               
//* 函数描述  : IIC1从设备固定地址连续接收数据                                         
//* 输入参数  :                                                                  
//* 参数描述  :                                                                 
//* 输出参数  : 无                                                               
//* 返回值    : 无                                                               
//******************************************************************************  
void IIC1_RecvBytes(uint8_t len,uint8_t* dat,uint8_t dev_addr) 
{
  uint8_t* recvBufferPtr = dat;
  
  I2CTimeout             = I2CT_LONG_TIMEOUT;
  while (I2C_Flag_Status_Get(I2C1, I2C_FLAG_BUSY))
  {
    if ((I2CTimeout--) == 0)
    {
      break;
    }
  }
  I2C_Acknowledg_Enable(I2C1);

  /* send start */
  I2C_Generate_Start_Enable(I2C1);
  
  I2CTimeout = I2CT_LONG_TIMEOUT;
  while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_MODE_FLAG)) /* EV5 */
  {
    if ((I2CTimeout--) == 0)
    {
      break;
    }
  }
  /* send addr */
  I2C_7bit_Addr_Send(I2C1, dev_addr, I2C_DIRECTION_RECV);
  I2CTimeout = I2CT_LONG_TIMEOUT;
  while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_RXMODE_FLAG)) /* EV6 */
  {
    if ((I2CTimeout--) == 0)
    {
      break;
    }
  }
  
//  I2C_Data_Send(I2C1,reg_addr);
//  I2CTimeout = I2CT_LONG_TIMEOUT;
//  while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_SENDING)) /* EV6 */
//  {
//    if ((I2CTimeout--) == 0)
//    {
//      break;
//    }
//  }

  if (len == 1)
  {
    I2C_Acknowledg_Disable(I2C1);
    (void)(I2C1->STS1); /*/ clear ADDR */
    (void)(I2C1->STS2);
    I2C_Generate_Stop_Enable(I2C1);
    
    I2CTimeout = I2CT_LONG_TIMEOUT;
    while (!I2C_Flag_Status_Get(I2C1, I2C_FLAG_RXDATNE))
    {
      if ((I2CTimeout--) == 0)
      {
        break;
      }
    }
    *recvBufferPtr++ = I2C_Data_Recv(I2C1);
    len--;
  }
  else if (len == 2)
  {
    I2C1->CTRL1 |= 0x0800; /*/ set ACKPOS */
    (void)(I2C1->STS1);
    (void)(I2C1->STS2);
    I2C_Acknowledg_Disable(I2C1);
    
    I2CTimeout = I2CT_LONG_TIMEOUT;
    while (!I2C_Flag_Status_Get(I2C1, I2C_FLAG_BYTEF))
    {
      if ((I2CTimeout--) == 0)
      {
        break;
      }
    }

    I2C_Generate_Stop_Enable(I2C1);
    
    *recvBufferPtr++ = I2C_Data_Recv(I2C1);
    len--;
    *recvBufferPtr++ = I2C_Data_Recv(I2C1);
    len--;
  }
  else
  {
    I2C_Acknowledg_Enable(I2C1);
    (void)(I2C1->STS1);
    (void)(I2C1->STS2);
    
    while (len)
    {
      if (len == 3)
      {
        I2CTimeout = I2CT_LONG_TIMEOUT;
        while (!I2C_Flag_Status_Get(I2C1, I2C_FLAG_BYTEF))
        {
          if ((I2CTimeout--) == 0)
          {
            break;
          }
        }
        I2C_Acknowledg_Disable(I2C1);
        *recvBufferPtr++ = I2C_Data_Recv(I2C1);
        len--;
        
        I2CTimeout = I2CT_LONG_TIMEOUT;
        while (!I2C_Flag_Status_Get(I2C1, I2C_FLAG_BYTEF))
        {
          if ((I2CTimeout--) == 0)
          {
            break;
          }
        }
        I2C_Generate_Stop_Enable(I2C1);

        *recvBufferPtr++ = I2C_Data_Recv(I2C1);
        len--;
        *recvBufferPtr++ = I2C_Data_Recv(I2C1);
        len--;
        
        break;
      }
        
      I2CTimeout = I2CT_LONG_TIMEOUT;
      while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_RECVD_FLAG)) /* EV7 */
      {
        if ((I2CTimeout--) == 0)
        {
          break;
        }
      }
      *recvBufferPtr++ = I2C_Data_Recv(I2C1);
      len--;
    }
  }
  
  I2CTimeout = I2CT_LONG_TIMEOUT;
  while (I2C_Flag_Status_Get(I2C1, I2C_FLAG_BUSY))
  {
    if ((I2CTimeout--) == 0)
    {
      break;
    }
  }
  
}

//******************************************************************************
//* 函数名称  : void IIC1_US_SendBytes(uint8_t dat)                                
//* 函数描述  : IIC1向设备固定开始地址连续发送数据                                         
//* 输入参数  :                                                                  
//* 参数描述  :                                                                 
//* 输出参数  : 无                                                               
//* 返回值    : 无                                                               
//******************************************************************************
void IIC1_US_SendBytes(uint8_t len,uint8_t* dat,uint8_t dev_addr,uint8_t reg_addr)  
{  
  uint8_t* sendBufferPtr = dat;
  I2CTimeout = I2CT_LONG_TIMEOUT;
  while (I2C_Flag_Status_Get(I2C1, I2C_FLAG_BUSY))
  {
    if ((I2CTimeout--) == 0)
    {
      break;
    }
  }
  I2C_Generate_Start_Enable(I2C1);
  
  I2CTimeout = I2CT_LONG_TIMEOUT;
  while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_MODE_FLAG)) /* EV5 */
  {
    if ((I2CTimeout--) == 0)
    {
      break;
    }
  }
  
  I2C_7bit_Addr_Send(I2C1, dev_addr, I2C_DIRECTION_SEND);   
  I2CTimeout = I2CT_LONG_TIMEOUT;
  while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_TXMODE_FLAG)) /* EV6 */
  {
    if ((I2CTimeout--) == 0)
    {
      break;
    }
  }
  
  I2C_Data_Send(I2C1,reg_addr);
  I2CTimeout = I2CT_LONG_TIMEOUT;
  while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_SENDING)) /* EV6 */
  {
    if ((I2CTimeout--) == 0)
    {
      break;
    }
  }

/* send data */
  while (len-- > 0)
  {
    I2C_Data_Send(I2C1, *sendBufferPtr++);
    I2CTimeout = I2CT_LONG_TIMEOUT;
    while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_SENDING)) /* EV8 */
    {
      if ((I2CTimeout--) == 0)
      {
        break;
      }
    }
  }

  I2CTimeout = I2CT_LONG_TIMEOUT;
  while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_SENDED)) /* EV8-2 */
  {
    if ((I2CTimeout--) == 0)
    {
      break;
    }
  }
  I2C_Generate_Stop_Enable(I2C1);
  
  while (I2C_Flag_Status_Get(I2C1, I2C_FLAG_BUSY))
  {
    if ((I2CTimeout--) == 0)
    {
      break;
    }
  }
}

//******************************************************************************
//* 函数名称  : IIC1_US_RecvBytes                               
//* 函数描述  : IIC1从设备固定地址连续接收数据                                         
//* 输入参数  :                                                                  
//* 参数描述  :                                                                 
//* 输出参数  : 无                                                               
//* 返回值    : 无                                                               
//******************************************************************************  
void IIC1_US_RecvBytes(uint8_t len,uint8_t* dat,uint8_t dev_addr,uint8_t reg_addr) 
{
  uint8_t* recvBufferPtr = dat;
  
  I2CTimeout             = I2CT_LONG_TIMEOUT;
  while (I2C_Flag_Status_Get(I2C1, I2C_FLAG_BUSY))
  {
    if ((I2CTimeout--) == 0)
    {
      break;
    }
  }
  I2C_PEC_Position_Set(I2C1, I2C_PEC_POS_CURRENT);
  I2C_Acknowledg_Enable(I2C1);

  /* send start */
  I2C_Generate_Start_Enable(I2C1);
  
  I2CTimeout = I2CT_LONG_TIMEOUT;
  while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_MODE_FLAG)) /* EV5 */
  {
    if ((I2CTimeout--) == 0)
    {
      break;
    }
  }
  /* send addr */
  I2C_7bit_Addr_Send(I2C1, dev_addr, I2C_DIRECTION_SEND);
  I2CTimeout = I2CT_LONG_TIMEOUT;
  while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_TXMODE_FLAG)) /* EV6 */
  {
    if ((I2CTimeout--) == 0)
    {
      break;
    }
  }
  /** Clear EV6 by setting again the PE bit */
  I2C_ON(I2C1);
  /** Send the address to write to */
  I2C_Data_Send(I2C1,reg_addr);
  I2CTimeout = I2CT_LONG_TIMEOUT;
  while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_SENDING)) /* EV6 */
  {
    if ((I2CTimeout--) == 0)
    {
      break;
    }
  }
  
  /* send start */
  I2C_Generate_Start_Enable(I2C1);
  
  I2CTimeout = I2CT_LONG_TIMEOUT;
  while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_MODE_FLAG)) /* EV5 */
  {
    if ((I2CTimeout--) == 0)
    {
      break;
    }
  }
  
  I2C_7bit_Addr_Send(I2C1, dev_addr, I2C_DIRECTION_RECV);
  /* Test on EV6 and clear it */
  I2CTimeout = I2CT_LONG_TIMEOUT;
  while (!I2C_Flag_Status_Get(I2C1, I2C_FLAG_ADDRF))    //EV6
  {
    if ((I2CTimeout--) == 0)
      break;
  }

  if (len == 1)
  {
    I2C_Acknowledg_Disable(I2C1);
    (void)(I2C1->STS1); /*/ clear ADDR */
    (void)(I2C1->STS2);
    
    /** Generates START condition to close communication */
    I2C_Generate_Start_Enable(I2C1);
  }
  else
  {
    (void)(I2C1->STS1); /*/ clear ADDR */
    (void)(I2C1->STS2);
  
  }
  
  while (len)
  {
    if(len <= 2)
    {
      if(len == 1)
      {
        /** Wait until RXNE flag is set */
        I2CTimeout = I2CT_LONG_TIMEOUT;
        while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_RECVD_FLAG))
        {
          if ((I2CTimeout--) == 0)
            break;
        }
        /** Read data from DAT */
        *recvBufferPtr = I2C_Data_Recv(I2C1);
        /** Point to the next location where the byte read will be saved */
        recvBufferPtr++;
        /** Decrement the read bytes counter */
        len--;
         /** Generates STOP condition to release SCL/SDA line */
        I2C_Generate_Stop_Enable(I2C1);
      }
      else
      {
        /** Wait until RXNE flag is set */
        I2CTimeout = I2CT_LONG_TIMEOUT;
        while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_RECVD_FLAG))
        {
          if ((I2CTimeout--) == 0)
            break;
        }
        /** Disable Acknowledgement */ 
        I2C_Acknowledg_Disable(I2C1);
                       
        /** Read data from DAT */
        *recvBufferPtr = I2C_Data_Recv(I2C1);
        /** Point to the next location where the byte read will be saved */
        recvBufferPtr++;
        /** Decrement the read bytes counter */
        len--;
        
        /** Generates START condition to close communication */
        I2C_Generate_Start_Enable(I2C1);
        
        while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_RECVD_FLAG))
        {
          if((I2CTimeout--) == 0)
            break;
        }                                                 
        /** Read data from DAT */
        *recvBufferPtr = I2C_Data_Recv(I2C1);              
        /** Point to the next location where the byte read will be saved */
        recvBufferPtr++;
        /** Decrement the read bytes counter */
        len--;
        
        /** Generates STOP condition to release SCL/SDA line */
        I2C_Generate_Stop_Enable(I2C1);
      
      }
    }
    else
    {
      /** Test on EV7 and clear it */
      I2CTimeout = I2CT_LONG_TIMEOUT;
      while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_RECVD_FLAG))
      {
        if((I2CTimeout--) == 0)
          break;
      }
      /** Read a byte from the EEPROM */
      *recvBufferPtr = I2C_Data_Recv(I2C1);
      /** Point to the next location where the byte read will be saved */
      recvBufferPtr++;
      /** Decrement the read bytes counter */
      len--;
      if (I2C_Flag_Status_Get(I2C1, I2C_FLAG_BYTEF))
      {
          /** Read a byte from the EEPROM */
          *recvBufferPtr = I2C_Data_Recv(I2C1);
          /** Point to the next location where the byte read will be saved */
          recvBufferPtr++;
          /** Decrement the read bytes counter */
          len--;
      }
    
    }
  }
}

        在进行传感器数据采集时出现了一个插曲,FLASH超了,本次测评的MCU只有64K的FLASH,所以使用的全彩的论坛图标就显得有点大了,只能忍痛去掉了。

三、串口测试

        这次的串口测试主要通过与NB-Iot模块的通信进行,获取模块的两个重要的身份识别码。本次依然采用空闲中断+DMA的方式进行,这种方式非常适用这种不定长的串口通信过程,大大减小多次串口中断对系统运行的干扰,由于时间原因,没有继续探究,串口通信没成功。

        在这里发现了一个困扰,如下图:

同样是DMA的demo,USART2的Tx对应的通道确实不一样的,在用户手册中也没有完整的对应关系,0x03: USART2_TX 0x04: USART2_RX,和demo中表述模式是不一样,这样很容易产生歧义,在之前也有提到,驱动程序中对各个字段的定义也是不全面的,对于小白来说很不友好。

串口初始化代码:

//******************************************************************************
//* 函数名称  : USART2_init
//* 函数描述  : 串口2的初始化
//* 输入参数  :
//* 参数描述  : 对应    引脚初始化及配置
//* 输出参数  : 无
//* 返回值    : 无
//******************************************************************************
void USART2_init(void)
{
  GPIO_InitType GPIO_InitStructure;
  NVIC_InitType NVIC_InitStructure;
  USART_InitType USART_InitStructure;
  /* Initialize GPIO_InitStructure */
  RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOA);
  RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_AFIO);
  RCC_APB1_Peripheral_Clock_Enable(RCC_APB1_PERIPH_USART2);
  
  GPIO_Structure_Initialize(&GPIO_InitStructure);
  /* Configure USARTz Tx as alternate function push-pull */
  GPIO_InitStructure.GPIO_Mode            = GPIO_MODE_AF_PP;
  GPIO_InitStructure.Pin            = GPIO_PIN_3|GPIO_PIN_2;
  GPIO_InitStructure.GPIO_Alternate = GPIO_AF5_USART2;
  GPIO_Peripheral_Initialize(GPIOA, &GPIO_InitStructure);
    
  /* USART2 configuration---------*/
  USART_InitStructure.BaudRate            = 115200;
  USART_InitStructure.WordLength          = USART_WL_8B;
  USART_InitStructure.StopBits            = USART_STPB_1;
  USART_InitStructure.Parity              = USART_PE_NO;
  USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
  USART_InitStructure.Mode                = USART_MODE_RX | USART_MODE_TX;
  USART_Initializes(USART2, &USART_InitStructure);

  /* Enable the USARTy Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel                    = USART2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority   = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority         = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd                 = ENABLE;
  NVIC_Initializes(&NVIC_InitStructure);
  
  USART2_DMA1_config();
  USART_DMA_Transfer_Enable(USART2,USART_DMAREQ_RX);

  /* Enable USARTz Receive and Transmit interrupts */
  USART_Interrput_Enable(USART2, USART_INT_IDLEF);
  USART_Enable(USART2);

}

//******************************************************************************
//* 函数名称  : USART2_DMA1_config
//* 函数描述  : 串口2 DMA接收配置
//* 输入参数  :
//* 参数描述  : 对应    引脚初始化及配置
//* 输出参数  : 无
//* 返回值    : 无
//******************************************************************************
void USART2_DMA1_config(void)
{
  DMA_InitType DMA_InitStructure;
  /* DMA clock enable */
  RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_DMA);

  /* USARTy TX DMA1 Channel (triggered by USARTy Tx event) Config */
  DMA_Reset(DMA_CH4);
  DMA_InitStructure.PeriphAddr     = (uint32_t)&(USART2->DAT);
  DMA_InitStructure.MemAddr        = (uint32_t)USART2RecePackBuf;
  DMA_InitStructure.Direction      = DMA_DIR_PERIPH_SRC;//外设到内存
  DMA_InitStructure.BufSize        = 64;
  DMA_InitStructure.PeriphInc      = DMA_PERIPH_INC_MODE_DISABLE;//外设地址不增加
  DMA_InitStructure.MemoryInc      = DMA_MEM_INC_MODE_ENABLE;//内存地址递增
  DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_WIDTH_BYTE;//外设数据长度
  DMA_InitStructure.MemDataSize    = DMA_MEM_DATA_WIDTH_BYTE;//8位数据
  DMA_InitStructure.CircularMode   = DMA_CIRCULAR_MODE_DISABLE;
  DMA_InitStructure.Priority       = DMA_CH_PRIORITY_HIGHEST;//最高DMA通道
  DMA_InitStructure.Mem2Mem        = DMA_MEM2MEM_DISABLE;
  DMA_Initializes(DMA_CH4, &DMA_InitStructure);
  
  DMA_Channel_Request_Remap(DMA_CH4,DMA_REMAP_USART2_RX);
  /* Enable USART RX DMA Channel */
  DMA_Channel_Enable(DMA_CH4);

}

        总感觉缺点东西,网上的资料也非常少。

        经过不断的定位测试发现还是DMA没有正常,不过配置都是正确的,少了一个USART_DMA_Transfer_Enable(USART2,USART_DMAREQ_RX);,加上后就能实现空闲中断加DMA收不定长数据了。进过测试确定CH4通道对应串口2的Rx是正确的,所以DMA_Polling对应的配置有误。

综合视频:

DSC_0167

 

 

 

 

 

 

 

 

 

 

 

 

 

最新回复

解决啦,我没有重新把这些时间数据放到新的数组中,加一步赋值操作就不用跳了。   详情 回复 发表于 2023-12-21 18:30
点赞 关注
个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 
 

回复
举报

6533

帖子

9

TA的资源

版主

沙发
 

最挫败的一次

 
 
 

回复

7042

帖子

11

TA的资源

版主

板凳
 
版主大佬真的很用心做每一次评测,是我们学习的版样!

点评

老哥有测试串口吗、感觉demo里有很多冲突的地方  详情 回复 发表于 2022-10-25 09:41
 
 
 

回复

6533

帖子

9

TA的资源

版主

4
 
lugl4313820 发表于 2022-10-25 07:14 版主大佬真的很用心做每一次评测,是我们学习的版样!

老哥有测试串口吗、感觉demo里有很多冲突的地方

个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

5
 

大佬在测试RTC的时候有出现年份跟月份跳变的情况嘛?我照着您的这版程序写了一下,发现跑在线调试时读取出来的年份会不定期跳变到2035年,月份有时也会跳变。

 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

6
 
modu 发表于 2023-12-21 18:08 大佬在测试RTC的时候有出现年份跟月份跳变的情况嘛?我照着您的这版程序写了一下,发现跑在线调试时读取出 ...

解决啦,我没有重新把这些时间数据放到新的数组中,加一步赋值操作就不用跳了。

 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表