[Atmel] AVRmega8 测速并通过LCD显示

[复制链接]
1970|0
 楼主| ddllxxrr 发表于 2014-9-28 21:20 | 显示全部楼层 |阅读模式
为了测电机速度可以通过光学中断如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

2404

主题

7001

帖子

68

粉丝
快速回复 在线客服 返回列表 返回顶部