目前共有2篇帖子。 內容轉換:不轉換▼
 
點擊 回復
614 1
【程序】使用内部低速晶振作为RTC的时钟源(库函数版)
一派護法 十九級
1樓 發表于:2017-3-24 10:45
#include <stm32f10x.h>

uint8_t seg8[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xa7, 0xa1, 0x86, 0x8e};

void ser_in(uint8_t data)
{
    uint8_t i;
    for (i = 0; i < 8; i++)
    {
        GPIO_ResetBits(GPIOB, GPIO_Pin_9); // SCLK=>PB9
        if (data & 0x80)
            GPIO_SetBits(GPIOB, GPIO_Pin_7); // DIO=>PB7
        else
            GPIO_ResetBits(GPIOB, GPIO_Pin_7);
        data <<= 1;
        GPIO_SetBits(GPIOB, GPIO_Pin_9);
    }
}

void par_out(void)
{
    GPIO_ResetBits(GPIOB, GPIO_Pin_8); // RCLK=>PB8
    GPIO_SetBits(GPIOB, GPIO_Pin_8);
}

int main(void)
{
    GPIO_InitTypeDef gpio;
    TIM_TimeBaseInitTypeDef tim;
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP | RCC_APB1Periph_TIM6, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    
    PWR_BackupAccessCmd(ENABLE); // 允许写入Backup寄存器
    RCC_BackupResetCmd(ENABLE); // 复位Backup Domain
    RCC_BackupResetCmd(DISABLE); // 必须清除复位标志, 否则下面的RCC_RTCCLKConfig函数会执行失败
    
    //RCC_ITConfig(RCC_IT_LSIRDY, ENABLE); // 开LSI就绪中断
    //NVIC_EnableIRQ(RCC_IRQn);
    
    RCC_LSICmd(ENABLE); // 开LSI晶振
    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); // RTC选LSI时钟
    RCC_RTCCLKCmd(ENABLE); // 开RTC时钟
    
    RTC_SetCounter(0x12345678); // 设置新时钟值
    RTC_WaitForLastTask(); // 等待设置完毕
    
    // 数码管扫描管脚配置
    gpio.GPIO_Mode = GPIO_Mode_Out_PP;
    gpio.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
    gpio.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &gpio);
    
    // 数码管扫描中断
    TIM_TimeBaseStructInit(&tim);
    tim.TIM_Period = 24;
    tim.TIM_Prescaler = 7199;
    TIM_TimeBaseInit(TIM6, &tim);
    TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);
    TIM_Cmd(TIM6, ENABLE);
    NVIC_EnableIRQ(TIM6_IRQn);
    
    while (1);
}

void TIM6_IRQHandler(void)
{
    static uint8_t i = 0;
    static uint32_t n;
    if (i == 0)
        n = RTC_GetCounter();
    if (TIM_GetFlagStatus(TIM6, TIM_FLAG_Update) == SET)
    {
        TIM_ClearFlag(TIM6, TIM_FLAG_Update);
        ser_in(seg8[n & 0x0f]);
        ser_in(1 << i);
        par_out();
        n >>= 4;
        i = (i + 1) % 8;
    }
}

/*
void RCC_IRQHandler(void)
{
    if (RCC_GetITStatus(RCC_IT_LSIRDY) == SET)
    {
        RCC_ClearITPendingBit(RCC_IT_LSIRDY); // 清中断标志位
    }
}
*/
一派護法 十九級
2樓 發表于:2017-3-24 10:54
【LSI的40kHz时钟分频成1s的方法】
RTC_SetPrescaler(39999); // 40kHz分频为1Hz
RTC_WaitForLastTask();
RTC_SetCounter(0x12345678); // 设置新时钟值
RTC_WaitForLastTask(); // 等待设置完毕

回復帖子

內容:
用戶名: 您目前是匿名發表
驗證碼:
(快捷鍵:Ctrl+Enter)
 

本帖信息

點擊數:614 回複數:1
評論數: ?
作者:巨大八爪鱼
最後回復:巨大八爪鱼
最後回復時間:2017-3-24 10:54
 
©2010-2024 Arslanbar Ver2.0
除非另有聲明,本站採用創用CC姓名標示-相同方式分享 3.0 Unported許可協議進行許可。