本文描述用RA2E1实现RTC时钟,并通过8*16点阵屏显示时间
添加r_rtc
rtc初始化,设置日期时间,设置中断1/2秒触发一次:
/* Initialize the RTC module*/
err = R_RTC_Open(&g_rtc0_ctrl, &g_rtc0_cfg);
/* Handle any errors. This function should be defined by the user. */
assert(FSP_SUCCESS == err);
/* R_RTC_CalendarTimeSet must be called at least once to start the RTC */
R_RTC_CalendarTimeSet(&g_rtc0_ctrl, &set_time);
/* Set the periodic interrupt rate to 1 second */
R_RTC_PeriodicIrqRateSet(&g_rtc0_ctrl, RTC_PERIODIC_IRQ_SELECT_1_DIV_BY_2_SECOND);
其中set_time数据结构:
rtc_time_t set_time =
{
.tm_sec = 0, /* 秒,范围从 0 到 59 */
.tm_min = 47, /* 分,范围从 0 到 59 */
.tm_hour = 10, /* 小时,范围从 0 到 23*/
.tm_mday = 23, /* 一月中的第几天,范围从 1 到 31*/
.tm_mon = 10, /* 月份,范围从 0 到 11*/
.tm_year = 124, /* 自 1900 起的年数,2021为121*/
.tm_wday = 4, /* 一周中的第几天,范围从 0 到 6*/
// .tm_yday=0, /* 一年中的第几天,范围从 0 到 365*/
// .tm_isdst=0; /* 夏令时*/
};
中断回调函数:
收到中断,设置标志为1。
volatile bool rtc_flag = 0;//RTC延时1s标志位
/* Callback function */
void rtc_callback(rtc_callback_args_t *p_args)
{
/* TODO: add your own code here */
if(p_args->event == RTC_EVENT_PERIODIC_IRQ)
rtc_flag=1;
}
void hal_entry(void)
主循环中将时间打印出来
while(1)
{
//Color_Test();
//printf("Color_Test\\\\r\\\\n");
//R_BSP_SoftwareDelay(1000, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT100->160
if(rtc_flag)
{
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_04, BSP_IO_LEVEL_LOW);
R_RTC_CalendarTimeGet(&g_rtc0_ctrl, &get_time);//获取RTC计数时间
rtc_flag=0;
rtc_second=get_time.tm_sec;//秒
rtc_minute=get_time.tm_min;//分
rtc_hour=get_time.tm_hour;//时
rtc_day=get_time.tm_mday;//日
rtc_month=get_time.tm_mon;//月
rtc_year=get_time.tm_year; //年
rtc_week=get_time.tm_wday;//周
printf(" %d y %d m %d d %d h %d m %d s %d w\\\\n",rtc_year+1900,rtc_month,rtc_day,rtc_hour,rtc_minute,rtc_second,rtc_week);
}
串口输出效果:
利用CH453驱动2个8*8点阵屏。
CH453需要用模拟IIC驱动,尝试用硬件IIC驱动没有成功。
#ifndef __IIC_H__
#define __IIC_H__
/* CH453的常用命令码,如果考虑与I2C兼容,那么高8位应该右移1位 */
#define CH453_SYSOFF 0x0400 // 关闭显示
#define CH453_SYSON 0x0401 // 开启显示
#define CH453_DIG0 0x1000 // 数码管位0显示,需另加8位数据
#define CH453_DIG1 0x1100 // 数码管位1显示,需另加8位数据
#define CH453_DIG2 0x1200 // 数码管位2显示,需另加8位数据
#define CH453_DIG3 0x1300 // 数码管位3显示,需另加8位数据
#define CH453_DIG4 0x1400 // 数码管位4显示,需另加8位数据
#define CH453_DIG5 0x1500 // 数码管位5显示,需另加8位数据
#define CH453_DIG6 0x1600 // 数码管位6显示,需另加8位数据
#define CH453_DIG7 0x1700 // 数码管位7显示,需另加8位数据
#define CH453_DIG8 0x1800 // 数码管位8显示,需另加8位数据
#define CH453_DIG9 0x1900 // 数码管位9显示,需另加8位数据
#define CH453_DIG10 0x1A00 // 数码管位10显示,需另加8位数据
#define CH453_DIG11 0x1B00 // 数码管位11显示,需另加8位数据
#define CH453_DIG12 0x1C00 // 数码管位12显示,需另加8位数据
#define CH453_DIG13 0x1D00 // 数码管位13显示,需另加8位数据
#define CH453_DIG14 0x1E00 // 数码管位14显示,需另加8位数据
#define CH453_DIG15 0x1F00 // 数码管位15显示,需另加8位数据
#define CH453_I2C_ADDR 0x40 // CH453的地址
#define CH453_I2C_MASK 0x3E // CH453的高字节命令掩码
void CH453_I2c_Start(void) // 操作起始
{
CH453_SDA_SET; /*发送起始条件的数据信号*/
CH453_SDA_D_OUT; /* 设置SDA为输出方向 */
CH453_SCL_SET;
CH453_SCL_D_OUT; /* 设置SCL为输出方向 */
DELAY_0_1US;
CH453_SDA_CLR; /*发送起始信号*/
DELAY_0_1US;
CH453_SCL_CLR; /*钳住I2C总线,准备发送或接收数据 */
}
void CH453_I2c_Stop(void) // 操作结束
{
CH453_SDA_CLR;
DELAY_0_1US;
CH453_SCL_SET;
DELAY_0_1US;
CH453_SDA_SET; /*发送I2C总线结束信号*/
DELAY_0_1US;
}
void CH453_I2c_WrByte(unsigned char dat) //写一个字节数据
{
unsigned char i;
for(i=0;i!=8;i++) // 输出8位数据
{
if(dat&0x80) {CH453_SDA_SET;}
else {CH453_SDA_CLR;}
DELAY_0_1US;
CH453_SCL_SET;
dat<<=1;
DELAY_0_1US; // 可选延时
CH453_SCL_CLR;
}
CH453_SDA_SET;
DELAY_0_1US;
CH453_SCL_SET; // 接收应答
DELAY_0_1US;
CH453_SCL_CLR;
}
void CH453_Write(unsigned short cmd) //写命令
{
CH453_I2c_Start(); /*启动总线*/
CH453_I2c_WrByte(((unsigned char)(cmd>>7)&CH453_I2C_MASK)|CH453_I2C_ADDR);
CH453_I2c_WrByte((unsigned char)cmd); /*发送数据*/
CH453_I2c_Stop(); /*结束总线*/
}
CH453初始化:CH453_Write( 0x040B );
数字字模:
3*8一个数字,每个DIG对应一列,每个SEG对应一行
uint8_t NUM[]=
{
0x7F,0x41,0x7F, //0
0x00,0x7F,0X00, //1
0x79,0x49,0x4F, //2
0x49,0x49,0x7F, //3
0x0F,0x08,0x7F, //4
0x4F,0x49,0x79, //5
0x7F,0x49,0x79, //6
0x01,0x01,0x7F, //7
0x7F,0x49,0x7F, //8
0x4F,0x49,0x7f, //9
0x00,0x22,0x00, //:
0x00,0x00,0x00, //空
};
显示数字:
地址,对应16列:
unsigned short CH453_DIG[]={0x1000,0x1100,0x1200,0x1300,0x1400,0x1500,0x1600,0x1700,0x1800,0x1900,0x1A00,0x1B00,0x1C00,0x1D00,0x1E00,0x1F00};
void disp_num(uint8_t num,uint8_t pos)
{
uint8_t i;
for(i=0;i<3;i++)
{
CH453_Write(CH453_DIG[i+pos] | NUM[num*3+i]);
}
}
显示时间:
if(rtc_flag)
{
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_04, BSP_IO_LEVEL_LOW);
R_RTC_CalendarTimeGet(&g_rtc0_ctrl, &get_time);//获取RTC计数时间
rtc_flag=0;
rtc_second=get_time.tm_sec;//秒
rtc_minute=get_time.tm_min;//分
rtc_hour=get_time.tm_hour;//时
rtc_day=get_time.tm_mday;//日
rtc_month=get_time.tm_mon;//月
rtc_year=get_time.tm_year; //年
rtc_week=get_time.tm_wday;//周
printf(" %d y %d m %d d %d h %d m %d s %d w\\\\n",rtc_year+1900,rtc_month,rtc_day,rtc_hour,rtc_minute,rtc_second,rtc_week);
if(rtc_hour/10!=0) disp_num(rtc_hour/10,0);
disp_num(rtc_hour%10,3);
if(rtc_second%2==0) disp_num(10,6);
else disp_num(11,6);
disp_num(rtc_minute/10,9);
disp_num(rtc_minute%10,13);
}
更多回帖