nrf51822 不能复位能直接驱动LED吗

很久没有记笔记了。今天要记点东西,不然以后又忘记了。
随着时代的发展,现在的SDK已经是13.0了。蓝牙5.0也就来了。废话就少说了,记笔记吧。
两年前搞过nRF51822 的无线升级功能,那时候用的还是 SDK5.20,直接用hex镜像进行升级的。后来的SDK就不再是hex,要用zip了,现在还不清楚具体做APP时候的用法。以后再说,先用官方提供了nRF_ToolBox能升级就很不错了。
现在用了新的SDK,试了很长一段时间,各种各样的文档都过了,各种各样的方法都试过了,就是不行,真特么尴尬。后来今天又试了,到官方论坛去搜各种各样的情况,尝试,到底还是有点眉目了。
SDK9.0的DFU例子,在..\nRF51_SDK_9.0.0_2e23562\examples\dfu\bootloader\pca10028\dual_bank_ble_s110 这个路径,我修改了一点点程序,
1.修改 bootloader_settings.c 文件下的这一行
m_boot_settings[CODE_PAGE_SIZE] __attribute__((at(BOOTLOADER_SETTINGS_ADDRESS))) __attribute__((used))
m_boot_settings[CODE_PAGE_SIZE] __attribute__((at(BOOTLOADER_SETTINGS_ADDRESS))) __attribute__((used)) = {BANK_VALID_APP};
没有这个,程序用一些手段烧进去了它就一直是bootloader那运行,进不了application,具体的原因查看下下面的这个链接,官方论坛网友提的一个问题和别人的解答:
2.修改main函数:
1 int main(void)
uint32_t err_
dfu_start =
app_reset = (NRF_POWER-&GPREGRET == BOOTLOADER_DFU_START);
8 #ifdef UART_DEBUG
uart_init();
<span style="color: #
M_LOG("\r\n[Boot]Uart Init OK.\r\n");
<span style="color: # #endif
<span style="color: #
<span style="color: #
if (app_reset)
<span style="color: #
<span style="color: #
M_LOG("[Boot]in DFU Mode...\r\n");
<span style="color: #
NRF_POWER-&GPREGRET = <span style="color: #;
<span style="color: #
<span style="color: #
<span style="color: #
leds_init();
<span style="color: #
<span style="color: #
// This check ensures that the defined fields in the bootloader corresponds with actual
<span style="color: #
// setting in the nRF51 chip.
<span style="color: #
APP_ERROR_CHECK_BOOL(*((uint32_t *)NRF_UICR_BOOT_START_ADDRESS) == BOOTLOADER_REGION_START);
<span style="color: #
APP_ERROR_CHECK_BOOL(NRF_FICR-&CODEPAGESIZE == CODE_PAGE_SIZE);
<span style="color: #
<span style="color: #
// Initialize.
<span style="color: #
timers_init();
<span style="color: #
<span style="color: #
err_code = app_timer_create( &feed_wd_timer_id, APP_TIMER_MODE_REPEATED, timer_index_feed_wd );
<span style="color: #
APP_ERROR_CHECK(err_code);
<span style="color: #
<span style="color: # #if 0
<span style="color: #
buttons_init();
<span style="color: # #endif
<span style="color: #
<span style="color: #
(void)bootloader_init();
<span style="color: # #if 0
<span style="color: #
if (bootloader_dfu_sd_in_progress())
<span style="color: #
<span style="color: # //
nrf_gpio_pin_clear(UPDATE_IN_PROGRESS_LED);
<span style="color: #
<span style="color: #
err_code = bootloader_dfu_sd_update_continue();
<span style="color: #
APP_ERROR_CHECK(err_code);
<span style="color: #
<span style="color: #
ble_stack_init(!app_reset);
<span style="color: #
scheduler_init();
<span style="color: #
<span style="color: #
err_code = bootloader_dfu_sd_update_finalize();
<span style="color: #
APP_ERROR_CHECK(err_code);
<span style="color: #
<span style="color: # //
nrf_gpio_pin_set(UPDATE_IN_PROGRESS_LED);
<span style="color: #
<span style="color: #
<span style="color: # #endif
<span style="color: #
<span style="color: #
// If stack is present then continue initialization of bootloader.
<span style="color: #
ble_stack_init(true);//!app_reset);//
<span style="color: #
scheduler_init();
<span style="color: #
M_LOG("[Boot]ble_stack_init OK...\r\n");
<span style="color: #
<span style="color: #
<span style="color: # #if 0
<span style="color: #
<span style="color: #
dfu_start |= ((nrf_gpio_pin_read(BOOTLOADER_BUTTON) == <span style="color: #) ? true: false);
<span style="color: #
<span style="color: #
if (dfu_start || (!bootloader_app_is_valid(DFU_BANK_0_REGION_START)))
<span style="color: # #else
<span style="color: #
if(app_reset)
<span style="color: # #endif
<span style="color: #
<span style="color: # //
nrf_gpio_pin_clear(UPDATE_IN_PROGRESS_LED);
<span style="color: #
<span style="color: #
err_code = app_timer_start(feed_wd_timer_id, APP_TIMER_TICKS(<span style="color: #00,APP_TIMER_PRESCALER), NULL);
<span style="color: #
APP_ERROR_CHECK(err_code);
<span style="color: #
<span style="color: #
<span style="color: #
// Initiate an update of the firmware.
<span style="color: #
err_code = bootloader_dfu_start();
<span style="color: #
APP_ERROR_CHECK(err_code);
<span style="color: #
<span style="color: # //
nrf_gpio_pin_set(UPDATE_IN_PROGRESS_LED);
<span style="color: #
<span style="color: #
<span style="color: #
if (bootloader_app_is_valid(DFU_BANK_0_REGION_START) && !bootloader_dfu_sd_in_progress())
<span style="color: #
<span style="color: #
<span style="color: #
(void)app_timer_stop( feed_wd_timer_id );
<span style="color: #
M_LOG("[Boot]bootloader_app_start...\r\n");
<span style="color: #
// Select a bank region to use as application region.
<span style="color: #
// @note: Only applications running from DFU_BANK_0_REGION_START is supported.
<span style="color: #
bootloader_app_start(DFU_BANK_0_REGION_START);
<span style="color: #
<span style="color: #
NVIC_SystemReset();
<span style="color: # }
里面除了屏蔽很多行代码,还多了几行代码,是某个软件定时器的,创建、开启和关闭。
err_code = app_timer_create( &feed_wd_timer_id, APP_TIMER_MODE_REPEATED, timer_index_feed_wd );
APP_ERROR_CHECK(err_code);
err_code = app_timer_start(feed_wd_timer_id, APP_TIMER_TICKS(<span style="color: #00,APP_TIMER_PRESCALER), NULL);APP_ERROR_CHECK(err_code);
(void)app_timer_stop( feed_wd_timer_id );
这个定时器就是解决今天尴尬的关键!
3.话说当 application 触发进入 OTA 模式很简单,只需要在加入以下代码即可:
<span style="color: # void ota_mode_entry(void)
<span style="color: # {
<span style="color: #
sd_softdevice_disable();
<span style="color: #
NRF_POWER-&GPREGRET = <span style="color: #xB1;
<span style="color: #
sd_softdevice_enable(NRF_CLOCK_LFCLKSRC_RC_250_PPM_8000MS_CALIBRATION,NULL);
<span style="color: #
NVIC_SystemReset();
<span style="color: # }
但是,但是!!!!蛋蛋是!!!
如果你的 application 启动了 看门狗, 当软件复位的时候,看门狗是不会停止的,它还在工作,当你不喂它,很显然它就狂吠你,导致重启。
这时候重启很显然就没办法再进行升级了,而是又进入了application。
nRF51822 的看门狗很奇怪,它一旦起来了,就不能软件关闭了,而且调用NVIC_SystemReset() 不会致使它的寄存器清除,它还在跑。
解决的办法只能是在 bootloader 程序加喂狗程序咯。论坛上有人直接在 for(;;)循环里面加喂狗代码,但是并不十分管用,因为有个低功耗休眠函数会阻塞程序,导致喂不到狗,
不知道论坛上的那些大神是怎么想的,我也懒得去研究他们的办法和解释,
所以只能加个软件定时器,1秒喂一次,就当是把它关闭了吧。下面是这个软件定时器的回调:
<span style="color: # static app_timer_id_t feed_wd_timer_
<span style="color: #
<span style="color: # static void timer_index_feed_wd( void *p_context )
<span style="color: # {
<span style="color: #
//feed the dog
<span style="color: #
NRF_WDT-&RR[<span style="color: #] = WDT_RR_RR_R
<span style="color: # }
记得还要吧timers_init()里的第二个参数调整加1
#define APP_TIMER_MAX_TIMERS
OK了,蛋蛋疼的OTA和看门狗之间的尴尬就化解了。
其他打包 zip 和烧录的 工作,就交给 帮助文档吧。
速度搜索一下 你的电脑,找到&How to generate the INIT file for DFU.pdf 文档。
用到的工具是: 1.hex2bin.exe & &2.nrfutil.exe
下面是命令行脚本的内容,这样就可以生成 zip 了。
.\hex2bin.exe app.hex.\nrfutil.exe dfu genpkg app.zip --application app.bin --application-version 0xffffffff --dev-revision 0xffff --dev-type 0xffff --sd-req 0x0064
阅读(...) 评论()板块整改中&>&NRF51822 点亮第一个灯,配置过程与代码
NRF51822 点亮第一个灯,配置过程与代码
上传大小:856KB
主要内容是用Keil软件新建一个NRF51822工程,用于点亮第一个灯,包含所有配置过程与代码。具体的NRF51822配置过程可以参考我的博客《蓝牙开发板NRF51822入门》
综合评分:4(2位用户评分)
所需积分/C币:
下载个数:24
{%username%}回复{%com_username%}{%time%}\
/*点击出现回复框*/
$(".respond_btn").on("click", function (e) {
$(this).parents(".rightLi").children(".respond_box").show();
e.stopPropagation();
$(".cancel_res").on("click", function (e) {
$(this).parents(".res_b").siblings(".res_area").val("");
$(this).parents(".respond_box").hide();
e.stopPropagation();
/*删除评论*/
$(".del_comment_c").on("click", function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_invalid/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parents(".conLi").remove();
alert(data.msg);
$(".res_btn").click(function (e) {
var q = $("#form1").serializeArray();
console.log(q);
var res_area_r = $.trim($(".res_area_r").val());
if (res_area_r == '') {
$(".res_text").css({color: "red"});
$.post("/index.php/comment/do_comment_reply/", q,
function (data) {
if (data.succ == 1) {
var $target,
evt = e || window.
$target = $(evt.target || evt.srcElement);
var $dd = $target.parents('dd');
var $wrapReply = $dd.find('.respond_box');
console.log($wrapReply);
var mess = $(".res_area_r").val();
var str = str.replace(/{%header%}/g, data.header)
.replace(/{%href%}/g, 'http://' + window.location.host + '/user/' + data.username)
.replace(/{%username%}/g, data.username)
.replace(/{%com_username%}/g, _username)
.replace(/{%time%}/g, data.time)
.replace(/{%id%}/g, data.id)
.replace(/{%mess%}/g, mess);
$dd.after(str);
$(".respond_box").hide();
$(".res_area_r").val("");
$(".res_area").val("");
$wrapReply.hide();
alert(data.msg);
}, "json");
/*删除回复*/
$(".rightLi").on("click",'.del_comment_r', function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_comment_del/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parent().parent().parent().parent().parent().remove();
$(e.target).parents('.res_list').remove()
alert(data.msg);
//填充回复
function KeyP(v) {
$(".res_area_r").val($.trim($(".res_area").val()));
评论共有2条
不错,我试试能不能建成一个工程。
很好,正在学习蓝牙相关的东西,这次看到这个很管用.
审核通过送C币
常用视频转换IC资料
创建者:tel
Moubus学习例程
创建者:tox33
Altium Designer Release
创建者:chengdong1314
上传者其他资源上传者专辑
数据库课程设计(物业管理系统delphi源码)
数据库课程设计(餐饮管理系统delphi源码)
数据库课程设计(校园综合管理系统delphi7原始资料)
我的图书管理系统(C#VS和SQL Server2005含报告文档)
开发技术热门标签
VIP会员动态
下载频道积分规则调整V1710.18
CSDN下载频道积分调整公告V1710.17
开通VIP,海量IT资源任性下载
spring mvc+mybatis+mysql+maven+bootstrap 整合实现增删查改简单实例.zip
CSDN&VIP年卡&4000万程序员的必选
为了良好体验,不建议使用迅雷下载
NRF51822 点亮第一个灯,配置过程与代码
会员到期时间:
剩余下载个数:
剩余C币:200
剩余积分:6726
为了良好体验,不建议使用迅雷下载
积分不足!
资源所需积分/C币
当前拥有积分
您可以选择
程序员的必选
绿色安全资源
资源所需积分/C币
当前拥有积分
当前拥有C币
(仅够下载10个资源)
全站1200个资源免积分下载
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
全站1200个资源免积分下载
资源所需积分/C币
当前拥有积分
当前拥有C币
您的积分不足,将扣除 10 C币
全站1200个资源免积分下载
为了良好体验,不建议使用迅雷下载
你当前的下载分为234。
你还不是VIP会员
开通VIP会员权限,免积分下载
你下载资源过于频繁,请输入验证码
你下载资源过于频繁,请输入验证码
您因违反CSDN下载频道规则而被锁定帐户,如有疑问,请联络:!
若举报审核通过,可奖励20下载分
被举报人:
举报的资源分:
请选择类型
资源无法下载
资源无法使用
标题与实际内容不符
含有危害国家安全内容
含有反动色情等内容
含广告内容
版权问题,侵犯个人或公司的版权
*详细原因:
NRF51822 点亮第一个灯,配置过程与代码nrf51822创建一个简单ble例程_图文_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
nrf51822创建一个简单ble例程
&&nrf51822 蓝牙 ble最小应用工程
阅读已结束,下载文档到电脑
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,方便使用
还剩26页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢nRF51822使用Timer制作4路PWM波详解
时间: 18:12:56
&&&& 阅读:7272
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&
Date:&Author:杨正 &QQ:&&&
一、&&&&&&&&&&&&pwm简介
PWM英文名叫Pulse Width Modulation,中文名叫脉宽调制。那它到底是什么呢?其实它是由定时器产生的,比普通的定时器多了一个比较寄存器。PWM里面有一个词叫占空比,即一个周期内,高电平持续时间与周期的比&#20540;。如下图:
占空比(dutycycle) = t/T。
PWM用途:控制电机调速,控制蜂鸣器播放音乐,控制led灯亮度等
二、&&&&&&&&&&&&Timer,PPI,GPIOTE之间的关系
由Timer产生一个事件,PPI捕获这个事件并把这个事件转化为任务传递给GPIOTE,由GPIOTE模块执行最终指定操作(该操作后面会讲到):
三、Timer定时器
要产生PWM波,需要将定时器产生的信号通过指定的引脚输出。定时器有两种模式,即计数器模式和定时器模式,要产生PWM波,自然要选择定时器模式,然而定时器模式里面也有一个计数器寄存器,即Counter。定时器模式还有一个捕获/比较寄存器,即CC寄存器。nRF51822的Timer中的Counter是递增的方式计数,当Counter的计数&#20540;与CC寄存器中的&#20540;相等时,就会产生一个事件。
nRF51822里面有三个定时器,因为TIMER0被CPU占用,所以只能使用TIMER1和TIMER2来做4路PWM波。使用TIMER1的CC[0]和CC[1]分别控制一路PWM波的频率和占空比,CC[2]和CC[3]分别控制第二路PWM波的频率和占空比。TIMER2类推,这样就可以做出4路PWM波。以下是第一路PWM波的timer init函数, 其他三路的timer init函数可以由此类推,eg:
&&& static voidtimer1_cc01_init(void)&&//第一路PWM波的timer
&&&&&&& NRF_CLOCK-&EVENTS_HFCLKSTARTED& = 0;
&&&&&&& NRF_CLOCK-&TASKS_HFCLKSTART&&&& = 1;
&&&&&&& while(NRF_CLOCK-&EVENTS_HFCLKSTARTED == 0)
&&&&&& NRF_TIMER1-&MODE =TIMER_MODE_MODE_T
NRF_TIMER1-&BITMOD=TIMER_BITMODE_BITMODE_16Bit&&TIMER_BITMODE_BITMODE_P&&//counter与指定cc寄存器的16位进行比较
&&&&&& NRF_TIMER1-&PRESCALER&& = 9;&&//9分频,每一个tick为32us
&&&&&& NRF_TIMER1-&TASKS_CLEAR = 1;&
&&&&&& NRF_TIMER1-&CC[0]=256; &&&//控制周期,周期相当于256*32us
&&&&& &NRF_TIMER1-&CC[1]= 1;&&&&//控制占空比
&NRF_TIMER1-&SHORTS=(TIMER_SHORTS_COMPARE0_CLEAR_Enabled&&TIMER_SHORTS_COMPARE0_CLEAR_Pos);
&&&&&& NRF_TIMER1-&INTENSET= (TIMER_INTENSET_COMPARE0_Enabled && TIMER_INTENSET_COMPARE0_Pos); &&&//使能中断,中断发生时就会产生COMPARE事件,就会即把compare寄存器置1
&&&&&& NVIC_EnableIRQ(TIMER1_IRQn);
&&&&&& NVIC_SetPriority(TIMER1_IRQn,APP_IRQ_PRIORITY_HIGH);&
void TIMER1_IRQHandler(void) &&//定时器的中断处理函数;Timer2的中断处理函数类&#20284;,这里不再给出。
&&& &//第一路PWM
//cc0 controlperiod, cc1 controls the duty cycle
&&&& &&&&NRF_TIMER1-&EVENTS_COMPARE[0]= 0;&
&//把Compare寄存器清零
&&&& &&&&NRF_TIMER1-&CC[1] = duty_cycle1_01; &&&&&&//每次timer中断都会重新获取CC[1]的&#20540;作为占空比
&&&&&&& //第二路PWM
&&&&&& &&&//cc2 control period, cc3 controls the duty cycle
&&&& &&&NRF_TIMER1-&EVENTS_COMPARE[2] = 0;
&&&& &&&NRF_TIMER1-&CC[3] = duty_cycle1_23;&&
四、ProgrammablePeripheral Interconnect (PPI)
nRF51822的寄存器分为三类:
Task寄存器:外设可以执行的task;
Event寄存器:外设带有的event;
普通寄存器;
Task寄存器和Event寄存器在PPI中的使用非常重要,例如,在PPI中,设置EEP寄存器为某个外设A的Event寄存器地址,TEP寄存器设为另外一个外设Task寄存器地址,那么当外设A的event发生时可以直接触发外设B的Task,而不经过CPU。
staticvoid ppi_init(void)& &//初始化PPI模块,设置EEP寄存器和TEP寄存器
&&&&&& // Configure PPI channel 01 to togglePWM_OUTPUT_PIN on every TIMER1 COMPARE match.
&&& NRF_PPI-&CH[0].EEP =(uint32_t)&NRF_TIMER1-&EVENTS_COMPARE[0];
&&& NRF_PPI-&CH[0].TEP =(uint32_t)&NRF_GPIOTE-&TASKS_OUT[0];&
&&& NRF_PPI-&CH[1].EEP =(uint32_t)&NRF_TIMER1-&EVENTS_COMPARE[1];
&&& NRF_PPI-&CH[1].TEP =(uint32_t)&NRF_GPIOTE-&TASKS_OUT[0];
&&&&&& &// Configure PPI channel 23 to toggle PWM_OUTPUT_PIN on every TIMER1COMPARE match.
&&&&&& NRF_PPI-&CH[2].EEP =(uint32_t)&NRF_TIMER1-&EVENTS_COMPARE[2];
&&& NRF_PPI-&CH[2].TEP =(uint32_t)&NRF_GPIOTE-&TASKS_OUT[1];&
&&& NRF_PPI-&CH[3].EEP =(uint32_t)&NRF_TIMER1-&EVENTS_COMPARE[3];
&&& NRF_PPI-&CH[3].TEP =(uint32_t)&NRF_GPIOTE-&TASKS_OUT[1];
&&&&&& &// Configure PPI channel 45 to toggle PWM_OUTPUT_PIN on every TIMER2COMPARE match.
&&&&&& NRF_PPI-&CH[4].EEP =(uint32_t)&NRF_TIMER2-&EVENTS_COMPARE[0];
&&& NRF_PPI-&CH[4].TEP =(uint32_t)&NRF_GPIOTE-&TASKS_OUT[2];&
&&& NRF_PPI-&CH[5].EEP =(uint32_t)&NRF_TIMER2-&EVENTS_COMPARE[1];
&&& NRF_PPI-&CH[5].TEP = (uint32_t)&NRF_GPIOTE-&TASKS_OUT[2];
&&&&&& &// Configure PPI channel 67 to toggle PWM_OUTPUT_PIN on every TIMER2COMPARE match.
&&&&&& NRF_PPI-&CH[6].EEP =(uint32_t)&NRF_TIMER2-&EVENTS_COMPARE[2];
&&& NRF_PPI-&CH[6].TEP =(uint32_t)&NRF_GPIOTE-&TASKS_OUT[3];&
&& &NRF_PPI-&CH[7].EEP =(uint32_t)&NRF_TIMER2-&EVENTS_COMPARE[3];
&&& NRF_PPI-&CH[7].TEP =(uint32_t)&NRF_GPIOTE-&TASKS_OUT[3];&
&&&&&&&&&&&&&
&&&&&& // Enable PPI channels 0-7.
&&& NRF_PPI-&CHEN = (PPI_CHEN_CH0_Enabled&& PPI_CHEN_CH0_Pos)
&&&&&&&&&&&&&&&&&&& | (PPI_CHEN_CH1_Enabled&& PPI_CHEN_CH1_Pos)
&&&&&& &&&&&&&&&&&&&&& | (PPI_CHEN_CH2_Enabled&& PPI_CHEN_CH2_Pos)
&&&&&&&&&&&&&&&&&&& | (PPI_CHEN_CH3_Enabled&& PPI_CHEN_CH3_Pos)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |(PPI_CHEN_CH4_Enabled && PPI_CHEN_CH4_Pos)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |(PPI_CHEN_CH5_Enabled && PPI_CHEN_CH5_Pos)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |(PPI_CHEN_CH6_Enabled && PPI_CHEN_CH6_Pos)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |(PPI_CHEN_CH7_Enabled && PPI_CHEN_CH7_Pos);
注:这里NRF_PPI-&CH[n]是指PPI通道。
PPI由两个端点寄存器组成,即Event End-Point (EEP),Task End-Point (TEP)。一个外设任务通过与任务相关的任务寄存器连接到TEP;同样的,一个外设事件通过与事件相关的事件寄存器连接到EEP。
NRF_PPI-&CH[0].EEP对应NRF_PPI-&CH[0].TEP,以此类推。
EVENT_COMPARE[0]对应CC[0],以此类推。
TASK_OUT[n]指定任务输出通道。
五、GPIOTasks and Events (gpiote)
GPIOTE模块也是设计成减少CPU占用的Task Event模式,使得事件不经过CPU直接得到响应。
Event引脚触发源:上升沿,下降沿等;
Task引脚操作方式:置位,清零,翻转;
Event和Task之间可以通过PPI连接在一起。
一旦把某个引脚分配给Task(OUT[n])或Event(IN[n]),那么该引脚只能被GPIOTE模块写操作,而普通的gpio写入无效。
当GPIOTE通道被配置用于操作一个任务引脚n,那么该引脚n的初&#20540;需要在CONFIG[n]寄存器的OUTINIT区域中设定。
staticvoid gpiote_init(void)&& &//初始化GPIOTE模块,设置4路PWM信号输出引脚
&&& APP_GPIOTE_INIT(APP_GPIOTE_MAX_USERS);
&&& // Configure PWM_OUTPUT_PIN_NUMBER as anoutput.
&&&nrf_gpio_cfg_output(PWM_OUTPUT_PIN_NUMBER0);&&&
&&&&&& nrf_gpio_cfg_output(PWM_OUTPUT_PIN_NUMBER1);
&&&&&& nrf_gpio_cfg_output(PWM_OUTPUT_PIN_NUMBER2);
&&&&&& nrf_gpio_cfg_output(PWM_OUTPUT_PIN_NUMBER3);
&&& // Configure GPIOTE channel 0 to toggle thePWM pin state
&&&&&& // @note Only one GPIOTE task can beconnected to an output pin.
&&&&&& nrf_gpiote_task_config(0,PWM_OUTPUT_PIN_NUMBER0&&&&& , \
&&&&&&&&&&&&&&&&&&&&&&&&&& NRF_GPIOTE_POLARITY_TOGGLE,NRF_GPIOTE_INITIAL_VALUE_HIGH);
&&&&&& nrf_gpiote_task_config(1,PWM_OUTPUT_PIN_NUMBER1&&&&& , \
&&&&&&&&&&&&&&&&&&&&&&&&&&NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);&&
&&&&&& nrf_gpiote_task_config(2,PWM_OUTPUT_PIN_NUMBER2&&&&& , \
&&&&&& &&&&&&&&&&&&&&&&&&&&NRF_GPIOTE_POLARITY_TOGGLE,NRF_GPIOTE_INITIAL_VALUE_HIGH);
&&&&&& nrf_gpiote_task_config(3,PWM_OUTPUT_PIN_NUMBER3&&&&& , \
&&&&&&&&&&&&&&&&&&&&&&&&&&NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);
注:重要函数static__INLINE void nrf_gpiote_task_config(uint32_t channel_number, uint32_tpin_number, nrf_gpiote_polarity_t polarity, nrf_gpiote_outinit_t initial_value)
channel_number:指定GPIOTE的通道[0:3],并配置成输出通道,与PPI中的TASK_OUT[n]对应;
pin_number:指定pin管脚,在GPIOTE中使用,也就是最终被pwm控制的管脚;
polarity:指定在GPIOTE中的极性,当任务信号到达就会执行该动作;
initial_value:指定pin管脚的初始&#20540;。
六、&&&&&&&&&&&&总结
问题一:通过pwm波控制灯的亮度范围是全灭到全亮,但是现在做出来的pwm波不能使灯全灭或者全亮。比如我的周期用了256,占空比的范围只能是1到255,这样的话通过占空比是不能控制灯全灭或者全亮。
解决方法:如果占空比为0,或者为256,就会在同一时间触发两个事件,如果占空比为0,即CC[1]=0,那么当计数器超过CC[0]的&#20540;(256)时,就会自动置零并从零开始重新计数,而且会产生一个事件,当计数器置零时,CC[1]的&#20540;也为零,所以CC[1]也会产生一个事件,所以同一时间会产生两个事件,分别由CC[0],CC[1]产生(这部分是个人理解)。
&&& 所以这样是不能控制灯全灭或者全亮。所以有以下办法能控制灯全亮或者全灭:
要设置该PWM引脚为低或者高,可以重新初始化这个引脚的GPIOTE:
nrf_gpiote_task_config(0,PWM_OUTPUT_PIN_NUMBER, NRF_GPIOTE_POLARITY_TOGGLE,
NRF_GPIOTE_INITIAL_VALUE_HIGH);设置为高或者低,然后把控制他的PPI disable掉。
或者还有一种方法,设置高配置为:
nrf_gpiote_task_config(0,PWM_OUTPUT_PIN_NUMBER,NRF_GPIOTE_POLARITY_LOTOHI,
NRF_GPIOTE_INITIAL_VALUE_HIGH)
设置低配置为nrf_gpiote_task_config(0, PWM_OUTPUT_PIN_NUMBER,NRF_GPIOTE_POLARITY_HITOLO,NRF_GPIOTE_INITIAL_VALUE_LOW)
可以试试哪种方法比较好用,这里给出后面这种方法:
&&& &power_manage();
& &&&if (duty_cycle1_01 == 255)
&&&&&&&& &&& nrf_gpiote_task_config(0,PWM_OUTPUT_PIN_NUMBER0,& \
& &&&&&&&&&&&&& &&&&&&&&&&&&&&&&&& NRF_GPIOTE_POLARITY_LOTOHI,NRF_GPIOTE_INITIAL_VALUE_HIGH);&//当占空比为255时,灯最暗(但是微亮),把引脚拉高,就会全灭
&&&&&&&& // nrf_gpiote_task_config(0,PWM_OUTPUT_PIN_NUMBER0,& \
&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&
NRF_GPIOTE_POLARITY_HITOLO,NRF_GPIOTE_INITIAL_VALUE_LOW);&&
//当占空比为1时,灯最亮(但不是全亮),把引脚拉低,就会全亮
标签:&&&&&&&&&&&&&&&
&&国之画&&&& &&&&chrome插件&&
版权所有 京ICP备号-2
迷上了代码!

我要回帖

更多关于 74hc595能直接驱动led 的文章

 

随机推荐