历史上的今天
今天是:2024年10月15日(星期二)
2021年10月15日 | S3C2440开发板裸机程序系列09—PWM控制舵机
2021-10-15 来源:eefocus
1. Timer1的PWM控制舵机
S3C2440的Timer0、Timer1、Timer2和Timer3具有PWM功能,以前的blog已经叙述过,详见:
S3C2440开发板裸机程序系列05—定时器PWM
TQ2440开发板的Timer0的TOUT0输出连接了Beep,所以,这次利用Timer1的TOUT1输出来连接舵机的控制信号。
舵机的内部有一个基准电路,产生周期为20ms,宽度为1.5ms的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。通过调整控制信号的高电平宽度,即可实现舵机不同转角的控制。

舵机控制原理详见:舵机的原理和控制
程序思路很简单:
设置GPB1为TOUT1的输出格式;
Timer1初始化,设置周期为20ms;
默认情况TOUT1输出的脉宽是低电平,需要将TCON第10位设置为1,即Inverter on for TOUT1
主程序检测串口输入,加号则增大脉宽,减号则减小脉宽。
2. Timer1的中断控制舵机
模仿舵机C51测试程序,用Timer1计时,周期0.5ms。在Timer1的中断控制程序中控制PWM的脉宽输出。
查看TQ2440的底板原理图,可知系统总线接口上有GPA0,就利用它作为PWM的输出了。


程序思路:
a.设置Timer1初始化
void Timer1_Init(void)
{
rTCFG0 &= ~(0xff) ; // Prescaler0 determine prescale value for Timer 0 and 1.
rTCFG0 |= 49 ; // Prescaler0 [7:0]
rTCFG1 &= ~(0xf0) ; // TCFG1[7:4] -- Select MUX input for PWM Timer1.
rTCFG1 |= 0x0<<4 ; // MUX1: 0-1/2, 1-1/4, 2-1/8, 3-1/16
// 50M/50/2=500K 500,000 = 1sec
rTCNTB1 = 250 ; // 500K/50 = 10000 ==> 20ms cycles
// 10000/40 <=> 20/0.5 , so 250 is 0.5ms
rTCON |= (1 << 9) ; //manual update for Timer 1.
rTCON = 0x09<<8; //D=1001,clear manual update; auto reload
}
b.设置Timer1中断
extern unsigned char count; //0.5ms次数标识
extern unsigned char jd; //角度标识
void Isr_Init(void)
{
pISR_TIMER1 = (U32)Timer1_Isr ;
}
void __irq Timer1_Isr(void)
{
if(count rGPADAT |= 0x01; //确实小于,PWM输出高电平 else rGPADAT &= (~(0x01)); //大于则输出低电平 count=(count+1); //0.5ms次数加1 count=count%40; //次数始终保持为40 即保持周期为20ms rSRCPND |= 1 << 11 ; rINTPND |= 1 << 11 ; } void Timer1_Interrupt_Init(void) { rINTMSK &= ~(1 << 11) ; } c.主程序查询串口按键输入(还有GPA0,Timer1,中断等的初始化) int Main() { unsigned char key; jd=2; count=0; rGPACON &= (~(0x01)); // set GPA0 output rGPADAT &= (~(0x01)); // GPA0=0 Timer1_Interrupt_Init(); Isr_Init(); Timer1_Init(); Uart0_Init(115200); Uart_Printf( "nPWM TEST ( Key Control )n" ); Uart_Printf( "Press +/- to increase/reduce the frequency of PWM n" ) ; Uart_Printf( "Press 'ESC' key to Exi nn" ); while(1) { key = Uart0_Getc(); if( (key == '=')||(key == '+')) //tq-zql:添加对小键盘的+的支持 { jd++; //角度标识加1 count=0; //按键按下 则20ms周期从新开始 if(jd==6) jd=5; } if( key == '-' ) { jd--; //角度标识减1 count=0; if(jd==0) jd=1; } Uart_Printf( "tFreq = %dn", jd ) ; if( key == ESC_KEY ) { return 1; } } return 0; }
史海拾趣
|
工业自动化1-36轴2相3相5相步进电机.伺服电机运动控制卡; 运动控制器; 运动驱动器;运动控制系统。 1、得到德国设计公司最先进的多轴运动控制技术方案,性能稳定可靠,高精密,电机运行噪音小 2、驱动控制2合1集成模板上,让你减少另外购买驱动器 ...… 查看全部问答> |
|
本帖最后由 paulhyde 于 2014-9-15 03:59 编辑 最近在做各个常用模块,做了几个,效果还不错,不过,做到AD,DA转换的时候感觉有点困难,模块做得不是很理想, 我们主要做AD0809,DA0832这两款比较常见的芯片,可是总是无法总结出一个比较经典,实 ...… 查看全部问答> |
|
CodeVisionAVR C Library Functions Reference CodeVisionAVR C 库函数介绍 译自CodeVisionAVR C Compiler Help … 查看全部问答> |
|
关于WINCE下,继承CButton类,实现一个图形按钮类;发现无论如何都是刷新背景。 在WINDOWS下,Invalidate(FALSE)或者OnEraseBkgnd直接返回,就不会率刷新背景。 但在WINCE下,如果如何都刷背景。 按钮要实现如下效果:当鼠标移动按钮上面时,显示一副图,移开后显示另一副图,发现在WINCE下经常有闪屏的情况,本人认为就是绘 ...… 查看全部问答> |
|
#define TYPE_R (0x30000008) Type = *(UCHAR *)(TYPE_R) 这个是访问EPLD的读操作,EPLD的数据port宽度定义为了8bit。 我不太明白的是*(UCHAR *)(TYPE_R)的语法代表什么意思,难道不是把地址0x30000008 ...… 查看全部问答> |
|
我自己的FON字体似乎visual studio 2005 不支持,大家知道为什么么? 最近作pdf417条形码,缺少一个字库,请问大家有么?能否共享一个? qq:61060673… 查看全部问答> |




