历史上的今天
今天是:2024年12月18日(星期三)
2020年12月18日 | TQ210裸机编程(8)——PWM
2020-12-18 来源:eefocus
事实上,要使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
史海拾趣
|
摘要:本文论述了采用单片机技术研制成功的泊车用超声波测距仪的基本原理,测量计算方法,实现方案。采用软件校正,提高了测量精度和整机的可靠性。实际使用表明,极大的提高了泊车时的安全性。 关键词:超声波 测距 单片机 Development of Ultra ...… 查看全部问答> |
|
在连接目标代码时,会提到运行地址和加载地址. 问:有什么区别吗? 如果程序是在flash里跑,是不是运行地址和加载地址是相同的? 如果程序是在ram里跑,但程序是存储在flash里的,是不是运行地址指向ram,而加载地址是指向flash? 没搞清楚! coldfire系 ...… 查看全部问答> |
|
再EVC下用CreateFile()打开IIC设备成功返回句柄,用返回的句柄调用WriteFile(),WriteFile的返回值wRetSize为0;GetLastError返回的也为0 代码如下: hT2C = CreateFile(TEXT(\"I2C1:\"), &nbs ...… 查看全部问答> |
|
我往STC89LE516AD单片机烧程式时,得烧上20次才进去一两次 每次烧程式,不停的给单片机上电复位,可就是不进去,一二十次才进去一两次,不知道是什么原因,按理说,有时能烧录,所以电路因该没有问题,但大多时候还是显示连接失败,有那位高人知道这是什么原因!… 查看全部问答> |
|
本人因为学习需要 购2410二手开发板一块 联系qq:42281797 tel:13554742552 本人因为学习需要 购2410二手开发板一块 联系qq:42281797 tel:13554742552 欢迎联系 谢谢… 查看全部问答> |
|
本帖最后由 dontium 于 2015-1-23 13:39 编辑 各位老师好,我想用2812做一个fft的程序,但不知如何下手,我想向各位请教一下,应该如何利用TI公司自带的fft库函数来实现,我现在把需要计算的小数值存放在外部ram中,不知道应该怎么处理,而且我知 ...… 查看全部问答> |




