- fsp_err_t err = FSP_SUCCESS;
- unsigned char send_buff[100];
- volatile bool uart_send_complete_flag = false;
- void user_uart9_callback (uart_callback_args_t * p_args)
- {
- if(p_args->event == UART_EVENT_TX_COMPLETE)
- {
- uart_send_complete_flag = true;
- }
- }
- int fputc(int ch)
- {
- err = R_SCI_UART_Write(&g_uart9_ctrl, (uint8_t *)&ch, 1);
- if(FSP_SUCCESS != err) __BKPT();
- while(uart_send_complete_flag == false)
- {
- }
- uart_send_complete_flag = false;
- return ch;
- }
uart_send_complete_flag = false;
return ch;
}
此时,将主程序修改为:
- void hal_entry(void)
- {
- err = R_SCI_UART_Open(&g_uart9_ctrl, &g_uart9_cfg);
- assert(FSP_SUCCESS == err);
- while(1)
- {
- printf("Hellow world ! \r\n");
- R_BSP_SoftwareDelay(1000, BSP_DELAY_UNITS_MILLISECONDS);
- }
- }
- 、
经程序的编译和下载,其测试结果如图12所示,说明打印功能已实现,
图12 输出测试
2. RTC计时器
在RA6M4内部,配以RTC计时器,使用它可方便地实现电子时钟功能。
要使用RTC功能,需使用RASC在原基础上使能RTC,见图13所示。然后,再按图14所示加入RTC。
图13 参数设置
图14 加入RTC
点击“Generate Project Content”,以再次生成工程代码。
再次使用KEIL打开生成的工程,在原程序中添加如下的函数:
- void rtc_callback(rtc_callback_args_t *p_args)
- {
- if(p_args->event == RTC_EVENT_PERIODIC_IRQ)
- rtc_flag=1;
- else if(p_args->event == RTC_EVENT_ALARM_IRQ)
- rtc_alarm_flag=1;
- }
- rtc_time_t set_time =
- {
- .tm_sec = 0, /* 秒,范围从 0 到 59 */
- .tm_min = 30, /* 分,范围从 0 到 59 */
- .tm_hour = 12, /* 小时,范围从 0 到 23*/
- .tm_mday = 20, /* 一月中的第几天,范围从 1 到 31*/
- .tm_mon = 11, /* 月份,范围从 0 到 11*/
- .tm_year = 121, /* 自 1900 起的年数,2021为121*/
- .tm_wday = 5, /* 一周中的第几天,范围从 0 到 6*/
- };
- rtc_alarm_time_t set_alarm_time=
- {
- .time.tm_sec = 5,
- .time.tm_sec = 5, /* 秒,范围从 0 到 59 */
- .time.tm_min = 30, /* 分,范围从 0 到 59 */
- .time.tm_hour = 12, /* 小时,范围从 0 到 23*/
- .time.tm_mday = 25, /* 一月中的第几天,范围从 1 到 31*/
- .time.tm_mon = 7, /* 月份,范围从 0 到 11*/
- .time.tm_year = 125, /* 自 1900 起的年数,2021为121*/
- .time.tm_wday = 5, /* 一周中的第几天,范围从 0 到 6*/
- .sec_match = 1,
- .min_match = 0,
- .hour_match = 0,
- .mday_match = 0,
- .mon_match = 0,
- .year_match = 0,
- .dayofweek_match = 0,
- };
将主程序修改为:
- void hal_entry(void)
- {
- err = R_SCI_UART_Open(&g_uart9_ctrl, &g_uart9_cfg);
- assert(FSP_SUCCESS == err);
- err = R_RTC_Open(&rtc_ctrl, &rtc_cfg);
- assert(FSP_SUCCESS == err);
- R_RTC_CalendarTimeSet(&rtc_ctrl, &set_time);
- R_RTC_PeriodicIrqRateSet(&rtc_ctrl, RTC_PERIODIC_IRQ_SELECT_1_SECOND);
- R_RTC_CalendarAlarmSet(&rtc_ctrl, &set_alarm_time);
- uint8_t rtc_second= 0; //秒
- uint8_t rtc_minute =0; //分
- uint8_t rtc_hour =0; //时
- uint8_t rtc_day =0; //日
- uint8_t rtc_month =0; //月
- uint16_t rtc_year =0; //年
- uint8_t rtc_week =0; //周
- rtc_time_t get_time;
- while(1)
- {
- if(rtc_flag)
- {
- R_RTC_CalendarTimeGet(&rtc_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-%d-%d %d:%d %d\n",rtc_year+1900,rtc_month,rtc_day,rtc_hour,rtc_minute,rtc_second,rtc_week);
- }
- if(rtc_alarm_flag)
- {
- rtc_alarm_flag=0;
- printf("/************Alarm Clock***********/\n");
- }
- }
- }
经程序的编译和下载,则其测试结果如图15所示,说明RTC计时功能已实现。
图15 计时效果
3. OLED屏显示
为了能够直接地观察计时效果,可为其添加一个OLED显示屏。
为省去连线的麻烦,可利用开发板上的J4接口来连接OLED屏。
在用RASC对所用引脚添加配置后,以KEIL打开新生成的工程。
为实现高低电平的输出其语句定义为:
#define OLED_SCLK_Set() R_IOPORT_PinWrite(&IOPORT_CFG_CTRL, BSP_IO_PORT_01_PIN_13, BSP_IO_LEVEL_HIGH)
#define OLED_SDIN_Set()R_IOPORT_PinWrite(&IOPORT_CFG_CTRL, BSP_IO_PORT_01_PIN_12, BSP_IO_LEVEL_HIGH)
#define OLED_SCLK_Clr()R_IOPORT_PinWrite(&IOPORT_CFG_CTRL, BSP_IO_PORT_01_PIN_13, BSP_IO_LEVEL_LOW)
#define OLED_SDIN_Clr()R_IOPORT_PinWrite(&IOPORT_CFG_CTRL, BSP_IO_PORT_01_PIN_12, BSP_IO_LEVEL_LOW)
以模拟I2C方式方式字节数据的函数为:
- void Write_IIC_Byte(unsigned char IIC_Byte)
- {
- unsigned char i;
- unsigned char m,da;
- da=IIC_Byte;
- OLED_SCLK_Clr();
- for(i=0;i<8;i++)
- {
- m=da;
- m=m&0x80;
- if(m==0x80)
- {OLED_SDIN_Set();}
- else
- OLED_SDIN_Clr();
- da=da<<1;
- delay_us(3);
- OLED_SCLK_Set();
- delay_us(3);
- OLED_SCLK_Clr();
- delay_us(3);
- }
- }
对应的初始化函数为:
- void OLED_Init(void)
- {
- Write_IIC_Command(0xAE); //display off
- Write_IIC_Command(0x40);//--set start line address
- Write_IIC_Command(0xb0);//Set Page Start Address for Page Addressing Mode,0-72
- Write_IIC_Command(0xc8);//Set COM Output Scan Direction
- Write_IIC_Command(0x81);//--set contrast control register
- Write_IIC_Command(0xff);
- Write_IIC_Command(0xa1);//--set segment re-map 0 to 127
- Write_IIC_Command(0xa6);//--set normal display
- Write_IIC_Command(0xa8);//--set multiplex ratio(1 to 64)
- Write_IIC_Command(0x1F);
- Write_IIC_Command(0xd3);//-set display offset
- Write_IIC_Command(0x00);//-not offset
- Write_IIC_Command(0xd5);//--set display clock divide ratio/oscillator frequency
- Write_IIC_Command(0xf0);//--set divide ratio
- Write_IIC_Command(0xd9);//--set pre-charge period
- Write_IIC_Command(0x22);
- Write_IIC_Command(0xda);//--set com pins hardware configuration
- Write_IIC_Command(0x02);
- Write_IIC_Command(0x8d);//--set DC-DC enable
- Write_IIC_Command(0x14);
- Write_IIC_Command(0xdb);//--set vcomh
- Write_IIC_Command(0x49);//0x20,0.77xVcc
- Write_IIC_Command(0xaf);//--turn on oled panel
- }
实现电子时钟显示显示效果的主程序为:
- void hal_entry(void)
- {
- err = R_RTC_Open(&rtc_ctrl, &rtc_cfg);
- assert(FSP_SUCCESS == err);
- R_RTC_CalendarTimeSet(&rtc_ctrl, &set_time);
- R_RTC_PeriodicIrqRateSet(&rtc_ctrl, RTC_PERIODIC_IRQ_SELECT_1_SECOND);
- R_RTC_CalendarAlarmSet(&rtc_ctrl, &set_alarm_time);
- uint8_t rtc_second= 0; //秒
- uint8_t rtc_minute =0; //分
- uint8_t rtc_hour =0; //时
- uint8_t rtc_day =0; //日
- uint8_t rtc_month =0; //月
- uint16_t rtc_year =0; //年
- uint8_t rtc_week =0; //周
- rtc_time_t get_time;
- OLED_Init();
- OLED_Clear();
- OLED_ShowString(0,0,"RA-Eco-RA6M4",16);
- OLED_ShowString(0,2," : :",16);
- while(1)
- {
- if(rtc_flag)
- {
- R_RTC_CalendarTimeGet(&rtc_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;//周
- OLED_ShowNum(0,2,rtc_hour,2,16);
- OLED_ShowNum(24,2,rtc_minute,2,16);
- OLED_ShowNum(48,2,rtc_second,2,16);
- }
- if(rtc_alarm_flag)
- {
- rtc_alarm_flag=0;
- }
- }
- }
经重新编译和下载,则其测试结果如图16所示,设计功能已实现。
图16 显示效果