Chia sẻ RTC và stm32f103c8t6

huunho

Thạc sỹ
#1
Chào các bạn.
Chíp STM32F103C8T6 là con chíp được gắn trên mạch nap Stlink v2, là 1 trong những chíp ARM giá rẻ nhưng nó có đủ các chức năng cần thiết cho các ứng dụng cơ bản và 1 vài ứng dụng nâng cao với tốc độ xử lý trung bình 72 Mhz. Ứng dụng cơ bản mà hôm nay mình đề cập tới là thời gian thực.

Thư viện HAL của ST cung cấp cho chúng ta cách cài đặt, sử dụng modun RTC trên F103 rất dễ dàng. Thời gian thực của F103 cho phép chúng ta đọc ghi ngẫu nhiên giờ, phút , giây, thứ ngày tháng năm theo kiểu số BCD hoặc Binary (so thập phân) thông qua các biến kiểu cấu trúc. Chúng ta có thể dùng phương pháp hỏi vòng để cập nhật thời gian. hoặc dùng ngắt sau mỗi giây
Ngoài ra cần phải gắn thạch anh 32.768Khz cho F103 để giữ nhip chính xác cho RTC.

bật LSE để sử dụng thạch anh 32.768jhz
RCC_OscInitStruct.LSEState = RCC_LSE_ON;

Cài đặt ngày giờ và báo thức

/* RTC init function */
void MX_RTC_Init(void)
{

RTC_TimeTypeDef sTime; // biến cấu trúc giờ
RTC_DateTypeDef DateToUpdate; // biến cấu trúc ngày
RTC_AlarmTypeDef sAlarm; // biến cấu trúc báo thức

/**Initialize RTC and set the Time and Date
*/
hrtc.Instance = RTC;
hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND;
hrtc.Init.OutPut = RTC_OUTPUTSOURCE_ALARM;
HAL_RTC_Init(&hrtc);

sTime.Hours = 0;
sTime.Minutes = 0;
sTime.Seconds = 0;
HAL_RTC_SetTime(&hrtc, &sTime, FORMAT_BCD); // cai bdat thoi gian voi dinh dang BCD

DateToUpdate.WeekDay = RTC_WEEKDAY_MONDAY;
DateToUpdate.Month = RTC_MONTH_JANUARY;
DateToUpdate.Date = 1;
DateToUpdate.Year = 0;
HAL_RTC_SetDate(&hrtc, &DateToUpdate, FORMAT_BCD); cai đặt ngày với dịnh dạng BCD

/**Enable the Alarm A
*/
sAlarm.AlarmTime.Hours = 0;
sAlarm.AlarmTime.Minutes = 0;
sAlarm.AlarmTime.Seconds = 5;
sAlarm.Alarm = RTC_ALARM_A;
HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, FORMAT_BCD); // cai đặt báo thức A với thời gian báo là 0:0:5
tức là khi đến thời điểm trên sẽ có ngắt báo thức sinh ra và có 1 xung vuông trên chân PC13

}

hàm sau truy cập thời gian theo cách hỏi vòng là tốn tài nghuyên của chíp: Mỗi lần thời gian thay đổi thì chân B5 bị đảo trạng thái
void MX(void)
{
static uint8_t i;
RTC_TimeTypeDef sTime;
HAL_RTC_GetTime(&hrtc,&sTime,FORMAT_BCD);
if(i!= sTime.Seconds)
{
i = sTime.Seconds;
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);
}
}
 
Sửa lần cuối:

huunho

Thạc sỹ
#2
Cuối cùng là Project đã chạy ngon trên mạch thật, được viết trên keil c v5 và cubemx. code này dung hỏi vong để cập nhật thời gian
 

Đính kèm

Sửa lần cuối:

huunho

Thạc sỹ
#3
Chỉ cần đặt lệnh sau trước vòng lặp While là các bạn đã có 1 ngắt sau mỗi giây để cập nhạt thời gian:
/* USER CODE BEGIN 2 */
HAL_RTCEx_SetSecond_IT(&hrtc);
/* USER CODE END 2 */

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)

Cuối cùng thêm lệnh sau trong hàm ngắt của RTC:
/**
* @brief This function handles RTC global interrupt.
*/
void RTC_IRQHandler(void)
{
/* USER CODE BEGIN RTC_IRQn 0 */

/* USER CODE END RTC_IRQn 0 */
HAL_RTCEx_RTCIRQHandler(&hrtc);
/* USER CODE BEGIN RTC_IRQn 1 */
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);
/* USER CODE END RTC_IRQn 1 */
}

Vậy là chúng ta đã khai thác triệt để modun RTC của F103 1 cách ngon lành.
đây là code cập nhật thời gian dựa vào ngắt không tốn tài nguyên chíp.
 

Đính kèm

huunho

Thạc sỹ
#4
Đến đây bạn nào tinh ý sẽ hiểu ngay là với code trên , mỗi khi bật nguồn thì modun RTC sẽ bị cài đặt lại thời gian mặc định dẫn đến sai giờ. vậy giải pháp là gì? Chúng ta chỉ cần dùng lệnh sau trước khi cài thời gian mặc định để biết RTC đã cài đặt chưa, nếu chưa có thể cài lại:
HAL_RTC_GetState(& hrtc);
HÀm này sẽ trả về 1 trong các giá trị sau để các bạn quyết định có cài đặt lại giờ hay không:

typedef enum
{
HAL_RTC_STATE_RESET = 0x00, /*!< RTC not yet initialized or disabled */
HAL_RTC_STATE_READY = 0x01, /*!< RTC initialized and ready for use */
HAL_RTC_STATE_BUSY = 0x02, /*!< RTC process is ongoing */
HAL_RTC_STATE_TIMEOUT = 0x03, /*!< RTC timeout state */
HAL_RTC_STATE_ERROR = 0x04 /*!< RTC error state */

}HAL_RTCStateTypeDef;

chẳng hạn thế này: if( HAL_RTC_GetState(& hrtc)== HAL_RTC_STATE_RESET)
{
cài thời gian măc định ở đây
};
 
Sửa lần cuối:

huunho

Thạc sỹ
#5
Ngoài ra , để tránh là trì hoãn xung nhịp cho RTC thì trước khi cài dặt RTC, cũng cần kiểm tra xem xung nhịp cho RTC đã được cài đạt chưa bằng lệnh:
void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency)
void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
 

guardian

Học sinh phổ thông
#7
bác nào giao tiếp stm32f1 với sim900a chwua giúp em phần gửi tin nhắn với @@
 

Quảng cáo Google