|
|

楼主 |
发表于 2016-11-18 15:07:56
|
显示全部楼层
您能给我提供一个都PWM信号占空比的编程思路么?
事实上在用A0引脚读PWM脉冲之前,我就是尝试用中断来读PWM信号的!
由于我着急,匆忙,以为编码器不同的角度对应PWM信号的不同频率,所以我参考“AVR单片机嵌入式系统原理与应用实践.pdf”第11章的例子,编写了程序,是读频率信号的频率的,其原理如下:
1. 使用两个定时计数器。T/C0工作在计数器方式,对外部T0引脚输入的脉冲信号计数(上升沿触发)。
2. T/C2工作在CTC方式,每隔1ms中断一次,每一次T/C2的中断中,都首先记录下T/C0寄存器TCNT0当前的计数值,因此前后两次TCNT0的差值(time0_new - time0_old)或(256 - time0_old + time0_new)就是1ms时间内T0脚输入的的脉冲个数(这个表达式要理解,其原理是溢出了,超过了256)。为了提高测量精度,程序对100个1ms的脉冲个数进行了累计(在变量freq中),即已知限定的时间为100ms。
下面是我的程序:
- unsigned int time_1ms_ok;
- unsigned int time0_old, time0_new, freq_time;
- unsigned long freq;
- void setup() {
- // 初始化
- freq = 0;
- freq_time = 0;
- time_1ms_ok = 0;
- time0_old = 0;
- DDRD = 0x00; // 端口PD4的第二功能,T/C0外部计数器输入
- TCCR0A = 0;
- TCCR0B = 1 << CS02 | 1 << CS01 | 0 << CS00; // 外部T0引脚下降沿触发计数,普通模式;
- //TCNT0 = 0x00; // 初始化计数值
- TCCR2A = 1 << WGM21;
- TCCR2B = 1 << CS22; // 内部时钟,64分频(16M/64 = 0.25MHz),CTC模式
- TCNT2 = 0x00; // 初始化计数值
- /*
- 0.25MHz/1000Hz = 250
- */
- OCR2A = 0xF9; // OCR2 = 0xF9(249) ,(249+1)*(1/0.25MHz) = 1ms
-
- TIMSK2 = 1 << OCIE2A; // 允许T/C2比较匹配中断
- TIFR2 = 1 << OCF2A;
- Serial.begin(9600);
- }
- void loop() {
- if (time_1ms_ok)
- {
- if (time0_new >= time0_old)
- freq = freq + (time0_new - time0_old);
- else
- freq = freq + (256 - time0_old + time0_new);
- time0_old = time0_new;
- freq_time += 1;
-
- if (freq_time >= 100)
- {
- // 显示计数值
- Serial.println(freq);
- freq_time = 0; // 100ms到
- freq = 0;
- }
- time_1ms_ok = 0;
- }
- }
- // 中断
- ISR(TIMER2_COMPA_vect)
- {
- time0_new = TCNT0; // 1ms到,记录当前T/C0的计数值
- time_1ms_ok = 1;
- }
复制代码
但后来我发现,这个程序只能读出PWM信号的频率,但以我的理解,绝对编码器的不同角度,对应不同的PWM信号占空比,所以光读频率还不行,得读占空比,对不?
如果是这样的话,问题就来了:在上面这个读频率的程序中,第1步要求把T/C0设置为上升沿计数还是下降沿计数,可如果要读PWM的占空比,需要既读上升沿、又要读下降沿,这可怎么设置呢??? |
|