1
完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本帖最后由 asiavikin 于 2014-10-7 22:20 编辑
各位大能: 我想编写一个89c52下控制舵机运行的c程序,实现从串口逐次控制pwm方波占空比的功能。比如,从串口向单片机发送一次ff010aff后,方波的宽度就增大一点;发送多次ff010aff后,方波的宽度就可以增大到最多2毫秒。如果发送ff010bff,方波宽度就应该减小,发送多次ff010bff后,方波的宽度就可以减小到最少0.5毫秒。 我在网上找到了一个程序,把它修改了一下后用proteus仿真,但我发现并不能象我想的那样逐次控制pwm方波:从串口输出了命令ff010aff后,方波的宽度一下就变到2毫秒了,从串口输出了命令ff010bff后,方波的宽度一下就变到0.5毫秒了。 我想请教各位大能,为什么我的程序不能象一些51的按键控制程序那样逐次地控制pwm方波的宽度?如何修改才能达到目的呢?请各位不吝赐教。 下面是我的程序:附件里是我的proteus仿真文件。 #include #include #include #define uchar unsigned char #define uint unsigned int uchar Buffer =0; //从串口接收的数据 uint i=0,j,URTAReceivedCount=0,n=1; uchar flag=0; uchar data Tempdatatable[4],CommandDatatable[4];//数据包 ***it servo0=P0^0; uchar serVal[2]; uint pwm[]={1382,1382,1382,1382,1382,1382,1382,1382}; //初始90度,(实际是1382.4,取整得1382) uchar pwm_flag=0; uint code ms0_5Con=461; //0.5ms计数 (实际是460.8,取整得461) uint code ms2_5Con=2304; //2.5ms计数 /******************************************************************** * 名称 : Delay_1ms() * 功能 : 延时子程序,延时时间为 1ms * x * 输入 : x (延时一毫秒的个数) * 输出 : 无 ***********************************************************************/ void Delay_1ms(uint i)//1ms延时 { uchar x,j; for(j=0;j for(x=0;x<=148;x++); } /******************************************************************** * 名称 : Send_Data() * 功能 : 向上位机传送字符 * 输入 : 无 * 输出 : 无 ***********************************************************************/ void Send_Data(uchar data type,uchar data cmd) { uchar data Buffer[4]; //构建数据包 uchar *p; uint Send_Count=0; p = Buffer; Buffer[0]=0XFF; Buffer[1]=type; Buffer[2]=cmd; Buffer[3]=0XFF; while(1){ if(*p==0XFF){ Send_Count++; //0XFF标志统计位 } SBUF = *p; //发送 while(!ti) //如果发送完毕,硬件会置位TI,等待发送完毕 { _nop_(); } p++; TI = 0; if(Send_Count == 2) //当统计到两次出现0XFF,则认为一个数据包发送完毕,跳出循环 { TI = 0; break; } } } /******************************************************************** * 名称 : Com_Int() * 功能 : 串口中断子函数 * 输入 : 无 * 输出 : 无 ***********************************************************************/ void Com_Int(void) interrupt 4 { uchar temp; ES=0; //关串口中断 RI=0; //软件清除接收中断 temp=SBUF; if(temp==0XFF && URTAReceivedCount<2) { Tempdatatable[0]==0XFF; //包头 URTAReceivedCount++; } else { Tempdatatable[n]=temp; n++; } if(URTAReceivedCount==2)//包尾 { Tempdatatable[0]=0XFF; Tempdatatable[3]=0XFF; n=1; URTAReceivedCount=0; //组包完毕 temp=""; //Send_Data(Tempdatatable[1],Tempdatatable[2]); //发送组成的数据包回去 } CommandDatatable[0]=Tempdatatable[0]; CommandDatatable[1]=Tempdatatable[1]; CommandDatatable[2]=Tempdatatable[2]; CommandDatatable[3]=Tempdatatable[3]; ES=1;//开串口中断 } /******************************************************************** * 名称 : Com_Init() * 功能 : 串口初始化,晶振11.0592,波特率9600,使能了串口中断 * 输入 : 无 * 输出 : 无 ***********************************************************************/ void Com_Init(void) { TMOD |= 0x20; PCON = 0x00; SCON = 0x50; TH1 = 0xFd; //设置波特率 9600 TL1 = 0xFd; TR1 = 1; //启动定时器1 ES = 1; //开串口中断 EA = 1; //开总中断 IT0=0; EX0=1; } /******************************************************************** * 功能 : 舵机PWM中断初始化 ***********************************************************************/ void Timer0Init() { //0度=0.5ms, 45度=1ms, 90度=1.5ms, 135度=2ms, 180度=2.5ms //2.5 ms初始值 F700, (12n/11059200=2.5/1000, n=2304, X=65536-2304=63232 > F700) TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响 TH0=-ms2_5Con>>8; //给定初值,17ms中断 TL0=-ms2_5Con; EA=1; //总中断打开 ET0=1; //定时器0中断打开 TR0=1; //定时器0开关打开 } /******************************************************************** * 功能 : 舵机PWM中断, //舵机控制函数 周期为20ms 一个循环20MS = 8*2.5ms ***********************************************************************/ void SteeringGear() interrupt 1 { switch(pwm_flag) { case 1: servo0=1; TH0=-pwm[0]>>8; TL0=-pwm[0]; break; case 2: servo0=0; TH0=-(ms2_5Con-pwm[0])>>8; TL0=-(ms2_5Con-pwm[0]); break; //... default: TH0=0xff; TL0=0x80; pwm_flag=0; } pwm_flag++; } void SteeringGearUp(uchar i) { if(pwm>ms0_5Con) pwm=pwm-10; } void SteeringGearDown(uchar i) { if(pwm } void main() { Delay_1ms(200); Com_Init();//串口初始化 Timer0Init();//舵机初始化 while(1) { if(CommandDatatable[0]==0XFF && CommandDatatable[3]==0XFF){ switch (CommandDatatable[1]) //根据键值不同,执行不同的内容 { case 0X01: //类型位0X01,表明是舵机数据包,进入舵机case switch(CommandDatatable[2]) { case 0X0A: SteeringGearUp(0); break; case 0X0B: SteeringGearDown(0); break; } break; default : TR0=0;TR2=0; break; } } } }
|
|
相关推荐
5个回答
|
|
回帖奖励 +1 分积分
看看再说
|
|
|
|
在你的主程序中,当收到串口数据后进行处理,处理后要把CommandDatatable清零呀!
要不你就收到一次,但是你会处理若干次,直到升到最大值或降到最小值 你想想看... |
|
|
|
太感谢了!我太粗心了。
|
|
|
|
此贴可以锁了。
|
|
|
|
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
205 浏览 0 评论
求助一下关于51系列单片机的Timer0的计时问题,TH0、TL0+1的时间是怎么算的?
1253 浏览 1 评论
【RA-Eco-RA4E2-64PIN-V1.0开发板试用】开箱+Keil环境搭建+点灯+点亮OLED
848 浏览 0 评论
【敏矽微ME32G070开发板免费体验】使用coremark测试敏矽微ME32G070 跑分
853 浏览 0 评论
【敏矽微ME32G070开发板免费体验】开箱+点灯+点亮OLED
1073 浏览 2 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
12013 浏览 31 评论
小黑屋| 手机版| Archiver| 德赢Vwin官网 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 02:33 , Processed in 0.750788 second(s), Total 77, Slave 60 queries .
Powered by 德赢Vwin官网 网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
德赢Vwin官网 观察
版权所有 © 湖南华秋数字科技有限公司
德赢Vwin官网 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号