嵌入式PWM实验报告

实验通过Cortex-A9处理器对Exynos4412的PWM进行操作,控制实验箱的蜂鸣器播放音乐,涉及PWM控制、寄存器配置、驱动编写及VMware+RedHat+XShell+ARM-Linux开发环境的使用。程序包括初始化、ioctl函数和file_operations结构体的实现,以及内核模块加载、设备文件创建和应用程序运行。

实验报告书

一、实验内容与目的

实验内容

通过对Exynos4412PWM的操作,控制实验箱的蜂鸣器实现发声,并播放音乐。

实验目的

  1. 掌握使用Cortex-A9控制PWM的方法。
  2. 掌握Cortex-A9PWM寄存器的配置方法。
  3. 掌握驱动的编写步骤。
  4. 熟悉VMware+RedHat+XShell+ARM-Linux交叉编译开发环境。

二、实验原理与程序(原理图、程序流程图、程序等)

PWM0_BUZZER原理图(底板原理图)

 

其连接引脚XpwmTOUT0_C(底板原理图)

 

 

Exynos4412原理图:

 

得:PWM0_BUZZER>>XpwmTOUT0_C>>GPD0_0

程序流程图

 

程序代码

驱动文件的核心代码

①初始化函数:init

static int fs4412_pwm_io_init()

{

    writel((readl(pwm->gpd0con) & ~(0xf)) | 0x2,pwm->gpd0con);

    //设置GPD0CON控制寄存器[3:0]的值为0x2, 则TOUT0信号会输出PWM信号。

    writel((readl(pwm->timer_base+TCFG0) & ~(0Xff) | 0xc7,pwm->timer_base+TCFG0);

       //一级分频  分频值为199  即200分频   199的16进制为0xC7

    writel((readl(pwm->timer_base + TCFG1) & ~(0xf) | 0x2,pwm->timer_base + TCFG1);

      //二级分频,选分频值为1/2 即2分频

    writel(600,pwm->timer_base+TCNTB0);

    //pwm初值为600

    writel(300,pwm->timer_base+TCMPB0);

    //pwm电平翻转值为300

    writel(readl(pwm->timer_base+TCON) & ~(0xf) | 0x2,pwm->timer_base+TCON);                                                   

       //定时器手动更新,即加载TCNTB0 和 TCMPB0的值

    return 0;

}

②与驱动程序相关联的函数:ioctl

static long fs4412_pwm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)

{

    int data;

    if (_IOC_DIR(cmd) == _IOC_WRITE)

        if (copy_from_user(&data, (void *)arg, sizeof(data)))

            return -EFAULT;

    switch(cmd)

    {

    case PWM_ON:

        writel(readl(pwm->timer_base+TCON) & ~(0xf) | 0x9,pwm->timer_base+TCON);

        //设置寄存器TCON,使定时器开启,并启用自动重载

        break;

    case PWM_OFF:

        writel(readl(pwm->timer_base+TCON) & ~(0xf) ,pwm->timer_base+TCON);

        //设置寄存器TCON,使定时器关闭,低四位清零

        break;

    case SET_PRE:

        writel(readl(pwm->timer_base+TCFG0) & ~(0xff) | (data & 0xff),pwm->timer_base+TCFG0);

        //设置寄存器TCFG0的值,低八位先清零,再根据应用程序数据传过来的数据进行低八位设置

        writel(readl(pwm->timer_base+TCON) & ~(0xf) | 0x9,pwm->timer_base+TCON);

        //定时器开启,并启用自动重载

        break;

    case SET_CNT:

        writel(data,pwm->timer_base+TCNB0);

         //设置pwm定时器的初值TCNB0

        writel(data/2,pwm->timer_base+TCMPB0);

         //设置pwm定时器的翻转值TCMPB0

        break;

    }

    return 0;

}

③标记化赋值函数(作用:提供文件系统入口点函数,就可访问设备驱动程序):fops

static struct file_operations fs4412_pwm_fops = {

    .owner = THIS_MODULE,

    .open = fs4412_pwm_open,

    .release = fs4412_pwm_rlease,

    .unlocked_ioctl = fs4412_pwm_ioctl,

};

驱动文件Makefile文件代码

obj-m := fs4412_pwm.o

KERNELDIR := /CBT-SuperIOT/linux-3.5

default:

    make -C $(KERNELDIR) M=$(shell pwd) modules

clean:

    rm -rf *.o  *.ko  *.mod.*   modules.*  Mo*.*

应用程序的核心代码

//打开pwm定时器cmd为 PWM_ON ,入口函数int ioctl(int fd ,int cmd ) ;

ioctl(dev_fd,PWD_ON);

//设置pwm定时器的频率,cmd为SET_PRE入口函数int ioctl(int fd , int cmd , char *argp );

ioctl(dev_fd,SET_PRE,&pre);

while (1){

for(i = 0;i<sizeof(MotherLoveMeOnceAgain)/sizeof(Note);i++ )

{

div = (PCLK/199/2)/(MotherLoveMeOnceAgain[i].pitch);

//设置pwm定时器的CNT值, cmd为SET_CNT,把div作为参数传入入口函数int ioctl(int fd , int cmd , char *argp );

ioctl(dev_fd,SET_CNT,&div);

usleep(MotherLoveMeOnceAgain[i ].dimation *50);

}

应用程序Makefile文件代码

CC = arm-linux-gcc

TARGET = All

OBJECT = pwm_test.o

$(TARGET):$(OBJECT)

    $(CC) $(OBJECT) -o pwm_test

$(OBJECT):test_pwm.c

    $(CC) -c test_pwm.c -o $(OBJECT)

clean:

    rm *.o pwm_test

三、实验操作步骤

硬件驱动编译、加载、运行步骤

  1. 编译驱动程序

编写fs4412_pwm.c驱动文件在pc端的Linux系统下编写

编写驱动文件的编译文件Makefile

使用make命令运行Makefile文件,使fs4412_pwm.c文件生成pwm.ko的内核模块文件

  1. 编译应用程序

编写pwm_test.c驱动文件在pc端的Linux系统下编写

编写驱动文件的编译文件Makefile,make一下

配置交叉开发环境

①连接Cortex-A9的3根线:电源线、串口线、网线。

②配置网络IP地址。

  1. PC Linux网络与PC主机在同一网段
  2. Cortex-A9网络与PC(或PC Linux)在同一网段内
  3. Ping: Cortex-A9和PC Linux是否可以通
  4. 关闭PC Linux端的防火墙和NFS服务

③使用XShell来连接Cortex-A9,并将PC Linux系统下的/CBT-SuperIOT目录挂载到Cortex-A9系统下的/mnt目录下

  1. 加载驱动程序

将内核文件加载到Linux系统的内核里面:insmod adc.ko

  1. 创建设备文件

生成设备文件mknod /dev/pwm c 500 0

  1. 运行应用程序

进入adc应用程序的目录中运行:./pwm_test

四、实验结果与总结

实验结果

     蜂鸣器可播放pwm_music.h文件的音乐。

实验总结

  1. 学习到了PWM的工作原理
  2. PWM需首先设置定时器对应引脚的复用选择。
  3. 设置定时器的输入工作频率的分频。
  4. 设置定时器的计数初值和比较寄存器。
  5. 最后设置定时的工作模式,并启动定时器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值