本文为在用龙芯1c做3D打印机过程中的笔记。龙芯1c做的3d打印机简称“龙印”,Git地址“http://git.oschina.NET/caogos/marlin_ls1c”
以步进电机驱动芯片A4988为例,给A4988一个脉冲,A4988就会驱动步进电机“走”一步(假设细分为1),在1秒内脉冲个数就决定了步进电机的速度。在marlin源码中,是通过在定时器中断里面将IO口拉高然后延时再拉低来产生一个脉冲的。很显然,通过这种延时的方式来产生脉冲会消耗大量的cpu资源,恰好龙芯1c的硬件pwm可以产生单个脉冲,这样就不必在定时器中断中延时了,大大降低了cpu占有率,当步进电机速度越快时,效果越明显。
硬件说明
龙芯1c共有4个pwm,其中pwm0和pwm1可以直接使用,pwm2和pwm3需要复用。pwm2和pwm3可以在多个引脚上复用,比如pwm2可以与CAMDATA2/GPIO52复用,也可以与CAMPCLKIN/GPIO46复用。由于智龙v2.1的板子上,CAMDATA2/GPIO52接有led,所以选择将pwm2与CAMPCLIN/GPIO46复用,pwm3类似,选择与CAMCLKOUT/GPIO47复用。
所以源码中有
// PWNn所在gpio
#define LS1C_PWM0_GPIO06 (6)
#define LS1C_PWM1_GPIO92 (92)
#define LS1C_PWM2_GPIO46_CAMPCLKIN (46) // 第四复用
#define LS1C_PWM3_GPIO47_CAMCLKOUT (47) // 第四复用
源码
应用程序
应用程序通过write()接口写入脉冲个数
test.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(void)
{
int fd = 0;
int ret = 0;
int pulse_num = 0;
fd = open("/dev/ls1c_pwm_pulse", O_RDWR);
if (-1 == fd)
{
printf("[%s] open device file.\n", __FUNCTION__);
return -1;
}
while (1)
{
pulse_num = 20;
ret = write(fd, &pulse_num, sizeof(pulse_num));
if (sizeof(pulse_num) != ret)
{
close(fd);
printf("[%s] write fail. ret=%d\n", __FUNCTION__, ret);
return -1;
}
sleep(1);
}
}
Makefile
HEADER_FILE = $(wildcard *.h)
SRC = $(wildcard *.c)
OBJ = $(SRC:.c=.o)
DEST = test
CC = mipsel-linux-gcc
all:$(DEST)
$(DEST):$(OBJ)
$(CC) $^ -o $@
cp $@ /nfsramdisk/LS1xrootfs-demo/test
$(OBJ):$(SRC) $(HEADER_FILE)
$(CC) -c $^
clean:
rm -f *.o $(DEST)
驱动
/*
* drivers\misc\ls1c_pwm_pulse.c
* 用龙芯1c的硬件pwm产生单个脉冲
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/time.h>
#include <linux/errno.h>
#include <linux/clk.h>
#include <linux/mutex.h>
#include <linux/kfifo.h>
enum {
LS1C_PWM_0 = 0,
LS1C_PWM_1 = 1,
LS1C_PWM_2 = 2,
LS1C_PWM_3 = 3,
};
// gpio配置寄存器
#define LS1C_GPIO_CFG0 (0xbfd010c0) // 控制gpio[31:0]
#define LS1C_GPIO_CFG1