本帖最后由 pengzhou91 于 2014-4-6 17:01 编辑
huangxz 发表于 2014-4-6 15:23 
滤波不合适,你建个matlab模型,仿真一下就知道了
#include<iom16v.h> //包含DDR等寄存器
#include<macros.h> //AVR单片机中特有的位指令(BIT)
#include"nRF2401.h"
#pragma interrupt_handler ext_int0_isr:2 //外部中断0
#pragma interrupt_handler ext_int1_isr:3 //外部中断1
#pragma interrupt_handler adc_isr:15 // AD转换结束中断
extern uchar RX_BUF[RX_PLOAD_WIDTH]={0};
unsigned char play_on=0;
uchar byte_count=0;
unsigned char adc_data_H = 0; //ADC采样值
unsigned char SPEED = 0x31;
void interrupt_init(void);
void ext_int0_isr(void);
void ext_int1_isr(void);
void timer0_init(void) //定时器0初始化函数
{
TCCR0 = 0X0A; //CTC模式,8分频,(8MHZ/8=1000kH)的时钟信号
TCNT0 = 0X00; //计数值寄存器,相当于设置计数初值
OCR0 = SPEED;
// OCR0 = 0X31;
// OCR0 = 0X31; //输出比较寄存器,CTC模式下计数上限值,比较匹配中断使能初值
//(49+1)/1000KHZ=0.05ms
}
void timer1_init(void) //定时计数器1的初始化
{
DDRD |= BIT(4) | BIT(5); //PD5脚为输出脚
PORTD &= BIT(4) | BIT(5); //M16的OC1A为输出0电平
TCCR1A=0x00;
TCCR1B=0x00;
TCCR1A |= (1<<COM1A1) | (1<<COM1B1) | (1<<WGM10); //比较匹配时清0,8位快速PWM;T/C1控制寄存器A
TCCR1B |= (1<<WGM12) | (1<<CS10); //无预分频,T/C1控制寄存器B
// OCR1A = 0x007F; //16位寄存器,输出比较寄存器1A-OCR1A
}
void adc_init(void) //---->ADC初始化
{
DDRA &= ~BIT(0); //输入方式
PORTA &= ~BIT(0); //不带上拉
ADMUX = 0X60; //AVCC ADC结果左对齐,选择通道ADC0
SFIOR &= 0x1F;
SFIOR |= 0x60; //选择T/C0比较匹配中断为ADC触发源
ADCSRA = 0XAB; //ADC使能,ADC自动转换触发8分频,允许ADC中断
}
//adc中断程序,最高采样率;为了保持与发射端相同频率,在此处理数据;
void adc_isr(void) //ADC中断函数
{
adc_data_H = ADCH;
if(play_on)
{
DDRD |= (1<<PD4);
OCR1A = RX_BUF[byte_count];
//PORTC = RX_BUF[byte_count];
RX_BUF[byte_count]=0;
byte_count++;
if (byte_count == 32)
{
byte_count = 0;
play_on = 0;
}
}
else//没有收到数据则关闭pwm
{
DDRD &= ~(1<<PD4);//没有数据时设置为输入,防止产生高频噪声;
}
OCR1B = adc_data_H;
TIFR = TIFR;//清除T/C0中断标志
ADCSRA |= (1<<ADIF);//清除ADC中断
}
int main(void)
{
DDRC = 0xFF;
PORTC = 0xFF;
init_NRF24L01();
SetRX_Mode();//设置为接收模式
interrupt_init();//外部中断
timer0_init();
timer1_init();
adc_init();
SREG |= BIT(7); //使能全局中断
while(1)
{
sta = SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况;
if(RX_DR) // 判断是否接收到数据RX_DR==1?
{
Low_24L01_CE; //SPI使能
SPI_Read_Buf(RD_RX_PLOAD,RX_BUF,TX_PLOAD_WIDTH);// 读取接收数据;
SPI_RW_Reg(WRITE_REG + STATUS, sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志
play_on = 1;
}
Hign_24L01_CE;//接收模式
}
return 0;
}
void interrupt_init(void)//中断初始化
{
MCUCR |= (1<<ISC11) | (1<<ISC01);//设置为下降沿触发
GICR |= (1<<INT0) | (1<<INT1);//使能外部中断
}
void ext_int0_isr(void)
{
SPEED++;
OCR0 = SPEED;
GIFR |= (1<<INTF0);
}
void ext_int1_isr(void)
{
SPEED--;
OCR0 = SPEED;
GIFR |= (1<<INTF1);
}
这是我主函数的程序,从PD5输出PWM波,还原声音,但是为什么还要设置PD4呢
|