首页 > 代码库 > 05day02pwm

05day02pwm

  1 /*  2 pwm  硬件手册24章  3 蜂鸣器   GPD0_0  配置成  tout0  pwm0的输出  4   5 从硬件手册P446页 查出  总线的频率是100Mhz  6   7 TCFG0  配置一级分频  0-7位  配置timer0~1的预分频  8 8~15  配置timer2 3 4预分频  9 TCFG1  设置5个timer的二级分频 10 TCON  pwm定时器的控制寄存器 11 [0]  定时器0的开关 12 [1]   将TCNTB0和TCMPB0的值分别写入定时器0内部 13 注意一点,写入的操是瞬间完成,写完之后要立即把该位清0 14 否则,写入的操作将会连续不断的持续进行,那么定时器就无法计数 15 [2]  输出电平的极性,参照1300 ,该值会影响到占空比的计算 16 [3]  单次开启还是连续开启  (每个计数周期结束之后会自动将TCMB0写入计数器中,开始新的周期) 17  18 TINT_CSTAT  使能和清除,对应的中断 19  20  21 linux 内核  设备和设备分离 22  23 */   24 #include <linux/module.h> 25 #include <linux/init.h> 26 #include <linux/kernel.h> //printk 27  28 #include <linux/miscdevice.h> //misc_register.... 29 #include <linux/fs.h> //file_operations 30 #include <mach/regs-gpio.h> //S5P_VA_GPIO2 31 #include <linux/ioport.h> //request_mem_region 32  33 #include <linux/io.h> 34  35 #include "pwm_ctl.h" 36  37 #define DEVNAME "ldm" 38  39  40 #define TCFG0   (*(volatile u32 *)ioremap(0x139d0000, 4)) 41 #define TCFG1    (*(volatile u32 *)ioremap(0x139d0004, 4)) 42 #define TCON    (*(volatile u32 *)ioremap(0x139d0008, 4)) 43 #define TCNTB0  (*(volatile u32 *)ioremap(0x139d000c, 4)) 44 #define TCMPB0  (*(volatile u32 *)ioremap(0x139d0010, 4)) 45 #define TINT_CSTAT  (*(volatile u32 *)ioremap(0x139d0044, 4)) 46  47 #define GPD0CON    (*(volatile u32 *)ioremap(0x114000a0, 4)) 48  49 struct   ldm_info  50 { 51     struct miscdevice dev; 52     struct file_operations  ops; 53 }; 54  55 struct ldm_info ldm; 56  57 //跟时钟配置相关 58  59  60 // int pwm_init() 61 // { 62 //     //GPD0CON 配置成复用模式 63  64 //     //设置频率 65  66 //     //设置TCNTB0  TCMPB0  两个寄存器 67 //     //提供应用层相关的接口 68  69 //     //把TCNTB0  和  TCMPB0  加载到 定时器中 70 //     TCON  |=   1 << 1; 71 //     TCON  &= ~(1 << 1); 72  73 //     //打开定时器,开启连续触发的模式 74  75  76 //     //加入到misc 子系统中 以提供给用户层访问 77  78  79 static inline void timer0_cout_set(u32  cmp, u32  cnt) 80 { 81     TCNTB0 = cnt; 82     TCMPB0 = cmp; 83  84     TCON  |=   1 << 1; 85     TCON  &= ~(1 << 1); 86 } 87  88 long ldm_ioctl(struct file *  file, unsigned int  cmd, unsigned long arg) 89 { 90  91     switch(cmd) { 92         case SET_CMP: 93             timer0_cout_set(arg, TIMER0_KHZ /2); 94             break; 95         default: 96             break; 97     } 98     return 0; 99 }100 101 static int ldm_init(void)102 {103     int ret = 0;104     printk("%s:%s, %d\n", __FILE__, __FUNCTION__, __LINE__);105 106     ////GPD0CON 配置成复用模式107     GPD0CON = (GPD0CON & ~0xf) | 0x2;108 109     //设置频率110     TCFG0 = (TCFG0 & ~0xff) | PWM_PRESCALER0;111     TCFG1 = (TCFG1 & ~0xf) | DIV;112 113     //占空比为50%114     timer0_cout_set(TIMER0_KHZ/4, TIMER0_KHZ /2);115 116     //把TCNTB0  和  TCMPB0  加载到 定时器中117     TCON  |=   1 << 1;118     TCON  &= ~(1 << 1);119 120     //打开定时器,选择连续触发模式121     TCON &= ~(1 << 2);122     TCON |=  1<< 3 | 1;123 124     //给应用层提供接口125     ldm.dev.minor =  MISC_DYNAMIC_MINOR;126     ldm.dev.name  = DEVNAME;127     ldm.dev.fops = &ldm.ops;128     ldm.ops.unlocked_ioctl = ldm_ioctl;129 130     ret = misc_register(&ldm.dev);131     if(ret < 0) {132         printk("misc_register  failed\n");133         goto err_misc_register;134     }135 136     return 0;137 err_misc_register:138     return -1;139 140 }141 142 static void ldm_exit(void)143 {144     printk("%s:%s, %d\n", __FILE__, __FUNCTION__, __LINE__);145     misc_deregister(&ldm.dev);146 }147 148 149 150 module_init(ldm_init);151 module_exit(ldm_exit);152 MODULE_LICENSE("GPL");

.h

 1 #pragma once 2  3 #include <linux/ioctl.h> 4 //参考下内核文档 linux/linux-3.5/Documentation/ioctl 5 //ioctl-decoding.txt  和 ioctl-number.txt 6 //例如 实现  控制LED灯 7 /* 8 _IO (魔数, 基数); 9 • _IOR (魔数, 基数, 变量型)10 • _IOW (魔数, 基数, 变量型)11 • _IOWR (魔数, 基数,变量型 )12 */13 14 enum 15 {    16     //4412  P446  100MHZ17     PCLK_PERIL = 100000000,18     PWM_PRESCALER0 = 99,19     DIV =  4,20 21     TIMER0_HZ = PCLK_PERIL / (PWM_PRESCALER0 + 1) / 16,22     TIMER0_KHZ  = TIMER0_HZ /1000,23 };24 25 //26 #define  SET_CMP   _IOW(‘l‘, 1, unsigned int)27 //底层的驱动生成的一系列 命令  这个头文件同样也需要提供给应用层28 29 #define DUTY_0   TIMER0_KHZ/230 //#define DUTY_25 31 #define DUTY_50    TIMER0_KHZ/432 //#define DUTY_7533 #define DUTY_100   0

.app

//应用层#include <stdio.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <sys/ioctl.h>#include "pwm_ctl.h"int main(int argc, char const *argv[]){    int fd = open("/dev/ldm", O_RDWR);    if(fd < 0) {           perror("open");           goto err_open;    }    //ioctl(fd, LED_STATUS, led_status);    //ioctl(fd, LED1_ON);    ioctl(fd, SET_CMP, DUTY_100);    close(fd);    return 0;err_open:    return -1;}

 

05day02pwm