打印
[Atmel]

AVRmega8 测速并通过LCD显示

[复制链接]
976|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
为了测电机速度可以通过光学中断如H21A1。这是一个设备,红外LED光电晶体管耦合在塑料外壳。然后用不透明材料允许中断信号之间的差距,这样转换的输出。这个设备可以连接到微控制器ICP管脚和这种方法测量PWM磁盘(洞在上边)可以测量速度。每次磁盘传递差距的洞,光学断续器将形成一个脉冲去ICP销触发计时器。如果需要测量间隔1 s,然后计算脉冲将等于在赫兹。

    让Atmega8单片机定时在8 mhz。这允许使用计时器缩放8,然后计时器将运行频率等于1 mhz(周期1μs)。每次脉冲到达ICP(Atmega8 - PB0管脚)然后在下降前脉冲输入捕获中断发生。中断服务程序计数定时器脉冲在两个脉冲的数量。数量的定时器计数定义磁盘转速(RPM -转每分钟)。
RPM = 60000000 /T
T -持续时间一个磁盘。结果将显示在2 x16液晶。

LCD data pins to AVR PORTD;
LCD control pins to AVR PORTC (RS->PC0, R/W->PC1, E->PC2).
//----------------
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "lcd_lib.h"
#define RPM 60000000u
#define ICP PINB0
//timer overflow counter
uint8_t ovs=0;
uint32_t T;
uint16_t PreviousTime, CurrentTime;
uint8_t buffer[15];
uint8_t calculate=0;
//timer1 input capture interrupt service routine
ISR(TIMER1_CAPT_vect)
{
if(calculate==0)
        {
                TCNT1=0;
                calculate=1;
        }
        else if (calculate==1)
                        {
                        //Saving current timer value on falling edge
                        CurrentTime=ICR1;
                        calculate=2;
                        }       
        else if(calculate==2)
                        {
                        T=(uint32_t)CurrentTime;
                        //form string with RPM value
                        sprintf(buffer,"RPM: %06u",RPM/T);
                        //output to LCD
                        LCDGotoXY(0,0);
                        LCDstring(buffer, 15);
                        calculate=0;
                        }
}
int main(void)
{
        LCDinit();//init LCD 8 bit, dual line, cursor right
        LCDclr();//clears LCD
        LCDhome();//cursonr home
        LCDstring("Count RPM", 9);
        PORTB|=1<<ICP;//pullup enable
        DDRB&=~(1<<ICP);//ICR1 as input
        TCNT1=0;// start counting from zero
        TIMSK|=(1<<TICIE1);//|(1<<TOIE1);//enable input capture interrupts
        TCCR1A=0;
        TCCR1B|=(1<<CS11);//start with prescaller 8, rising edge ICP1
        sei();
        while(1)//loop  
        {
        }
        return 0;
}




相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:http://shop34182318.taobao.com/ http://shop562064536.taobao.com

2398

主题

6949

帖子

66

粉丝