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条评论)
登录后参与讨论