原创 MEGA128驱动超声波测距模块US-100

2012-11-4 15:05 2276 15 15 分类: MCU/ 嵌入式

AVRstudio6下写的,IDE自带GCC。使用Timer1的输入捕获,晶振8M.

 

#include <stdio.h>
#define F_CPU 8000000
#include <util/delay.h>
#include <avr/io.h>
#include <avr/iom128.h>
#include <avr/interrupt.h>    //中断信号头文件
 
#define LED         PORTE                //数据口
#define LEDDDR         DDRE                 //数据口方向寄存器
 
#define PORT_DATA  PORTC
#define PORT_SEL   PORTA
#define DDR_DATA   DDRC
#define DDR_SEL    DDRA
 
#define DDR_WAVE_TRIG DDRD
#define DDR_WAVE_ECHO   DDRD
#define PORT_WAVE_TRIG PORTD
#define PORT_WAVE_ECHO   PORTD
#define PIN__WAVE_TRIG  PIND
#define PIN__WAVE_ECHO  PIND
#define TRIG  PD6
#define ECHO  PD4
 
#define delay_us(x)     _delay_us(x)    //AVR GCC延时函数 x(us)
#define delay_ms(x)     _delay_ms(x)    //AVR GCC延时函数 x(ms)
 
#define uchar           unsigned char
#define uint            unsigned int
#define ulong           unsigned long
 
volatile ulong ov_counter=0;
volatile uint rising_edge,falling_edge;
volatile ulong pulse_clocks = 1000;//高电平宽度
volatile uint    temp;
 
const char Table[10]={0x3f,0x06,0x5b,0x4f,0x66,
                0x6d,0x7d,0x07,0x7f,0x6f};
 
char Date[4]={1,2,3,4};
 
void Display(char *p)
{
char i,sel=0x01;
for(i=0;i<4;i++)
{
PORT_SEL = sel;     // 1 表示选通
PORT_DATA = ~Table[p];
 
if(i == 0)
PORT_DATA &= ~(1<<7);
 
delay_ms(2);
PORT_DATA= 0xFF ;
sel= sel<<1;
}
}
 
void Io_Init(Void)
{
DDR_DATA = 0xFF;
PORT_DATA = 0x00;
 
DDR_SEL  = 0x0F;
PORT_SEL = 0x0F;
 
DDR_WAVE_ECHO &= ~(1<<ECHO);//ECHO设输入 ,ICP1
DDR_WAVE_TRIG |= (1<<TRIG);// 触发脉冲设输出
 
PORT_WAVE_ECHO &= ~(1<<ECHO);//ECHO和TRIG均初始化为0
PORT_WAVE_TRIG &= ~(1<<TRIG);
 
  LEDDDR |= 0XFF;
  LED = 0xFF;
}
 
void Initial_Timer(void)
{
TCCR1B = 0;
TCCR1A = 0x00;
TCCR1B = (1<<ICNC1)|(1<<ICES1)|(1<<CS11);//8, 上升沿触发
 
TIMSK |= (1<<TICIE1)|(1<<TOIE1);//使能ICP捕捉中断,溢出中断
}
/*
(count * div)/8M * 340/2 m
(count * div)/8M * 340/2 *1000 mm
count*8/8000000 * 170*1000 =
count*17/100 mm ;
*/
void Calc_Distance( char* p)
{
volatile unsigned long TN = 0;
TN = (falling_edge*17/100);// 单位为mm
p[0] = TN/1000;
p[1] = (TN % 1000)/100;
p[2] = (TN % 100)/10;
p[3] = TN % 10;
}
 
void GenerateTrig(void)
{
PORT_WAVE_TRIG |= (1<<TRIG);
delay_us(30);
PORT_WAVE_TRIG &= ~(1<<TRIG);
}
/*
void main()
{
unsigned int count = 0;
Io_Init();
Initial_Timer();
//asm("SEI"); //打开全局中断
 
while(1)
{
GenerateTrig();
while(!(PIN__WAVE_ECHO & (1<< ECHO))) // wait for echo raising
 {;}
   TCNT1H = 0;
TCNT1L = 0;
while((PIN__WAVE_ECHO & (1<< ECHO))) // wait for echo falling
 {;}
falling_edge = TCNT1L;
temp = TCNT1H;
falling_edge |= temp<<8;
Calc_Distance(Date);
Display(Date);
   Display(Date);
}
 
}
*/
void main()
{
unsigned int count = 0;
Io_Init();
Initial_Timer();
asm("SEI"); //打开全局中断
 
while(1)
{
 
Calc_Distance(Date);
 
count++;
if(count > 100)//产生一次Trig
{
count = 0;
GenerateTrig();
}
 
Display(Date);
}
 
}
 
ISR(TIMER1_OVF_vect)
{
ov_counter++;
}
 
ISR(TIMER1_CAPT_vect)
{
    if(PIN__WAVE_ECHO & (1<< ECHO)) //上升沿
{
TCNT1H = 0;
   TCNT1L = 0;
   TCCR1B &= ~(1<<ICES1); //改为下降沿中断
   ov_counter=0;
 
LED ^= (1<<PE7);
LED |= ~((1<<PE7)|(1<<PE6));
    }
    else //下降沿
{
   falling_edge = ICR1L;
   temp = ICR1H;
   falling_edge |= temp<<8;
   
TCCR1B |= (1<<ICES1);
LED ^= (1<<PE6);
LED |= ~((1<<PE7)|(1<<PE6));
    }
}
 
/*
ISR(TIMER1_CAPT_vect)
{
if(PIN__WAVE_ECHO & (1<< ECHO)) //上升沿
{
rising_edge = ICR1L;
temp = ICR1H;
rising_edge |= temp<<8;
 
TCCR1B &= ~(1<<ICES1); //改为下降沿中断
ov_counter=0;
 
LED ^= (1<<PE7);
LED |= ~((1<<PE7)|(1<<PE6));
}
else //下降沿
{
falling_edge = ICR1L;
temp = ICR1H;
falling_edge |= temp<<8;
 
TCCR1B |= (1<<ICES1);
pulse_clocks = (ulong)falling_edge - (ulong)rising_edge + (ulong)ov_counter*0x10000;
LED ^= (1<<PE6);
LED |= ~((1<<PE7)|(1<<PE6));
}
}
*/

文章评论0条评论)

登录后参与讨论
我要评论
0
15
关闭 站长推荐上一条 /2 下一条