嵌入式PWM实验报告

实验报告书

一、实验内容与目的

实验内容

通过对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. 最后设置定时的工作模式,并启动定时器。

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
嵌入 PWM 是一种用于控制舵机的有效技术。舵机可以通过改变脉冲宽度来调整角度位置,因此使用 PWM 来模拟脉冲信号是非常合适的。 对于嵌入系统,我们可以使用 C 语言编写控制舵机的代码。首先,我们需要初始化 PWM 模块,并设置频率和占空比。然后,我们可以使用一个循环来不断地修改占空比,从而控制舵机的角度。 以下是一个简单的示例代码: ```c #include <msp430.h> #define PWM_PERIOD 1000 // PWM 周期 #define MIN_ANGLE 500 // 最小角度位置对应的占空比 #define MAX_ANGLE 2500 // 最大角度位置对应的占空比 void initPWM() { P1DIR |= BIT2; // P1.2 输出 P1SEL |= BIT2; // P1.2 使用 PWM 功能 TA0CTL = TASSEL_2 + MC_1; // 选择 SMCLK 作为时钟源,设置为增计数模 TA0CCR0 = PWM_PERIOD - 1; // 设置 PWM 周期 TA0CCTL1 = OUTMOD_7; // 设定输出模PWM TA0CCR1 = MIN_ANGLE; // 初始角度设为最小位置 } void setAngle(int angle) { if (angle < 0) { angle = 0; } else if (angle > 180) { angle = 180; } // 将角度转换成对应的占空比 int dutyCycle = (int)(MIN_ANGLE + (MAX_ANGLE - MIN_ANGLE) * angle / 180.0); TA0CCR1 = dutyCycle; // 设置占空比 } int main() { WDTCTL = WDTPW + WDTHOLD; // 关闭看门狗定时器 initPWM(); // 初始化 PWM while(1) { setAngle(90); // 将舵机角度设为 90 度 __delay_cycles(1000000); // 延时 setAngle(0); // 将舵机角度设为 0 度 __delay_cycles(1000000); // 延时 } } ``` 以上代码通过 MSP430 的 PWM 模块来控制舵机的角度,其中使用了 `initPWM` 函数来初始化 PWM 模块,`setAngle` 函数用于设置舵机的角度,`main` 函数则是一个简单的循环示例,用于不断地改变舵机的角度。希望这个示例能够帮助您理解如何利用嵌入 PWM 控制舵机的代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值