OpenEdv-开源电子网

 找回密码
 立即注册

扫一扫,访问微社区

正点原子新作:阿波罗STM32F767&F429&探索者STM32F4开发板&赶快来下载资料哦。

查看: 328|回复: 2
打印 上一主题 下一主题

【分享】ARM之S5P6818PWM实验

[复制链接]

  离线 

37

主题

232

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
485
金钱
485
注册时间
2017-10-31
在线时间
61 小时
跳转到指定楼层
楼主
发表于 2017-12-5 09:36:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
正点原子公众号
S5P6818PWM实验
一、PWM概念
PWMPulse Width Modulation):脉冲宽度调制。
占空比:就是输出的PWM中,高电平保持的时间与该PWM的时钟周期的时间之比。
二、PWM应用
它是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用于测量,通信,功率控制与变换等许多领域。脉冲宽度调制(PWM)是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。
常见应用有:电机控制,DAC输出等
三、S5P6818PWM概述
S5P6818532PWM定时器。这些定时器为ARM子系统提供外部中断。另外,Timers 0,1,2,3,包括PWM功能并且驱动外部I/O引脚。PWM定时器0有一个可选的死区产生器,支持驱动大电流设备的能力。Timer4是外部定时器没有输出引脚。
定时器使用APB-PCLK作为时钟源。Timers 01共享一个8位可编程的预分频器,位PCLK提供第一级分频。Timers 2,34共享另外一个8位预分频器。每个定时器有自己私有的的时钟分配器,提供一个二级时钟分频(分频值为1,2,4,8,16)。
每个定时器都有一个32位递减计数器,通过定时器时钟驱动。递减计数器初始值加载从TCNTB0。当递减计数器到达0时,定时器中断请求产生并通知CPU,定时器操作完成。当定时器递减计数器到达0时,相对应的TCNTBn中的值自动加载到递减计数器中开始下一个周期。然而,如果定时器停止,例如,通过清除定时器TCONn的使能位,在定时器处于运行模式时,TCNTBn中的值不在加载到定时器中。
PWM功能使用TCMPB0寄存器的值。定时器控制逻辑改变输出电平如果递减计数器的值和比较寄存器的值相匹配在定时器控制逻辑。因此,比较寄存器决定PWM输出的高低电平时间。
四、S5P6818框图
        file:///C:\Users\Administrator\AppData\Local\Temp\ksohtml\wpsD54D.tmp.jpg
五、S5P6818 PWM控制蜂鸣器硬件电路图
file:///C:\Users\Administrator\AppData\Local\Temp\ksohtml\wpsD57D.tmp.jpg
六、相关寄存器分析
TCFG0
l Base Address: 0xC001_8000h (PWM)
l Address = Base Address + 0x00h, Reset Value = 0x0000_0101
Name
Bit
Type
Description
Reset Value
RSVD
[31:24]
Reserved
DEAD ZONE LENGTH
[23:16]
RW
Dead zone length
8'h0
PRESCALER 1
[15:8]
RW
Prescaler 1 value for Timer 2, 3 and 4
8'h1
PRESCALER 0
[7:0]
RW
Prescaler 0 value for timer 0 & 1
8'h1

定时器输入时钟频率 = PCLK/({prescaler value + 1})/{divider value}
{prescaler value} = 1 to 255
{divider value} = 1, 2, 4, 8, 16
Dead Zone Length = 0 to 254
NOTE: If Dead Zone Length is set as "n", Real Dead Zone Length is "n + 1" (n = 0 to 254). Source clock of PCLK is BUS_DPLL in BLK_MIF
TCFG1
l Base Address: 0xC001_8000h (PWM)
l Address = Base Address + 0x04h, Reset Value = 0x0000_0000
Name
Bit
Type
Description
Reset Value
DIVIDER MUX2
[11:8]
RW
Select Mux input for PWM Timer 2
0000 = 1/1
0001 = 1/2
0010 = 1/4
0011 = 1/8
0100 = 1/16
0101 = External TCLK1
0110 = External TCLK1
0111 = External TCLK1
4'h0
TCON
l Base Address: 0xC001_8000h (PWM)
l Address = Base Address + 0x08h, Reset Value = 0x0000_0000
Name
Bit
Type
Description
Reset Value
TIMER 2 AUTO RELOAD
ON/OFF
[15]
RW
0 = One
1 = Interval Mode -Shot (Auto-Reload)
1'b0
TIMER 2 OUTPUT
INVERTER ON/OFF
[14]
RW
0 = Inverter Off
1 = TOUT2 Inverter-On
1'b0
TIMER 2 MANUAL
UPDATE
[13]
RW
0 = No Operation
1 = Update TCNTB2,TCMPB2
1'b0
TIMER 2 START/STOP
[12]
RW
0 = Stop
1 = Start Timer 2
1'b0
TCNTB2
l Base Address: 0xC001_8000h (PWM)
l Address = Base Address + 0x24h, Reset Value = 0x0000_0000
Name
Bit
Type
Description
Reset Value
TIMER 2 COUNT BUFFER
[31:0]
RW
Timer 2 Count Buffer Register
32'h0
TCMPB2
l Base Address: 0xC001_8000h (PWM)
l Address = Base Address + 0x28h, Reset Value = 0x0000_0000
Name
Bit
Type
Description
Reset Value
TIMER 2 COMPARE BUFFER
[31:0]
RW
Timer 2 Compare Buffer Register
32'h0
TCNTO2
l Base Address: 0xC001_8000h (PWM)
l Address = Base Address + 0x2Ch, Reset Value = 0x0000_0000
Name
Bit
Type
Description
Reset Value
TIMER 2 COUNT OBSERVATION
[31:0]
R
Timer 2 Count Observation Register
32'h0


回复

使用道具 举报

  离线 

37

主题

232

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
485
金钱
485
注册时间
2017-10-31
在线时间
61 小时
2#
 楼主| 发表于 2017-12-5 09:37:16 | 只看该作者
七、实验代码
寄存器定义:
/*  
*S5P6818 SFR address define
*farsight
*2017.10.1
*version: 1.0
*/

#ifndef ___S5P6818_PWM_H_
#define ___S5P6818_PWM_H_

#define          __REG(x)        (*(volatile unsigned int *)(x))  
#define    uint32                       unsigned int

/************* PWM ******************/
typedef struct {
uint32 TCFG0;
uint32 TCFG1;
uint32 TCON;
uint32 TCNTB0;
uint32 TCMPB0;
uint32 TCNTO0;
uint32 TCNTB1;
uint32 TCMPB1;
uint32 TCNTO1;
uint32 TCNTB2;
uint32 TCMPB2;
uint32 TCNTO2;
uint32 TCNTB3;
uint32 TCMPB3;
uint32 TCNTO3;
uint32 TCNTB4;
uint32 TCNTO4;
uint32 TINT_CSTAT;
}pwm;

#define PWM       (* (volatile pwm *)0xC0018000)
#endif

实验代码:
#include "s5p6818_PWM.h"

void Delay_Ms(unsigned int ms)
{
unsigned int i,j;
for (i = 0; i < ms; i++)
for (j = 0; j < 2500; j++);
}

void PWM_Init(void)
{
//有源蜂鸣器,直接让蜂鸣器发出声音
#if 0
// 1. 设置GPIOC14引脚为GPIO功能
GPIOC.ALTFN0 = GPIOC.ALTFN0 & (~(0x3 << 28)) | (0x1 << 28);
// 2. 设置GPIOC14引脚为输出功能
GPIOC.OUTENB = GPIOC.OUTENB | (0x1 << 14);
// 3. 设置GPIOC14引脚输出高电平
GPIOC.OUT = GPIOC.OUT | (0x1 << 14);

#else// 有原蜂鸣器,让蜂鸣器的声音发生变化,通过PWM调节蜂鸣器的声音
// 1. 设置GPIOC14引脚为PWM功能
GPIOC.ALTFN0 = GPIOC.ALTFN0 & (~(0x3 << 28)) | (0x2 << 28);
// 2. 设置一级预分频值,设置PWM2通道,设置TCFG0[15:8]位,设置为249       f = 150M / (249+1) = 600000Hz
PWM.TCFG0 = PWM.TCFG0 & (~(0xFF << 8)) | (249 << 8);
// 3. 设置二级与分频值,设置TCFG1[11:8]位,设置为0100,进行16分频                       f = 600000Hz / 16 = 37500Hz
PWM.TCFG1 = PWM.TCFG1 & (~(0xF << 8)) | (0x4 << 8);
// 4. 设置PWM的最终周期,设置TCNTB2, 设置为100     f = 37500Hz / 100 = 375;
PWM.TCNTB2 = 100;
// 5. 设置PWM的占空比,设置为50%, 设置为50
PWM.TCMPB2 = 50;
// 6. 打开手动加载
PWM.TCON = PWM.TCON | (0x1 << 13);
// 7. 关闭手动加载
PWM.TCON = PWM.TCON & (~(0x1 << 13));
// 8. 打开自动加载
PWM.TCON = PWM.TCON | (0x1 << 15);
// 9. 使能PWM定时器
PWM.TCON = PWM.TCON | (0x1 << 12);
#endif

}

int main()
{
printf("*******PWM test*********!\n");
PWM_Init();

while(1)
{

}
return 0;
}
回复 支持 反对

使用道具 举报

  离线 

0

主题

1

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2018-5-11
在线时间
0 小时
3#
发表于 2018-5-11 20:38:17 | 只看该作者
楼主,我想使用PWM来调节LED灯的亮度,请问应该怎么配置呢?谢谢!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则




QQ|联系我们|手机版|官方淘宝店|新浪微博|微信公众平台|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2018-6-20 11:30

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表
/* */