Mchf支持实时时钟教程
- 格式:pdf
- 大小:2.67 MB
- 文档页数:13
一、表盘设置模块1、设计表盘设置对话框:IDD_SET_SCALE,生成ScaleSetDlg类圆形ID:IDC_ELLIPSE;方形:IDC_RECT;菱形:IDC_RHOMBUS;三角形:IDC_TRIANGLE选择:IDC_OTHER反色:IDC_O金色:IDC_GLOD确定:IDOK;取消:IDCANCLE2、为圆形单选按钮通过类向导添加关联变量IDC_ELLIPSE:int m_type;反色IDC_O:int m_logColor为类添加一个颜色变量COLORREF m_color;3、重载Onpaint()函数:当windows或应用程序请求重画应用程序窗口的一部分时,调用该函数。
void ScaleSetDlg::OnPaint(){CPaintDC dc(this);//设备上下文环境描述符CPen penBorder(PS_SOLID, 1, RGB(255, 255, 255));//白色画笔CPen *ppenOld = dc.SelectObject(&penBorder);//将白色画笔选入设备CBrush brPoint(m_color);//刻度颜色的画刷CBrush* pbrOld = dc.SelectObject(&brPoint);//将刻度颜色的画刷选入设备CRect rectLogcolor;GetDlgItem(IDC_OTHER)->GetWindowRect(&rectLogcolor);//获取空间相对于屏幕位置ScreenToClient(rectLogcolor);//转化为对话框的相对位置dc.FillRect(CRect(rectLogcolor.left + 5, rectLogcolor.top - 25, rectLogcolor.right - 5, rectLogcolor.bottom - 15), &brPoint);dc.SelectObject(ppenOld);//恢复设备最初的画笔dc.SelectObject(pbrOld);//恢复设备最初的画刷}4 为选择按钮添加OnOther()void ScaleSetDlg::OnBnClickedOther(){// TODO: 在此添加控件通知处理程序代码CColorDialog dlg;//CColorDiaDlg里面含有CHOOSECOLOR结构体,而该结构体中的rgbResult含有用户选择的颜色值dlg.m_cc.Flags |= CC_RGBINIT;//颜色对话框,CC_RGBINIT让对话框默认使用由rgbResult指定的颜色dlg.m_cc.rgbResult = m_color;//对话框属性if (IDOK == dlg.DoModal())//CColorDiaDlg::DoModal():返回值为IDOK或IDCANCLE{m_color = dlg.m_cc.rgbResult;//获取用户输入的颜色值Invalidate();}}二、表盘的绘制模块1:创建CClockScale类,添加变量:#include"DeskClock.h"#include <math.h>#define PI 3.1415926COLORREF m_color;//刻度颜色int m_logColor;CPoint m_ptMiddle;//表盘的中心点UINT m_nPointWidth;//表盘刻度之间的宽度MAJORTYPE m_style;//刻度的样式void SetScaleStyle(MAJORTYPE type);void SetScaleColor(COLORREF colorref);void SetLogColor(int color);MAJORTYPE GetScaleStyle();COLORREF GetScaleColor();int GetLogColor();在stdafx.h中定义枚举类型变量:enum MAJORTYPE{TYPE_ELLIPSE = 0,//圆形TYPE_RECT=1,//方形TYPE_RHOMBUS=2,//菱形TYPE_TRIANGLE=3//三角形};2,构造函数:m_color = 0xFF0000;m_style = TYPE_RHOMBUS;m_logColor = 0;3,为所有属性生成set 和get方法在.h中先声明方法:void CClockScale::SetScaleStyle(MAJORTYPE type){m_style = type;}void CClockScale::SetScaleColor(COLORREF colorref) {m_color = colorref;}void CClockScale::SetLogColor(int color){m_logColor = color;}MAJORTYPE CClockScale::GetScaleStyle(){return m_style;}COLORREF CClockScale::GetScaleColor(){return m_color;}int CClockScale::GetLogColor(){return m_logColor;}4,添加位图资源,IDB_LOG, IDB_LOGMASK编写表盘绘制函数void DrawScale(CDC *pDC, CPoint &ptMiddle);void CClockScale::DrawScale(CDC *pDc,CPoint &ptMiddle) {//计算钟面的中心位置m_ptMiddle.x = ptMiddle.x;m_ptMiddle.y = ptMiddle.y;if (m_ptMiddle.y < 0){m_ptMiddle.y = 0;}//计算钟面的半径UINT nRidius = min(m_ptMiddle.x,m_ptMiddle.y);//计算两个刻度之间的距离m_nPointWidth = (int)nRidius/20;// 绘制LOGCBitmap maskbmp,logbmp;maskbmp.LoadBitmap(IDB_LOGMASK);logbmp.LoadBitmap(IDB_LOG);CDC MaskDC,memDC;MaskDC.CreateCompatibleDC(pDc);MaskDC.SelectObject(&maskbmp);memDC.CreateCompatibleDC(pDc);memDC.SelectObject(&logbmp);if(m_nPointWidth > 8){if(m_logColor == 0 ){pDc->BitBlt(m_ptMiddle.x - 25 ,ptMiddle.y - nRidius * 0.7,96,96,&MaskDC,0,0,SRCAND);//该函数对指定的源设备环境区域中的像素进行位块转换,以传送到目标设备环境pDc->BitBlt(m_ptMiddle.x - 25,ptMiddle.y - nRidius * 0.7,96,96,&memDC,0,0,MERGEPAINT);}else if(m_logColor == 1 ){pDc->BitBlt(m_ptMiddle.x - 25 ,ptMiddle.y - nRidius * 0.7,96,96,&MaskDC,0,0,MERGEPAINT);pDc->BitBlt(m_ptMiddle.x - 25,ptMiddle.y - nRidius * 0.7,96,96,&memDC,0,0,SRCAND);}}if (m_nPointWidth < 2){m_nPointWidth = 2;}//保存各个刻度点的位置CPoint ptFace;//设置刻度点的颜色CBrush brPoint(m_color);CBrush* pbrOld = pDc->SelectObject(&brPoint);//刻度所在的圆半径为钟面半径的90%int nFaceLength = MulDiv(nRidius,9,10);//绘制各个刻度for (int nMin=0; nMin<60; nMin++){//bHour为假表示绘制的是分钟刻度BOOL bHour = FALSE;//计算一个刻度点的位置ptFace = ComputerFacePoint(nMin,nFaceLength);//当分钟数是5的倍数时,bHour为真表示绘制小时刻度if (nMin%5==0){bHour = true;}//绘制一个刻度点DrawFacePoint(pDc,ptFace,bHour);}pDc->SelectObject(pbrOld);return;}5,编写计算刻度函数CPoint ComputerFacePoint(UINT min, int nFaceLength)CPoint CClockScale::ComputerFacePoint(UINT min, int nFaceLength){CPoint ptCalc;//将分钟转换为角度数double fDegrees = 180+((15+min)%60)*6;//再转换为弧度数double fAngle = fDegrees/180;//计算刻度点位置ptCalc.x = m_ptMiddle.x + (int)(cos(fAngle*PI)*nFaceLength);ptCalc.y = m_ptMiddle.y + (int)(sin(fAngle*PI)*nFaceLength);//返回刻度点位置return(ptCalc);}6,编写刻度绘制函数void DrawFacePoint(CDC *pDC, const CPoint &ptFace, BOOL bMajor)void CClockScale::DrawFacePoint(CDC *pDC, const CPoint &ptFace, BOOL bMajor){CRect rectPoint(ptFace.x,ptFace.y,ptFace.x,ptFace.y);//绘制小时刻度点if (bMajor){//增加高度和宽度,使单点变为小的矩形区rectPoint.InflateRect((m_nPointWidth/2)+2,(m_nPointWidth/2)+2);DrawMajor(pDC, m_style,rectPoint);}//绘制分钟刻度点else{//只有当刻度点之间的距离足够大时才绘制if (m_nPointWidth > 2){rectPoint.InflateRect(1,1);pDC->Draw3dRect(&rectPoint,GetSysColor(COLOR_BTNHIGHLIGHT),GetSysColor(CO LOR_BTNSHADOW));//COLOR_BTNHIGHLIGHT表示加亮区,COLOR_BTNSHADOW表示按钮的3d阴影}}return;}7,编写表盘小时刻度函数void DrawMajor(CDC *pDC, MAJORTYPE type, CRect rectPoint)void CClockScale::DrawMajor(CDC *pDC, MAJORTYPE type, CRect rectPoint)CPen *oldPen;CPoint ptRhombus[4] ;CPen penBorder(PS_SOLID,1,RGB(255,255,255));switch(type){case TYPE_ELLIPSE:pDC->Ellipse(rectPoint);break;case TYPE_RECT:pDC->Rectangle(&rectPoint);pDC->Draw3dRect(&rectPoint,GetSysColor(COLOR_BTNHIGHLIGHT),GetSysColor(CO LOR_BTNSHADOW));break;case TYPE_RHOMBUS:oldPen = pDC->SelectObject(&penBorder);ptRhombus[1].x = rectPoint.left + rectPoint.Width()/2;ptRhombus[1].y = rectPoint.top;ptRhombus[0].x = rectPoint.left;ptRhombus[0].y = rectPoint.top + rectPoint.Height()/2;ptRhombus[3].x = rectPoint.left + rectPoint.Width()/2;ptRhombus[3].y = rectPoint.bottom;ptRhombus[2].x = rectPoint.right;ptRhombus[2].y = rectPoint.top + rectPoint.Height()/2;pDC->Polygon(ptRhombus,4);pDC->SelectObject(oldPen);break;case TYPE_TRIANGLE:oldPen = pDC->SelectObject(&penBorder);ptRhombus[0].x = rectPoint.left;ptRhombus[0].y = rectPoint.top + rectPoint.Height()/2;ptRhombus[1].x = rectPoint.left + rectPoint.Width()/2;ptRhombus[1].y = rectPoint.top;ptRhombus[2].x = rectPoint.right;ptRhombus[2].y = rectPoint.top + rectPoint.Height()/2;pDC->Polygon(ptRhombus,3);pDC->SelectObject(oldPen);break;}}三:表针模块的设计与实现:1设计对话框IDD_SET_HAND,生成HandSetDlg类时针边框颜色选择:IDC_HBCOLOR指针颜色:IDC_HCOLOR分针边框:IDC_MBCOLOR,指针:IDC_MCOLOR秒针:IDC_SBCOLOR2,为对话框类添加变量:COLORREF m_HbordColor; // 时针边框颜色COLORREF m_HColor;//时针实体颜色COLORREF m_MbordColor;//分针边框颜色COLORREF m_MColor;//分针实体颜色COLORREF m_SbordColor;//秒针颜色3,重载OnPaint()void HandSetDlg::OnPaint(){CPaintDC dc(this); // device context for painting// TODO: 在此处添加消息处理程序代码// 不为绘图消息调用 CDialog::OnPaint()CPen penBorderH(PS_SOLID, 1, RGB(200, 200, 200));CPen *ppenOld = dc.SelectObject(&penBorderH);//绘制时针边框颜色CBrush brPointH(m_HbordColor);CBrush* pbrOld = dc.SelectObject(&brPointH);CRect rectHbcolor;GetDlgItem(IDC_HBCOLOR)->GetWindowRect(&rectHbcolor);//获取空间相对于屏幕位置ScreenToClient(rectHbcolor);//转化为对话框的相对位置dc.FillRect(CRect(rectHbcolor.left+5,rectHbcolor.top-25,rectHbcolor.right-5,rectHbc olor.bottom-15),&brPointH);//绘制时针实体颜色CBrush brH(m_HColor);dc.SelectObject(&brH);CRect rectHcolor;GetDlgItem(IDC_HCOLOR)->GetWindowRect(&rectHcolor);//获取空间相对于屏幕位置ScreenToClient(rectHcolor);//转化为对话框的相对位置dc.FillRect(CRect(rectHcolor.left + 5, rectHcolor.top - 28, rectHcolor.right - 5, rectHcolor.bottom - 18), &brH);//绘制分针边框颜色CBrush brPointM(m_MbordColor);dc.SelectObject(&brPointM);CRect rectMbcolor;GetDlgItem(IDC_MBCOLOR)->GetWindowRect(&rectMbcolor);//获取空间相对于屏幕位置ScreenToClient(rectMbcolor);//转化为对话框的相对位置dc.FillRect(CRect(rectMbcolor.left + 5, rectMbcolor.top - 28, rectMbcolor.right - 5, rectMbcolor.bottom - 18), &brPointM);//绘制分针实体颜色CBrush brM(m_MColor);dc.SelectObject(&brM);CRect rectMcolor;GetDlgItem(IDC_MCOLOR)->GetWindowRect(&rectMcolor);//获取空间相对于屏幕位置ScreenToClient(rectMcolor);//转化为对话框的相对位置dc.FillRect(CRect(rectMcolor.left + 5, rectMcolor.top - 28, rectMcolor.right - 5, rectMcolor.bottom - 18), &brM);//绘制秒针颜色CBrush brS(m_SbordColor);dc.SelectObject(&brS);CRect rectSbcolor;GetDlgItem(IDC_SBCOLOR)->GetWindowRect(&rectSbcolor);//获取空间相对于屏幕位置ScreenToClient(rectSbcolor);//转化为对话框的相对位置dc.FillRect(CRect(rectSbcolor.left + 5, rectSbcolor.top - 28, rectSbcolor.right - 5, rectSbcolor.bottom - 18), &brM);//恢复设备对象dc.SelectObject(ppenOld);dc.SelectObject(pbrOld);}4,为颜色选择对话框添加处理函数:void HandSetDlg::OnBnClickedHbcolor(){// TODO: 在此添加控件通知处理程序代码CColorDialog dlg;//颜色对话框dlg.m_cc.Flags |= CC_RGBINIT;//颜色对话框属性dlg.m_cc.rgbResult = m_HbordColor;//当前指针边框颜色显示到颜色对话框上if (IDOK == dlg.DoModal())//显示颜色对话框{m_HbordColor = dlg.m_cc.rgbResult;//获取用户选择的颜色Invalidate();//重绘界面}// TODO: 在此添加控件通知处理程序代码}void HandSetDlg::OnBnClickedHcolor(){// TODO: Add your control notification handler code hereCColorDialog dlg;dlg.m_cc.Flags |= CC_RGBINIT;dlg.m_cc.rgbResult = m_HColor;if (IDOK == dlg.DoModal()){m_HColor = dlg.m_cc.rgbResult;Invalidate();} // TODO: 在此添加控件通知处理程序代码}void HandSetDlg::OnBnClickedMbcolor(){CColorDialog dlg;dlg.m_cc.Flags |= CC_RGBINIT;dlg.m_cc.rgbResult = m_MbordColor;if (IDOK == dlg.DoModal()){m_MbordColor = dlg.m_cc.rgbResult;Invalidate();} // TODO: 在此添加控件通知处理程序代码}void HandSetDlg::OnBnClickedMcolor(){CColorDialog dlg;dlg.m_cc.Flags |= CC_RGBINIT;dlg.m_cc.rgbResult = m_MColor;if (IDOK == dlg.DoModal()){m_MColor = dlg.m_cc.rgbResult;Invalidate();}//TODO: 在此添加控件通知处理程序代码}void HandSetDlg::OnBnClickedSbcolor(){// TODO: 在此添加控件通知处理程序代码CColorDialog dlg;dlg.m_cc.Flags |= CC_RGBINIT;dlg.m_cc.rgbResult = m_SbordColor;if (IDOK == dlg.DoModal()){m_SbordColor = dlg.m_cc.rgbResult;Invalidate();}四:表针绘制模块:1,创建CClockHand类,添加变量和函数声明:CPoint m_ptMiddle;// 圆心UINT m_nPointWidth;//刻度之间的宽度double m_nRidius;//表盘半径COLORREF m_HbordColor;//时针边框颜色COLORREF m_HColor;//时针实体颜色COLORREF m_MbordColor;//分针边框颜色COLORREF m_MColor;//分针实体颜色COLORREF m_SbordColor;//秒针颜色void SetHandColor(COLORREF hBColor, COLORREF hColor, COLORREF mBColor, COLORREF mColor, COLORREF sColor);void GetHandColor(COLORREF &hBColor, COLORREF &hColor, COLORREF &mBColor, COLORREF &mColor, COLORREF &sColor);void GetHandPoints(int nValue, HANDTYPE typeHand, CPoint *pptHand, CTime oTime);void DrawHand(CDC*pDC, int nValue, HANDTYPE typeHand, CPoint&ptMiddle, CTime oTime); 2,在stdAfx.h中定义HANDTYPEenum HANDTYPE{HOUR_HAND,MINUTE_HAND,SECOND_HAND};3,编写构造函数:CClockHand::CClockHand(): m_ptMiddle(0){m_HbordColor = RGB(255, 255, 255);m_HColor = RGB(128, 128, 0);m_MbordColor = RGB(255, 255, 255);m_MColor = RGB(0, 128, 128);m_SbordColor = RGB(255, 128, 128);}4,编写Set和Get方法void CClockHand::SetHandColor(COLORREF hBColor, COLORREF hColor, COLORREF mBColor, COLORREF mColor, COLORREF sColor){m_HbordColor = hBColor;m_HColor = hColor;m_MbordColor = mBColor;m_MColor = mColor;m_SbordColor = sColor;}void CClockHand::GetHandColor(COLORREF &hBColor, COLORREF &hColor, COLORREF &mBColor, COLORREF &mColor, COLORREF &sColor){hBColor = m_HbordColor;hColor = m_HColor;mBColor = m_MbordColor;mColor = m_MColor;sColor = m_SbordColor;}5根据表针类型以及时间计算对应的表针的坐标的函数注意前面加#include “CClockScale.h”void GetHandPoints(int nValue, HANDTYPE typeHand, CPoint *pptHand,CTime oTime);void CClockHand::GetHandPoints(int nValue, HANDTYPE typeHand, CPoint *pptHand,CTime oTime) {UINT nMinute = oTime.GetMinute();CClockScale Scale;Scale.m_ptMiddle.x = m_ptMiddle.x;Scale.m_ptMiddle.y = m_ptMiddle.y;int nLength = 0;//根据指针的类型区分switch(typeHand){case HOUR_HAND://时针长为钟面半径的一半nLength = MulDiv(m_nRidius, 50, 100);//因为绘制时针按照分针进行,故需要一些变换nValue *= 5;nValue += (nMinute/12);break;case MINUTE_HAND:nLength = MulDiv(m_nRidius, 70, 100);break;case SECOND_HAND:nLength = MulDiv(m_nRidius, 80, 100);break;default:ASSERT(false);}//得到时针和分针外形的四个点if (typeHand == HOUR_HAND || typeHand == MINUTE_HAND){pptHand[0] = puterFacePoint(nValue+30,m_nPointWidth*2);pptHand[1] = puterFacePoint(nValue+15,m_nPointWidth);pptHand[2] = puterFacePoint(nValue,nLength);pptHand[3] = puterFacePoint(nValue-15,m_nPointWidth);}//得到秒针的两个端点else{pptHand[0] = m_ptMiddle;pptHand[1] = puterFacePoint(nValue,nLength);}}6、编写绘制时针指针的函数:void DrawHand(CDC *pDC,int nValue,HANDTYPE typeHand,CPoint &ptMiddle,CTime oTime);void CClockHand::DrawHand(CDC *pDC, int nValue,HANDTYPE typeHand,CPoint &ptMiddle,CTime oTime){m_ptMiddle.x = ptMiddle.x;m_ptMiddle.y = ptMiddle.y;m_nRidius = min(m_ptMiddle.x,m_ptMiddle.y);m_nPointWidth = (int)m_nRidius/20;CPoint ptHand[4];//得到指针的位置GetHandPoints(nValue,typeHand,ptHand, oTime);CBrush brHandH(m_HColor);CPen penHandH(PS_SOLID,1,m_HbordColor);CBrush brHandM(m_MColor);CPen penHandM(PS_SOLID,1,m_MbordColor);CPen penrgb(PS_SOLID,1,m_SbordColor);switch(typeHand){case HOUR_HAND://设置画刷、画笔pDC->SelectObject(&brHandH);pDC->SelectObject(&penHandH);//绘制一个四边形pDC->Polygon(ptHand,4);break;case MINUTE_HAND://设置画刷、画笔pDC->SelectObject(&brHandM);pDC->SelectObject(&penHandM);//绘制一个四边形pDC->Polygon(ptHand,4);break;case SECOND_HAND:pDC->SelectObject(&penrgb);pDC->MoveTo(ptHand[0]);pDC->LineTo(ptHand[1]);break;}}五:数字时钟设置模块:1,设计对话框IDD_SET_NUMTIME:生成NumTimeSeTDlg类表盘内:IDC_IN ;表盘外:IDC_OUT;自定义:IDC_USER;表盘内位置:IDC_COMIN;外:IDC_COMOUTX坐标:IDC_COMX;Y坐标:IDC_COMY;定制...:IDC_COLOR;隐藏:IDC_HIDE;显示:IDC_SHOW;2,添加NumTimeSetDlg类,为控件添加关联变量:IDC_COMIN 类型:CComboBox 变量名:m_comIn;IDC_COMOUT 类型:CComboBox 变量名:m_comOutIDC_COMX;int m_x;IDC_COMY:int m_y;IDC_HIDE:int m_show;IDC_IN :int m_position;IDC_CHECK1:BOOL m_bgColor;添加控制状态的变量:int m_inType;//表盘b内位置int m_outType;//表盘外位置COLORREF m_color;//字体颜色3,添加初始化函数OnInitDiaLog()CDialog::OnInitDialog();// TODO: Add extra initialization herem_comIn.InsertString(0, _T("正上方"));m_comIn.InsertString(1, _T("正下方"));m_comIn.InsertString(2, _T("正左方"));m_comIn.InsertString(3, _T("正右方"));m_comIn.SetCurSel(m_inType);m_comOut.InsertString(0, _T("左上角"));m_comOut.InsertString(1, _T("右上角"));m_comOut.InsertString(2, _T("左下角"));m_comOut.InsertString(3, _T("右下角"));m_comOut.InsertString(4, _T("上侧居中"));m_comOut.InsertString(5, _T("下侧居中"));m_comOut.InsertString(6, _T("左侧居中"));m_comOut.InsertString(7, _T("右侧居中"));m_comOut.SetCurSel(m_outType);SetPositionEnable();return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE4,编写SetPositionEnable()单选位置函数void NumTimeSetDlg::SetPositionEnable(){switch(m_position){case 0:GetDlgItem(IDC_COMIN)->EnableWindow(true);GetDlgItem(IDC_COMOUT)->EnableWindow(false);GetDlgItem(IDC_COMX)->EnableWindow(false);GetDlgItem(IDC_COMY)->EnableWindow(false);break;case 1:GetDlgItem(IDC_COMIN)->EnableWindow(false);GetDlgItem(IDC_COMOUT)->EnableWindow(true);GetDlgItem(IDC_COMX)->EnableWindow(false);GetDlgItem(IDC_COMY)->EnableWindow(false);break;case 2:GetDlgItem(IDC_COMIN)->EnableWindow(false);GetDlgItem(IDC_COMOUT)->EnableWindow(false);GetDlgItem(IDC_COMX)->EnableWindow(true);GetDlgItem(IDC_COMY)->EnableWindow(true);break;}}5,为控件添加处理函数(1)void NumTimeSetDlg::OnIn(){// TODO: 在此添加控件通知处理程序代码UpdateData(true);//获取用户选中状态,UpdateData(true):将控件的值赋值给成员变量,即从窗口编辑框中读取数据,若为false,将成员变量的值赋值给相关联的控件SetPositionEnable();//使能设置}(2)void NumTimeSetDlg::OnOut(){// TODO: Add your control notification handler code hereUpdateData(true);SetPositionEnable();}(3)void NumTimeSetDlg::OnUser(){// TODO: Add your control notification handler code here UpdateData(true);SetPositionEnable();}(4)void NumTimeSetDlg::OnSelchangeComin(){// TODO: Add your control notification handler code here m_inType = m_comIn.GetCurSel();}(5)void NumTimeSetDlg::OnSelchangeComout(){// TODO: Add your control notification handler code here m_outType = m_comOut.GetCurSel();}(6)void NumTimeSetDlg::OnColor(){// TODO: Add your control notification handler code here CColorDialog dlg;dlg.m_cc.Flags|=CC_RGBINIT ;dlg.m_cc.rgbResult=m_color;if(IDOK==dlg.DoModal()){m_color = dlg.m_cc.rgbResult;Invalidate();}}(7)void NumTimeSetDlg::OnHide(){// TODO: Add your control notification handler code here UpdateData(true);}(8)void NumTimeSetDlg::OnShow(){// TODO: Add your control notification handler code here UpdateData(true);}6重写OnPaint()实现将字体颜色绘制到窗体上的功能:void NumTimeSetDlg::OnPaint(){CPaintDC dc(this); // device context for painting// TODO: Add your message handler code hereCPen penBorder(PS_SOLID, 1, RGB(200, 200, 200));CPen *ppenOld = dc.SelectObject(&penBorder);CBrush brPoint(m_color);CBrush* pbrOld = dc.SelectObject(&brPoint);CRect rectcolor;GetDlgItem(IDC_COLOR)->GetWindowRect(&rectcolor);//获取空间相对于屏幕位置ScreenToClient(rectcolor);//转化为对话框的相对位置dc.FillRect(CRect(rectcolor.left + 5, rectcolor.top - 25, rectcolor.right - 5, rectcolor.bottom - 15), &brPoint);dc.SelectObject(ppenOld);//恢复设备最初的画笔dc.SelectObject(pbrOld);//恢复设备最初的画刷}六,数字时钟绘制模块:1,添加CClockNum类,添加变量:public:int m_inType;//表盘内的位置int m_outType;//表盘外的位置int m_position;//数字时钟位置类型int m_pType;/int m_X;//数字时钟横坐标int m_Y;//数字时钟纵坐标COLORREF m_color;//数字时钟的字体颜色bool m_bgColor;//数字时钟字体背景色2.编写构造函数:CClockNum::CClockNum(){m_position = 0;m_inType = 1;m_outType = 5;m_color = RGB(0, 255, 0);m_bgColor = false;}3,编写数字时钟绘制函数void DrawTime(CDC *pDc,CRect rectClient,CTime oTime);//绘制函数void CClockNum::DrawTime(CDC *pDc, CRect rectClient, CTime oTime){SetPosition(rectClient);UINT nHour, nMinute, nSecond;nHour = oTime.GetHour();nMinute = oTime.GetMinute();nSecond = oTime.GetSecond();CString strTime, strHour, strMinute, strSecond;strHour.Format(_T("%d"), nHour);if (nHour <10){strHour.Format(_T("0%d"), nHour);}strMinute.Format(_T("%d"), nMinute);if (nMinute <10){strMinute.Format(_T("0%d"), nMinute);}strSecond.Format(_T("%d"), nSecond);if (nSecond <10){strSecond.Format(_T("0%d"), nSecond);}strTime.Format(_T("%s : %s : %s"), strHour, strMinute, strSecond);pDc->SetTextColor(m_color);if (!m_bgColor){int nBKMode = pDc->SetBkMode(TRANSPARENT);//CDD::SetBkMode,若参数值为OPAQUE时去掉文字背景色,为TRANSPARENT去掉文字背景色pDc->TextOut(m_X, m_Y, strTime);pDc->SetBkMode(nBKMode);}else{pDc->TextOut(m_X, m_Y, strTime);}}4,编写设置数字时钟位置的函数:void SetPosition(CRect rectClient);//设置数字时钟位置的函数void CClockNum::SetPosition(CRect rectClient){CPoint ptMiddle;ptMiddle.x = rectClient.Width() / 2;ptMiddle.y = rectClient.Height() / 2 - 15;int nRidius = min(ptMiddle.x, ptMiddle.y);if (m_position == 0){ // 内部switch (m_inType){case 0: // 上m_X = ptMiddle.x - 35;m_Y = ptMiddle.y - nRidius * 0.7;break;case 1: // 下m_X = ptMiddle.x - 35;m_Y = ptMiddle.y + nRidius * 0.7;break;case 2: // 左m_X = ptMiddle.x - nRidius * 0.8 + 25;m_Y = ptMiddle.y;break;case 3: // 右m_X = ptMiddle.x + nRidius * 0.8 - 95;m_Y = ptMiddle.y;break;}}else if (m_position == 1){ // 外部switch (m_outType){case 0: // 左上角m_X = 22;m_Y = 10;break;case 1: // 右上角m_X = rectClient.right - 100;m_Y = 10;break;case 2: // 左下角m_X = 22;m_Y = rectClient.bottom - 30;break;case 3: // 右下角m_X = rectClient.right - 96;m_Y = rectClient.bottom - 30;break;case 4: // 上侧居中m_X = ptMiddle.x - 33;m_Y = 2;break;case 5: // 下侧居中m_X = ptMiddle.x - 33;m_Y = rectClient.bottom - 30;break;case 6: // 左侧居中m_X = 10;m_Y = ptMiddle.y;break;case 7: // 右侧居中m_X = rectClient.right - 86;m_Y = ptMiddle.y;break;}}}七,数字日期模块的设置:1,创建对话框IDD_SET_DATE;生成DateSetDlg类;左右分布:IDC_LEFT;上下分布:IDC_UP;表盘内:IDC_IN;表盘外:IDC_OUT日期颜色定制:IDC_DATECOLOR;星期颜色定制:IDC_WEEKCOLOR 隐藏:IDC_HIDE;显示:IDC_SHOW;2,为控件添加关联变量:IDC_COMIN:CComboBox m_comIn;IDC_COMOUT:CComboBox m_comOut;IDC_IN :int m_in;IDC_HIDE:int m_show;IDC_UP:int m_up;在.h文件下添加其余变量:COLORREF m_dColor; // 日期颜色COLORREF m_wColor; // 星期颜色int m_inType;int m_outType;3.添加初始化函数:BOOL DateSetDlg::OnInitDialog(){CDialog::OnInitDialog();m_comIn.InsertString(0, _T("正上方"));m_comIn.InsertString(1, _T("正下方"));m_comIn.InsertString(2, _T("正左方"));m_comIn.InsertString(3, _T("正右方"));m_comIn.SetCurSel(m_inType);m_comOut.InsertString(0, _T("左上角"));m_comOut.InsertString(1, _T("右上角"));m_comOut.InsertString(2, _T("左下角"));m_comOut.InsertString(3, _T("右下角"));m_comOut.SetCurSel(m_outType);SetPositionEnable();return TRUE;}4,编写SetPositionEnable()单选位置函数void SetPositionEnable();void DateSetDlg::SetPositionEnable(){if(m_up == 0){GetDlgItem(IDC_IN)->EnableWindow(false);GetDlgItem(IDC_COMIN)->EnableWindow(false);GetDlgItem(IDC_OUT)->EnableWindow(false);GetDlgItem(IDC_COMOUT)->EnableWindow(false);return;}if(m_in == 0){GetDlgItem(IDC_IN)->EnableWindow(true);GetDlgItem(IDC_COMIN)->EnableWindow(true);GetDlgItem(IDC_OUT)->EnableWindow(true);GetDlgItem(IDC_COMOUT)->EnableWindow(false);}elseGetDlgItem(IDC_IN)->EnableWindow(true);GetDlgItem(IDC_COMIN)->EnableWindow(false);GetDlgItem(IDC_OUT)->EnableWindow(true);GetDlgItem(IDC_COMOUT)->EnableWindow(true);}}5,为控件添加事件处理函数void DateSetDlg::OnUp(){// TODO: Add your control notification handler code here UpdateData(true);SetPositionEnable();}void DateSetDlg::OnLeft(){// TODO: Add your control notification handler code here UpdateData(true);SetPositionEnable();}void DateSetDlg::OnIn(){// TODO: Add your control notification handler code here UpdateData(true);SetPositionEnable();}void DateSetDlg::OnOut(){// TODO: Add your control notification handler code here UpdateData(true);SetPositionEnable();}void DateSetDlg::OnDatecolor(){// TODO: Add your control notification handler code here CColorDialog dlg;dlg.m_cc.Flags |= CC_RGBINIT;dlg.m_cc.rgbResult = m_dColor;if (IDOK == dlg.DoModal())m_dColor = dlg.m_cc.rgbResult;Invalidate();}}void DateSetDlg::OnWeekcolor(){// TODO: Add your control notification handler code here CColorDialog dlg;dlg.m_cc.Flags |= CC_RGBINIT;dlg.m_cc.rgbResult = m_wColor;if (IDOK == dlg.DoModal()){m_wColor = dlg.m_cc.rgbResult;Invalidate();}}void DateSetDlg::OnSelchangeComIn(){// TODO: Add your control notification handler code here m_inType = m_comIn.GetCurSel();}void DateSetDlg::OnSelchangeComOut(){// TODO: Add your control notification handler code here m_outType = m_comOut.GetCurSel();}void DateSetDlg::OnShow(){// TODO: 在此添加控件通知处理程序代码UpdateData(true);SetPositionEnable();}void DateSetDlg::OnHide(){// TODO: 在此添加控件通知处理程序代码UpdateData(true);SetPositionEnable();}6,重载OnPaint()void DateSetDlg::OnPaint(){CPaintDC dc(this); // device context for paintingCPen penBorder(PS_SOLID, 1, RGB(200, 200, 200));CPen *ppenOld = dc.SelectObject(&penBorder);CBrush brPoint(m_dColor);CBrush* pbrOld = dc.SelectObject(&brPoint);CRect rectDcolor;GetDlgItem(IDC_DATECOLOR)->GetWindowRect(&rectDcolor);//获取空间相对于屏幕位置ScreenToClient(rectDcolor);//转化为对话框的相对位置dc.FillRect(CRect(rectDcolor.left + 5, rectDcolor.top - 25, rectDcolor.right - 5, rectDcolor.bottom - 15), &brPoint);CBrush brPointw(m_wColor);dc.SelectObject(&brPointw);CRect rectWcolor;GetDlgItem(IDC_WEEKCOLOR)->GetWindowRect(&rectWcolor);//获取空间相对于屏幕位置ScreenToClient(rectWcolor);//转化为对话框的相对位置dc.FillRect(CRect(rectWcolor.left + 5, rectWcolor.top - 25, rectWcolor.right - 5, rectWcolor.bottom - 15), &brPointw);dc.SelectObject(ppenOld);//恢复设备最初的画笔dc.SelectObject(pbrOld);//恢复设备最初的画刷}八、数字日期的绘制模块1、创建CClockDate类,添加变量:int m_inType;//在表盘内部的位置int m_outType;//在表盘外部的位置int m_position;//数字日期的位置bool m_bUp;//日期与星期的位置关系(上下还是左右)int m_DX;//日期的横坐标int m_DY;//日期的纵坐标int m_WX;//星期的横坐标int m_WY;//星期的纵坐标COLORREF m_dColor;//日期的字体颜色COLORREF m_wColor;//星期的字体颜色2.编写构造函数:CClockDate::CClockDate(){m_dColor = RGB(0,255,0);m_wColor = RGB(0,255,0);m_position = 0;m_inType = 1;m_outType = 1;m_bUp = false;}3,绘制数字时钟:DrawDate()void DrawDate(CDC *pDc, CRect rectClient,CTime oTime);void CClockDate::DrawDate(CDC *pDc, CRect rectClient, CTime oTime) {SetPosition(rectClient);/*UINT nYear, nMonth, nDay, nDayOfWeek;nYear = oTime.GetYear();nMonth = oTime.GetMonth();nDay = oTime.GetDay();CString strDate, strYear, strMonth, strDay, strDayOfWeek;strYear.Format(_T("%d"), nYear);strMonth.Format(_T("%d"), nMonth);if (nMonth <10){strMonth.Format(_T("0%d"), nMonth);}strDay.Format(_T("%d"), nDay);if (nDay <10){strDay.Format(_T("0%d"), nDay);}strDate.Format(_T("%s年%s月%s日"), strYear, strMonth, strDay);strDayOfWeek = weekDay(oTime);*/CString strDate = CTime::GetCurrentTime().Format("%Y年%m月%d日");CString strDayOfWeek = weekDay(oTime);int nBKMode = pDc->SetBkMode(TRANSPARENT);pDc->SetTextColor(m_dColor);pDc->TextOut(m_DX, m_DY, strDate);pDc->SetTextColor(m_wColor);pDc->TextOut(m_WX, m_WY, strDayOfWeek);pDc->SetBkMode(nBKMode);}4,计算星期几日期的位置计算函数:SetPosition()void SetPosition(CRect rectClient);void CClockDate::SetPosition(CRect rectClient){CPoint ptMiddle;ptMiddle.x = rectClient.Width()/2;ptMiddle.y = rectClient.Height()/2 - 15;int nRidius = min(ptMiddle.x,ptMiddle.y);if(!m_bUp){m_DX = ptMiddle.x + nRidius * 0.8 - 110;m_DY = ptMiddle.y + 20 ;m_WX = ptMiddle.x - nRidius * 0.8 + 35;m_WY = ptMiddle.y + 20 ;return;}if(m_position == 0){ // 内部switch(m_inType){case 0: // 上m_DX = ptMiddle.x - 46;m_DY = ptMiddle.y - nRidius * 0.7 + 50;m_WX = ptMiddle.x - 16;m_WY = ptMiddle.y - nRidius * 0.7 + 30;break;case 1: // 下m_DX = ptMiddle.x - 46;m_DY = ptMiddle.y + nRidius * 0.7 - 50;m_WX = ptMiddle.x - 16;m_WY = ptMiddle.y + nRidius * 0.7 - 30;break;case 2: // 左m_DX = ptMiddle.x - nRidius * 0.8 + 10;m_DY = ptMiddle.y + 50;m_WX = ptMiddle.x - nRidius * 0.8 + 45;m_WY = ptMiddle.y + 30 ;。
2011 年 10 月文档 ID 022298 第 1 版1/21AN3988应用笔记适用于 STM32F40x/41x 微控制器的时钟配置工具简介本应用笔记介绍了适用于 STM32F4xx 微控制器系列的时钟系统配置工具。
此工具的目的是帮助用户配置微控制器时钟,并将电源和 Flash 访问模式等参数考虑在内。
此配置工具在“STM32F4xx_Clock_Configuration_VX.Y .Z.xls ”文件中实现,该文件随 STM32F4xx 标准外设库提供,并可以从 下载。
此工具支持 STM32F4xx 的下列功能:●配置系统时钟、HCLK 源和输出频率。
●配置 Flash 延迟(等待周期数取决于 HCLK 频率)。
●设置 PCLK1、PCLK2、TIMCLK (定时器时钟)、USBCLK 和 I2SCLK 频率。
●生成含有上述全部设置的可直接使用的 system_stm32f4xx.c 文件(STM32F4xx CMSIS Cortex-M4 器件外设访问层系统源文件)。
在本文档中,STM32F4xx_Clock_Configuration_VX.Y .Z.xls 称为“时钟工具”。
在使用时钟工具之前,必须阅读 STM32F4xx 微控制器参考手册 (RM0090)。
本应用笔记不是参考手册的替代。
此工具仅支持 A 版 STM32F4xx 。
注:对于 VX.Y .Z ,请参见工具版本,例如 V1.0.0目录AN3988目录1词汇表 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52使用入门 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.1软件要求 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.2硬件要求 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72.2.1简介 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72.2.2STM32F4xx 微控制器的时钟方案 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72.2.3I2S 时钟发生器 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93教程 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113.1向导模式 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113.1.1分步过程 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113.2专家模式 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 4已知限制 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 5结论 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 6版本历史 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202/21文档 ID 022298 第 1 版AN3988表格索引表格索引表 1.术语定义. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5表 2.等待周期数与 CPU 时钟 (HCLK) 频率对应关系 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9表 3.文档版本历史 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20文档 ID 022298 第 1 版3/21图片索引AN3988图片索引图 1.时钟方案. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8图 2.I2S 时钟发生器架构 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9图 3.向导模式用户界面. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11图 4.HSE 值超出范围. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12图 5.VDD 超出范围. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12图 6.HCLK 错误消息. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13图 7.选择时钟源 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13图 8.无可用配置错误. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14图 9.文件生成错误 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14图 10.专家模式用户界面. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15图 11.超出系统时钟频率. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16图 12.超出 PLL 输入频率 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16图 13.I2S 频率超出范围 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 4/21文档 ID 022298 第 1 版AN3988词汇表1 词汇表表 1.术语定义术语说明HCLK AHB 时钟PCLK1APB1 时钟PCLK2APB2 时钟TIMCLK定时器时钟USB OTG FS USB 全速 OTGF CPU Cortex-M4 时钟Ext.Clock外部时钟V DD电源HSI高速内部时钟HSE高速外部时钟MCLK主时钟I2S内部集成音频Fs采样频率I2SCLK I2S 时钟RNG随机数发生器SDIO安全数字输入/输出接口文档 ID 022298 第 1 版5/21使用入门AN3988 2 使用入门本节介绍开始使用时钟工具所需的系统要求和步骤。
MSP430F5系列16位超低功耗单片机模块原理第14章RTC 实时时钟A版本: 1.0日期: 2008.9.原文: TI slau208.pdf (5xxfamily User's Guide)翻译: 周欣南京信息工程大学编辑: DC 微控技术论坛版主注:以下文章是翻译TI slau208.pdf 文件中的部分内容。
由于我们翻译水平有限,有整理过程中难免有所不足或错误;所以以下内容只供参考.一切以原文为准。
文章更新详情请密切留意微控技术论坛。
Page 1 of 14第14章实时时钟A实时时钟模块提供了具有日历模式、灵活可编程闹钟和校准的时钟计数器。
这一章节介绍了实时时钟A模块。
实时时钟模块A执行于MSP430X5XX器件中。
14.1 实时时钟介绍实时时钟模块提供了一个具有可以配置成一般目的计数器的日历时钟。
实时时钟特点有:l可配置成实时时钟模式或者一般目的的计数器l在日历模式中提供了秒钟,分钟,小时,星期,日期,月份和年份l具有中断能力l实时时钟模式里可选择BCD码或者二进制格式l实时时钟模式里具有可编程闹钟l实时时钟模式里具有时间偏差的逻辑校正实时时钟框图见图14-1。
注意:实时时钟初始化实时时钟模块的大多数寄存器没有初始条件。
在使用这个模块之前,用户必须通过软件对寄存器进行配置。
Page 2 of 14Page 3 of 14图14-1 实时时钟14.2 实时时钟操作实时时钟模块可以被配置成具有日历作用的实时时钟或者是一个具有RTCMODE 比特一般目的的32位计数器。
14.2.1 计数器模式当RTCMODE 被重置时,计数器模式被选择。
在这个模式中,通过软件可以得到一个32位的计数器。
从日历模式切换到计数器模式是通过重置计数值(RCTNT1,RCTNT2,RCTNT3,RCTNT4),和预换算计数器(RT0PS,RT1PS)。
时钟的增量计数器可源于ACLK、SMCLK或者是分频之后的ACLK或SMCLK。
M41ST84实时时钟的读操作
一、读操作的开始条件
M41ST84的读操作由一个代表START标志的高电平来开始。
二、普通读模式
1.两个阶段
普通读模式是一种包含完整寻址过程的读设备模式。
他包含寻址和读数据两个阶段。
两个阶段都要进行从设备地址寻址,但他们的读写模式不同。
2.寻址
寻址阶段为写模式,因为该阶段不仅要写入从设备地址,还要以写模式写入指定的字节索引地址。
该阶段拥有完整的START和STOP标志,在STOP标志后跟随读取过程时序。
3.读取
读取过程中利用第二次发送从地址和读状态模式,用以使从设备确认读取过程开始。
并在每一个ACK后发送开始数据直到发送STOP标志,使从设备停止发送数据。
三、交替读模式
1.寻址
本模式中只发送从设备地址到I2C总线上。
2.读取
读取过程可看作一个普通读模式的读取过程的延续。
其方式和过程近似于普通读模式的读取过程。
time库的clock用法-回复"clock"是Python中的一个时间库,它提供了一种测量时间的方法。
它可以用来计算程序的运行时间,了解程序的性能,并进行时间戳的转换。
在本文中,我们将详细介绍"clock"库的用法,并通过一些示例帮助您理解其功能。
首先,我们需要导入"clock"库。
在Python中,可以通过以下方式导入:pythonimport time导入后,我们可以开始使用"clock"库来测量程序的运行时间。
"clock"库中有两个主要的函数可用于此目的:1. "clock()": 用于测量程序的运行时间。
它返回从程序启动到当前时间的秒数,可以用来计算程序的执行时间。
2. "sleep()": 用于暂停程序的执行,以模拟程序中的延迟。
它接受一个浮点数参数,表示需要暂停的秒数。
让我们以一个简单的例子开始,计算一个函数的执行时间。
假设我们有一个计算斐波那契数列的函数,它接受一个整数作为参数,并返回相应位置的斐波那契数。
我们将使用"clock"函数来测量该函数的运行时间。
以下是代码示例:pythonimport timedef fibonacci(n):if n <= 0:return 0elif n == 1:return 1else:return fibonacci(n-1) + fibonacci(n-2)start_time = time.clock()result = fibonacci(10)end_time = time.clock()execution_time = end_time - start_timeprint("Execution time:", execution_time, "seconds")在上面的代码中,我们定义了一个名为"fibonacci"的递归函数,用于计算斐波那契数列。
php实时倒计时的三种实现方法实例php实时倒计时的三种实现方法实例导语:php实时倒计时的实现方法,你会吗?下面的是店铺为大家搜集的php实时倒计时的三种实现方法实例,希望对你能有所帮助。
要求:1、要有小时分钟秒的实时倒计时的显示。
2、用户端修改日期时间不会影响到倒计时的正常显示(也就是以服务器时间为准)。
其实这和很多考试等系统时间限制功能的要求一样。
解决思路:1、总不能用ajax每秒都获取服务器时间吧,所以实时倒计时一定要用javascript实现。
这很简单,网上一大把的例子。
2、现在问题是解决用户端修改日期时间对我们的'显示的影响。
解决的办法是计算出用户端的时间和服务器的时间差,这样问题就完全解决了,只需要运行一次php,实时倒计时的时间就和服务器的时间同步了。
理论是同步的,但实际测试会有1秒的误差(具体原因就是和网速有关,网速越快,误差就越小),但这决不会影响到我们上面的要求了。
代码1:<?php //php的时间是以秒算,js的时间以毫秒算date_default_timezone_set("Asia/Hong_Kong");//地区//配置每天的活动时间段 $starttimestr = "09:00:00"; $endtimestr = "18:30:00"; $starttime = strtotime($starttimestr); $endtime = strtotime($endtimestr); $nowtime = time(); $lefttime = $endtime-$nowtime;//实际剩下的时间(秒) ?>代码2,修改了代码1的一些bug: <?php //php的时间是以秒算,js的时间以毫秒算date_default_timezone_set("Asia/Hong_Kong");//地区//配置每天的活动时间段 $starttimestr = "09:00:00"; $endtimestr = "18:30:00"; $starttime = strtotime($starttimestr); $endtime = strtotime($endtimestr); $nowtime = time(); $lefttime =$endtime-$nowtime;//实际剩下的时间(秒) ?>代码3,思路不同,简单多了:<?php //php的时间是以秒算,js的时间以毫秒算date_default_timezone_set("Asia/Hong_Kong");//地区//配置每天的活动时间段 $starttimestr = "09:00:00"; $endtimestr = "13:50:00"; $starttime = strtotime($starttimestr); $endtime = strtotime($endtimestr); $nowtime = time(); if ($nowtime<$starttime){ die("活动还没开始,活动时间是:{$starttimestr}至{$endtimestr}"); } $lefttime = $endtime-$nowtime;//实际剩下的时间(秒)。
HT49 MCU中Time Base(时基)的使用说明文件编码:HA0025s本文主要介绍HT49系列中Time Base(时基)的使用方法和注意事项简单介绍Time Base可以提供一个周期性溢出时间周期以产生规则性的内部中断。
时钟来源在掩膜时选择,有系统时钟/4(指令时钟),实时时钟振荡器,看门狗振荡器三种选择,若选择系统时钟/4为时钟来源,则在HALT状态下,Time Base会停止工作,选其它两个则不会。
掩膜时还可选择它的溢出时间周期为时钟来源/212~时钟来源/215;一旦Time Base产生溢出时间信号,在正常情况下,程序会跳到14H去调用该中断服务子程序。
Time Base的溢出时间信号也可提供给定时/计数器1,作为其时钟来源,以便获得更长的溢出时间周期。
应用举例掩膜选择:时钟来源为内部WDT振荡器Timer1的时钟来源为Time Base时钟Time Base频率为时钟来源/215LCD duty:1/4 duty程序描述:1.开始LCD仿真显示信息“WAIT”2.产生第一次Time Base中断,显示信息“THE 1 TBI”3.第二次Time Base溢出时间信号使定时/计数器1溢出(其计数初值为0FEH),则显示信息“TMER1 OV”其中LCD仿真用49timebase说明:使用LCD只是为了比较直观地看到Time Base中断产生程序清单如下:;――――――――――――――――――――――――――――――――――――――;FILE NAME:49TIMEBASE.ASM;目的:为了说明Time Base的使用;;;;―――――――――――include ht49r50a-1.incdata .section ‘data’count db ?;―――――――――――code .section ‘code’00horgstartjmporg10htimer1;跳到定时/计数器1中断服务子程序jmp14horgtimebase ;跳到Time Base中断服务子程序jmp;―――――――――――org 20hstart:count ;显示“WAIT”clrbpclrsetbp.0mov a,40hmp1,amovmova,01hmov [02h],a ;显示操作结束set intc0.0 ;开总中断mova,03h ;开定时/计数器1和Time Base中断intc1,amova,80h ;设定定时/计数器1的计数模式movmovtmr1c,a;设定定时/计数器1的初值mova,0fehtmr1,amovtmr1c.4 ;允许定时/计数器1计数setjmp $ ;原地踏步timer1: ;定时/计数器1溢出中断服务程序clr bp ;显示信息“ TIMER1 OV”bp.0setmov a,40hmp1,amova,08hmovmov[02h],a ;显示操作结束reti ;定时/计数器溢出后,程序结束Base中断服务子程序timebase: ;Timeinccount ;计时基time base的中断次数a,countmova,02hsubszacc ;判断中断是否满2次firstjmpretifirst:;TimeBase第一次中断时,显示信息“THE 1 TB1”bpclrbp.0seta,40hmovmp1,amova,02hmov[02h],a ;显示操作结束movreti ;显示操作结束,中断返回end校对日期:2001/8/27校对人:邓纲校对内容:1. 第一页12行把“超时”改成“溢出”2. 第一页15行把“超时”改为“溢出”3. 第一页25行插入“LCD duty:1/4 duty”4. 把所有的“超时”改为“溢出”问题:1. HT49C50的TIMER1中断时常不能响应2. 使用HT49C50-1时不能使用使用ICE2000中的TOOLS ---LCD SIMULATOR选项,但是如果在使用HT49C50时打开了TOOLS ---LCD SIMULATOR选项,则当MCU被改成HT49C50-1时可以继续使用LCD SIMULATOR。
1. Linux下有两类时钟:1.1 实时钟RTC它由板上电池驱动的“Real Time Clock”也叫做RTC或者叫CMOS时钟,硬件时钟。
当操作系统关机的时候,用这个来记录时间,但是对于运行的系统是不用这个时间的。
1.2 系统时钟“System clock”也叫内核时钟或者软件时钟,是由软件根据时间中断来进行计数的,内核时钟在系统关机的情况下是不存在的,所以,当操作系统启动的时候,内核时钟是要读取RTC时间来进行时间同步.2. 标准计时器2.1 时钟滴答计时(jiffies)的几个基本参数2.1.1 时钟周期(clock cycle)的频率-晶振频率计时器Timer晶体振荡器在1秒内产生的时钟脉冲个数就是时钟周期的频率, 要注意把这个Timer的时钟周期频率与时钟中断的频率区别开来, Linux用宏CLOCK_TICK_RATE来表示计时器的输入时钟脉冲的频率(比如我的为#define CLOCK_TICK_RATE 1193180),该宏定义在arm/mach-xxx/include/mach/timex.h头文件中。
2.1.2 时钟中断(clock tick)我们知道当计数器减到0值时,它就在IRQ0上产生一次时钟中断,也即一次时钟中断, 计数器的初始值决定了要过多少时钟周期才产生一次时钟中断,因此也就决定了一次时钟滴答的时间间隔长度.2.1.3 时钟中断的频率(HZ)即1秒时间内Timer所产生的时钟中断次数。
确定了时钟中断的频率值后也就可以确定Timer的计数器初值。
Linux内核用宏HZ来表示时钟中断的频率,而且在不同的平台上HZ有不同的定义值。
对于SPARC、MIPS、ARM和i386等平台HZ的值都是100。
该宏在ARM平台上的定义如下(/arch/arm/include/asm/param.h)2.1.4 计数器的初始值计数器的初始值由宏LATCH定义在文件:include/linux/jiffies.h#define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */ 2.1.5 jiffies在Linux 内核中,时间由一个名为jiffies 的全局变量衡量,该变量标识系统启动以来经过的滴答数。
用C8051FXXX系列芯片实现实时时钟功能
Cugnal Integrated Products, Inc
【期刊名称】《电子质量》
【年(卷),期】2001(000)011
【摘要】当系统时钟使用高频内置振荡器时,辅助振荡器可用来驱动石英作实时时钟(RTC).系统时钟信号可取自内置和辅助振荡器,改变RTC信号源时不会降低其精度,RTC使用定时器2,它是为给辅助输入信号下降沿计数而设置的.CPO用来把石英振荡波形转换成方波.
【总页数】3页(P69-71)
【作者】Cugnal Integrated Products, Inc
【作者单位】无
【正文语种】中文
【中图分类】TN4
【相关文献】
1.串行的多功能实时时钟芯片MC68HC68T1 [J], 罗杰;魏丰;龚洁
2.PIC系列单片机片内定时器实时时钟的实现 [J], 孙东胜;王继雄;王福源
3.实时时钟芯片x1226使用设计与功能实现 [J], 孙宏志;束杨;靳程;董其武;雷晨;孙艺玫
4.基于增强51芯片W77E516和RV8803-C7实时时钟的实现方法 [J], 韩霜
5.恩智浦推出射频芯片系列,用于实现长距离智能汽车钥匙功能 [J],
因版权原因,仅展示原文概要,查看原文内容请购买。
STM32-实时时钟(RTC)STM32系列基于专为要求高性能、低成本、低功耗的嵌入式应用专门设计的ARM Cortex®-M0,M0+,M3, M4和M7内核(ST's product portfolio contains a comprehensive range of microcontrollers, from robust, low-cost 8-bit MCUs up to 32-bit ARM-based Cortex®-M0 and M0+, Cortex®-M3, Cortex®-M4 Flash microcontrollers with a great choice of peripherals. ST has also extended this range to include an ultra-low-power MCU platform) 。
实时时钟(RTC)是一个专用于保持时间的计时元素。
在许多的应用中,特别是在需要执行精确定时操作的应用,RTC是非常有用的工具。
除了钟表这类应用的例子外还包括洗衣机、医药柜、数据记录仪等。
RTC基本上是一个定时计数器,但和MCU的其他定时器不同的是,它更精确一些。
在此之前文章中,我们探讨了STM32定时器,但他们对PWM生成、时基和其它波形相关任务的应用程序是有用的。
那些都不适合于精确的计时功能。
在大多数的8位MCU中,像普通的PIC和AVR,并有没有内置RTC模块,所以当我们需要一个板载的精确计时器件时,只能使用类似常见的DS1302或PCF8563的专用RTC 芯片。
这些芯片还需要一些额外的电路、布线以及电路板空间。
但是,目前大多数先进的微控制器都集成了设计人员可以想到的每一个可能的硬件。
这仅取决于设计者决定使用现代微控制器的哪个资源,来满足特定的设计目标。
制造用于满足应用特定需求的MCU的时代已经过去了,在设计中使用并涉及多个元件的时代也已经过去了。
VxWorks for x86 系统中实时时钟的应用0 引言VxWorks 是美国WRS(Wind River System)公司推出的一个具有微内核、可裁剪的高性能强实时操作系统,该实时操作系统在航空、广播、运输、医疗、自动化生产和科学研究等领域中有着广泛的应用,尤其是在国防和军事上的一些高精尖技术及实时性要求极高的领域中,就更体现出了其优越的性能。
X86 或80X86 是Intel 公司开发的微处理器体系结构的泛称。
采用X86 架构的Intel CPU 及其兼容CPU 都使用X86 指令集,作为个人计算机的标准平台,它们构成了当今数量最大的CPU 阵营。
VxWorks 可支持多种不同体系结构的32 位CPU,其中就包括现在使用最为广泛的X86 系列CPU。
1 VxWorks for x86 系统中的系统时间我们知道,在VxWorks for x86 系统中没有直接读取RTC(实时时钟控制器)的函数,在目标板每次加电或重启后,用time.h 中的函数第一次读到的时间始终是“THU JAN 01 00:00:00 1970”。
这里取到的系统时间是从开机到现在的时间,也就是说,VxWorks 的系统日期和时间是相对于一个基准的日期时间计算出来的,这一基准时间就是“THU JAN O1 00:00:00 1970”,其他日期时间对系统来说都是相对于这一基准时间已经过的秒数。
因此,这样取到的系统时间是没有任何使用价值的。
然而,在实际应用中,我们经常需要用到“真实的”VxWorks系统时间,比如在文件系统中创建文件时,我们就希望文件创建的时间是实时时钟的时间,同时在日志文件中记录的时间也希望是实时时钟的时间。
但是,在文件系统中能直接访问的却是上述那个“没有使用价值的”系统时间。
这种情况就为应用带来了很大的不便。
为了获得一个有实际使用价值的系统时间,我们就需要系统时间能与目标板的实时时钟保持同步。
实际上。
TI Stellaris LM4F 定时器(Timer)指南[作者: Richard Ma][Email: ******************]1.功能介绍 (1)2.定时器模式(Timer) (2)2.1.单次运行与连续运行模式 (2)2.2.定时器程序设置 (2)2.3.定时器读取及中断设置 (3)2.4.示例程序 (4)3.捕捉模式(Capture) (7)3.1.边沿计数模式 (7)3.1.1.功能介绍 (7)3.1.2.边沿计数程序设置 (7)3.1.3.边沿计数程序示例 (10)3.2.边沿计时模式 (12)3.2.1. 功能介绍 (12)3.2.2. 边沿计时程序设置 (13)3.2.3. 边沿计时程序示例 (14)4.附录 (17)Texas Instruments在Stellaris LM4F上提供了更多更强大的定时器(Timer)模块,除了传统的32/16-bit定时器,更增加了64/32-bit定时器。
这些定时器均支持定时器(Timer)模式、捕捉(Capture)模式以及PWM模式。
本文主要介绍Timer和Capture 模式的用法。
1.功能介绍LM4F的定时器模块有两种,一种是32/16-bit的,另一种是64/32-bit的。
每一个定时器模块,可以单独工作(如32/16-bit作为32-bit定时器使用),或拆为两个独立定时器A和B进行工作(如32/16-bit作为两个16-bit定时器使用)。
下表对定时器模块支持的功能做了一个汇总:2.定时器模式(Timer)2.1.单次运行与连续运行模式定时器的基本功能为计数(包括加计数和减计数两种),Stellaris LM4F中以系统时钟为计数节拍(当计数器被拆分使用时可以使用预分频功能,为了简单起见这里不作讨论)。
当加计数时,计数器由零开始,逐步加一,直到到达用户预设值;减计数则由某一用户预设值开始,逐步减一,直到计数为零。
HD系列实时钟模块编程说明作者:技术支持部胡富云一、概述HD系列手持终端目前使用两个型号的RTC实时钟模块,分别为3511及35190芯片,另外,GPRS模块也具备实时钟功能,CDMA模块可以通过取基站时钟来恢复本地系统时钟,下面将简单介绍下各个模块的取时间及设置时间方法二、3511模块函数列表int get_all_time_for_3511( typ_RTC_date_rec * pdr, typ_RTC_time_rec * ptr); //取3511模块时间,typ_RTC_date_rec,typ_RTC_time_rec分别为结构体,在API.H中有定义void reset_3511(void);unsigned char get_state_3511(void);void set_state_3511(unsigned char cstat);int set_all_time_for_3511( typ_RTC_date_rec dr, typ_RTC_time_rec tr); //设置3511模块时间void set_time_for_3511( typ_RTC_time_rec tr);int time_okay_3511(void); //检测模块运行是否正常#define init_3511() { reset_3511(); set_state_3511(0x40);} //模块重启设置3511时间示例{if(time_okay_3511() == 0) //如果模块运行不正常,则重新初始化模块init_3511();if(time_okay_3511() != 0){sys_date.l_word = RTC_read_date();sys_time.l_word = RTC_read_time();set_all_time_for_3511(sys_date, sys_time); //将系统时间同步给3511时钟}}获取3511时钟来同步系统时间示例if(time_okay_3511() == 0){init_3511();}if(time_okay_3511() == 0){}else{typ_RTC_time_rec tr;typ_RTC_date_rec dr;get_all_time_for_3511(&dr,&tr); //获取3511时钟日期时间RTC_set_date(dr.l_word); //同步系统日期RTC_set_time(tr.l_word); //同步系统时间}以上代码中,需要在文件头中包含RTC3511.H,在LD文件中加入Lib3511gpio1.a才可编译通过三、35190模块函数列表int get_all_time_for_35180( typ_RTC_date_rec * pdr,typ_RTC_time_rec * ptr);void reset_35180(void);int set_all_time_for_35180( typ_RTC_date_rec dr, typ_RTC_time_rec tr);void set_time_for_35180( typ_RTC_time_rec tr);int time_okay_35180(void);函数与3511类似,不同的是,reset_35180该函数执行后,时间会被重置回2000-01-0100:00:00,必须要提示重新校正时间。
mcHF实用教程——支持实时时钟
作者:BI3MEK
目录
一、环境要求 (3)
(一)主板要求 (3)
(二)配件要求 (4)
二、实施步骤 (4)
(一)增加触摸屏(非必须操作) (4)
1.原版0.4版本方案 (4)
2.原版0.5版本方案 (5)
3.使用BI3MEK0.5版本 (6)
(二)屏幕改为SPI接口方式 (7)
1.原版0.4版本PCB (7)
2.原版0.5版本PCB (7)
4.使用BI3MEK 0.5版本的PCB (8)
(三)改实时时钟 (8)
步骤一:接好电池 (9)
步骤二:接好晶振 (10)
步骤三:接好按键 (11)
步骤四:RTC使能 (12)
三、注意事项 (13)
mcHF是由英国火腿M0NKA Chris设计的入门级别的SDR 电台。
具有短波机常见的工作模式。
机器小巧、廉价、操作方便、显示直观,令人生爱。
目前mcHF机器硬件版本已经发展到0.6版本,具有更好的性能,但是一直未开放实时时钟功能,本文将介绍对国内常见的0.4和0.5版本升级实时时钟功能(RTC)。
一、环境要求
McHF机器如果要改为支持RTC实时时钟,需要使用STM32单片机的内置时钟模块,原设计该时钟模块的引出脚用于显示屏的并口显示模式,如果确需增加RTC功能,必须要求显示屏支持SPI模式。
另外由于修改还会对两个按键造成影响,需要重新定义按键,因此软件软件环境要求固件版本为1.58以上。
具体要求如下:
(一)主板要求
升级RTC功能一般要求0.4以上版本的pcb。
国内PCB 的主要版本为0.4、0.5、0.6以及BI3MEK设计的0.5、0.6版本PCB。
官方PCB(0.4-0.6)如要升级RTC功能,均要修改硬件。
BI3MEK设计的0.5版本与官方0.5版本修改方法相同,但是布局不同,0.6版本PCB直接集成了本文所述的时钟功能,无需任何更改。
(二)配件要求
A.具有支持SPI功能的显示屏一个
配件要求中最重要的是显示屏要支持SPI接口,目前知道支持SPI接口的显示屏有原版的HY28型显示屏,以及BI3MEK制作的2.0版本的显示屏(1.0只支持并口),其他显示屏,否支持暂不清楚。
B.32768晶振一个
C.3V锂电池一块
D.导线若干。
二、实施步骤
(一)增加触摸屏(非必须操作)
1.原版0.4版本方案
对于0.4版本,使用触摸屏操作比较简单,按照图1蓝色线条操作即可,图2是网上操作的图片,可供参考。
连接MCU的PA4 到 LCD屏的 TP_IRQ脚
连接R30/R33到LCD屏的TP_SDO脚
连接R31/R34 到 LCD屏的TP_SDI脚
连接R32/R35 到LCD屏的TP_SCK
连接MCU的PA9到LCD的TP_CS
图1 添加触摸屏操作原理图
图2 添加触摸屏操作示意图
2.原版0.5版本方案
此版本对触摸屏的支持不是很完整,具体修改如下:
A.焊接上电阻R30、R31、R32
B.拆掉电阻R33和R34
C.不要安装电阻R47b和R47d,如果没有安装ESP8266模块的,只需要拆掉R47b即可。
D.将阻R33连接LCD侧的焊盘和电阻R47d连接MCU侧的焊盘连起来。
E.将电阻R34连接LCD侧的焊盘与电阻R47b连接MCU 侧的焊盘连接起来。
3.使用BI3MEK0.5版本
因设计上已经预留支持触摸屏,此版本操作比较方便,焊接上R_CS和R_IRQ,去掉R33、R34即可即可。
实际效果如图3
图3 BI3MEK 0.5版本安装触摸屏
(二)屏幕改为SPI接口方式
在官方的原理图中,STM32F407VET6的时钟引脚被占用,如要使用,必须留出时钟引脚,因此要将原显示屏设计的并口方式改为SPI接口方式。
具体原理图变更如下:
1.原版0.4版本PCB
图4 0.4版本更改SPI接口原理图
A.去掉R30、R31、R32这3个0欧姆电阻;
B.连接R33、R34、R35三个0欧姆电阻。
R33用于屏幕的SDO,R34用于连接屏幕的SDI,R35用于屏幕的SCK。
2.原版0.5版本PCB
如果你的板子已经支持了触摸屏,很容易找到焊盘,对照图1中红色线条,只需要连接三条线即可,否则的话你要仔细找到对应的焊盘,做好连线。
具体连接如下: A.连接R30的靠近MCU侧的焊盘到显示屏的16脚,即MCU的PC2引脚接到显示屏的SDO引脚。
B.连接R31的靠近MCU测的焊盘到显示屏的17脚,即
MCU的PC3脚连接到显示屏的SDI脚。
C.连接R32的靠近MCU测的焊盘到显示屏的13脚,即MCU的PB13脚连接到显示屏的SCK脚。
注意:连线前一定要确认你的显示屏支持SPI方式。
4.使用BI3MEK 0.5版本的PCB
对于使用BI3MEK的0.5版本PCB的,由于使用的1.0显示屏不支持SPI口,首先需要更换2.0版本的显示屏。
此版本首先需要去掉R30、R31、R323个电阻,连接三条线即可,具体见图5。
图5 修改SPI方式接线图
(三)改实时时钟
对于mcHF短波机,改制实时时钟是利用STM32单片机内置的时钟模块,硬件比较简单,由于芯片小且引脚密集,对焊接技术要求较高。
请仔细按一下步骤操作。
步骤一:接好电池
1.确保更新到最新的固件。
2.去掉C82
3.割断PCB上C82连接3V电源的铜皮。
注意,只割断此处,不要殃及其他线条。
4.用万用表检测一下,确保割断。
5.连接好电池座,要注意电池的正极接C82的正极,也就是单片机的6脚。
电池负极接C82脚的负极,也就是接地。
图6 增加电池修改前原理图
图7 增加电池修改后原理图
对于BI3MEK0.5版本的PCB,可按图5方式修改,此处C82不去掉也可以。
6.开机,转到system info菜单中,正常的话“Backup RAM Battery”项应显示“Yes”, "Real Time Clock" 项应显示 "N/A"。
如果显示不正确,请按照之前步骤仔细查看,是否存在连线等问题。
步骤二:接好晶振
1.割断STM单片机的PC14与PC15与按键的铜皮,注意,如果水平高,可以不预留铜皮,直接从单片机引脚飞线,如果感觉没把握要预留好可以焊接32.768Khz晶振的铜皮长度。
此处的PC14是STM32单片机的8脚,原用于连接按键M1,PC15是STM32单片机的9脚,原来用于连接按键F3。
割断的时候要仔细,确保没有割错。
割断后,单片机的8脚脚和9脚用来连接晶振,不再与其他元件相连。
也就是说,8脚和9脚只接晶振。
2.将晶振的两脚分别与单片机的8脚和9脚焊接好,一种就是直接焊到铜皮上,也可以用飞线焊,焊好后将晶振固定好,最好加上胶固定。
对于BI3MEK0.5版本,可以按图8操作。
图8 晶振连接示意图
步骤三:接好按键
1.将割断的M1按键和F3按键,分别连接到LCD显示屏的D0和D1,也就是显示屏的23和24脚。
对于BI3MEK版本可按图9处理。
图9 按键处理
步骤四:RTC使能
1.确认连接无误后,开机。
2.转到"Expert/Debug Menu"菜单。
3.选择"RTC Start"项,机器将重启。
4.重启后,屏幕左侧将显示时钟。
进入"Expert/Debug Menu"进行时间调整。
到这时,你心爱的mcHF机器将增加实时时钟功能了。
如果重启后,只是绿灯亮,屏幕是黑的,表示晶振没有工作。
可以拔掉电源和去除电池,重新开机,将恢复到初始状态。
仔细检查各元件再重复上述步骤。
三、注意事项
由于时间仓促,手头资料有限,可能会出现错误,请大家予以批评指正。
按照以上教程,广大爱好者KE 对照原理图和线路板改制,由于PCB线条较细,元件引脚较密集,改制过程中要细心耐心,更要有比较好的焊接功底。
在此祝愿大家升级成功!
73
BI3MEK
2017.3.24。