极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 26422|回复: 7

请教单片机发脉冲,定时器Timer1、OCR1A、OCR1B方面的问题

[复制链接]
发表于 2017-2-4 23:08:51 | 显示全部楼层 |阅读模式
本帖最后由 cciew 于 2017-2-4 23:49 编辑

1:arduino uno  用的1号定时器, 程序这样写D9(OCR1A)脚 可以发生脉冲!   

pinMode(9, OUTPUT);
    TCCR1B = 0;
    DDRD = 0x08;
    TCCR1A = 0x82;
    TCCR1B = 0x10;
    ICR1=8000000/feb-1;  //频率=16MHz/2/feb -1
    OCR1A=25*80000/feb;  //占空比 %
    TCCR1B |= 0x01;
2:现在想用D9,D10(OCR1B),同时发生脉冲,实验结果D9 D10 都不能发生脉冲了!
   pinMode(9, OUTPUT);
     pinMode(10, OUTPUT);    
    TCCR1B = 0;
    DDRD = 0x08;
    TCCR1A = 0x82;
    TCCR1B = 0x10;
    ICR1=8000000/feb-1;  //频率=16MHz/2/feb -1
    OCR1A=25*80000/feb;  //占空比 %
   OCR1B=80*80000/feb;  //占空比 %   
   TCCR1B |= 0x01;

请教相关方面的高人,给看看,应该怎样写,谢谢!
回复

使用道具 举报

 楼主| 发表于 2017-2-4 23:11:59 | 显示全部楼层
本帖最后由 cciew 于 2017-2-4 23:38 编辑

    pinMode(9, OUTPUT);
    pinMode(10, OUTPUT);
    TCCR1B = 0;
    DDRD= 0x08;
    TCCR1A = 0xA1;
    TCCR1B = 0x09;
    ICR1=8000000/feb-1;  //频率=16MHz/2/feb -1
    OCR1A=25*80000/feb;  //占空比 %
    OCR1B=80*80000/feb;  //占空比 %
后来改成这样写了, D9 D10可以发生不同占空比的脉冲了,可是又不能改脉冲宽度(频率)了。
回复 支持 反对

使用道具 举报

发表于 2017-2-5 08:23:06 | 显示全部楼层
看下链接。。。。
http://forum.arduino.cc/index.php/topic,16612.0.html#4
回复 支持 反对

使用道具 举报

发表于 2017-2-5 08:25:11 | 显示全部楼层
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-2-5 21:40:18 | 显示全部楼层
Paderboy 发表于 2017-2-5 08:25
http://playground.arduino.cc/Code/PwmFrequency

http://playground.arduino.cc/Main/TimerPWMCheatshe ...

谢谢Paderboy,资料很详细!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-2-5 21:48:33 | 显示全部楼层
本帖最后由 cciew 于 2017-2-5 21:50 编辑

现在已经搞定了!
用D9,D10(OCR1B),同时发生不同频率的脉冲!
   pinMode(9, OUTPUT);
     pinMode(10, OUTPUT);     
    TCCR1B = 0;
    //DDRD = 0x08;
    TCCR1A = 0xA2;
    TCCR1B = 0x10;
    ICR1=8000000/feb-1;  //频率=16MHz/2/feb -1
    OCR1A=25*80000/feb;  //占空比 %
   OCR1B=80*80000/feb;  //占空比 %   
   TCCR1B |= 0x01;

问题主要出在 TCCR1A
TCCR1A = 0xA2;  =10100010 ,前面两个10, 表示1A,1B端口使能!
相关知识:
http://www.arduino.cn/thread-11204-1-1.html
http://www.diy-robots.com/?p=852

尤其仔细阅读以下内容:
Janitor 说:
2013/06/05 于 21:16
感谢博主的经验分享。
但是对于原文中以下部分我有一些疑惑。
“这段代码看上去有点晕,其实很简单。_BV(n)的意思就是1< COM2A1,表示COM2A的第1位(靠,其实是第2位,不过程序员们是从0开始数数的)。所以_BV(COM2A1)表示COM2A = 10;类似的,_BV(WGM21) | _BV(WGM20) 表示 WGM2 = 011。”
从ATmega328P datasheet 中的 Register summary中可以找到8位寄存器TCCR2A。COM2A1,COM2B1,WGM21,WGM20是TCCE2A中的位的名称,本身不是寄存器。
Address Name Bit7 Bit6 Bit5 Bit4 Bit3Bit2 Bit1 Bit0
(0xB0) TCCR2A COM2A1 COM2A0 COM2B1 COM2B0 – – WGM21 WGM20
所以_BV(COM2A0)即1<<COM2A0即01000000,依次类推命令
TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM21) |_BV(WGM20)
可以转化为
TCCR2A = 01000000 | 00100000 | 00000010 | 00000001

TCCR2A = 01100011
回复 支持 反对

使用道具 举报

发表于 2017-4-12 10:32:17 | 显示全部楼层
cciew 发表于 2017-2-5 21:48
现在已经搞定了!
用D9,D10(OCR1B),同时发生不同频率的脉冲!
   pinMode(9, OUTPUT);

这个好,终于弄个好点的解释了!
回复 支持 反对

使用道具 举报

发表于 2017-4-12 10:37:18 | 显示全部楼层
好文 学习经验
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-9 00:37 , Processed in 0.061626 second(s), 21 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表