datasheet

Tiny210裸机PWM控制蜂鸣器

2018-10-12来源: eefocus 关键字:Tiny210裸机  PWM控制  蜂鸣器

start.S源码:

.global _start

_start:

    ldr sp, =0xD0030000  // 初始化栈,因为后面要调用C函数 

    bl clock_init                // 初始化时钟 

    bl ddr_init                   // 初始化内存 

    bl nand_init                // 初始化NAND 

    ldr r0, =0x36000000  // 要拷贝到DDR中的位置 

    ldr r1, =0x0                // 从NAND的0地址开始拷贝 

    ldr r2, =bss_start       // BSS段的开始地址 

    sub r2,r2,r0                // 要拷贝的大小 

    bl nand_read            // 拷贝数据 

clean_bss:

    ldr r0, =bss_start

    ldr r1, =bss_end

    mov r3, #0

    cmp r0, r1

    ldreq pc, =on_ddr

clean_loop:

    str r3, [r0], #4

    cmp r0, r1    

    bne clean_loop        

    ldr pc, =on_ddr

on_ddr:

    ldr sp, =0x3f000000    // 重新初始化栈,指向内存 

    ldr pc, =main

=====================================================================

timer.c源码:

#define    GPD0CON     (*(volatile unsigned int *)0xE02000A0) 

#define    TCFG0           (*(volatile unsigned int *)0xE2500000) 

#define    TCFG1           (*(volatile unsigned int *)0xE2500004) 

#define    TCON            (*(volatile unsigned int *)0xE2500008) 

#define    TCNTB0         (*(volatile unsigned int *)0xE250000C) 

#define    TCMPB0        (*(volatile unsigned int *)0xE2500010) 

#define    TCNTO0        (*(volatile unsigned int *)0xE2500014) 

void pwm_init(void)

{

    // 配置为GPD0_0用于PWM输出 

    GPD0CON |= (0x2 << 0);     // TOUT_0 

}

void timer0_init(void)

{

    // 设置时钟源

    // Timer0 input clock Frequency = 66700000 / ( {prescaler + 1} ) / {divider value} 

    //      = 66700000 / (1+1) / 1

    //      = 33350000( 即1s计数33350000次 )

    TCFG0 &= ~(0xff);

    TCFG0  |= 1;        // Prescaler = 1 

    TCFG1  &= ~0xf;     // 0000 = 1/1 

    // 设置TCNTB0(即PWM的频率) 

    TCNTB0 = 33350;     // PWM的频率为1KHz  

                               

    // 设置TCMPB0(即PWM的占空比) 

    TCMPB0 = 16675;     // 占空比为50% 

    TCON &= ~(1<<2);    // 不进行电平反转(即引脚初始值为0) 

    TCON |= (1<<3);     // auto-reload 

}

void pwm_start(void)

{

    TCON |= (1<<1);   // set manual update 

    TCON |= (1<<0);   // start timer 0 

    TCON &= ~(1<<1);  // clean manual update 

}

void pwm_stop(void)

{

    TCON &= ~(1<<0);   // stop timer 0 

}

=====================================================================

command.c源码:

#include "lib.h"

#include "nand.h"

#include "timer.h"

int help(int argc, char * argv[])

{

    wy_printf("do_command 《%s》 \n", argv[0]);      //"《"实际为"<"

    wy_printf("help message: \n");

    wy_printf("md - memory dispaly\n");

    wy_printf("mw - memory write\n");

    wy_printf("nand read - nand read sdram_addr nand_addr size\n");

    wy_printf("nand write - nand write sdram_addr nand_addr size\n");

    wy_printf("pwm on - turn on buzzer \n");

    wy_printf("pwm off - turn off buzzer\n");

    return 0;

}

int md(int argc, char * argv[])

{    

    unsigned long *p = (unsigned long *)0;

    int i, j;

    wy_printf("do_command 《%s》 \n", argv[0]);

    if (argc <= 1) {

        wy_printf ("Usage:\n%s\n", "md address");

        return 1;

    }

    

    if (argc >= 2)

        p = (unsigned long *)atoi(argv[1]);

        

    for (j = 0; j < 16; j++)

    {    

        wy_printf("%x: ", p);

        for (i = 0; i < 4; i++)

            wy_printf("%x ", *p++);    

        wy_printf("\n");

    }

        

    return 0;

}

int mw(int argc, char * argv[])

{    

    unsigned long *p = (unsigned long *)0;

    int v = 0;

    wy_printf("do_command 《%s》 \n", argv[0]);//"《"实际为"<"

    if (argc <= 2) {

        wy_printf ("Usage:\n%s\n", "md address data");

        return 1;

    }

    

    if (argc >= 2)

        p = (unsigned long *)atoi(argv[1]);

        

    if (argc >= 3)

        v = atoi(argv[2]);

        

    *p = v;

    

    return 0;

}

int nand(int argc, char *argv[])

{

    int nand_addr, sdram_addr;

    unsigned int size;

    

    if (argc < 5)

    {

        wy_printf("nand read sdram_addr nand_addr size\n");

        wy_printf("nand write sdram_addr nand_addr size\n");

        return 0;

    }

    sdram_addr = atoi(argv[2]);

    nand_addr = atoi(argv[3]);

    size = atoi(argv[4]);

    wy_printf("do_command 《%s》 \n", argv[0]);

    wy_printf("sdram 0x%x, nand 0x%x, size 0x%x\n", sdram_addr, nand_addr, size);

    if (strcmp(argv[1], "read") == 0)

        nand_read((unsigned char *)sdram_addr, nand_addr, size);

    if (strcmp(argv[1], "write") == 0)

        nand_write(sdram_addr, nand_addr, size);    

    wy_printf("nand %s finished!\n", argv[1]);

    return 0;

}

int pwm(int argc, char *argv[])

{

    pwm_init();

    

    if (argc < 2)

    {

        wy_printf("pwm on - turn on buzzer \n");

        wy_printf("pwm off - turn on buzzer\n");

        return 0;

    }

    if (strcmp(argv[1], "on") == 0)

        pwm_start();

    if (strcmp(argv[1], "off") == 0)

        pwm_stop();

    return 0;

}

void run_command(int argc, char * argv[])

{

    if (strcmp(argv[0], "help") == 0)

    {

        help(argc, argv);

return;

[1] [2] [3]

关键字:Tiny210裸机  PWM控制  蜂鸣器

编辑:什么鱼 引用地址:http://www.eeworld.com.cn/mcu/2018/ic-news101241712.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:自己写bootloader倒计时启动内核
下一篇:Tiny210裸机IIC之at24cxx操作

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

Tiny210裸机之UART串口操作

S5PV210的时钟的时候,一定要参考该图。上面给出的clock_init()函数,设置的寄存器参数,都是用的推荐值,在手册中都能够查到。我以HCLKD为什么等于166.75MHz为例,来讲述如何借助芯片手册的361页和362页的图来配置时钟:      1.HCLKD是用于显示域(如LCD等)的时钟,因此在361页的途中找到HCLK_DSYS,顺着箭头方向往回找,发现它是由DIVhclkd分频而来,即HCLK_DSYS = MOUT_DSYS / (HCLK_DSYS_RATIO + 1),类似的分频系数对应于CLK_DIVn寄存器;    
发表于 2018-10-13

Tiny210裸机之实现printf功能

注意:本节串口的printf等函数的实现方法可以参考OK6410的裸机“11th_uart_stdio”实验源码,该方法更实用。start.S源码:.global _start    _start:    ldr sp, =0xD0030000    @初始化堆栈        b main
发表于 2018-10-13

Tiny210裸机简单命令的实现

;   (*(volatile unsigned int *)0xe0100100) #define CLK_SRC0      (*(volatile unsigned int *)0xe0100200) #define CLK_DIV0      (*(volatile unsigned int *)0xe0100300) #define MPLL_CON      (*(volatile unsigned int
发表于 2018-10-13

Tiny210裸机之nand_flash操作

了,大家看我共享的代码,就明白,放在了"Tiny210学习日记_代码"目录下了,名为"6_nand"。测试:1).使用md命令:WY_BOOT # WY_BOOT # WY_BOOT # md 0xd0030000do_command  D0030000: 00EACEED CE4F284F 781CF81F 395E9CDE D0030010: 6B7DCBCF D4F870DB 9F07E61F 53BB9C51 2).使用nand read命令:WY_BOOT # WY_BOOT # nand read 0xd0030000 0x0
发表于 2018-10-13

Tiny210裸机之DDR_SDRAM重定位

u-boot里面的,只是自己从头对照寄存器去理解了一下,完全符合598页的初始化步骤),放在了"Tiny210学习日记_代码"目录下了,名为"7_ddr"注意:之前的代码,包括该部分代码,都没有重定位的操作,IROM最多可以拷贝16K的代码到IRAM中,够用了!但是,由于后面我会讲到LCD显示图片,声卡播放WAV文件,bootloader也随之慢慢变大,16K的大小可能不够,再加上现在已经把重定位的条件都准备好了,所以接下来将是重定位。(相关知识,大家可以学习韦东三一期视频的重定位部分),这里,我就不在细说,直接给出代码,和讲几个关键地方。以下为start.s的代码:.global
发表于 2018-10-13

Tiny210裸机之bootm命令启动内核

;  MACH_SMDKV210        SMDKV210        2456从而说明此时的机器ID是2456。注意:这个过程说得有点绕和啰嗦,再次抱歉。参数三:一句话,实在是没有什么可以说的,韦老大的视频里面讲得太详细了!!大家直接看视频和我上传的关于这章的代码吧,放在了"Tiny210学习日记_代码"目录下了,名为"9_bootm"。注意:本章写的代码,只能通过bootm命令来启动内核,延时自动启动内核,我会在后面章节讲到。
发表于 2018-10-13

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2018 EEWORLD.com.cn, Inc. All rights reserved
pt type="text/javascript" src="//v3.jiathis.com/code/jia.js?uid=2113614" charset="utf-8">