MiniProject 010123120 Embedded System Design Lab นาฬิกาปลุก
RTC (Real Time Clock)
RTC คือ อุปกรณ์ที่ให้ค่าเวลาตามจริง ซึ่งทำงานโดยการจับสัญญาณนาฬิกาที่ได้มาจาก Crystal (หรือ xtal ที่ 32.768 KHz) ซึ่งการที่ต้องใช้การอ่านค่าเวลา จากRTC module เพราะว่าจะไม่มีการถูกรบกวนไปด้วยคำสั่งต่างๆซึ่งในการใช้งานฟังก์ชันของHAL_RTC นั้น โดยการ Init RTC และเซตค่าวันเริ่มต้นให้สำหรับการเริ่มทำงาน แล้วถ้าจะทำการดูเวลา ณ ขณะนั้น ก็ให้ แสดงค่าออกมาโดยฟังก์ชั่น HAL_RTC_GetTime()
คุณสมบัติของ RTC บนบอร์ดทดลอง STM32F103
1. 32 kHz oscillator for RTC with
calibration
2. VBAT supply for RTC and backup registers
3. VBAT =
1.8 to 3.6 V: power supply for RTC, external clock 32 kHz oscillator and backup
registers (through power switch) when VDD is
not present.
4. The
internal low-power RC oscillator or the high-speed external clock divided by
128.
5. Backup registers are ten 16 bit register used to store 20 byte of user application data when VDD power is not present
Library ของ HAL_RTC ที่นำมาใช้
1.
การกำหนดค่าต่างๆให้
HAL_RTC เพื่อจะเริ่มทำงาน โดยค่าที่จะกำหนดให้สำหรับ RTC ได้แก่
1.1. RTC_HandleTypeDef
RTC_TypeDef*
RTC_HandleTypeDef::Instance เป็นการประกาศตัวแปร Register
base address
RTC_InitTypeDefRTC_HandleTypeDef::Initเป็นRTC required parameters
RTC_DateTypeDefRTC_HandleTypeDef::DateToUpdateCurrent
date set by userand updated automatically
1.2. RTC_InitTypeDef
: ไว้สำหรับกำหนดค่า output หรือ กำหนดว่าเป็น
Asynchronous ตัวหารความถี่
uint32_t
RTC_InitTypeDef::AsynchPredivSpecifies the RTC
AsynchronousPredivider value.โดยที่ค่าจะเป็นตั้งแต่ 0x00 ถึง 0xFFFF หรือจะเป็น RTC_AUTO_1SECOND
uint32_tRTC_InitTypeDef::OutPutSpecifies
which signal will be routed to the RTCTamper pin.
1.3. RTC_TimeTypeDef
เป็นตัวแปรไว้สำหรับกำหนดค่าเวลาของ
RTC
1.4. RTC_DateTypeDef
เป็นตัวแปรไว้สำหรับกำหนดค่าของวันที่ให้ RTC
1.5. HAL_RTC_Init
เป็นฟังก์ชันไว้สำหรับตั้งค่าเริ่มต้นให้กับ HAL_RTC
1.6. HAL_RTC_SetDate
เป็นฟังก์ชันไว้สำหรับ
เซตค่าเริ่มต้นของวันที่ ที่ได้ตั้งไว้
1.7. HAL_RTC_SetTime
เป็นฟังก์ชันไว้สำหรับ
เซตค่าเริ่มต้นของเวลาที่ได้ตั้งไว้
1.8. HAL_RTC_GetTime
เป็นฟังก์ชันไว้สำหรับ
รับค่าเวลาที่อ่านได้
RTC Code Example for STM32F103 RBT6
main.c
#include
"stm32f1xx_hal.h"
#include
<stdio.h>
RTC_HandleTypeDef
hrtc;
UART_HandleTypeDef
huart2;
void
SystemClock_Config(void);
static void
MX_GPIO_Init(void);
static void
MX_RTC_Init(void);
static void
MX_USART2_UART_Init(void);
//time --
seconds, minutes, hours
int sec = 0; // set second
int minu = 10; // set minute
int hour = 10; // set houur
int main(void)
{
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);
MX_RTC_Init();
MX_USART2_UART_Init();
RTC_TimeTypeDef time_1;
int num = 1;
int sec1
= sec;
int minu1 = minu;
int hour1 = hour;
char str[3];
int count1=0;
while (1)
{
HAL_RTC_GetTime(&hrtc,&time_1,RTC_FORMAT_BCD);
/* USER CODE END WHILE */
sprintf(str, "%d", hour1);
HAL_UART_Transmit(&huart2,&str,sizeof(str),1000);
HAL_UART_Transmit(&huart2,":",sizeof(":"),1000);
sprintf(str, "%d", minu1);
HAL_UART_Transmit(&huart2,&str,sizeof(str),1000);
HAL_UART_Transmit(&huart2,":",sizeof(":"),1000);
sprintf(str, "%d", sec1);
HAL_UART_Transmit(&huart2,&str,sizeof(str),1000);
HAL_UART_Transmit(&huart2,"\n",sizeof("\n"),1000);
if(sec1 >= 60){
sec1=0;
minu1++;
}
if(minu1 >= 60){
minu1=0;
hour1++;
}
if(hour1 >=24){
hour1=0;
}
if(num != time_1.Seconds ){
num = time_1.Seconds;
sec1 = sec1+1;
}
// PB8 output
// PB9 input
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_9) ==
GPIO_PIN_SET){
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);
}else{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);
}
HAL_Delay(900);
}
}
void
SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;
RCC_OscInitStruct.OscillatorType =
RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
RCC_OscInitStruct.PLL.PLLState =
RCC_PLL_NONE;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType =
RCC_CLOCKTYPE_SYSCLK;
RCC_ClkInitStruct.SYSCLKSource =
RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider =
RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider =
RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider =
RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct,
FLASH_LATENCY_0);
PeriphClkInit.PeriphClockSelection =
RCC_PERIPHCLK_RTC;
PeriphClkInit.RTCClockSelection =
RCC_RTCCLKSOURCE_LSI;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
__HAL_RCC_AFIO_CLK_ENABLE();
}
/* RTC init
function */
void
MX_RTC_Init(void)
{
RTC_TimeTypeDef sTime;
RTC_DateTypeDef DateToUpdate;
/**Initialize RTC and set the Time and
Date
*/
hrtc.Instance = RTC;
hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND;
hrtc.Init.OutPut = RTC_OUTPUTSOURCE_NONE;
hrtc.DateToUpdate.WeekDay =
RTC_WEEKDAY_MONDAY;
hrtc.DateToUpdate.Month =
RTC_MONTH_JANUARY;
hrtc.DateToUpdate.Date = 1;
hrtc.DateToUpdate.Year = 0;
HAL_RTC_Init(&hrtc);
sTime.Hours = hour;
sTime.Minutes = minu;
sTime.Seconds = sec ;
HAL_RTC_SetTime(&hrtc, &sTime,
FORMAT_BCD);
HAL_RTC_SetDate(&hrtc,
&DateToUpdate, FORMAT_BCD);
}
void
MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength =
UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl =
UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart2);
}
void
MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__GPIOC_CLK_ENABLE();
__GPIOA_CLK_ENABLE();
__GPIOB_CLK_ENABLE();
/*Configure GPIO pin : PB8 */
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pin : PB9 */
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
#ifdef
USE_FULL_ASSERT
/**
* @brief Reports the name of the source
file and the source line number
* where the assert_param error has
occurred.
*
@param file: pointer to the source file name
* @param line: assert_param error line
source number
* @retval None
*/
void
assert_failed(uint8_t* file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to
report the file name and line number,
ex: printf("Wrong parameters value:
file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
|
สำหรับผลการทดลอง จะได้ดังนี้
UART
UART (Universal
Asynchronous Receiver Transmitter) คืออุปกรณ์ที่ทำหน้าที่รับและส่งข้อมูลแบบAsynchronous
ซึ่งเป็นการสื่อสารอนุกรมแบบ Asynchronous
การสื่อสารอนุกรมแบบ Asynchronous
เป็นการส่งข้อมูลโดยไม่อาศัยสัญญาณ
clock
มาเป็นตัวกำหนดจังหวะการรับส่งข้อมูลแต่ใช้วิธีกำหนด รูปแบบ Format
การรับส่งข้อมูลขึ้นมาแทน และ อาศัยการกำหนด
ความเร็วของการรับและส่ง ที่เท่ากันทั้งฝั่งรับและฝั่งส่ง
ข้อดี : สามารถสื่อสารแบบ Full Duplex รับและส่งได้ในเวลาเดียวกัน
ข้อเสีย : มีโอกาสที่ข้อมูลจะสูญหายระหว่างรับส่งข้อมูลหรือมีความผิดพลาดของข้อมูลได้
รูปแบบการรับส่งข้อมูลแบบ Asynchronous
มีรูปแบบดังนี้
เริ่มต้นจาก Start
bit ซึ่งเป็น Logic 0 จากนั้นจะตามด้วย ข้อมูล
แล้วจะถูกปิดด้วย Stop Bit เป็น Logic 1
UART บนบอร์ดทดลอง STM32F103
พอร์ต
RS232
เป็นสัญญาณ RS232 ซึ่งผ่านวงจรแปลงระดับสัญญาณ
MAX3232 แล้ว โดยสามารถใช้เชื่อมต่อกับสัญญาณ RS232 เพื่อรับส่งข้อมูลได้
โดยในการทำงานนี้ จะเลือกใช้ USART-2
USART-2 ใช้ขาสัญญาณจาก PA2(TXD2) เป็นขาสำหรับส่งข้อมูล และ PA3(RXD2)เป็นขาสำหรับรับข้อมูล
สำหรับ function ในการรับส่งข้อมูลแบบ
UART
1. เป็นfunction HAL ซึ่งไว้ใช้สำหรับการกำหนดค่าของ BaudRate, WordLength, StopBits, Parity, Mode HwFlowCtl, OverSampling
2. เป็น
function HAL ซึ่งไว้ใช้สำหรับส่งค่าไปแสดงผลบน Serial
monitor
3. เป็น function HAL ซึ่งไว้สำหรับกำหนดค่าต่างๆ
ให้กับ UART
- USART_TypeDef*Instance เป็น Register base address
- USART_InitTypeDefInitUsart communication parameters
- uint8_t* USART_HandleTypeDef::pTxBuffPtrPointer to UsartTx transfer Buffer
- uint16_t USART_HandleTypeDef::TxXferSizeUsartTx Transfer size
- __IO uint16_t USART_HandleTypeDef::TxXferCountUsartTx Transfer Counter
- uint8_t* USART_HandleTypeDef::pRxBuffPtr Pointer to Usart Rx transfer Buffer
- uint16_t USART_HandleTypeDef::RxXferSizeUsart Rx Transfer size
- __IO uint16_t USART_HandleTypeDef::RxXferCountUsart Rx Transfer Counter
- DMA_HandleTypeDef* USART_HandleTypeDef::hdmatxUsartTx DMA Handleparameters
- DMA_HandleTypeDef* USART_HandleTypeDef::hdmarxUsart Rx DMA Handleparameters
- HAL_LockTypeDefUSART_HandleTypeDef::Lock Locking object
- __IO HAL_USART_StateTypeDefUSART_HandleTypeDef::State Usartcommunication state
- __IO uint32_t USART_HandleTypeDef::ErrorCode USART Error code
เป็นการประกาศตัวแปรของ
RTC
และ UARTซึ่งจะไว้ดำเนินการต่างๆของ RTC
และ UART
เป็นฟังก์ชัน ไว้กำหนดค่าต่างๆให้กับ RTC
-
RTC_TimeTypeDefsTime : เป็นการประกาศตัวแปรเวลาของ RTC
-
RTC_DateTypeDefDateToUpdate : เป็นการประกาศตัวแปรวันที่ของ
RTC
-
กำหนดค่าต่างๆให้กับ
RTC ได้แก่ Asynchronous Predivider value , Output และประกาศตัวแปรเพื่อกำหนดค่าเริ่มต้นของวันที่และเวลา
-
HAL_RTC_SetTime
เป็นการกำหนดค่าเริ่มต้นให้กับเวลาของ
-
HAL_RTC_SetDate
เป็นการกำหนดค่าเริ่มต้นให้กับวันที่ของ RTC
เป็นการประกาศตัวแปร RTC_TimeTypeDefไว้สำหรับเก็บค่าเวลาของ RTC
เป็นส่วนรับค่าเวลาของ RTC
โดยจะใช้ในรูปแบบของ BCD(คือการเอาตัวเลขฐานสองมาเขียนแทนเลขฐานสิบ)
เป็นการเก็บค่าลงใน array
ชื่อ str แล้วนำไปแสดงผลโดยส่งค่า ผ่าน UART
โดย HAL_UART_Transmit(ชื่อตัวแปรUART_HandleTypeDef, ข้อความที่จะส่ง,
ขนาดข้อความ, Timeout)