TQ210裸机编程(8)——PWM

发布者:数据之翼最新更新时间:2020-12-18 来源: eefocus关键字:TQ210  裸机编程  PWM 手机看文章 扫描二维码
随时随地手机看文章

事实上,要使TQ210板子上的蜂鸣器发声是非常容易的,因为天嵌给TQ210的蜂鸣器为有源蜂鸣器,只要给蜂鸣器供电,蜂鸣器就会发出固定频率的声音。


TQ210板子上的蜂鸣器接在TOUT1引脚,只要给它高电平,蜂鸣器就会发声。


如下代码:


/* 配置GPD0[1]为输出 */

GPD0CON &= ~(0xF << 4);

GPD0CON |= 1 << 4;

/* GPD0[1]输出高电平即可使蜂鸣器发声 */

GPD0DAT |= 1 << 1;


S5PV210包含5个32位的脉宽调制定时器。这些定时器都可产生中断。每个定时器可选择输入时钟为PCLK或SCLK_PWM。


定时器的操作比较简单,下面列出操作步骤:


1、设置TCFG0寄存器:配置定时器的一级分频值


1、设置TCFG1寄存器:配置定时器的二级分频值


3、设置TCNTBn寄存器:递减计数器缓冲寄存器


3、设置TCMPBn寄存器:比较缓冲寄存器


4、设置TCON寄存器:


(1)手动更新on(执行后,CPU会把TCNTBn的值加载到递减计数器中)


(2)手动更新off、自动重载、启动定时器


当递减计数器的值减到和TCMPBn的值相等时,则翻转输出引脚极性;


当递减计数器的值减到0时,如果使能了定时器中断则产生中断,如果使能了自动重载则重载TCNTBn的值到递减计数器,开始重新计数


频率计算:


我之前的时钟配置为PCLK_PSYS=66MHz,这里就由它为定时器提供时钟源。


Timer Input Clock Frequency = PCLK / ( {prescaler value + 1} ) / {divider value}


我的配置为:prescaler value = 65


                      divider value = 8


Timer Input Clock Frequency = 66MHz / (65 + 1) / 8 = 125000

假设输出频率为n,则

TCNTB1 = 1125000 / n


比如输出1Hz,占空比为50%



TCNTB1 = 125000 / 1;

TCMPB1 = TCNTB1 / 2;


具体代码如下:


start.S


.global _start /* 声明一个全局的标号 */

_start:

 

bl clock_init

 

bl main /* 跳转到C函数去执行 */

 

halt:

b halt

 

clock.c


#define APLLCON0 *((volatile unsigned int *)0xE0100100)

#define MPLLCON *((volatile unsigned int *)0xE0100108)

#define EPLLCON0 *((volatile unsigned int *)0xE0100110)

#define VPLLCON *((volatile unsigned int *)0xE0100120)

#define CLK_SRC0 *((volatile unsigned int *)0xE0100200)

#define CLK_DIV0 *((volatile unsigned int *)0xE0100300)

#define CLK_DIV1 *((volatile unsigned int *)0xE0100304)

#define CLK_DIV2 *((volatile unsigned int *)0xE0100308)

#define CLK_DIV3 *((volatile unsigned int *)0xE010030C)

 

void clock_init()

{

/* 1、设置PLL_LOCK寄存器(这里使用默认值) */

/* 2、设置PLL_CON寄存器(使用芯片手册推荐的值) */

APLLCON0 = (1 << 0) | (3 << 8) | (125 << 16) | (1 << 31); /* FOUTAPLL = 1000MHz */

MPLLCON = (1 << 0) | (12 << 8) | (667 << 16) | (1 << 31); /* FOUTMPLL = 667MHz */

EPLLCON0 = (1 << 0) | (12 << 8) | (667 << 16) | (1 << 31); /* FOUTEPLL = 96MHz */

VPLLCON = (3 << 0) | (6 << 8) | (108 << 16) | (1 << 31); /* FOUTVPLL = 54MHz */

/* 3、选择PLL为时钟输出 */

/* MOUT_MSYS = SCLKAPLL = 1000MHz

** MOUT_DSYS = SCLKMPLL = 667MHz

** MOUT_PSYS = SCLKMPLL = 667MHz

*/

CLK_SRC0 = (1 << 0) | (1 << 4) | (1 << 8) | (1 << 12);

/* 4、设置系统时钟分频值 */

/* freq(ARMCLK) = MOUT_MSYS / (APLL_RATIO + 1) = 1000MHz / (0 + 1) = 1000MHz

** freq(HCLK_MSYS) = ARMCLK / (HCLK_MSYS_RATIO + 1) = 1000MHz / (4 + 1) = 200MHz

** freq(PCLK_MSYS) = HCLK_MSYS / (PCLK_MSYS_RATIO + 1) = 200MHz / (1 + 1) = 100MHz

** freq(HCLK_DSYS) = MOUT_DSYS / (HCLK_DSYS_RATIO + 1) = 667 / (3 + 1) = 166MHz

** freq(PCLK_DSYS) = HCLK_DSYS / (PCLK_DSYS_RATIO + 1) = 166 / (1 + 1) = 83MHz

** freq(HCLK_PSYS) = MOUT_PSYS / (HCLK_PSYS_RATIO + 1) = 667 / (4 + 1) = 133MHz

** freq(PCLK_PSYS) = HCLK_PSYS / (PCLK_PSYS_RATIO + 1) = 133 / (1 + 1) = 66MHz

*/

CLK_DIV0 = (0 << 0) | (4 << 8) | (1 << 12) | (3 << 16) | (1 << 20) | (4 << 24) | (1 << 28);

}


main.c


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

#define GPD0DAT *((volatile unsigned int *)0xE02000A4)

 

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

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

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

#define TCNTB1 *((volatile unsigned int *)0xE2500018)

#define TCMPB1 *((volatile unsigned int *)0xE250001C)

#define TCNTO1 *((volatile unsigned int *)0xE2500020)

 

int main()

{

#if 0

/* 配置GPD0[1]为输出 */

GPD0CON &= ~(0xF << 4);

GPD0CON |= 1 << 4;

/* GPD0[1]输出高电平即可使蜂鸣器发声 */

GPD0DAT |= 1 << 1;

#endif

/* 配置GPD0[1]为定时器1输出:TOUT1 */

GPD0CON &= ~(0xF << 4);

GPD0CON |= 2 << 4;

 

/*

** 配置定时器输入频率

** Timer Input Clock Frequency = PCLK / ( {prescaler value + 1} ) / {divider value} 

** = 66MHz / (65 + 1) / 8 = 125000

** 假设输出频率为n,则

** TCNTB1 = 1125000 / n

*/

TCFG0 = 65;

TCFG1 = 3 << 4;

 

/* 产生1Hz,占空比为50%的输出频率 */

TCNTB1 = 125000 / 1;

TCMPB1 = TCNTB1 / 2;

 

TCON = (1 << 9); /* 手动更新on */

TCON = (1 << 8) | (1 << 11); /* 启动定时器/手动更新off/自动重载 */

 

while (1);

return 0;

}


Makefile


beeper.bin: start.o clock.o main.o

arm-linux-ld -Ttext 0xD0020010 -o key.elf $^

arm-linux-objcopy -O binary key.elf $@

arm-linux-objdump -D key.elf > key.dis

%.o : %.c

arm-linux-gcc -c $< -o $@

%.o : %.S

arm-linux-gcc -c $< -o $@

clean:

rm *.o *.elf *.bin *.dis

关键字:TQ210  裸机编程  PWM 引用地址:TQ210裸机编程(8)——PWM

上一篇:TQ210裸机编程——按键点灯 (二)
下一篇:TQ210 TFTP 更新固件方法

推荐阅读最新更新时间:2024-11-12 08:05

msp430F149调PWM
还说好好安下心调我的PID 结果又被某人喊调一个占空比为10%的PWM波 这不,直接上代码吧: But first,还是要先解释一下端口:按键改变PWM的占空比 按键IO口如下: 然后就是用P2.3和P2,4口输出两路PWM信号 #include msp430x14x.h #define uchar unsigned char #define uint unsigned int #define keyin (P1IN & 0x0f) uchar T ={10,20,40,100,150,200}; //高电平持续 void delay(void) { uint tmp; for(tmp =
[单片机]
msp430F149调<font color='red'>PWM</font>
PWM视频代码剖析与解释
1、不同频率LED灯闪烁 接下来我们以下面LED灯的闪烁代码为例子,改变延时长短来看LED灯的效果 void setup() { pinMode(2, OUTPUT); } void loop() { digitalWrite(2, HIGH); delay(50); // Wait for xx millisecond(s) digitalWrite(2, LOW); delay(50); // Wait for xx millisecond(s) } 500ms延时闪烁(1Hz频率) 200ms延时闪烁(2.5Hz频率) 50延时ms闪烁(10Hz频率) 通过三个对比实验我们发现随着频率的升高,我们
[单片机]
<font color='red'>PWM</font>视频代码剖析与解释
STM32中的PWM的频率和占空比的设置
网上看到一篇文章,不是很完整,但是有助于我理解,个人觉得还可以,具体的代码,网上有很多,大家可以参考参考计算一下。 下面的这个是stm32的定时器逻辑图,上来有助于理解: TIM3的ARR寄存器和PSC寄存器, 确定PWM频率。 这里配置的这两个定时器确定了PWM的频率,我的理解是:PWM的周期(频率)就是ARR寄存器值与PSC寄存器值相乘得来,但不是简单意义上的相乘,例如要设置PWM的频率参考上次通用定时器中设置溢出时间的算法,例如输出100HZ频率的PWM,首先,确定TIMx的时钟,除非APB1的时钟分频数设置为1,否则通用定时器TIMx的时钟是APB1时钟的2倍,这时的TIMx时钟为72MHz,用这个TIMx时钟72
[单片机]
STM32中的<font color='red'>PWM</font>的频率和占空比的设置
Allegro MicroSystems, LLC推出全新四路DMOS全桥式PWM电机驱动器IC
美国马萨诸塞州伍斯特市 Allegro MicroSystems, LLC发布全新四路DMOS全桥式驱动器IC A5988,它能够驱动多达两个步进电机或四个直流电机,每一全桥式输出额定值可达1.6A和40V。A5988集成有固定停机时间脉宽调制(PWM)电流稳压器,以及2位非线性DAC(数模转换器),可允许步进电机以整步、半步、以及四分之一步进模式控制,直流电机则能够以正转、反转及自由停机模式(coast modes)控制。PWM电流稳压器采用了Allegro 已获专利的混合衰减模式,以减轻可闻电机噪声、提高步进精度、并降低功耗。新器件面向消费产品和办公室自动化市场,终端应用包括闭路电视(摇摄和斜摄)应用、扫描仪、POS机,以及激
[电源管理]
Allegro MicroSystems, LLC推出全新四路DMOS全桥式<font color='red'>PWM</font>电机驱动器IC
PWM输出实验步骤,PWM输出代码
  脉冲宽度调制(PWM),是英文“ Pulse Width Modulation” 的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制。STM32 的定时器除了 TIM6 和 7。其他的定时器都可以用来产生 PWM 输出。其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出。而通用定时器也能同时产生多达 4路的 PWM 输出。         CCR1:捕获比较(值)寄存器(x=1,2,3,4):设置比较值。   CCMR1: OC1M[2:0]位:对于PWM方式下,用于设置PWM模式1【110】或者PWM模式2【111】、CCE
[单片机]
<font color='red'>PWM</font>输出实验步骤,<font color='red'>PWM</font>输出代码
利用PWM生成正弦波程序
/******************************************************************* 实验名称:产生正弦波演示实验 器件:ATmega16L 晶振:外部 12M 接线方法: 1.PD5接低通滤波输入 2.用示波器测其输出波形 *******************************************************************/ #include iom16v.h #include macros.h #include signal.h #pragma interrupt_handler timer1:9 char auc
[单片机]
STM32CubeMx普通PWM基本使用方法
本文实例说明: 这里是使用 TIM3_CH2输出 一个频率为50kHz; 占空比为50% 的PWM信号。 1先配置STM32CubeMX 参数,如图: 重点说明: PWM 频率 = APB1 Timer clocks (MHz) / APB1 Timer clocks (MHz) :64MHz Counter Period : 20 Prescaler :设置为64-1 那么此时PWM时钟设置为: f = 64000000 / 64 /20 = 50KHz Pulse :设置为10 ,也就是占比为:10/20 = 50% Fast Mode:如果频率太高可以使能快速模式。可以大大提高PWM反
[单片机]
STM32CubeMx普通<font color='red'>PWM</font>基本使用方法
STM32单片机如何通过定时器的控制输出PWM
STM32F103ZET6里共有8个定时器,其中高级定时器有TIM1-TIM5、TIM8,共6个。 我这里输出PWM的定时器是TIM2,空闲的定时器是TIM3。以TIM2为主定时器,TIM3为从定时器对TIM2的输出脉冲数进行计数。 查表可知,TIM3为从定时器选择TIM2为触发源,需要配置TS=001,即选择ITR1。 实现通过定时器控制输出PWM个数的功能,可以有如下一种配置方式: void TIM2_Mas te r__TIM3_Slave_Configuration(u32 PulseFrequency) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OC
[单片机]
STM32单片机如何通过定时器的控制输出<font color='red'>PWM</font>
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved