cc2530的pwm实现

  本文记录如何利用cc2530的timer1产生pwm输出。在此之前,先看看timer1的一些特性。

  先看timer1的操作模式,分别是Free-Running, Modulo, Up-and-Down。

  具体的讲,Free-Running就是在每个时钟沿到来是计数器加1,从0x0000一直加到0xFFFF(如果设置了溢出中断,则发生中断,默认开启中断,在TIMIF.T1OVFIM可以失能中断),计数范围固定不变,可以通过预分频来控制计数频率。

Modulo则是通过设置T1CC0H,T1CC0L两个寄存器来改变timer1的计数上限。但是,如果timer1启动时,计数值大于T1CC0H,T1CC0L,则timer1会继续向上计数到0xFFFF,然后产生溢出中断。如果timer1启动时,计数值小于T1CC0H,T1CC0L,则当计数值等于T1CC0H,T1CC0L,计数值重置。

另外有一点需要注意,在配置T1CC0H,T1CC0L确保定时器暂停,先写低位在写高位

Up-and-Down,并不是pwm模式,我看网蜂pdf的定时器章节里,在T1CTL的描述中,把Up-and-Down写成了pwm。实际上,这并不是PWM模式。可以理解是,Modulo模式中加多一个到达计数最大值时,往回计数到0x0000时产生溢出中断。适用于中心对称PWM。

其实,datasheet里面的图已经很清晰了。

  接下来是比较输出,设置T1CC0H,T1CC0L,当计数值与T1CC0H,T1CC0L相等时,相关通道产生输出。timer1总共有5个通道(0~4)。比较输出总共有9钟模式,但是要注意4~5,6~7这两对是对应着不同操作模式,通过T1CCTLn.CMP来设置。datasheet是这样描述的,还是挺好理解的。

使用PWM的话,一般应该是选择后6种吧。前2种,如果不软件改变输出状态,那么状态就只改变一次,第3种则没有PWM效果,但是可以实现时间大于0xFFFF的输出翻转。还有就是不是每一个通道都有上述9种模式。比如通道0就没有最后两个模式。

最后就是设置IO了,将对应的IO口设置为外设IO就可以了。先来看看外设IO分布情况

可以看出来,timer1的对应的IO口和串口0,1重合,这里为了方便,可以通过PERCFG.U1CFG和PERCFG.U0CFG把IO设置到Alternative 2 location,也就是P1口。否则timer将不会有比较输出。

  弄清楚这些之后就是配置寄存器的问题了。给出我自己的代码(代码仅供参考,具体请根据datasheet配置相关寄存器)。先看定时器部分。

 1 #include "Timer.h"
 2 #include "led.h"
 3
 4 void Timer1_Init(unsigned char mode, unsigned char div)
 5 {
 6     unsigned char temp;
 7
 8     T1CCTL0 = 0x24;
 9     T1CC0L = 0x00;    //设置低位,在运行中修改,仅当计数值为0时生效
10     T1CC0H = 0xF0;    //写入高位时,低位会从buffer中写入
11
12     //配置工作模式和分频系数
13     temp = div << 2;
14     temp |= mode;
15     T1CTL = temp;
16
17     //使能Timer1中断
18     T1IE = 1;
19
20 }
21
22 #pragma vector = T1_VECTOR
23     __interrupt void T1_ISR(void)
24     {
25
26         D0 = ~D0;
27         T1STAT &= ~(1 << 5);
28         T1IF = 0;    //清除T1中断标志
29     }

Tiemr.c

 1 #ifndef __TIMER_H
 2     #define __TIMER_H
 3
 4     #include <ioCC2530.h>
 5
 6     //T1CTL
 7     //预分频设置                                    Free_Running_time
 8     #define DIV_1                        0            //0.004096
 9     #define DIV_8                        1            //0.032768
10     #define DIV_32                    2            //0.131072
11     #define DIV_128                    3     //0.524288s
12     //定时器工作模式
13     #define Suspended                0
14     #define Free_Running        1
15     #define Modulo                    2
16     #define Up_And_Down            3
17
18     //Timer speed
19     #define T_32M                            0
20     #define T_16M                         1
21     #define T_8M                            2
22     #define T_4M                            3
23     #define T_2M                            4
24     #define T_1M                            5
25     #define T_500K                        6
26     #define T_250K                        7
27
28
29     //T1STAT
30
31     //function
32     void Timer1_Init(unsigned char mode, unsigned char div);
33
34 #endif

Timer.h

再看LED部分

 1 #include "led.h"
 2
 3 /* P1.1 | P1.3 | P1.5 | P1.7 | P2.1 | P2.3 | GND
 4  *  D2  |  S2  |      |      |      |      |
 5  * P1.0 | P1.2 | P1.4 | P1.6 | P2.0 | P2.2 | P2.4
 6  *  D1  |  S3  |  D3  |      |  S0  |      |
 7  *-----------------------------------------------
 8  * P0.6 | P0.4 | P0.2 | P0.0  | RESET | GND
 9  *      |      | L_R  |       |  S4   |
10  * P0.7 | P0.5 | P0.3 | P0.1  | VDD   | VDD
11  *      |      | L_T  | D4 S1 |       |
12  *-----------------------------------------------
13 */
14
15 // D1~D3
16
17 void LED_Init(void)
18 {
19   P1SEL &= ~0x13; //设置为GPIO
20   P1DIR |= 0x13;  //设置为输出
21   P1INP &= ~0x13; //
22
23     P0SEL |= 0x04;    //设置为外设IO
24     P0DIR |= 0x04;
25     P0INP &= ~0x04;
26
27     PERCFG |= 0x03; //设置串口映射到P1
28
29   D0 = LED_OFF;
30   D1 = LED_OFF;
31   D2 = LED_OFF;
32 }

led.c

 1 #ifndef __LED_H
 2     #define __LED_H
 3
 4     #include <ioCC2530.h>
 5
 6     #define LED_ON  0
 7     #define LED_OFF 1
 8
 9     #define D0    P1_0
10     #define D1    P1_1
11     #define D2    P1_4
12
13     #define D0_NUM 1
14     #define D1_NUM 2
15     #define D2_NUM 3
16
17     void LED_Init(void);
18
19 #endif

led.h

建议仿真文件选择ioCC2530F256.ddf,可以看更多的寄存器情况,方便调试

最后附上TI E2E社区一个帖子 点我

cc2530的pwm实现

时间: 2024-10-07 08:39:13

cc2530的pwm实现的相关文章

cc2530 timer 3 PWM &lt;可调占空比&gt;

前提: 开始用的是 cc2530 timer 1来做PWM的,已经可调占空比了,但是由于硬件的改动,需要用timer 3 和 timer 4 代替.由于调试过程中出了些小问题,于是自己把这个贴出来.关键点注释出来. 说说  硬件吧: timer 1    P1_0 口 timer 3   P1_6   P1_7口. 注意: P1_6 对应着timer 3的通道 0 ,也就是对应着 t3cc0 这类寄存器,而非t3cc1; P1_7对应着timer 3的通道1,也就是对应着t3cc1 这类寄存器.

CC2530定时器使用

?? 定时器学习   文件夹 说明...1 协议栈函数使用...2 设置初始化定时器...2 回调函数(中断服务函数)3 启动定时器...3 停止定时器...4 寄存器操作...4 查询方式...4 中断方式(使用定时器3)7 说明 依据数据手冊可知CC2530总共同拥有4个定时器,可是定时器2被系统占用,可用的仅仅有三个,分别为定时器1/3/4 Timer在协议栈的代码位置为hal_timer.c,hal_timer.h,4个定时器的ID分别为 /* Timer ID definitions

[ZigBee] 13、ZigBee基础阶段性回顾与加深理解——用定时器1产生PWM来控制LED亮度(七色灯)

引言:PWM对于很多软件工程师可能又熟悉又陌生,以PWM调节LED亮度为例,其本质是在每个周期都偷工减料一些,整体表现出LED欠压亮度不同的效果.像大家看到的七色彩灯其原理也类似,只是用3路PWM分别控制红.绿.蓝三种颜色的灯输出亮度,再结合混色原理表现出丰富多彩的炫光效果~ 写在前面:前十几篇介绍了CC2530的一些外设的基本用法,接下来几篇拿几个例子回顾并加深一下之前的知识点,上面引言是普及.下面高能预警! 第一个例子:用定时器1产生PWM来控制LED亮度 我们在<[ZigBee] 5.Zi

TI CC2530基础实验(定时器1查询方式——自由运行模式)

本实验实现通过CC2530的定时器1(16位)查询方式控制LED1以1S的周期性闪烁,此实验使用的三个寄存器T1CTL(定时器1控制寄存器),T1STAT(定时器1状态寄存器),IRCON. 有关CC2530的GPIO基本知识.普通GPIO操作有关寄存器的介绍.IAR Embedded Workbench IDE软件使用:TI CC2530基础实验(普通GPIO操作--点亮led灯) 电路原理图: 寄存器分析: 1.定时器1控制寄存器 定时器1的T1CTL寄存器下的模式分析: [自由运行模式]:

CC2530定时器

一.定时/技术器的基本原理 定时/计数器,是一种能够对内部时钟信号或外部输入信号进行计数,当计数值达到设定要求时,向CPU提出中断处理请求,从而实现定时或者计数功能的外设.         定时/计数器的最基本工作原理是进行计数.不管是定时器还是计数器,本质上都是计数器,可以进行加1(减1)计数,每出现一个计数信号,计数器就会自动加1(自动减1),当计数值从0变成最大值(或从最大值变成0)溢出时,定时/计数器就会向CPU提出中断请求. 二.CC2530的定时/计数器 根据数据手册可知 CC253

基于tiny4412的Linux内核移植 -- PWM子系统学习(八)

作者信息 作者: 彭东林 邮箱:[email protected] QQ:405728433 平台简介 开发板:tiny4412ADK + S700 + 4GB Flash 要移植的内核版本:Linux-4.4.0 (支持device tree) u-boot版本:友善之臂自带的 U-Boot 2010.12 (为支持uImage启动,做了少许改动) busybox版本:busybox 1.25 交叉编译工具链: arm-none-linux-gnueabi-gcc (gcc version 4

CC1310生成PWM波

工作中因为时间紧迫,我不得不抛开TI提供的TI-RTOS.sdk和xdctools等工具,采用ucos + 库函数的方式去开发.最开始一头扎进去,碰见的就PWM的生成. PWM方面,TI自带封装好了PWM函数进行pwm的生成. 假如:我的需求是PWM的周期是2s,占空比50%,MCU主频是48MHz.于是我直接设置 params.periodUnits = PWM_PERIOD_US; params.periodValue = pwmPeriod; params.dutyUnits = PWM_

HAL之PWM

PWM是定时器的一个输出功能,要分配在有对应输出的管脚上.分频和定时值决定了周期,捕获寄存器的值就是占空比,当计数寄存器的值小于捕获值时输出固定电平(H),当大于时翻转电平,当计数器值溢出时将重载值载入,此时继续翻转电平. 一 在stm32cubeMX中线在有对应PWM输出的引脚设置PWM功能 二 在外设功能TIMx的对应通道上设置PWM模式 三在定时器配置时设置分频值,定时值,如果设置paulse则为固定pwm输出:或者这里不设置写一个设置函数,然后在while中不断修改paulse,则Pau

STM32定时器输出PWM频率和步进电机控制速度计算

1.STM32F4系列定时器输出PWM频率计算 第一步,了解定时器的时钟多少: 我们知道AHP总线是168Mhz的频率,而APB1和APB2都是挂在AHP总线上的. (1)高级定时器timer1, timer8以及通用定时器timer9, timer10, timer11的时钟来源是APB2总线(2)通用定时器timer2~timer5,通用定时器timer12~timer14以及基本定时器timer6,timer7的时钟来源是APB1总线 从STM32F4的内部时钟树可知: 当APB1和APB