4412 4路pwm输出
一、4412 xpwmTOUT1
这是4412的GPD0_1路,itop中被使用为LCD的背光电路的pwm功能。因此如果使用教程中的代码,同样操作GPD0_1是行不通的。
会出现错误,所以需要解除在内核中的占用
修改arch/arm/mach-exynos/mach-itop4412.c,找到并注释
samsung_bl_set(&smdk4x12_bl_gpio_info, &smdk4x12_bl_data);
在内核中取消相关的模块编译,(不确定)
Device Driver>>Graphics support>>Backlight & LCD device support(取消)
然后在平台文件中增加注册设备:
&s3c_device_timer[],
然后是测试代码:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/fb.h>
#include <linux/backlight.h>
#include <linux/err.h>
#include <linux/pwm.h>
#include <linux/slab.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
#include <linux/ioctl.h>
#include <asm-generic/uaccess.h> #define DEVICE_NAME "my_pwm3_dev"
#define DRIVER_NAME "my_pwm3_drv" #define PWM_MAGIC 'p'
#define PWM_MAX_NR 3 #define PWM_IOCTL_STOP _IO(PWM_MAGIC, 0)
#define PWM_IOCTL_SET_FREQ _IO(PWM_MAGIC, 1)
#define PWM_IOCTL_SET_DUTY _IO(PWM_MAGIC, 2) #define NS_IN_1HZ (1000000000UL) #define BUZZER_PWM_ID 0
#define PWM1_ID 1
#define PWM2_ID 2
#define PWM3_ID 3 #define BUZZER_PMW_GPIO EXYNOS4_GPD0(0)
#define PWM1_GPIO EXYNOS4_GPD0(1)
#define PWM2_GPIO EXYNOS4_GPD0(2)
#define PWM3_GPIO EXYNOS4_GPD0(3) static struct pwm_device *pwm4buzzer;
static struct semaphore lock;
static int period_ns = ;
static unsigned long freq = ;
static unsigned long duty = ; static void pwm_set_freq(void)
{
//配置周期
period_ns = NS_IN_1HZ / freq;
//配置占空比
if(duty < )
duty = ;
pwm_disable(pwm4buzzer);
pwm_config(pwm4buzzer, period_ns / duty, period_ns);
pwm_enable(pwm4buzzer);
//配置相应的GPIO,蜂鸣器IO配置成PWM输出模式
s3c_gpio_cfgpin(PWM3_GPIO, S3C_GPIO_SFN());
} static void pwm_stop(void)
{
s3c_gpio_cfgpin(PWM3_GPIO, S3C_GPIO_OUTPUT); pwm_config(pwm4buzzer, , NS_IN_1HZ / );
pwm_disable(pwm4buzzer);
} static int ops_pwm_open(struct inode *inode, struct file *file)
{
if(!down_trylock(&lock))
return ;
else
return -EBUSY;
} static int ops_pwm_close(struct inode *inode, struct file *file)
{
up(&lock);
return ;
} static long ops_pwm_ioctl(struct file *filep, unsigned int cmd,
unsigned long arg)
{
if(_IOC_TYPE(cmd)!=PWM_MAGIC) return -EINVAL;
if(_IOC_NR(cmd) > PWM_MAX_NR) return -EINVAL; switch(cmd) {
case PWM_IOCTL_SET_FREQ:
if(arg == )
return -EINVAL;
get_user(freq, (unsigned long __user *)arg);
printk(KERN_EMERG "freq is %ld\n", freq);
pwm_set_freq();
break;
case PWM_IOCTL_STOP:
pwm_stop();
break;
case PWM_IOCTL_SET_DUTY:
get_user(duty, (unsigned long __user *)arg);
printk(KERN_EMERG "duty is %ld\n", duty);
pwm_set_freq();
break;
default:
pwm_stop();
break;
}
return ;
} static struct file_operations pwm_ops = {
.owner = THIS_MODULE,
.open = ops_pwm_open,
.release = ops_pwm_close,
.unlocked_ioctl = ops_pwm_ioctl,
}; static struct miscdevice pwm_misc_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &pwm_ops,
}; static int __init iTop4412_pwm_dev_init(void)
{
int ret;
gpio_free(PWM3_GPIO); ret = gpio_request(PWM3_GPIO, DEVICE_NAME);
if(ret) {
printk(KERN_EMERG "request GPIO %d for pwm failed\n", PWM3_GPIO);
return ret;
} gpio_set_value(PWM3_GPIO, );
s3c_gpio_cfgpin(PWM3_GPIO, S3C_GPIO_OUTPUT); pwm4buzzer = pwm_request(PWM3_ID, DEVICE_NAME);
if (IS_ERR(pwm4buzzer)) {
printk(KERN_EMERG "request pwm %d for %s failed\n", PWM3_ID, DEVICE_NAME);
return -ENODEV;
}
pwm_stop(); sema_init(&lock, );
ret = misc_register(&pwm_misc_dev);
if(ret < ) {
gpio_free(BUZZER_PMW_GPIO);
pwm_free(pwm4buzzer);
misc_deregister(&pwm_misc_dev);
} printk(KERN_EMERG "\tinitialized\n"); return ret;
} static void __exit iTop4412_pwm_dev_exit(void)
{
gpio_free(BUZZER_PMW_GPIO);
pwm_free(pwm4buzzer);
misc_deregister(&pwm_misc_dev); printk(KERN_EMERG "\texit\n");
return;
} module_init(iTop4412_pwm_dev_init);
module_exit(iTop4412_pwm_dev_exit); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Chen Tuo");
MODULE_DESCRIPTION("Exynos4 PWM Driver");
my_pwm3.c
然后是应用程序:
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/ioctl.h> #define PWM2_NAME "/dev/my_pwm3_dev" #define PWM_MAGIC 'p'
#define PWM_MAX_NR 3 #define PWM_IOCTL_STOP _IO(PWM_MAGIC, 0)
#define PWM_IOCTL_SET_FREQ _IO(PWM_MAGIC, 1)
#define PWM_IOCTL_SET_DUTY _IO(PWM_MAGIC, 2) int fd = -; void open_pwm1(void);
void close_pwm1(void);
void set_pwm_freq(int freq);
void set_pwm_duty(int duty);
void stop_pwm(void); void open_pwm1(void)
{
fd = open(PWM2_NAME, O_RDWR);
if(fd < ) {
perror("open pwm1 device");
exit();
} // atexit(close_pwm1);
} void close_pwm1(void)
{
if(fd >= ) {
ioctl(fd, PWM_IOCTL_STOP);
close(fd);
fd = -;
}
} void set_pwm_freq(int freq)
{
int ret = ioctl(fd, PWM_IOCTL_SET_FREQ, &freq);
if(ret < ) {
perror("set the frequency of the buzzer");
exit();
}
} void set_pwm_duty(int duty)
{
int ret = ioctl(fd, PWM_IOCTL_SET_DUTY, &duty);
if(ret < ) {
perror("set the duty of the pwm");
exit();
}
} void stop_pwm(void)
{
int ret = ioctl(fd, PWM_IOCTL_STOP);
if(ret < ) {
perror("Stop the buzzer");
exit();
}
} int main(int argc, char *argv[])
{
int freq = ; open_pwm1();
stop_pwm();
if(argc < ) {
printf("usage:%s [cmd] [arg]\n", argv[]);
printf("\tstop:%s [0] [0] \n",argv[]);
printf("\tset freq:%s [1] [arg]\n", argv[]);
printf("\tset duty:%s [2] [arg]\n", argv[]);
}
switch(atoi(argv[]))
{
case :
set_pwm_duty(atoi(argv[]));
break;
case :
set_pwm_freq(atoi(argv[]));
break;
case :
default:
stop_pwm();
return -;
} return ;
}
my_pwm3_app.c
最后是Makefile:
TARGET_NAME = my_pwm3
#TARGET_NAME = example_pwm
APP1_NAME = my_pwm3_app
#APP2_NAME = open_atomic_int_two
obj-m += $(TARGET_NAME).o KDIR := /home/topeet/chen/kernel-3.0/iTop4412_Kernel_3. PWD ?= $(shell pwd) all:app1
make -C $(KDIR) M=$(PWD) modules
app1:
arm-none-linux-gnueabi-gcc $(APP1_NAME).c -o $(APP1_NAME) -static
#app2:
# arm-none-linux-gnueabi-gcc $(APP2_NAME).c -o $(APP2_NAME) -static clean:
rm -rf *.o *.ko *.mod.c *.symvers *.order \
.$(TARGET_NAME)* $(APP1_NAME) $(APP2_NAME)
Makefile
二、4412 I2C_SDA7和I2C_SCL7
注释平台文件中的代码:
// s3c_i2c7_set_platdata(NULL);
// i2c_register_board_info(7, i2c_devs7, ARRAY_SIZE(i2c_devs7));
和这个
// &s3c_device_i2c7,
然后make menuconfig
>>Device Drivers>>Input device support>>Touchscreens【】取消选择
三、尝试编写控制PWM波形的驱动和应用程序
my_pwm3.c(驱动)
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/fb.h>
#include <linux/backlight.h>
#include <linux/err.h>
#include <linux/pwm.h>
#include <linux/slab.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
#include <linux/ioctl.h>
#include <asm-generic/uaccess.h> #define DEVICE_NAME "my_pwm3_dev"
#define DRIVER_NAME "my_pwm3_drv" #define PWM_MAGIC 'p'
#define PWM_MAX_NR 3 #define PWM_IOCTL_STOP _IO(PWM_MAGIC, 0)
#define PWM_IOCTL_SET_FREQ _IO(PWM_MAGIC, 1)
#define PWM_IOCTL_SET_DUTY _IO(PWM_MAGIC, 2) #define NS_IN_1HZ (1000000000UL) #define BUZZER_PWM_ID 0
#define PWM1_ID 1
#define PWM2_ID 2
#define PWM3_ID 3 #define BUZZER_PMW_GPIO EXYNOS4_GPD0(0)
#define PWM1_GPIO EXYNOS4_GPD0(1)
#define PWM2_GPIO EXYNOS4_GPD0(2)
#define PWM3_GPIO EXYNOS4_GPD0(3) static struct pwm_device *pwm4buzzer;
static struct semaphore lock;
static int period_ns = ;
static unsigned long freq = ;
static unsigned long duty = ; static void pwm_set_freq(void)
{
//配置周期
period_ns = NS_IN_1HZ / freq;
//配置占空比
if(duty < )
duty = ;
pwm_disable(pwm4buzzer);
pwm_config(pwm4buzzer, period_ns / duty, period_ns);
pwm_enable(pwm4buzzer);
//配置相应的GPIO,蜂鸣器IO配置成PWM输出模式
s3c_gpio_cfgpin(PWM3_GPIO, S3C_GPIO_SFN());
} static void pwm_stop(void)
{
s3c_gpio_cfgpin(PWM3_GPIO, S3C_GPIO_OUTPUT); pwm_config(pwm4buzzer, , NS_IN_1HZ / );
pwm_disable(pwm4buzzer);
} static int ops_pwm_open(struct inode *inode, struct file *file)
{
if(!down_trylock(&lock))
return ;
else
return -EBUSY;
} static int ops_pwm_close(struct inode *inode, struct file *file)
{
up(&lock);
return ;
} static long ops_pwm_ioctl(struct file *filep, unsigned int cmd,
unsigned long arg)
{
if(_IOC_TYPE(cmd)!=PWM_MAGIC) return -EINVAL;
if(_IOC_NR(cmd) > PWM_MAX_NR) return -EINVAL; switch(cmd) {
case PWM_IOCTL_SET_FREQ:
if(arg == )
return -EINVAL;
get_user(freq, (unsigned long __user *)arg);
printk(KERN_EMERG "freq is %ld\n", freq);
pwm_set_freq();
break;
case PWM_IOCTL_STOP:
pwm_stop();
break;
case PWM_IOCTL_SET_DUTY:
get_user(duty, (unsigned long __user *)arg);
printk(KERN_EMERG "duty is %ld\n", duty);
pwm_set_freq();
break;
default:
pwm_stop();
break;
}
return ;
} static struct file_operations pwm_ops = {
.owner = THIS_MODULE,
.open = ops_pwm_open,
.release = ops_pwm_close,
.unlocked_ioctl = ops_pwm_ioctl,
}; static struct miscdevice pwm_misc_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &pwm_ops,
}; static int __init iTop4412_pwm_dev_init(void)
{
int ret;
gpio_free(PWM3_GPIO); ret = gpio_request(PWM3_GPIO, DEVICE_NAME);
if(ret) {
printk(KERN_EMERG "request GPIO %d for pwm failed\n", PWM3_GPIO);
return ret;
} gpio_set_value(PWM3_GPIO, );
s3c_gpio_cfgpin(PWM3_GPIO, S3C_GPIO_OUTPUT); pwm4buzzer = pwm_request(PWM3_ID, DEVICE_NAME);
if (IS_ERR(pwm4buzzer)) {
printk(KERN_EMERG "request pwm %d for %s failed\n", PWM3_ID, DEVICE_NAME);
return -ENODEV;
}
pwm_stop(); sema_init(&lock, );
ret = misc_register(&pwm_misc_dev);
if(ret < ) {
gpio_free(BUZZER_PMW_GPIO);
pwm_free(pwm4buzzer);
misc_deregister(&pwm_misc_dev);
} printk(KERN_EMERG "\tinitialized\n"); return ret;
} static void __exit iTop4412_pwm_dev_exit(void)
{
gpio_free(BUZZER_PMW_GPIO);
pwm_free(pwm4buzzer);
misc_deregister(&pwm_misc_dev); printk(KERN_EMERG "\texit\n");
return;
} module_init(iTop4412_pwm_dev_init);
module_exit(iTop4412_pwm_dev_exit); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Chen Tuo");
MODULE_DESCRIPTION("Exynos4 PWM Driver");
my_pwm3.c
my_pwm3_app.c
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/ioctl.h> #define PWM2_NAME "/dev/my_pwm3_dev" #define PWM_MAGIC 'p'
#define PWM_MAX_NR 3 #define PWM_IOCTL_STOP _IO(PWM_MAGIC, 0)
#define PWM_IOCTL_SET_FREQ _IO(PWM_MAGIC, 1)
#define PWM_IOCTL_SET_DUTY _IO(PWM_MAGIC, 2) int fd = -; void open_pwm1(void);
void close_pwm1(void);
void set_pwm_freq(int freq);
void set_pwm_duty(int duty);
void stop_pwm(void); void open_pwm1(void)
{
fd = open(PWM2_NAME, O_RDWR);
if(fd < ) {
perror("open pwm1 device");
exit();
} // atexit(close_pwm1);
} void close_pwm1(void)
{
if(fd >= ) {
ioctl(fd, PWM_IOCTL_STOP);
close(fd);
fd = -;
}
} void set_pwm_freq(int freq)
{
int ret = ioctl(fd, PWM_IOCTL_SET_FREQ, &freq);
if(ret < ) {
perror("set the frequency of the buzzer");
exit();
}
} void set_pwm_duty(int duty)
{
int ret = ioctl(fd, PWM_IOCTL_SET_DUTY, &duty);
if(ret < ) {
perror("set the duty of the pwm");
exit();
}
} void stop_pwm(void)
{
int ret = ioctl(fd, PWM_IOCTL_STOP);
if(ret < ) {
perror("Stop the buzzer");
exit();
}
} int main(int argc, char *argv[])
{
int freq = ; open_pwm1();
stop_pwm();
if(argc < ) {
printf("usage:%s [cmd] [arg]\n", argv[]);
printf("\tstop:%s [0] [0] \n",argv[]);
printf("\tset freq:%s [1] [arg]\n", argv[]);
printf("\tset duty:%s [2] [arg]\n", argv[]);
}
switch(atoi(argv[]))
{
case :
set_pwm_duty(atoi(argv[]));
break;
case :
set_pwm_freq(atoi(argv[]));
break;
case :
default:
stop_pwm();
return -;
} return ;
}
my_pwm3_app.c
Makefile
TARGET_NAME = my_pwm3
#TARGET_NAME = example_pwm
APP1_NAME = my_pwm3_app
#APP2_NAME = open_atomic_int_two
obj-m += $(TARGET_NAME).o KDIR := /home/topeet/chen/kernel-3.0/iTop4412_Kernel_3. PWD ?= $(shell pwd) all:app1
make -C $(KDIR) M=$(PWD) modules
app1:
arm-none-linux-gnueabi-gcc $(APP1_NAME).c -o $(APP1_NAME) -static
#app2:
# arm-none-linux-gnueabi-gcc $(APP2_NAME).c -o $(APP2_NAME) -static clean:
rm -rf *.o *.ko *.mod.c *.symvers *.order \
.$(TARGET_NAME)* $(APP1_NAME) $(APP2_NAME)
Makfile
总结:内核接收ioctl的信息时需要使用特定的函数进行保护,防止被乱七八糟的传入数据。
4412 4路pwm输出的更多相关文章
- 16路PWM输出的pca9685模块
今天要介绍的就是该模块,该模块是16路pwm模块,使用I2C总线可以控制16路舵机(led). 接线OE空着就可以,其他VCC是芯片供电+5,SCL时钟线,SDA信号线,GND地线. 芯片介绍可以看: ...
- J20航模遥控器开源项目系列教程(五)| 制作STM32F0接收机,8路PWM输出,SBUS输出,PPM输出 | 加密狗无线化,畅玩飞行模拟器
我们的开源宗旨:自由 协调 开放 合作 共享 拥抱开源,丰富国内开源生态,开展多人运动,欢迎加入我们哈~ 和一群志同道合的人,做自己所热爱的事! 项目开源地址:https://github.com/J ...
- STM32 PWM输出(映射)
STM32 的定时器除了 TIM6 和 7.其他的定时器都可以用来产生 PWM 输出.其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出.而通用定时器也能同时产生多达 4 ...
- 定时器同步+触发三ADC采样+输出6路PWM波
为了熟悉定时器定时器和ADC 用STM32F407DIS做了一个简单的工程: 通过高级定时器TIM1溢出更新时间作为触发输出信号(TRGO),触发TIM8开始计数: 同时TIM1的通道1.2.3以及分 ...
- (五)转载:通用定时器PWM输出
1. TIMER输出PWM基本概念 脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有 ...
- STM32 HAL库学习系列第4篇 定时器TIM----- 开始定时器与PWM输出配置
基本流程: 1.配置定时器 2.开启定时器 3.动态改变pwm输出,改变值 HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1); 函数总结: __HAL_TIM ...
- STM32(7)——通用定时器PWM输出
1.TIMER输出PWM基本概念 脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种 ...
- stm32 PWM输出学习
STM32 的定时器除了 TIM6 和 7,其他的定时器都可以用来产生 PWM 输出.其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出.通用定时器也能同时产生多达 4路 ...
- STM32F103ZET6 PWM输出
1.通用定时器的PWM功能 STM32F103ZET6有4个通用定时器,分别是TIM2.TIM3.TIM4.TIM5. 通用定时器由一个可编程预分频器驱动的16位自动装载计数器构成. 通用定时器的很多 ...
随机推荐
- ES命令
基础概念 Elasticsearch有几个核心概念.从一开始理解这些概念会对整个学习过程有莫大的帮助. 接近实时(NRT) Elasticsearch是一个接近实时的搜索平台.这意味 ...
- 【ABAP系列】SAP ABAP常用正则表达式大全
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP常用正则表达式大 ...
- 20190813 On Java8 第一章 对象的概念
第一章 对象的概念 抽象 Alan Kay 总结了对象的五大基本特征 万物皆对象. 程序是一组对象,通过消息传递来告知彼此该做什么. 每个对象都有自己的存储空间,可容纳其他对象. 每个对象都有一种类型 ...
- 08 (h5*) js第9天--原型、继承
目录: 1:原型和原型链 2:构造函数的原型可以改变 3:原型的最终指向 4:先修改原型指向,在添加方法. 5:实例对象中的属性和原型属性重合, 6:一个神奇的原型链 7:继承 8:原型链 9:利用c ...
- 什么是php扩展
PHP扩展英文为PHP Extension and Application Repository,简称pear(下面都以pear简称),中文全称为PHP扩展与应用库.是为了创建一个类似于Perl CP ...
- PowerShell - Invoke VBA function
$xl = new-object -comobject Excel.Application $source_wb = $xl.workbooks.open($source) $xl.visible=$ ...
- JavaScript GetAbsoultURl
var img = document.createElement('A'); img.src = "/img/weixin.jpg"; // 设置相对路径给Image, ...
- Python 根据入栈顺利判定出栈顺序
1.读取入栈,出栈数据: 2.把数据分别转化成整数列表: 3.新建栈列表,用入栈数据进行压栈:如果栈列表不为空,并且栈顶层数据为出栈的元素:删除栈列表的顶层数据: 4.如果栈列表不为空,说明栈列表里面 ...
- [SOL] #148. 数字格子问题
说实话这题确实挺菜的... 废话少说,直接上代码^O^ Code: #include <bits/stdc++.h> using namespace std; inline int rea ...
- Educational Codeforces Round 69 (Rated for Div. 2) A~D Sloution
A. DIY Wooden Ladder 题意:有一些不能切的木板,每个都有一个长度,要做一个梯子,求梯子的最大台阶数 做梯子的木板分为两种,两边的两条木板和中间的若干条台阶木板 台阶数为 $k$ 的 ...