使用的是360度舵机,通过定时器0每隔10毫秒调速一次,通过调节定时器1的占空比 改变速度
#include <fpioa.h>
#include <plic.h>
#include <pwm.h>
#include <stdio.h>
#include <sysctl.h>
#include <syslog.h>
#include <timer.h>
#define TIMER_NOR (0) //定时器0
#define TIMER_CHN (0) //通道0
#define TIMER_PWM (1) // 定时器1为pwm mode
#define TIMER_PWM_CHN0 (0) // pwm通道0
#define TIMER_PWM_CHN1 (1)
#define SERVO_FREQ (50) //频率
#define SERVO0_DUTY_MAX (0.125) //最大占空比
#define SERVO0_DUTY_MIN (0.025) //最小占空比
#define SERVO1_DUTY_MAX (0.12)
#define SERVO1_DUTY_MIN (0.03)
#define SERVO0_STEP (0.001) //步进
#define SERVO1_STEP (0.001)
int timer_callback(void *ctx) {
static int count = 0;
static double cnt0 = (SERVO0_DUTY_MAX + SERVO0_DUTY_MIN) / 2; //中间占空比
static double cnt1 = (SERVO1_DUTY_MAX + SERVO1_DUTY_MIN) / 2;
static int flag0 = 0;
static int flag1 = 0;
count++;
if (count % 5 == 0) {
pwm_set_frequency(TIMER_PWM, TIMER_PWM_CHN0, SERVO_FREQ, cnt0);
pwm_set_frequency(TIMER_PWM, TIMER_PWM_CHN1, SERVO_FREQ, cnt1);
flag0 ? (cnt0 -= SERVO0_STEP) : (cnt0 += SERVO0_STEP);
flag1 ? (cnt1 -= SERVO1_STEP) : (cnt1 += SERVO1_STEP);
if (cnt0 > SERVO0_DUTY_MAX) { //大于最大的,占空比减
cnt0 = SERVO0_DUTY_MAX;
flag0 = 1;
} else if (cnt0 < SERVO0_DUTY_MIN) { //小于最小的,占空比加
cnt0 = SERVO0_DUTY_MIN;
flag0 = 0;
}
if (cnt1 > SERVO1_DUTY_MAX) {
cnt1 = SERVO1_DUTY_MAX;
flag1 = 1;
} else if (cnt1 < SERVO1_DUTY_MIN) {
cnt1 = SERVO1_DUTY_MIN;
flag1 = 0;
}
printf("Duty is %g, %g\n", cnt0 * 100, cnt1 * 100);
}
return 0;
}
int main(void) {
/*io口映射 */
fpioa_set_function(17, FUNC_TIMER1_TOGGLE1); // io17
fpioa_set_function(35, FUNC_TIMER1_TOGGLE2); // io35
/* Init 平台级中断控制器 */
plic_init();
/* 为RISC-V的机器模式启用全局中断 */
sysctl_enable_irq();
/* 初始化定时器0 */
timer_init(TIMER_NOR);
/* 设置定时器时间间隔 */
timer_set_interval(TIMER_NOR, TIMER_CHN, 10000000);
/* 设置定时器回调为重复模式 */
timer_irq_register(TIMER_NOR, TIMER_CHN, 0, 1, timer_callback, NULL);
/*使能定时器 */
timer_set_enable(TIMER_NOR, TIMER_CHN, 1);
/* Init PWM */
pwm_init(TIMER_PWM);
/* Set PWM to 50Hz */
pwm_set_frequency(TIMER_PWM, TIMER_PWM_CHN0, SERVO_FREQ,
(SERVO0_DUTY_MAX + SERVO0_DUTY_MIN) / 2);
pwm_set_enable(TIMER_PWM, TIMER_PWM_CHN0, 1);
/* Set PWM to 50Hz */
pwm_set_frequency(TIMER_PWM, TIMER_PWM_CHN1, SERVO_FREQ,
(SERVO1_DUTY_MAX + SERVO1_DUTY_MIN) / 2);
pwm_set_enable(TIMER_PWM, TIMER_PWM_CHN1, 1);
while (1) continue;
}