完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我想用M051实现PWM输出的频率0.1Hz-20Hz间的低频调频。但是该PWM我是用P2.0引脚配置CNR、CMR来实现频率的可调,而CNR则由始终分频而来的。
通过数据整理发现,当设置16分频时候,CNR = 375时 为20Hz,CNR = 750时 为10Hz,CNR = 1500时 为5Hz。CNR = 3000时 为2.5Hz,CNR = 6000时 为0.75Hz,CNR = 12000时 为0.375Hz,CNR = 24000时 为0.1875Hz,CNR = 96000时 为0.09375Hz,才约等于0.1Hz,若我要实现0.1-20Hz的频率变化,而每按1次按键 频率增加0.5Hz。这该怎么设计算法? 因为以上数据得出该变化是375-96000成2的X次方增加。而随之的是20Hz随2的X次方减少。所以想问问有没其他方法配置频率? |
|
相关推荐
1个回答
|
|
实现PWM输出的频率可调的方法有很多种,以下是一种可以实现您需要的功能的思路:
1. 首先确定PWM定时器的时钟源,一般可以选择内部时钟或外部时钟。假设选择内部时钟,通过设置CLK_SEL0[7:6]及CLK_SEL1[3:2]来选择内部时钟的分频系数。 2. 然后确定PWM的基本参数,包括PWM频率、占空比、计数器的最大值(CNR)等。根据您的需求,此处计数器的最大值可以通过不同的分频系数来进行调整。 3. 在程序中加入按键检测模块,在按键被按下时修改PWM定时器的各个参数以实现频率的调节。 4. 为了实现按键一次增加0.5Hz的功能,可以将按键的响应时间进行延时,例如设置一个定时时间,当按键被按下时,启动该定时器进行延时,当定时时间到达后再进行增加或减少。 5. 需要注意的是,频率的计算应该进行取整或舍入操作,以保证PWM输出的稳定性。 6. 测试程序时,可以通过示波器或LED等外部设备来观察PWM波形的变化,以验证程序是否实现了预期的功能。 以下是一个简单的伪代码实现: ``` // 定义默认的PWM参数 #define DEFAULT_FREQ 20 // 20Hz #define DEFAULT_DUTY 50 // 50% duty cycle #define DEFAULT_DIV 16 // 16分频 #define DEFAULT_CNR 375 // 对应20Hz的计数器最大值 // 定义按键的延时时间,单位为ms #define KEY_DELAY 500 // 定义计数器的最大值和当前分频系数 int cnr = DEFAULT_CNR; int divider = DEFAULT_DIV; // 定义定时器中断处理函数,用于更新占空比 void PWM_ISR(void) { // 更新占空比 P2_0 = (CMR * 100) / cnr; } // 定义按键检测函数,用于检测按键并更新PWM参数 void detect_key() { if (key_pressed()) { // 按键被按下后,启动延时定时器 start_delay_timer(KEY_DELAY); // 更新PWM参数 if (freq_up()) { // 增加频率 cnr = cnr * 2; divider = divider * 2; } else if (freq_down()) { // 减少频率 cnr = cnr / 2; divider = divider / 2; } else if (duty_up()) { // 增加占空比 CMR++; } else if (duty_down()) { // 减少占空比 CMR--; } // 进行舍入操作,保证计数器的最大值为整数 cnr = (int)(cnr + 0.5); } } // 主函数 int main() { // 初始化PWM定时器和按键检测模块 init_pwm_timer(DEFAULT_FREQ, DEFAULT_DUTY, cnr); init_key_detect(); // 启动定时器中断并进入主循环 enable_timer_interrupt(PWM_ISR); while (1) { // 检测按键并更新PWM参数 detect_key(); // 更新PWM定时器的分频参数 set_pwm_divider(divider); } } ``` |
|
|
|
只有小组成员才能发言,加入小组>>
3278 浏览 9 评论
2956 浏览 16 评论
3458 浏览 1 评论
9000 浏览 16 评论
4051 浏览 18 评论
1110浏览 3评论
572浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
568浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2302浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1859浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-24 16:57 , Processed in 0.995164 second(s), Total 80, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号