天嵌 ARM开发社区

 找回密码
 注册
查看: 2683|回复: 7

在TQ2440运行程序,开发板自动重启,求助!

[复制链接]
zhangbo0805 发表于 2013-11-14 12:25:13 | 显示全部楼层 |阅读模式
开发环境是fedoral10 TQ2440 编译工具 GCC4.3.3
目的:驱动舵机,控制舵机的旋转。舵机型号是MG996R。
方法:利用pwm_timer 输出控制舵机。
问题 : 写好驱动程序,和应用程序 ,在开发板上运行的时候,用示波器观察能得到想要的结果。但是一连上舵机,每次一运行应用程序,开发板就自动重启。

驱动程序如下:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/clk.h>
#include <linux/device.h>
#include <asm/io.h>
#include <mach/hardware.h>
#include <mach/regs-gpio.h>
#include <plat/regs-timer.h>
#define PWM_MAJOR 232                  //主设备号
#define PWM_NAME "my2440_pwm"        //设备名称

static int device_major = PWM_MAJOR; //系统动态生成的主设备号

//打开设备
static int pwm_open(struct inode *inode, struct file *file)
{

    //对GPB0复用口进行复用功能设置,设置为TOUT0 PWM输出
    s3c2410_gpio_cfgpin(S3C2410_GPB1, S3C2410_GPB1_TOUT1);
    s3c2410_gpio_pullup(S3C2410_GPB1, 1);
    return 0;

}

//关闭设备
static int pwm_close(struct inode *inode, struct file *file)
{
    return 0;
}

//对设备进行控制

static int pwm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
    if(cmd <= 0)//如果输入的参数小于或等于0的话,就让蜂鸣器停止工作
    {
        //这里又恢复GPB0口为IO口输出功能,由原理图可知直接给低电平可让蜂鸣器停止工作
        s3c2410_gpio_cfgpin(S3C2410_GPB1, S3C2410_GPB1_OUTP);
        s3c2410_gpio_pullup(S3C2410_GPB1, 1);
        s3c2410_gpio_setpin(S3C2410_GPB1, 0);
    }

    else//如果输入的参数大于0,就让蜂鸣器开始工作,不同的参数,蜂鸣器的频率也不一样
    {
        //定义一些局部变量
        unsigned long tcon;
        unsigned long tcnt;
        unsigned long tcfg1;
        unsigned long tcfg0;
        struct clk *clk_p;
        unsigned long pclk;
        //以下对各寄存器的操作结合上面讲的开始一个PWM定时器的步骤和2440手册PWM寄存器操作部分来看就比较容易理解
        tcfg1 = __raw_readl(S3C2410_TCFG1);     //读取定时器配置寄存器1的值
        tcfg0 = __raw_readl(S3C2410_TCFG0);     //读取定时器配置寄存器0的值
        tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK;
        tcfg0 |= (50 - 1);                      //设置tcfg0的值为49
        tcfg1 &= ~S3C2410_TCFG1_MUX1_MASK;
        tcfg1 |= S3C2410_TCFG1_MUX1_DIV16;      //设置tcfg1的值为0x0011即:1/16
        __raw_writel(tcfg1, S3C2410_TCFG1);     //将值tcfg1写入定时器配置寄存器1中
        __raw_writel(tcfg0, S3C2410_TCFG0);     //将值tcfg0写入定时器配置寄存器0中
        clk_p = clk_get(NULL, "pclk");
        pclk = clk_get_rate(clk_p);   //从系统平台时钟队列中获取pclk的时钟频率,在include/linux/clk.h中定义
        tcnt = (pclk/50/16)/50;      //计算定时器0的输出时钟频率(pclk/{prescaler0 + 1}/divider value)
        printk("pclk = %ld,tcnt = %ld \n",pclk,tcnt);
        __raw_writel(tcnt, S3C2410_TCNTB(1));   //设置定时器0计数缓存寄存器的值
        __raw_writel(tcnt/cmd, S3C2410_TCMPB(1)); //设置定时器0比较缓存寄存器的值
        tcon = __raw_readl(S3C2410_TCON);       //读取定时器控制寄存器的值
        tcon &= ~0xf00;
        tcon |= 0xb00;  //关闭死区、自动重载、关反相器、更新TCNTB0&TCMPB0、启动定时器0
        __raw_writel(tcon, S3C2410_TCON);  //设置定时器控制寄存器的0-4位,即对定时器0进行控制
        tcon &= ~0x200;
        __raw_writel(tcon, S3C2410_TCON); //清除定时器0的手动更新位
    }

    return 0;

}

//设备操作结构体

static struct file_operations pwm_fops =

{
    .owner   = THIS_MODULE,
    .open    = pwm_open,
    .release = pwm_close,
    .ioctl   = pwm_ioctl,
};

//定义一个设备类

static struct class *pwm_class;
static int __init pwm_init(void)

{
    //注册为字符设备,主设备号为0让系统自动分配,设备名为my2440_pwm,注册成功返回动态生成的主设备号
    device_major = register_chrdev(PWM_MAJOR, PWM_NAME, &pwm_fops);
    if(device_major < 0)
    {
        printk(PWM_NAME " register falid!\n");
        return device_major;
    }

    if(IS_ERR(pwm_class))
    {
        printk(PWM_NAME " register class falid!\n");
        return -1;
    }
    return 0;
}

static void __exit pwm_exit(void)
{
    unregister_chrdev(device_major, PWM_NAME);
}
module_init(pwm_init);
module_exit(pwm_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Huang Gang");
MODULE_DESCRIPTION("my2440 pwm driver");

linux命令:insmod my2440_pwm.ko
               mknod /dev/my2440_pwm c 232 0

应用程序:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>

int main(int argc, char **argv)

{
    int tmp;
    int fd;
    int i;
    tmp = 14;
    fd = open("/dev/my2440_pwm", O_RDWR);
    if(fd < 0)
    {
        printf("Open PWM Device Faild!\n");
        exit(1);
    }
    printf(" %d \n",tmp);
    ioctl(fd, tmp);
   
    return 0;
}

linux 命令:arm-linux-gcc -o pwmtt pwm_test.c
开发板:    chmod 777 pwmtt
                ./pwmtt

大神们帮帮忙把,小弟感激不敬啦!


亚瑟王 发表于 2013-11-14 15:56:30 | 显示全部楼层
试一下不联机的情况下是否会重启,PWM是否工作正常。
 楼主| zhangbo0805 发表于 2013-11-14 17:28:50 | 显示全部楼层
亚瑟王 发表于 2013-11-14 15:56
试一下不联机的情况下是否会重启,PWM是否工作正常。

不联机是什么概念呢?PWM波 在示波器上面 显示正常,得到了我想得到的波形。
亚瑟王 发表于 2013-11-14 18:27:25 | 显示全部楼层
zhangbo0805 发表于 2013-11-14 17:28
不联机是什么概念呢?PWM波 在示波器上面 显示正常,得到了我想得到的波形。

不连接陀机。
我怀疑你的电路设计有问题,没有做好防护引起的。
 楼主| zhangbo0805 发表于 2013-11-14 18:58:20 | 显示全部楼层
亚瑟王 发表于 2013-11-14 18:27
不连接陀机。
我怀疑你的电路设计有问题,没有做好防护引起的。

不连接舵机是好的,可以运行。那如果是舵机的问题,我改怎么解决?
runner547 发表于 2013-11-15 10:05:23 | 显示全部楼层
你有没有加驱动芯片!
runner547 发表于 2013-11-15 10:09:38 | 显示全部楼层
你是PWM口直接接舵机,还是舵机前端有控制芯片,注意芯片的电平是否一样!
 楼主| zhangbo0805 发表于 2013-11-17 21:17:20 | 显示全部楼层
runner547 发表于 2013-11-15 10:09
你是PWM口直接接舵机,还是舵机前端有控制芯片,注意芯片的电平是否一样!

直接驱动舵机。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

i.MX8系列ARM cortex A53 M4 工控板上一条 /1 下一条

Archiver|手机版|小黑屋|天嵌 嵌入式开发社区 ( 粤ICP备11094220号-2 )

GMT+8, 2024-9-28 13:21 , Processed in 1.031290 second(s), 18 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表