本帖最后由 jinglixixi 于 2023-6-24 11:23 编辑
#申请原创# @21小跑堂
由于LKS32MC071没有内置RTC计时器,因此要实现电子时钟类的计时功能需外挂RTC计时模块,这里采用的DS1302功能模块。 在使用时,DS1302模块与开发板的连接关系为: SCK ---P00 IO ---P32 RST ---P210 图1 所用接口
为便于编程,对各引脚输出高低电平的语句定义为: #define SCK_Set() GPIO_SetBits(GPIO0, GPIO_Pin_0) #define SCK_Clr() GPIO_ResetBits(GPIO0, GPIO_Pin_0) #define IO_Set() GPIO_SetBits(GPIO3, GPIO_Pin_2) #define IO_Clr() GPIO_ResetBits(GPIO3, GPIO_Pin_2) #define RST_Set() GPIO_SetBits(GPIO2, GPIO_Pin_10) #define RST_Clr() GPIO_ResetBits(GPIO2, GPIO_Pin_10) #define IO_IN GPIO_ReadInputDataBit(GPIO3,GPIO_Pin_2) DS1302模块对所用引脚的配置函数为: void ds1302_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_Init(GPIO0, &GPIO_InitStruct);
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIO2, &GPIO_InitStruct);
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
GPIO_Init(GPIO3, &GPIO_InitStruct);
}
在使用过程中,DS1302模块的数据引脚既使用输出模式,又使用输入模式,故定义了输入与输出模式的函数,其内容如下: void INPUT_MODE_SET(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
GPIO_Init(GPIO3, &GPIO_InitStruct);
}
void OUTPUT_MODE_SET(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
GPIO_Init(GPIO3, &GPIO_InitStruct);
}
DS1302模块写入时间值的函数为: void ds1302_write_time(void)
{
ds1302_write_byte(ds1302_control_add,0x00);
ds1302_write_byte(ds1302_sec_add,0x80);
ds1302_write_byte(ds1302_year_add,time_buf[1]);
ds1302_write_byte(ds1302_month_add,time_buf[2]);
ds1302_write_byte(ds1302_date_add,time_buf[3]);
ds1302_write_byte(ds1302_hr_add,time_buf[4]);
ds1302_write_byte(ds1302_min_add,time_buf[5]);
ds1302_write_byte(ds1302_sec_add,time_buf[6]);
ds1302_write_byte(ds1302_day_add,time_buf[7]);
ds1302_write_byte(ds1302_control_add,0x80);
}
DS1302模块读取时间值的函数为: void ds1302_read_time(void)
{
time_buf[1]=ds1302_read_byte(ds1302_year_add);
time_buf[2]=ds1302_read_byte(ds1302_month_add);
time_buf[3]=ds1302_read_byte(ds1302_date_add);
time_buf[4]=ds1302_read_byte(ds1302_hr_add);
time_buf[5]=ds1302_read_byte(ds1302_min_add);
time_buf[6]=(ds1302_read_byte(ds1302_sec_add))&0x7f;
time_buf[7]=ds1302_read_byte(ds1302_day_add);
}
为便于观察RTC计时效果,这里为其配备了OLED屏的显示功能。
该OLED屏是一款I2C接口的显示屏,它占用引脚少,显示信息较丰富,其显示效果如图2所示。 图2 显示效果
该显示屏与开发板的连接关系为: SDA ---P22 CLK ---P23 定义引脚输出高低电平输出的语句为: #define SDA_high GPIO_SetBits(GPIO2, GPIO_Pin_2) #define SDA_low GPIO_ResetBits(GPIO2, GPIO_Pin_2) #define SCL_high GPIO_SetBits(GPIO2, GPIO_Pin_3) #define SCL_low GPIO_ResetBits(GPIO2,GPIO_Pin_3)
对所用引脚的配置函数为: void oled_gpio_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_StructInit(&GPIO_InitStruct);
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3;
GPIO_Init(GPIO2, &GPIO_InitStruct);
}
OLED屏初始化函数为: void OLED_Init(void)
{
OLED_WR_Byte(0xAE,OLED_CMD);
OLED_WR_Byte(0x02,OLED_CMD);
OLED_WR_Byte(0x10,OLED_CMD);
OLED_WR_Byte(0x40,OLED_CMD)
OLED_WR_Byte(0x81,OLED_CMD);
OLED_WR_Byte(0xff,OLED_CMD);
OLED_WR_Byte(0xA1,OLED_CMD);
OLED_WR_Byte(0xC8,OLED_CMD);
OLED_WR_Byte(0xA6,OLED_CMD);
OLED_WR_Byte(0xA8,OLED_CMD);
OLED_WR_Byte(0x3f,OLED_CMD);
OLED_WR_Byte(0xD3,OLED_CMD);
OLED_WR_Byte(0x00,OLED_CMD);
OLED_WR_Byte(0xd5,OLED_CMD);
OLED_WR_Byte(0x80,OLED_CMD);
OLED_WR_Byte(0xD9,OLED_CMD);
OLED_WR_Byte(0xF1,OLED_CMD);
OLED_WR_Byte(0xDA,OLED_CMD);
OLED_WR_Byte(0x12,OLED_CMD);
OLED_WR_Byte(0xDB,OLED_CMD);
OLED_WR_Byte(0x40,OLED_CMD);
OLED_WR_Byte(0x20,OLED_CMD);
OLED_WR_Byte(0x02,OLED_CMD);
OLED_WR_Byte(0x8D,OLED_CMD);
OLED_WR_Byte(0x14,OLED_CMD);
OLED_WR_Byte(0xA4,OLED_CMD);
OLED_WR_Byte(0xA6,OLED_CMD);
OLED_WR_Byte(0xAF,OLED_CMD);
OLED_WR_Byte(0xAF,OLED_CMD);
OLED_Clear();
OLED_Set_Pos(0,0);
}
实现RTC计时值显示的函数为: void RTC_disp(void)
{
sj[0]=(time_buf[4]>>4)+'0';
sj[1]=(time_buf[4]&0x0f)+'0';
sj[3]=(time_buf[5]>>4)+'0';
sj[4]=(time_buf[5]&0x0f)+'0';
sj[6]=(time_buf[6]>>4)+'0';
sj[7]=(time_buf[6]&0x0f)+'0';
OLED_ShowChar(0,4,sj[0],16);
OLED_ShowChar(8,4,sj[1],16);
OLED_ShowChar(16,4,':',16);
OLED_ShowChar(24,4,sj[3],16);
OLED_ShowChar(32,4,sj[4],16);
OLED_ShowChar(40,4,':',16);
OLED_ShowChar(48,4,sj[6],16);
OLED_ShowChar(56,4,sj[7],16);
}
实现图3所示显示效果的主程序为: int main(void)
{
Hardware_init();
Delay_Ms(500);
OLED_Init();
OLED_Clear();
OLED_ShowString(0,0,"LKS32MC071",16);
OLED_ShowString(0,2,"OLED & DS1302",16);
ds1302_init();
ds1302_write_time();
for (;;)
{
ds1302_read_time();
RTC_ disp ();
GPIO_SetBits(GPIO0, GPIO_Pin_6);
Delay_Ms(400);
GPIO_ResetBits(GPIO0, GPIO_Pin_6);
Delay_Ms(400);
}
}
图3 计时效果
有了DS1302模块的计时功能,就可以和点阵板相配合来实现计时公告牌的功能。
|
赞~!学习一下!