1、阅读 Real Time Clock (RTC) 的简要描述
2、观看RTC框图后,并向下找到Read/Write Register(读写寄存器BCD)
3、在Register Description(寄存器描述中找到所需要的寄存器)年月日、时分秒以及RTC控制寄存器
备注:一般全局控制器需要,局部控制器看情况,不确定的可以先选上,在后续操作中再判断是否需要,并记录好所找的的寄存器基地址+偏移地址
4、阅读初步筛选好的寄存器的详细信息并进一步进行筛选,怎么实现需求
5、进行相关代码的编写
6、牢记main函数只是实现函数的调用,其他函数尽可能的进行封装
main.c:由于这里只使用了串口和RTC,所以只对串口进行了封装
#include "uart.h" //通用控制器 #define RTCCON *(unsigned int volatile*)0x10070040 //秒、分、时、天、月、年 #define BCDSEC *(unsigned int volatile*)0x10070070 #define BCDMIN *(unsigned int volatile*)0x10070074 #define BCDHOUR *(unsigned int volatile*)0x10070078 #define BCDDAY *(unsigned int volatile*)0x10070080 #define BCDMON *(unsigned int volatile*)0x10070084 #define BCDYEAR *(unsigned int volatile*)0x10070088 //自定义睡眠函数 void delay(){ int t = 0xfffff*3; while(t--); } void rtc_init(){ RTCCON = 1; BCDYEAR = 0X022; BCDMON = 0x9; BCDDAY = 0x7; BCDHOUR = 0x18; BCDMIN = 0x29; BCDSEC = 0x30; } void rtc_show(){ char c = 0; //年 uart_send('2'); uart_send( ((BCDYEAR>>8)&0xf)+'0' ); uart_send( ((BCDYEAR>>4)&0xf)+'0' ); uart_send( ((BCDYEAR>>0)&0xf)+'0' ); uart_send('-'); //月 uart_send( ((BCDMON>>4)&0x1)+'0' ); uart_send( ((BCDMON>>0)&0xf)+'0' ); uart_send('-'); //日 uart_send( ((BCDDAY>>4)&0x3)+'0' ); uart_send( ((BCDDAY>>0)&0xf)+'0' ); uart_send(' '); //时 uart_send( ((BCDHOUR>>4)&0x3)+'0' ); uart_send( ((BCDHOUR>>0)&0xf)+'0' ); uart_send(':'); //分 uart_send( ((BCDMIN>>4)&0x8)+'0' ); uart_send( ((BCDMIN>>0)&0xf)+'0' ); uart_send(':'); //秒 uart_send( ((BCDSEC>>4)&0x8)+'0' ); uart_send( ((BCDSEC>>0)&0xf)+'0' ); //windows换行需要一个 \n + \r uart_str("\n\r"); } void main() { uart_init(); rtc_init(); while(1){ rtc_show(); delay(); } }
uart.c:
#define GPA1CON *(unsigned int volatile*)0x11400020 #define ULCON2 *(unsigned int volatile*)0x13820000 #define UCON2 *(unsigned int volatile*)0x13820004 #define UTXH2 *(unsigned int volatile*)0x13820020 #define URXH2 *(unsigned int volatile*)0x13820024 #define UBRDIV2 *(unsigned int volatile*)0x13820028 #define UFRACVAL2 *(unsigned int volatile*)0x1382002c #define UTRSTAT2 *(unsigned int volatile*)0x13820010 void uart_init(){ //波特率发生器 //GPA1CON 0x11400020 [7:4] 0x2 = UART_2_TXD 发送 GPA1CON = GPA1CON & ~(0xf<<4) | (0x2<<4); //GPA1CON 0x11400020 [3:0] 0x2 = UART_2_RXD 接收 GPA1CON = GPA1CON & ~(0xf<<0) | (0x2<<0); //指定数据位有几位,这里是8位 ULCON2 = 0x3; //全局控制,清除0-5位待用,0x1<<2:轮询发送 <<0:轮询接收 UCON2 = UCON2 & ~0x3f | (0x1<<2) | (0x1<<0); //100MHZ = 100000000 100MHZ/(115200*16)-1 115200:波特率的位/秒 UBRDIV2 = 53; UFRACVAL2 = 4; } void uart_send(char c){ //检测有效数据,防止无效数据的发送 //当传输buf无有效数据传输,且传输移位为空时,该位自动设置为1 while( !(UTRSTAT2&(0x1<<2)) ); UTXH2 = c; } void uart_str(char *s){ while(*s!='\0'){ uart_send(*s); s++; } } char uart_recv(){ //检测有效数据 //当接收buf含通过RXDn端口接收的有效数据时,自动将该位设置为1 while( !(UTRSTAT2&0x1) ); //接收数据位为8位 return (URXH2 & 0xff); }
Makefile:
all: arm-linux-gcc myadd.S -o start.o -c -g arm-linux-gcc uart.c -o uart.o -c -g arm-linux-gcc main.c -o main.o -c -g arm-linux-ld start.o uart.o main.o -o start.elf -Ttest.lds arm-linux-objcopy start.elf start.bin -O binary clean: rm *.o *.elf *.bin
uart.h:
#ifndef __MY_UART__ #define __MY_UART__ void uart_init(); void uart_send(char c); void uart_str(char *s); #endif
test.lds、myadd.S:ARM之串口的收发_承诺$枷锁的博客-CSDN博客
效果:
FS4412 # go 41000000 ## Starting application at 0x41000000 ... 2022-09-07 18:09:00 2022-09-07 18:09:01 2022-09-07 18:09:02 2022-09-07 18:09:02 2022-09-07 18:09:03 2022-09-07 18:09:04 2022-09-07 18:09:05 2022-09-07 18:09:06 2022-09-07 18:09:07 2022-09-07 18:09:08