打印
[AVR单片机]

AVR程序求分析

[复制链接]
1776|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
RQren2008|  楼主 | 2013-9-30 01:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
做了一个mega128的程序,主要功能分为两部分:
1.单片机驱动AD9833产生一个正弦波;
2.单片机AD采集一路模拟电压值,上电之后采集的第一个数据作为初始值,当后来采集的数据和初始值的差大于一个阈值是,就把PB口置为高电平;
现在的问题是:
1.如果程序里只有AD9833的程序时,结果是对的,能够驱动芯片产生需要的波形;
2.当加上AD采集程序以后,并口的电平不发生变化了,AD9833的波形也改变不了(波形改变不了实际也是因为并口电平不发生变化,因为AD9833的时序是用PC口给的)
所以求教各位大神,帮忙看一下程序,在此多谢了!
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
  
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define Set_Bit(val, bitn)    (val |=(1<<(bitn)))
#define Clr_Bit(val, bitn)    (val&=~(1<<(bitn)))
void  Wave_Generate(ulong,uchar);
volatile uint data[10];
uint Config_Data[8];
volatile uchar flag_first = 0,flag_over = 0;
volatile uint data_first = 0,data_now = 0,data_cha = 0;
volatile uint count = 0;

void main(void)
{
   DDRB = 0xFF;   
   DDRC = 0xFF;
   PORTB |= 0xFF;
   PORTC=0xFF;
   PORTC &= 0xFD;
   Wave_Generate(1000,1);
   initialize_adc();   
   while(1)
{
//flag_over和flag_first是两个标志位,这两个标志位在SIGNAL(SIG_ADC)中断里改变
    //flag_first意思是第一次采集,把这个数作为初始化的值,flag_over是指一组10个数已经采集完毕
  if(flag_over == 1)
  {
     uchar j;
     uchar k;
     if(flag_first == 1)
  {
           data_now = data[0];
     for(j = 1; j < 10; j++)
     {
             data_now = data_now + data[k];
     }
     data_now = data_now/10;//对10个数取平均
     if (data_now > data_first)//取采集的数和初始化的值的差值
     {
      data_cha = data_now - data_first;
     }
     else
     {
      data_cha = data_first - data_now;
     }
     if (data_cha > 0x14)//判断差值是否大于阈值
     {
    PORTB = 0xFF;  
     }
     else
     {
    PORTB = 0x00;  
     }
  }
  else//如果是第一次采集就把这个值作为初始化值
  {
    data_first = data[0];
    for(k = 1; k < 10; k++)
    {
             data_first = data_first + data[k];
    }
    data_first = data_first/10;
  }
  flag_over = 0;
  }
}
}
void initialize_adc(void)//初始化AD参数
{
     ADMUX=0xc6;//采用内部2.56V参考电压,AD采集口用ADC6
  ADCSR=0xef;
  sei();//打开信号中断
}

SIGNAL(SIG_ADC)//AD采集中断,作用是采集10个数存入一个数组
{
   if (flag_over == 0)
   {
     data[count]=ADC;
     count = count + 1;
       if(count > 9)
     {
        count = 0;
        flag_over = 1;
        flag_first = 1;
     }
}
}
//向ad9833写一命令字(2Bytes)
void AD9833_Send_Word(uint Data_In)
{
    uchar i;
Set_Bit(PORTC, 1);//SCLK=1;
Clr_Bit(PORTC, 0);//FSYNC=0;
    for(i=0;i<16;i++)
    {
       Set_Bit(PORTC, 1);//SCLK=1;
    if(Data_In & 0x8000)
      Set_Bit(PORTC, 2);//SDATA=1;
    else
      Clr_Bit(PORTC, 2);//SDATA=0;
   Clr_Bit(PORTC, 1);//SCLK=0;
       Data_In=Data_In<<1;
    }
Set_Bit(PORTC, 0);//FSYNC=1;
Clr_Bit(PORTC, 1);//SCLK=0;
}
//波形发生函数
//入口参数: 频率:Freq (<=12000000)
//形状:0(正弦波),1(三角波),2(方波)
//默认: Fmclk=25MHz, 0相移,方波不分频.
void  Wave_Generate(ulong Freq,uchar Shape)
{
   ulong temp;
    uchar k;
    if(Freq>12000000) Freq=12000000;
    switch(Shape)
     {
     case 0: Config_Data[0]=0x2108;
             Config_Data[7]=0x2008;
             break;
     case 1: Config_Data[0]=0x210A;
             Config_Data[7]=0x200A;
             break;
     case 2: Config_Data[0]=0x2128;
             Config_Data[7]=0x2028;
             break;
     default:Config_Data[0]=0x2108;
             Config_Data[7]=0x2008;
     }
    temp=Freq*10.73;   //temp=Freq*(0x10000000/20000000);
    Config_Data[1]=temp&0x00003fff;
    Config_Data[3]=Config_Data[1];
    Config_Data[2]=(temp&0x0fffc000)>>14;
    Config_Data[4]=Config_Data[2];
    Config_Data[1]=Config_Data[1]|0x4000;
    Config_Data[2]=Config_Data[2]|0x4000;
    Config_Data[3]=Config_Data[3]|0x8000;
    Config_Data[4]=Config_Data[4]|0x8000;
    Config_Data[5]=0xC000;
    Config_Data[6]=0xE000;
   for(k=0;k<8;k++)
   {
      AD9833_Send_Word(Config_Data[k]);
   }
}

相关帖子

沙发
RQren2008|  楼主 | 2013-9-30 13:00 | 只看该作者
放假没人吗?求大神啊,多谢了!

使用特权

评论回复
板凳
XZL| | 2013-9-30 14:04 | 只看该作者
这种现象多数是中断服务函数出问题了

使用特权

评论回复
地板
XZL| | 2013-9-30 14:05 | 只看该作者
看看中断优先级,定时器中断间隔是否太快导致其它中断多次被打断?

使用特权

评论回复
5
qin552011373| | 2013-10-4 08:38 | 只看该作者
XZL 发表于 2013-9-30 14:05
看看中断优先级,定时器中断间隔是否太快导致其它中断多次被打断?

AVR的中断没有优先级   谁先发生先执行谁的

使用特权

评论回复
6
qin552011373| | 2013-10-4 08:39 | 只看该作者
你程序里有没有用到其他的功能,譬如说定时器

使用特权

评论回复
7
RQren2008|  楼主 | 2013-10-8 21:10 | 只看该作者
qin552011373 发表于 2013-10-4 08:39
你程序里有没有用到其他的功能,譬如说定时器

这个程序是完整的程序,所有的代码都在这了,查了好久还是没查出原因,得求大神多多赐教了

使用特权

评论回复
8
qin552011373| | 2013-10-9 07:02 | 只看该作者
这样子吧   你把你读取到的ADC的值用串口回传给计算机   看看具体的值是多少   大概看程序   没发现什么问题的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

14

主题

67

帖子

1

粉丝