請問如何在CC2531 USB Dongle上實現PWM ?
你好,TI的研發人員
目前使用TI CC2531 USB Dongle,想在上面試試PWM。
程式是使用SampleRemote project 在 Texas Instruments\Z-Stack Lighting 1.0.1\Projects\zstack\ZLL\SampleRemote\CC2530DB
想了解設定CC2531 PWM的流程是怎樣呢??
請問有沒有CC2531與PWM的相關文件可以參考??
有參考了這篇文章 http://e2e.ti.com/support/low_power_rf/f/156/t/118346.aspx?pi267162=2
在datasheet中也看到可使用Timer1、3、4來做PWM輸出
請問如果使用T1,是在SampleRemote project 中的哪支程式去設定Timer1 PWM的參數??
直接参照
SampleLight project 在 C:\Texas Instruments\Z-Stack Lighting 1.0.1\Projects\zstack\ZLL\SampleLight\CC2530DB 选择RouterZlight工程,已经在CC2531上实现4通道的PWM的功能的,用Timer1 实现的
謝謝你的回答,但是我剛接觸這部分。
所以不好意思,可以再說的詳細一點嗎?
SampleLight.eww 執行後選擇 Zlight - Router
那請問在哪支程式檔的哪個部分是撰寫Timer1設定PWM的地方??
是否有詳細的關鍵字?
因為我在SampleLight 搜尋T1CTL,只有出現在ioCC2530.h檔案,所以不確定SampleLight中哪部分是撰寫PWM的地方
T1CTL是一个寄存器,详细可看CC2530 datasheet.
http://www.ti.com/lit/ug/swru191d/swru191d.pdf
其实datasheet对各种PWM都有做详细描述,可仔细阅读103页开始的内容。
应该是hal_timer.c 是底层PWM的实现,可借鉴。
TY ,謝謝你的回答! 這份datasheet關於Timer1以及PWM的部分我有看到
但剛開始接觸這些東西...看了datasheet還是不太懂...
所以想參考SampleLight的做法
但不知道使用Timer1作為用PWM輸出的部分是寫在SampleLight project中的哪個程式檔中?
能不能貼上一些相關的程式碼讓我能夠去查詢SampleLight project中使用Timer1來做PWM輸出的部分 ?
不然只是看datasheet,真的沒有頭緒跟方向下去做
在C:\Texas Instruments\Z-Stack Lighting 1.0.1\Components\hal\target\CC2530PMP4712 中的hal_timer.c文件中,
你可以看下初始化函数就知道了,协议栈用到的是#define ENABLE_LAMP P0SEL |= ( 0x08 | 0x10 | 0x20 | 0x40); /* P0.3:6 */
VV 你好 !! 真的很謝謝你的幫忙~
在CC2530PMP4712 的hal_timer.c以及hal_board_cfg.h都有看到Timer1的相關設定
而我要使用的是C:\Texas Instruments\Z-Stack Lighting 1.0.1\Projects\zstack\ZLL\SampleRemote
在CC2530EB中的hal_timer.c內容是空白的。
所以我可以參考CC2530PMP4712中的hal_timer.c以及hal_board_cfg.h關於Timer1的設定,用來設定CC2530EB中的hal_timer.c及hal_board_cfg.h的Timer1嗎??
例如:CC2530PMP4712-hal_timer.c
1.前面定義的一些typedef struct
2.FUNCTIONS - Local
3.HalTimer1Init
4.halTimer1SetPeriod
5.halTimer1SetChannelDuty..以及接下去的一些函式
這些都需要在CC2530EB中的hal_timer.c裡面做設定 ?
只是我只用到Timer1來做PWM輸出,所以就不需要其他的Timer,對吧??
那為什麼在這邊看到一些用Timer1還做PWM輸出的部分,都與下面論壇中的程式設定不太一樣呢??
例如程式定義P0DIR及其他參數的部分??
http://e2e.ti.com/support/low_power_rf/f/156/t/118346.aspx
所以我也必須去選擇使用free-running mode 或 up/down mode來使用PWM嗎?
我軟體目前使用如下圖,使用了add-on-lighting-kit,使CC2531可以使用SampleRemote
Q1 : 那現在要在SampleRemote中加入PWM,那是要把hal_timer.c
從
Z-Stack Lighting 1.0.1\Components\hal\target\CC2530PMP4712
複製到
Z-Stack Lighting 1.0.1\Components\hal\target\CC2530USB嗎?
Q2 : 除了這個檔案以外還有其他檔案要複製到CC2530USB這個target嗎?
Q3 : 假設加入PWM的檔案都從CC2530PMP4712複製到CC2530USB後,要在SampleRemote project中哪之程式去做暫存器的設置呢?(如下面網址中暫存器的設置)
http://e2e.ti.com/support/low_power_rf/f/156/t/118346.aspx?pi267162=1
Q4 : 如果可直接使用Timer裡面的function,那我要怎麼知道我的operation mode (Free-Running , Modulo or Up/Down Mode) 以及 output compare mode 還有我要設為PWM輸出的Pin腳位是哪支腳??
我想利用示波器測量PIN腳來觀看輸出的波形,所以需要知道如何暫存器的設定、PWM輸出腳位的設定
謝謝!!
你好,
1:不同的工程是针对不同的硬件对象的,CC2530EB是针对和SmartRF05EB来搭配使用的开发套件,在这个开发套件的code上,没有使用PWM的控制。
CC2530PMP4712的工程,是正对ZLight2 这个开发套件的,你可以TI网上了解下这个开发套件,上面实现了PWM的功能。你可以参考上面的例程来做。
2:任何一个单片机的操作,都会跟寄存器打交道,只是看每个人写代码的风格了,为了让硬件相关的程序封装的更好,所以一般我们会给开发者把设置底层硬件的寄存器的API写好,换句话说,你根据API可以知道具体是怎样操作的,具体内部怎么实现你可以不用管。当然如果你想追究下去也很容易,
#define ENABLE_LAMP P0SEL |= ( 0x08 | 0x10 | 0x20 | 0x40); /* P0.3:6 */
定时器的寄存器配置也是一样的。
至于P0DIR是因为,当用作定时器的通道IO输出的时候,P0SEL已经配置为 periphera方式,所以就不需要在配置方向了。
你选择什么方式实现PWM,都无所谓。
3:Q1,可以这样做
Q2,其他的可能需要,你debug程序的时候,根据报错,自己可以去修改添加的
Q3,你调试以后就会发现的
Q4:具体去看CC2530的user guide,Timer1 PWM输出都是固定的Pin脚的,多看user guide和datasheet。
谢谢。
我有看過
1.A USB Enabled System-On-Chip Solution for 2.4-GHz IEEE 802.15.4
關於PWM只有第20頁簡單說明關於Timer的這一頁提到
2.CC2531 USB Hardware User's Guide
裡面沒有提到PWM的相關說明
3.CC253x-4x User Guide. (Rev. D) _swru191d
第九章關於Timer1的有說明,例如
使用modulo mod : channel使用1或2,output compare mode用4、5、6或7。
使用free-running mode : channel output compare mode用4、5、6或7。
使用up/down mode : channel使用1或2,channel output compare mode用4、5。
但找不到Timer1 PWM输出的固定Pin脚是哪支? 可否指導一下?
還是在第9.8Output Compare Mode開頭提到
"In output compare mode, the I/O pin associated with a channel is set as an output."
I/O Pin是在這邊決定的嗎?是甚麼意思呢?
你好 想再請問一下
在zll_samplelight.c中看到下列程式
halTimer1SetChannelDuty (WHITE_LED, PWM_FULL_DUTY_CYCLE);
WHITE_LED定義為HAL_T1_CH4
而HAL_T1_CH4定義為4
請問這邊設置channel 4 的dutycycle100%,是代表channel 4輸出的佔空比為100%
但此輸出是從哪個pin腳輸出呢?
那麼你提到的#define ENABLE_LAMP P0SEL |= ( 0x08 | 0x10 | 0x20 | 0x40);
是指PWM的輸出給LED燈的輸出腳位嗎?
关于用Timer1 实现PWM 通道输出的,IO口都是有规定的,其实在user guide上都能找到。
http://www.ti.com/lit/ug/swru191d/swru191d.pdf
vv 你好! 抱歉~是我沒注意!
我在Table 7.1 看到有關 I/O口的設置
另外在hal_board_cfg.h看到以下程式碼
#if defined (PWM_ALT2)
#define INIT_PWM_PINS() \
{ \
/* Drive LED1 from timer 1 ch2 and LED2 from timer 1 ch1 */ \
/* unfortunitly we can not connect any other leds to the timer PWM */ \
/* on the SmartRF05EB/BB */ \
PERCFG |= 0x40; /* set timer 1 to use alt configuration*/ \
P1SEL |= ( 0x1 | 0x2 ); \
P1DIR |= ( 0x1 | 0x2 ); \
}
#else
#define INIT_PWM_PINS() \
{ \
PERCFG &= ~(0x40); /* bit 6 = 0 */ \
P0SEL |= ( 0x08 | 0x10 | 0x20 | 0x40); /* P0.3:6 */ \
P0DIR |= ( 0x08 | 0x10 | 0x20 | 0x40); /* P0.3:6 */ \
}
#endif
所以我在SampleRemote project中,如果沒有定義PWM_ALT2
那麼Channel 1 , 2 , 3 , 4使用的PWM output pin就分別是你之前提到的P0.3~P0.6,對吧??
那當我在SampleRemote project - zllSampleRemote_Init函式中使用下面程式來設定Timer1 - channel 1的dutycycle是50%時
halTimer1SetChannelDuty (HAL_T1_CH1, 500);
是代表我給CC2531 USB Dongle供電時,可以用示波器從P0.3看到50%的波形圖,對嗎??
你好,
#if defined (PWM_ALT2)
#define INIT_PWM_PINS() \
{ \
/* Drive LED1 from timer 1 ch2 and LED2 from timer 1 ch1 */ \
/* unfortunitly we can not connect any other leds to the timer PWM */ \
/* on the SmartRF05EB/BB */ \
PERCFG |= 0x40; /* set timer 1 to use alt configuration*/ \
P1SEL |= ( 0x1 | 0x2 ); \
P1DIR |= ( 0x1 | 0x2 ); \
}
#else
#define INIT_PWM_PINS() \
{ \
PERCFG &= ~(0x40); /* bit 6 = 0 */ \
P0SEL |= ( 0x08 | 0x10 | 0x20 | 0x40); /* P0.3:6 */ \
P0DIR |= ( 0x08 | 0x10 | 0x20 | 0x40); /* P0.3:6 */ \
}
#endif
这边提到的PWM_ALT2并不是指IO定义里面的Alt。上面代码里面也注释了,PWM_ALT2是针对SmartRF05EB或者BB开发板的,而下面的是针对Zlight2开发板的,你可以在官网下载开发板的user guide,原理图,参考设计,就会看清楚了。
如果没有定义PWM_ALT2,那么就是按照下面的方式在Timer1 输出PWM波形。可以的,但是你也确认Usb dongle上面,P0.3有没有被用掉。原理图在官网上也有。
謝謝 !!
1. 我將 hal_timer.c 從 CC2530PMP4712 複製到 CC2530USB.
並在CC2530USB目錄中的hal_board_cfg.h中加入下面紅色的程式
#define HAL_BOARD_INIT() \
{ \
uint16 i; \
\
SLEEPCMD &= ~OSC_PD; /* turn on 16MHz RC and 32MHz XOSC */ \
while (!(SLEEPSTA & XOSC_STB)); /* wait for 32MHz XOSC stable */ \
asm("NOP"); /* chip bug workaround */ \
for (i=0; i<504; i++) asm("NOP"); /* Require 63us delay for all revs */ \
CLKCONCMD = (CLKCONCMD_32MHZ | OSC_32KHZ); /* Select 32MHz XOSC and the source for 32K clock */ \
while (CLKCONSTA != (CLKCONCMD_32MHZ | OSC_32KHZ)); /* Wait for the change to be effective */ \
SLEEPCMD |= OSC_PD; /* turn off 16MHz RC */ \
\
/* Turn on cache prefetch mode */ \
PREFETCH_ENABLE(); \
INIT_PWM_PINS(); \
\
HAL_TURN_OFF_LED1(); \
LED1_DDR |= LED1_BV; \
HAL_TURN_OFF_LED2(); \
LED2_DDR |= LED2_BV; \
}
#define INIT_PWM_PINS() \
{ \
PERCFG &= ~(0x40); /* bit 6 = 0 */ \
P0SEL |= ( 0x08 | 0x10 | 0x20 | 0x40); /* P0.3:6 */ \
P0DIR |= ( 0x08 | 0x10 | 0x20 | 0x40); /* P0.3:6 */ \
}
/* ----------- Debounce ---------- */
2. 在zll_sampleremote-CC2531EMK.c中加入下面紅色的程式
void zllSampleRemote_Init( byte task_id )
{
HalTimer1Init(0);
......
halTimer1SetChannelDuty (HAL_T1_CH1,500);
}
但是在示波器上還是沒有出現50%的波形,我是不是有那裡少做或做錯了甚麼?
你要去看remote里面,这些IO有没有被其他的外设使用掉,寄存器配置的地方priority有没有错误,都需要你去检查一下的。
成功了!!! 他有在示波器上顯示50%的波形,我在SampleRemote中設置斷點,並看寄存器的值
圖中寄存器的值是在程式執行到halTimer1SetChannelDuty (HAL_T1_CH1, 500);後擷取
我在SampleRemote中加的程式如下:
INIT_PWM_PINS()
P2DIR = 0x80;
HalTimer1Init(0);
halTimer1SetChannelDuty (HAL_T1_CH1, 500);
Q1 : 只是為什麼T1CC1H 是 0x00 ??
Q2 : 另外想請問如果直接給T1CC1L/H 和 T1CC0L/H值,那麼period和duty cycle怎麼計算呢??
例如
T1CC0L = 0xff;
T1CC0H = 0x7f;
T1CC1L = 0x78;
T1CC1H = 0x10;
那麼period 和 duty cycle要怎麼計算呢??
謝謝