利用51单片机(STC89C52)和DS1302时钟芯片实现实时时钟和可调时钟功能,并在LCD1602液晶屏上显示时分秒。
并在此基础上实现,运用Matlab的GUI工具编辑一个可视化界面,用以跟单片机进行串口通信,既可以在MATLAB中实时修改时钟内容同步到单片机上,也可以在单片机中实时修改时钟内容,同步到PC上。
实现功能为:
运用keil编写时钟程序,烧录到单片机中,时钟程序实现的功能是实现时钟的显示,并且能用开发板上的四个按钮进行时钟的修改,一个按钮进入修改模式,一个按钮对时间进行移位,另两个实现时间的增减。
编辑GUI界面,实现对单片机的控制,其中,GUI界面通过串口采样开发板上时钟的数值,并在GUI界面上进行显示。同样的,可以通过GUI界面实现对开发板上时钟的修改并同步。
实时时钟的实现与上篇文章(51单片机案例(1)——利用DS1302实现实时时钟和可调时钟的功能)基本相同,唯一的区别在于在LCD1602第一行不再显示年月日,而是以固定字符CLOCK:代替。
在上文中,由于我用的是郭天祥的51单片机开发板,而郭天祥的51单片机的四个独立按键S2,S3,S4,S5和LCD1602存在引脚冲突(共用引脚P3),因此选择矩阵键盘第四列的四个按键S9,S13,S17,S21作为上述的四个按键。但是,当我使用串口时,用于串口与P3.0引脚冲突,导致按键S9无法正常使用,因此我这里使用的按键为S4,S13,S17,S21,故在按键中稍作修改。
这里读者也需要确认,请不要与LCD1602引脚、串口引脚冲突即可。
51单片机接收数据利用的是串口相关程序,串口内容可参考文章:51单片机之串口通信详解及代码示例。接收数据利用中断4进行,在中断4函数中,接收串口数据,并赋值给MODE和数组date,让data+1,由于接收的为MODE、时、分、秒、MODE这五个程序,因此当Count>4时置零重新接收。代码如下:
MODE=SBUF;
date[Count]=SBUF;
Count++;
if(Count>4)Count=0;
MODE表示模式,在实时时钟功能中设置的MODE为0和1,为0表示正常显示时间,为1表示调整时间,这时时/分/秒开始闪烁。
在本文中,我们增加了两种MODE模式,分别是2和3,当串口接收到模式2时表示PC端正在修改时钟,这时单片机时钟暂停,等待PC端修改时钟完成;当串口接收到模式3时,表示PC端修改时钟完成,这时单片机时钟继续,代码如下:
switch(MODE){
case 0:TimeShow();break;
case 1:{TimeSet();break;}//设置时间并向MATLAB发送数据【未完待续】
case 2:break; //时钟暂停
case 3:{UART_TimeSet();MODE=0;break;} //时钟继续
}
这里调用UART_TimeSet函数将串口接收的date数组赋值给DS1302_Time数组并显示,代码如下:
//串口设置时钟
void UART_TimeSet(){
DS1302_Time[0]=date[1];
DS1302_Time[1]=date[2];
DS1302_Time[2]=date[3];
LCD_ShowNum(2,1,DS1302_Time[0],2);
LCD_ShowNum(2,4,DS1302_Time[1],2);
LCD_ShowNum(2,7,DS1302_Time[2],2);
DS1302_SetTime();
}
向PC发送数据设置在MODE1模式中,当MODE==1时,即调整完时钟确认后开始发送数据,发送的数据为DS1302_Time数组,代码如下:
else if(MODE==1{
MODE=0;
DS1302_SetTime();
UART_SendByte(DS1302_Time[0]);
UART_SendByte(DS1302_Time[1]);
UART_SendByte(DS1302_Time[2]);}
设置可编辑文本框中实时显示滑动条的值,并设置为整数:
function slider1_Callback(hObject, eventdata, handles)
% hObject handle to slider1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
sliderdata = get(hObject,'Value'); %得到滑动条的值
set(handles.edit1,'string',round(sliderdata)); % 设置滑动条的值,设置的是数值
设置当在可编辑文本框中修改内容,进度条实时修改更新:
function edit1_Callback(hObject, eventdata, handles)
% hObject handle to edit1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
editdata = get(hObject,'String'); %得到可编辑文本的值
set(handles.slider1,'Value',str2num(editdata)); % 设置滑动条的值,设置的是数值,value类型
MATLAB GUI时钟功能的实现利用的是timer函数(TimerFcn),关于其详细内容可以参考文章:MATLAB GUI设计之利用timer函数(TimerFcn)实现定时功能详解,这里也不进行详细介绍。
操作说明如下:
START点击开始,MATLAB开始计时,默认从0开始,也可自行调整。
ADJUST点击进入修改模式,同时单片机开发板亦会进入修改模式,同步调整时分秒,滑动滑动条或在可编辑文本框中输入数值进行调整,调整完成后点击second、minute或hour确认调整的是时、分还是秒。当点击hour时,由于小时为0-23,因此这时滑动条自动修改大小为0-23,对于second和minute,滑动条大小为0-59。
EXIT点击退出界面。
GET点击后打开串口,从单片机中获取数值。
这里介绍一下我的接线,由于郭天祥51单片机板子没有DS1302时钟芯片而我又需要用到,因此这里花两块钱买了一个DS1302,将DS1302的CLK连接P2.6,DAT连接P2.4,RST连接P2.5,如下图所示。
首先将keil程序下载到单片机,然后启动单片机再启动并MATLAB程序。
这时启动单片机,单片机时钟会正常显示,默认从12:59:55开始运行。
这时单独START MATLAB程序,时钟会正常显示,默认从00:00:00开始运行。
利用单片机按钮修改时钟并同步到MATLAB GUI中:在单片机上通过按下四个按键进行修改,这里修改为14:00:12。然后在点击确认确认修改之前,首先在MATLAB GUI中点击GET按钮,然后再点击确认修改,这时单片机和MATLAB会同步到14:00:12同时运行。
利用MATLAB GUI中的ADJUST按钮修改时钟并同步到51单片机中,点击ADJUST按钮后,MATLAB和51单片机按钮同时暂停,这时滑动条、可编辑文本框和三个按钮显示,进行时分秒相应调节。这里调节为06:06:06,调节后点击OK按钮(ADJUST的文本自动变为OK),这时单片机和MATLAB会同步到06:06:06同时运行。
运行视频如下:
单片机串口与PC的通信实现实时时钟和双向可调时钟功能
当然本项目也存在改进空间,比如有一个常见问题是利用单片机按钮修改时钟并同步到MATLAB GUI中:在在点击确认确认修改之前,首先在MATLAB GUI中点击GET按钮,然后再点击确认修改,才能同步到MATLAB GUI中,这样就会造成操作复杂,可以考虑其他方法实现~
ok,以上便是全部内容了,由于本文工作量颇大,代码量很多,因此我设置成了付费,如果需要源代码,联系方式如下【请备注:DS1302】(白嫖党慎入)。
参考: