这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » (SD卡+FATFS,进行中)zangchao ARM DIY进程帖

共92条 10/10 |‹ 5 6 7 8 9 10 跳转至
工程师
2012-06-16 20:43:55     打赏
91楼

        实时时钟是一个独立的定时器。RTC模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。 RTC模块和时钟配置系统(RCC_BDCR寄存器)处于后备区域,即在系统复位或从待机模式唤醒后,RTC的设置和时间维持不变。 
        系统复位后,对后备寄存器和RTC的访问被禁止,这是为了防止对后备区域(BKP)的意外写操作。执行以下操作将使能对后备寄存器和RTC的访问: 
       ● 设置寄存器RCC_APB1ENR的PWREN和BKPEN位,使能电源和后备接口时钟 
       ● 设置寄存器PWR_CR的DBP位,使能对后备寄存器和RTC的访问。




附上代码
1 RTC配置代码
/* 秒中断标志,进入秒中断时置1,当时间被刷新之后清0 */
__IO uint32_t TimeDisplay; 

/*
 * 函数名:NVIC_Configuration
 * 描述  :配置RTC秒中断的主中断优先级为1,次优先级为0
 * 输入  :无
 * 输出  :无
 * 调用  :外部调用
 */
void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

  /* Configure one bit for preemption priority */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

  /* Enable the RTC Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

/*
 * 函数名:RTC_Configuration
 * 描述  :配置RTC
 * 输入  :无
 * 输出  :无
 * 调用  :外部调用
 */
void RTC_Configuration(void)
{
  /* Enable PWR and BKP clocks */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

  /* Allow access to BKP Domain */
  PWR_BackupAccessCmd(ENABLE);

  /* Reset Backup Domain */
  BKP_DeInit();

  /* Enable LSE */
  RCC_LSEConfig(RCC_LSE_ON);
  /* Wait till LSE is ready */
  while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
  {}

  /* Select LSE as RTC Clock Source */
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

  /* Enable RTC Clock */
  RCC_RTCCLKCmd(ENABLE);

  /* Wait for RTC registers synchronization */
  RTC_WaitForSynchro();

  /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();

  /* Enable the RTC Second */
  RTC_ITConfig(RTC_IT_SEC, ENABLE);

  /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();

  /* Set RTC prescaler: set RTC period to 1sec */
  RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */

  /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();
}


/*
 * 函数名:Time_Regulate
 * 描述  :返回用户在超级终端中输入的时间值,并将值储存在
 *         RTC 计数寄存器中。
 * 输入  :无
 * 输出  :用户在超级终端中输入的时间值,单位为 s
 * 调用  :内部调用
 */
uint32_t Time_Regulate(void)
{
  uint32_t Tmp_HH = 0xFF, Tmp_MM = 0xFF, Tmp_SS = 0xFF;

  printf("\r\n==============时间设定=====================================");
  printf("\r\n  请设置小时");

  while (Tmp_HH == 0xFF)
  {
    Tmp_HH = USART_Scanf(23);
  }
  printf(":  %d", Tmp_HH);
  printf("\r\n  请设置分钟");
  while (Tmp_MM == 0xFF)
  {
    Tmp_MM = USART_Scanf(59);
  }
  printf(":  %d", Tmp_MM);
  printf("\r\n  请设置秒");
  while (Tmp_SS == 0xFF)
  {
    Tmp_SS = USART_Scanf(59);
  }
  printf(":  %d", Tmp_SS);

  /* Return the value to store in RTC counter register */
  return((Tmp_HH*3600 + Tmp_MM*60 + Tmp_SS));
}


/*
 * 函数名:Time_Adjust
 * 描述  :时间调节
 * 输入  :无
 * 输出  :无
 * 调用  :外部调用
 */
void Time_Adjust(void)
{
  /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();
  /* Change the current time */
  RTC_SetCounter(Time_Regulate());
  /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();
}


/*
 * 函数名:Time_Display
 * 描述  :显示当前时间值
 * 输入  :-TimeVar RTC计数值,单位为 s
 * 输出  :无
 * 调用  :内部调用
 */ 
void Time_Display(uint32_t TimeVar)
{
  uint32_t THH = 0, TMM = 0, TSS = 0;

  /* Compute  hours */
  THH = TimeVar / 3600;
  /* Compute minutes */
  TMM = (TimeVar % 3600) / 60;
  /* Compute seconds */
  TSS = (TimeVar % 3600) % 60;

  printf("\n 当前时间: %0.2d:%0.2d:%0.2d\r\n", THH, TMM, TSS);
}


/*
 * 函数名:Time_Show
 * 描述  :在超级终端中显示当前时间值
 * 输入  :无
 * 输出  :无
 * 调用  :外部调用
 */  
void Time_Show(void)
{
  printf("\n\r");

  /* Infinite loop */
  while (1)
  {
    /* If 1s has paased */
    if (TimeDisplay == 1)
    {
      /* Display current time */
      Time_Display(RTC_GetCounter());
      TimeDisplay = 0;
    }
  }
}


/*
 * 函数名:USART_Scanf
 * 描述  :串口从超级终端中获取数值
 * 输入  :- value 用户在超级终端中输入的数值
 * 输出  :无
 * 调用  :内部调用
 */
uint8_t USART_Scanf(uint32_t value)
{
  uint32_t index = 0;
  uint32_t tmp[2] = {0, 0};

  while (index < 2)
  {
    /* Loop until RXNE = 1 */
    while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET)
    {}
    tmp[index++] = (USART_ReceiveData(USART1));
  // 从串口终端里面输进去的数是ASCII码值
    if ((tmp[index - 1] < 0x30) || (tmp[index - 1] > 0x39))
    {
      printf("\n\r请输入从0到9之间的数据");
      index--;
    }
  }
  /* Calculate the Corresponding value */
  index = (tmp[1] - 0x30) + ((tmp[0] - 0x30) * 10);
  /* Checks */
  if (index > value)
  {
    printf("\n\rPlease enter valid number between 0 and %d", value);
    return 0xFF;
  }
  return index;
}
2 USART配置代码
void USART1_printf(USART_TypeDef* USARTx, uint8_t *Data,...)
{
 const char *s;
  int d;  
  char buf[16];

  va_list ap;
  va_start(ap, Data);

 while ( *Data != 0)     // 判断是否到达字符串结束符
 {                             
  if ( *Data == 0x5c )  //'\'
  {          
   switch ( *++Data )
   {
    case 'r':                 //回车符
     USART_SendData(USARTx, 0x0d);
     Data ++;
     break;

    case 'n':                 //换行符
     USART_SendData(USARTx, 0x0a); 
     Data ++;
     break;
    
    default:
     Data ++;
        break;
   }   
  }
  else if ( *Data == '%')
  {           //
   switch ( *++Data )
   {    
    case 's':            //字符串
     s = va_arg(ap, const char *);
          for ( ; *s; s++)
     {
      USART_SendData(USARTx,*s);
      while( USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET );
          }
     Data++;
          break;

        case 'd':          //十进制
          d = va_arg(ap, int);
          itoa(d, buf, 10);
          for (s = buf; *s; s++)
     {
      USART_SendData(USARTx,*s);
      while( USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET );
          }
     Data++;
          break;
     default:
      Data++;
        break;
   }  
  } /* end of else if */
  else USART_SendData(USARTx, *Data++);
  while( USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET );
 }
}


工程师
2012-06-17 20:47:19     打赏
92楼
       这次DIY收获很大啊,本科毕设时用过这个STM32做了东西,但是限于时间加上水平不够,没有搞出来,只是把硬件做出来。而这次利用这个板子最大的获益之处就是,调试了CAN和USART的协议转换,自己帮外面做了个小项目,设计了一个板子,小赚了几K,不过创造价值远不止这些,据老师说被奸商剥削太多了,哎,学生就是没有经验。
         上个自己做的板子的图片:

共92条 10/10 |‹ 5 6 7 8 9 10 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]