更新:
其实宏晶科技早就已经做过这个功能了,此外还有好多功能集成到STC-ISP软件中,由于受限于信息获取渠道的影响,这些功能可能并不为大家所知(什么???你早就知道了?咋不早点告诉我(;`O´)o)。
这个软件系列可以去STC官网下载,以STC-ISP-V6.88G为例,里面集成了除我们熟知的烧录程序界面外的EEPROM数据填充、串口调试、HID、各型号MCU头文件、各型号MCU例程、UART串口波特率计算、定时器初值计算、软件延时计算等实用功能。
--------------------------------------------------------分割线------------------------------------------------------------
由于之前比较懒,不太愿意套公式来计算单片机的初值,于是写了一段代码来自动计算初值。值得注意的是,因为定时器有最大定时时间,所以输入定时时间请介于最大和最小的定时时间。有的时候我们需要定时1S钟,但是通过给主时钟分频、让定时器工作在12T模式仍然定不了这么久时间,可以取定时时间的因数。如最大定时时间是65ms,那么我们可以定时50ms,在中断函数中判断中断的触发次数为 次时转向1s定时指向的函数。
演示界面:
源码如下,需将文件编码格式设置为GBK:
#include <iostream>
#include <windows.h>
//#include <cstdlib>
using namespace std;
int main()
{
P: system("cls");
int S,K,MODE,WAYS,LOAD,LOAD1,TH,TL;
int flag=0;//程序自动判断mS/uS标志
int flag1=0;//非法输入标志
double sec;//单位时间
double T;//定时时间
double check;//检验时间
double F;
cout << "请输入主时钟、分频系数、工作模式(12T/1T)、工作方式(0/1/2/3)、定时时间:" << endl;
cout<<"\n";
cout << "工作方式0:16位自动重载初值" << endl;
cout << "工作方式1:16位不重载初值" << endl;
cout << "工作方式2:8位自动重载初值" << endl;
cout << "工作方式3:T0分成两个8位定时/计数器,T1停止计数" << endl;
cout<<"\n";
cout << "主时钟Fosc(MHz)=";
cin>>F;
cout<< endl;
do{
if(++flag1>1)cout <<"请正确输入数据!"<< endl;
cout << "分频系数(1/2/4/8/16/32/64)=";
cin>>S;
cout<<endl;}while(S!=1&&S!=2&&S!=4&&S!=8&&S!=16&&S!=32&&S!=64);
flag1=0;
do{
if(++flag1>1)cout <<"请正确输入数据!"<< endl;
cout <<"工作模式(12T/1T)=";
cin>>MODE;
cout<<endl;}while(MODE!=1&&MODE!=12);
flag1=0;
do{
if(++flag1>1)cout <<"请正确输入数据!"<< endl;
cout <<"工作方式(0/1/2/3)=";
cin>>WAYS;
cout<<endl;}while(WAYS!=0&&WAYS!=1&&WAYS!=2&&WAYS!=3);
flag1=0;
if(MODE==12)K=12;
else K=1;
cout<<"检验:";
cout<<"主时钟:"<<F<<"MHz"<<" "<<"分频系数:"<<S<<" "<<"定时器模式:"<<MODE<<"T"<<" "<<"定时器工作模式:方式"<<WAYS<<endl;
cout<<endl;
sec=1.0*K/(F/S);
cout<<"最小定时时间:"<<sec<<"uS"<<endl;
switch(WAYS)
{
case 0: ;
case 1: if(sec*65536/1000>1)cout<<"最大定时时间:"<<sec*65536/1000<<"mS"<<endl;
else {cout<<"最大定时时间:"<<sec*65536<<"uS"<<endl;flag=1;}
break;
case 2: ;
case 3: if(sec*256/1000>1)cout<<"最大定时时间:"<<sec*256/1000<<"mS"<<endl;
else {cout<<"最大定时时间:"<<sec*256<<"uS"<<endl;flag=1;}
break;
default:cout<<"错误!"<<endl;
}
cout<<endl;
if(flag==0){
cout << endl<<"定时时间(ms)=";
cin>>T; T*=1000;cout << endl;
}
else {
cout << endl<<"定时时间(us)=";
cin>>T;cout << endl;
}
switch(WAYS)
{
case 0:;
case 1:{
LOAD=65536-T*(F/S)/K;
LOAD1=LOAD;
TL=0XFF&LOAD1;TH=0XFF&(LOAD1>>8);
if(LOAD==TH*256+TL){
check=(65536.0-LOAD)*(1.0*K/(F/S));
cout<<"验证通过,装载值为:"<<LOAD<<" "<<"计数值:"<<65536-LOAD<<" "<<"校验时间:"<<check<<"uS"<<" "<<"误差:"<<(check-T)*100/T<<"%"<<endl;
cout<<"\n";
cout<<"TL="<<TL<<endl;
cout<<"TH="<<TH<<endl;
}
else {
cout<<"验证失败,装载值仅供参考:"<<LOAD<<endl;
cout<<"TL="<<TL<<endl;
cout<<"TH="<<TH<<endl;
}
break;}
case 2:;
case 3:{
LOAD=256-T*(F/S)/K;
LOAD1=LOAD;
TL=0XFF&LOAD1;TH=0XFF&(LOAD1>>8);
if(LOAD==TH*256+TL){
check=(256.0-LOAD)*(1.0*K/(F/S));
cout<<"验证通过,装载值为:"<<LOAD<<" "<<"计数值:"<<256-LOAD<<" "<<"校验时间:"<<check<<"uS"<<" "<<"误差:"<<(check-T)*100/T<<"%"<<endl;
cout<<"\n";
cout<<"TL="<<TL<<endl;
cout<<"TH="<<TH<<endl;
}
else {
cout<<"验证失败,装载值仅供参考:"<<LOAD<<endl;
cout<<"TL="<<TL<<endl;
cout<<"TH="<<TH<<endl;
}
break;}
default:cout<<"错误"<<endl;break;
}
cout<<endl;
cout<<"退出请点击右上角的【X】"<<endl;
cout<<endl;
system("pause");
goto P;
return 0;
}