本文描述用RA2E1实现RTC时钟,并通过8*16点阵屏显示时间
一、FSP配置
添加r_rtc
二、程序
rtc初始化,设置日期时间,设置中断1/2秒触发一次:
err = R_RTC_Open(&g_rtc0_ctrl, &g_rtc0_cfg);
assert(FSP_SUCCESS == err);
R_RTC_CalendarTimeSet(&g_rtc0_ctrl, &set_time);
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,
.tm_min = 47,
.tm_hour = 10,
.tm_mday = 23,
.tm_mon = 10,
.tm_year = 124,
.tm_wday = 4,
};
中断回调函数:
收到中断,设置标志为1。
volatile bool rtc_flag = 0;
void rtc_callback(rtc_callback_args_t *p_args)
{
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);
}
串口输出效果:
三、增加个8*16点阵屏显示效果
利用CH453驱动2个8*8点阵屏。
CH453需要用模拟IIC驱动,尝试用硬件IIC驱动没有成功。
#ifndef __IIC_H__
#define __IIC_H__
#define CH453_SYSOFF 0x0400
#define CH453_SYSON 0x0401
#define CH453_DIG0 0x1000
#define CH453_DIG1 0x1100
#define CH453_DIG2 0x1200
#define CH453_DIG3 0x1300
#define CH453_DIG4 0x1400
#define CH453_DIG5 0x1500
#define CH453_DIG6 0x1600
#define CH453_DIG7 0x1700
#define CH453_DIG8 0x1800
#define CH453_DIG9 0x1900
#define CH453_DIG10 0x1A00
#define CH453_DIG11 0x1B00
#define CH453_DIG12 0x1C00
#define CH453_DIG13 0x1D00
#define CH453_DIG14 0x1E00
#define CH453_DIG15 0x1F00
#define CH453_I2C_ADDR 0x40
#define CH453_I2C_MASK 0x3E
void CH453_I2c_Start(void)
{
CH453_SDA_SET;
CH453_SDA_D_OUT;
CH453_SCL_SET;
CH453_SCL_D_OUT;
DELAY_0_1US;
CH453_SDA_CLR;
DELAY_0_1US;
CH453_SCL_CLR;
}
void CH453_I2c_Stop(void)
{
CH453_SDA_CLR;
DELAY_0_1US;
CH453_SCL_SET;
DELAY_0_1US;
CH453_SDA_SET;
DELAY_0_1US;
}
void CH453_I2c_WrByte(unsigned char dat)
{
unsigned char i;
for(i=0;i!=8;i++)
{
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,
0x00,0x7F,0X00,
0x79,0x49,0x4F,
0x49,0x49,0x7F,
0x0F,0x08,0x7F,
0x4F,0x49,0x79,
0x7F,0x49,0x79,
0x01,0x01,0x7F,
0x7F,0x49,0x7F,
0x4F,0x49,0x7f,
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);
}