|
小弟最近在做一个简单的任务,需要先测试,用m128 10位 AD 采样,得到数字信号,然后将此信号经过串口发送和接受(自发自收),再将受到的数据送到PWM(10位)的OCR寄存器,以控制PWM的占空比,输出接个低通滤波,到到AD 采样端的原始信号,
一些主要的数据如下,用T0定时 器工作于自动装载的模式,中断频率为64K,在中断中实现 AD 一次采样 并将 数据经后面处理,
现在问题出来了,我的AD采样与 写PWM的OCR寄存器的操作都放在中断里,如果是 直接把AD采样的值送到OCR寄存器中,则 低通滤波器输出的波形很好(输入信号1KHZ),和原始信号一致,但若将采样的数据通过串口自发自收后再写入OCR寄存器中,则输入信号在200HZ以上时输入波形严重失真,输入100 HZ 时输出波形则还不错
我用的是一阶的低通滤波器,R = 1K ,C =0.1uf 截止频率在1KHZ 附近。 pwm的最大频率为16KHZ
一下是部分主要程序,中断里的操作
#pragma vector=TIMER0_COMP_vect
__interrupt void irqHandler(void) //比较中断,AD采样数据 64khz
{
adc_buffer[0] = ADCL; //read ADCL first,or there will be a trouble
dc_buffer[1] = ADCH;
usart_putchar(adc_buffer[1]);
usart_buffer[0] = usart_waitchar( );
usart_putchar(adc_buffer[0]);
usart_buffer[1] = usart_waitchar( );
OCR1AH = usart_buffer[1];
OCR1AL = usart_buffer[0];
// 启动下一次ADC采样
ADCSRA |= (1<<ADSC); //adc sample frequecy is the same as LRclk
}
我尝试过将串口收发程序放在主程序中处理,不见效。
不使用串口收发时收发则输出正常:
#pragma vector=TIMER0_COMP_vect
__interrupt void irqHandler(void) //比较中断,AD采样数据 64khz
{
adc_buffer[0] = ADCL; //read ADCL first,or there will be a trouble
adc_buffer[1] = ADCH;
OCR1AH = adc_buffer[1]
OCR1AL = adc_buffer[0]
// 启动下一次ADC采样
ADCSRA |= (1<<ADSC); //adc sample frequecy is the same as LRclk
}
已排除是滤波器的问题,看来应该就是串口收发的问题了,是不是因为在处理数据的顺序上不合理而导致?
收发均采用轮询方式,参照马老师的程序
void usart_putchar(unsigned char c)
{
while(!(UCSR0A & 0x20));
UDR0 = c;
}
int usart_getchar(void)
{
unsigned char status,res;
if(!(UCSR0A & 0x80)) return -1; //no data to be received
status = UCSR0A;
res = UDR0;
if (status & 0x1c) return -1; // If error, return -1
return res;
}
char usart_waitchar(void) //receive an efficient char from PC
{
int c;
while((c=usart_getchar())==-1);
return (char)c;
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|