- 1、本文档共4页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
51单片机控制舵机程序精度,数量,占用时间优化方案及程序
#includereg52.h
#includeintrins.h
//本程序经软仿真调试在机器周期为1us时理论误差为0,不需要占用太多的cpu运行时间就可以控制8路舵机,精度为1ms-2ms平均分成100份,在时间消耗和舵机数量上
//明显优于网上常见的舵机控制程序,keil3使用9(最高)编译器优化时达到理论误差为0,编译器优化级别过低时无法使用
unsigned char gai;
unsigned char nt[8];
unsigned char nw[8];
unsigned char pwmbuffer[8] = {50,50,50,50,50,50,50,50};
void set(unsigned char m,unsigned char n){
if((m8)(n101)){ //如果输入合法则记录新数据并将状态改变标志置位
pwmbuffer[m] = n;
gai = 1;
}
}
void tim(void){
unsigned char a1,a2,tempt,tempw; //a1,a2作为循环变量,tempt,tempw作为排序交换用临时变量
for(a1 = 0; a1 8; a1++){ //由舵机控制数据设置用于排序的表(两行八列)
nt[a1] = pwmbuffer[a1]; //第几个舵机所需的高电平时长
nw[a1] = 1 a1; //用第几位置一来表示第几个舵机
}
for(a1 = 0; a1 7; a1++){ //简单排序算法,找出最小的与第一个交换,在从剩余的中找出最小的与第二个交换,以此类推
unsigned char min = a1; //用于记录哪一个是最小的
for(a2 = a1 + 1; a2 8; a2++){ //从剩余项中找出最小的
if(nt[a2] nt[min]){
min = a2;
}
}
tempt = nt[a1]; //交换
tempw = nw[a1];
nt[a1] = nt[min];
nw[a1] = nw[min];
nt[min] = tempt;
nw[min] = tempw;
}
for(a1 = 1; a1 8; a1++){ //之前记录应该变成低电平的输出口,之后记录应该是低电平的输出口
nw[a1] |= nw[a1-1];
}
a2 = 0;
for(a1 = 0; a1 7; a1++){ //去掉重复
if(nt[a1] != nt[a1 + 1]){
nt[a2] = nt[a1];
nw[a2] = nw[a1];
a2++;
}
}
nt[a2] = nt[7];
nw[a2] = nw[7];
for(a2++; a2 8; a2++){
nt[a2] = 0;
nw[a2] = 0xFF;
}
for(a1 = 7; a1 0; a1--){ //之前记录每个输出口应持续高电平的时间,之后记录与上一次变化间隔时间
if(nt[a1]){
nt[a1] = nt[a1] - nt[a1-1] - 1;
}
}
for(a1 = 0; a1 8; a1++){ //避免对0减1发生溢出跳到255,因为已经去掉重复所以不影响经度
nw[a1] = ~nw[a1];
if(nt[a1] 2){
nt[a1] = 1;
}
else{
nt[a1] -= 1;
}
}
}
void Timer0(void)
{
TMOD = 0xF0;
TMOD |= 0x01;
TL0 = 0xE0;
TH0 = 0xB1;
TR0 = 1;
ET0 = 1;
}
void setuart(unsigned int a){
SCON = 0x50; //设置串口为模式1
TMOD = 0x0F; //设置定时器T1为自动重装模式
TMOD |= 0x20; //设置定时器T1为自动重装模式
TH1 = 256 -12/2/16)/a; //计算T1重载值
TL1 = TH1; //手动初次重装
ET1 = 0; //定时器中断关闭
ES = 1; //串口中断启动
EA = 1; //总中断启动
TR1 = 1;
文档评论(0)