当前位置:首页 > 单片机 > 单片机
[导读] 先说一下我的硬件情况:一块ATMEGA128实验板;一个带编码器的80:1的变速电机,编码器的输出端连接到单片机的PD4和PD5引脚;一块电机驱动电路,该电路的输入为:24v电源、两路pwm信号输入,输出即为电机的正负极,要

先说一下我的硬件情况:一块ATMEGA128实验板;一个带编码器的80:1的变速电机,编码器的输出端连接到单片机的PD4和PD5引脚;一块电机驱动电路,该电路的输入为:24v电源、两路pwm信号输入,输出即为电机的正负极,要用该电路来驱动电机,则必须让两路pwm输入信号的一路占空比为0,另一路不为0,相当于让电机的一极接地,另一极接pwm,通过控制两路pwm的占空比来控制电机的转速和转动方向。pwm信号的输入端连接到单片机的PD6和PD7引脚。

下面是我的程序的设计思路:这个程序用了两个定时器:timer0和timer1。

timer0用来产生pwm。timer0产生pwm信号是这样实现的:程序中有一个timer0的溢出事件计数器,和两个保存两路pwm信号占空比的变量,当timer0溢出事件计数器计数超过100时,如果某个pwm信号占空比不为0,则把相应pwm引脚置高电平,同时清零此计数器,当此计数器等于某个占空比时,则把相应引脚置低电平,从而实现timer0溢出事件计数器从0计数到100时输出一个周期的pwm信号。通过调节timer0的溢出频率,即可调节pwm信号输出的频率。

timer1用来对编码器的输出进行计数,同时调整pwm的占空比,实现对电机的控制。对编码器的输出计数是利用了timer1的输入捕捉功能,由于电机可以正转,也可以反转,导致编码器的CHA和CHB的输出也不同,所以可以在程序中可以判断电机是正转还是反转,再对编码器的输出脉冲进行计数,当电机正转的时候计数增加,电机反转的时候计数减少,所以编码器的计数值是有正负的。从而可以知道什么时候该通过调整pwm来控制电机。

下面是我的调试过程,也算是一点经验吧:以开始的思路是只要编码器的计数值不为0,我就要让电机反方向转动,以保持电机抱死,发送给电机的pwm是固定的数值,但是这样反而是抱不死,它在前后地抖动,而且pwm的占空比越大,电机抖动得越厉害,这样显然不行;后来想了一个办法,就是如果编码器的计数值在一定的范围内,我就不用让电机反方向转动。因为这个电机是变速电机,如果电机里面只转动一点点,在外面看来就相当于不动,这样的话就给电机预留了一部分转动的空间,用来消除抖动,就是说在这个空间内是不发送pwm给电机的,或者说电机两极的pwm占空比都为0。这样一来,当pwm占空比比较低时,是可以消除抖动,但是力气不大,就是说还是可以用钳子拧得动,调了很久都无法在抖动和电机力气之间取得平衡。后来又想了一个办法,在这个基础上再改进,因为之前的pwm占空比都是不变的,所以很难达到令人满意的效果,现在的方法是,根据电机被拧动的角度,或者说编码器的计数值大小来调整pwm的占空比,编码器的计数值偏离0越多(正或负得越大),pwm的占空比就越大,电机的力气也就越大,从而不会出现电机一旦被拧动就马上以最大速度转回去的情况,抖动也就消除了,而且电机力气很大。


编译环境是AVR Studio 5.0,下面是程序代码:#include #include interrupt.h="">intforward = 0, reverse = 0;//存储电机正转和反转pwm占空比的变量inttimer0_count = 0;//timer0溢出事件计数器intcapt_count = 0;//输入捕捉事件计数器voidport_init(void){PORTA = 0x00;DDRA = 0x00;PORTB = 0x00;DDRB = 0x00;PORTC = 0x00; //m103 output onlyDDRC = 0x00;PORTD = 0x00;DDRD = 0xC0;PORTE = 0x00;DDRE = 0x00;PORTF = 0x00;DDRF = 0x00;PORTG = 0x00;DDRG = 0x00;}voidtimer0_init(void){TCCR0 |= 5;//256分频,普通模式TIMSK |= 0x01;//timer0溢出中断TCNT0 = 0xFE;//TCNT0赋初值}voidtimer1_init(void){TCCR1B = 0x00;//停止TCCR1A = 0x00;//普通模式TCCR1C = 0x00;TCNT1 = 0;//计数初值TCCR1B = 0xC4;//启动定时器,256分频,使能输入捕捉噪声抑制器,输入捕捉触发沿选择:上升沿TIMSK = 0x24;//输入捕捉中断使能,T/C1溢出中断使能}/************************************************************************//* timer0溢出中断函数,产生提供给电机的pwm *//************************************************************************/ISR(TIMER0_OVF_vect)//200kHz{TCNT0 = 0xFE;//TCNT0重新赋值//当timer0_count等于100时,如果正转或反转的占空比不为0,则相应引脚输出高电平if(++timer0_count >= 100)//对timer0溢出事件计数100次,相当于100分频,最后输出到电机的pwm频率是2kHz{timer0_count = 0;if(forward != 0)//forward, reverse存储电机正转和反转pwm占空比的变量{PORTD |= (1<<6);}if(reverse != 0){PORTD |=(1<<7);}}//当timer0_count等于正转或反转的占空比时,相应引脚输出低电平,实现输出pwm信号if(timer0_count == forward){PORTD &= ~(1 << 6);}if(timer0_count == reverse){PORTD &= ~(1 << 7);}}/************************************************************************//* timer1输入捕捉中断函数,对编码器输出的上升沿进行计数 *//************************************************************************/ISR(TIMER1_CAPT_vect){  if(PIND & (1 << 5))//电机反转  {capt_count--;}//输入捕捉计数器减1  else//电机正转  {capt_count++;}//输入捕捉计数器加1}/************************************************************************//* timer1溢出中断函数,100Hz,用于调整电机转速和转动的方向,实现电机抱死*//************************************************************************/ISR(TIMER1_OVF_vect){TCNT1 = 64910; //重新给TCNT1赋值staticunsigned charmotor_state = 0; //电机的状态,标志电机是正转还是反转,0:正转,1:反转switch(motor_state){case0://电机正转时if(capt_count > 40) //如果编码器正转计数超过40,则电机需要反转,以保持电机不动{reverse = capt_count - 40;} //直接把编码器计数值减去40,作为反转的占空比elseif(capt_count < 0) //如果编码器计数值小于0{motor_state = 1;} //进入状态1else//如果编码器计数值在0~40内,为了不发生抖动,不需要反转{reverse = 0;} //反转的占空比为0,相当于负极接地forward = 0; //正转的占空比为0,相当于正极接地break;case1:if(capt_count < -40) //如果编码器反转计数超过40,则电机需要正转,以保持电机不动{forward = (-capt_count) - 40;}//直接把编码器计数值减去40,作为正转的占空比elseif(capt_count > 0) //如果编码器计数值大于0{motor_state = 0;} //返回状态0else//如果编码器计数值在-40~0内,为了不发生抖动,不需要正转{forward = 0;} //正转的占空比为0,相当于正极接地reverse = 0; //反转的占空比为0 ,相当于负极接地break;default:break;}}voidInit_Devices(void){cli();//关闭全局中断port_init();//I/O口初始化timer1_init();//定时/计数器1初始化timer0_init();//计时/计数器0初始化sei();//打开全局中断}intmain(void){Init_Devices();while(1){}return0;}


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭