| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4326 人关注过本帖
标题:各位达人,有个 AVR 单片机的问题,想求教一下,麻烦啦。
只看楼主 加入收藏
sol2010
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2012-2-27
收藏
 问题点数:0 回复次数:0 
各位达人,有个 AVR 单片机的问题,想求教一下,麻烦啦。

    我最近在做一个案子,就是利用TCS3200 检测 LED 的颜色,TCS3200 检测到不同的颜色会输出不同的频率,也就利用单片的 做一个检测频率的程序,我已经利用51单片机初步实现频率检测的程序,但是51能检测的最大频率为:30~40 KHz,不能满足更高 频率的测量要求,所以我就选用 AVR 单片机(ATMEGA8L)来做,算法也是参照51写的,一个测量过程的算法是这样:配置 AVR 单 片的 INTO 的中断方式为上升沿触发,中断程序中有个计数器,第一次触发时,打开定时器1(定时器1用的是16位的计数方式)开 始 50ms 的定时, 中断每触发一次,计数器加1,直到50ms定时中断到了,关闭 INT0 和定时器1 ,然后调用数据处理函数,根据 计数器的值算出检测到的频率值。可是 AVR 单片机在运行的时候程序好像跑飞了一样,一个测量过程,定时器1好像中断了好几次 ,我分析了一下,应该是中断嵌套的时候出错了,我做了一些修正算法,但是程序还是不能正常的运行测量。我附上我写的程序,请各位达人,帮我看看,谢谢啦!
程序:
#include <iom8v.h>
#include <macros.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#define uint unsigned int
#define ulint unsigned long int
#define uchar unsigned char
#define Led_ON    PORTB &= ~BIT(PB1)
#define Led_OFF   PORTB |= BIT(PB1)
#define Beep_ON   PORTB |= BIT(PB2)
#define Beep_OFF  PORTB &= ~BIT(PB2)

#define S0_ON     PORTC |= BIT(PC0)
#define S0_OFF    PORTC &= ~BIT(PC0)
#define S1_ON     PORTC |= BIT(PC1)
#define S1_OFF    PORTC &= ~BIT(PC1)
#define S2_ON     PORTC |= BIT(PC2)
#define S2_OFF    PORTC &= ~BIT(PC2)
#define S3_ON     PORTC |= BIT(PC3)
#define S3_OFF    PORTC &= ~BIT(PC3)
// low effectiv
#define OE_ON     PORTD |= BIT(PD6)
#define OE_OFF    PORTD &= ~BIT(PD6)     

void Init();
void InitUART();
void InitTC1();
void InitINT0();
void delayms(uint z);
void Receive(uchar rbuf);
void SendChar(uchar TempBuf);
void SendString(const uchar *AddressPointer);
void AnalysisCommand();
void DisposeValue(ulint temp_data);
void ShowValue(uchar *p , signed char j);
void TestRed();
void TestBlue();
void TestGreen();
void TestClear();
void TestAll();

ulint count = 0 ;
uchar TimerONFlag ;
uchar ConvertFlag ;
uchar TestAllFlag ;
const uchar  waittime=15;
const uchar CommandPrompt[]={"Command error , please check ! "};

struct
{
    uchar  index ;
    uchar  index_end;
    uchar  r_flag_end1;
    uchar  r_flag_end2;
    uchar  comm_infor[20];
} Receive_command={0,19,0,0,{0}};

void main()
{
   
   Init();
   delayms(2000);
   SendString("Color Test ! \r");
   SendString("Begin ...");
   SendChar('\r');
   while(1)
     {
            
               TestRed();
              while(ConvertFlag==0);
              delayms(2000);        
     }
}

void Init()
{
    DDRD &= ~BIT(PD0) + ~BIT(PD2) ;      // set PD0, PD2  as input      RXD ,INT0
    DDRD |=BIT(PD1)+ BIT(PD6);              // set  PD1, PD6(OE) as output     TXD
    DDRB |= BIT(PB1) + BIT(PB2) ;  // set PB1 , PB2 as output
    DDRC |= BIT(PC0) + BIT(PC1) + BIT(PC2) + BIT(PC3) + BIT(PC4) + BIT(PC5) ;  // PC0--PC5,(S0--S3) as output
   
    TimerONFlag=0 ;     // not open Timer
   
    CLI();                  // clear global interrupt
   
    InitUART();
    InitTC1();
    InitINT0();
    S0_ON;                    // 100% output
    S1_ON;
      
    SEI();                       // set global interrupt
}

void InitUART()
{
     UCSRA = 0X00 ;
     UCSRB = 0X00 ;
     UCSRC = 0X00 ;                                   // control register clear
     UCSRA |= BIT(UDRE) ;                             // data buf empty  , could receive data
     UCSRB |= BIT(RXCIE) + BIT(RXEN) + BIT(TXEN);     // enable RXB interrupt
     UCSRC |= BIT(URSEL) + BIT(UCSZ1)+ BIT(UCSZ0);    // SET 1
     UBRR=0x2F;                                       // baud=9600  7.3728 Mhz    U2X = 0
}

void InitTC1()
{
      TCCR1A &= ~BIT(WGM11) + ~BIT(WGM10);
     TCCR1B &= ~BIT(WGM12) + ~BIT(WGM13) +  ~BIT(CS10) + ~BIT(CS12) ;
     TCCR1B |=  BIT(CS11);                // 8 divide frequency , usual mode  
     TCNT1 = 0X4BFF ;                    // 50ms
}

void InitINT0()
{
      MCUCR |= BIT(ISC01) + BIT(ISC00) ;     // INT0 rise edge trigger
}

void TestRed()
{
    S2_OFF;
    S3_OFF;
    OE_OFF;
    delayms(waittime);
    ConvertFlag=0;
    SendString("R :");
    GICR |= BIT(INT0);                    // enable INT0
}
void TestBlue()
{
    S2_OFF;
    S3_ON;
    OE_OFF;
    delayms(waittime);
    ConvertFlag=0;
    SendString("B :");
    GICR |= BIT(INT0);                     // enable INT0
}
void TestGreen()
{
    S2_ON;
    S3_ON;
    OE_OFF;
    delayms(waittime);
    ConvertFlag=0;
    SendString("G :");
    GICR |= BIT(INT0);                            // enable INT0
}

void TestClear()
{
    S2_ON;
    S3_OFF;
    OE_OFF;
    delayms(waittime);
    ConvertFlag=0;
    SendString("I :");
    GICR |= BIT(INT0);                            // enable INT0
}

void TestAll()
{
    TestRed();
    while(ConvertFlag==0);
    TestGreen();
    while(ConvertFlag==0);
    TestBlue();
    while(ConvertFlag==0);
    TestClear();
    while(ConvertFlag==0);
}

void SendChar(uchar TempBuf)
{      
    UCSRB &= ~BIT(RXCIE) ;               // unable RXB interrupt?
    UDR = TempBuf ;
    while((UCSRA & BIT(TXC))==0);  
    UCSRA &= ~BIT(TXC) ;               // clear flag bit
    UCSRB |= BIT(RXCIE) ;              // enable RXB interrupt
}

void SendString(const uchar *AddressPointer)
{
    UCSRB &= ~BIT(RXCIE);                       // unable RXB interrupt
    while('\0' != *AddressPointer )
        {
            UDR = *AddressPointer;
            while((UCSRA & BIT(TXC))==0);       //  waiting  send finish            
            UCSRA |= BIT(TXC);                  // send finish flag  set 0
            AddressPointer++;
        }
    UCSRB |= BIT(RXCIE);                      // enable RXB interrupt   
}

void AnalysisCommand()
{
    uchar i;
    if((0==(strcmp( Receive_ ,"on"))) || (0==(strcmp( Receive_ ,"ON"))))
          {   
            Led_ON;
            Beep_ON;
            SendString("Led ON");
            SendChar('\r');
        }
       else if((0==(strcmp( Receive_ ,"off")))||(0==(strcmp( Receive_ ,"OFF"))))
           {   
           Led_OFF;
           Beep_OFF;
           SendString("Led OFF");
           SendChar('\r');
        }
       else
          {
            SendString(CommandPrompt);
            for(i=0;i<Receive_command.index;i++)
                Receive_[i]='\0';
              Receive_command.index=0;
            return ;   
        }
    for(i=0;i<Receive_command.index;i++)
        Receive_[i]='\0';
    Receive_command.index=0;
}

void Receive(uchar rbuf )
{
    uchar i;
     uchar r_flag=0;
     if((13==rbuf)||(10==rbuf))
         {
            if(13==rbuf)
             Receive_command.r_flag_end1=1;
          if(10==rbuf)
             Receive_command.r_flag_end2=1;
          r_flag= (1==Receive_command.r_flag_end1) && (1==Receive_command.r_flag_end2);
          if(1==r_flag)
            {
                Receive_command.r_flag_end1=0;
                Receive_command.r_flag_end2=0;
                AnalysisCommand();
            }            
       }
    else
       {
               if((1==Receive_command.r_flag_end1)||(1==Receive_command.r_flag_end2))
                 {
                    Receive_command.r_flag_end1=0;
                 Receive_command.r_flag_end2=0;
                 for(i=0;i<Receive_command.index;i++)
                     Receive_[i]='\0';
                 Receive_command.index=0;                                        // count set 0            
              }   
           Receive_[Receive_command.index]=rbuf;
           Receive_command.index++ ;
           if(Receive_command.index>=Receive_command.index_end)         // avoid array overflow
              {
                  for(i=0;i<Receive_command.index;i++)
                       Receive_[i]=0;
                  Receive_command.index=0;  
              }   
       }
}

void DisposeValue(ulint temp_data)
{
    uchar value[20]={0};  
       signed char i=0;
    if(temp_data==0)
        {
            if(TestAllFlag)
                 SendString("Light is Weak , Please check! ");
             else
                 SendString("Light is Weak , Please check! \r ");
            count=0;   
            ConvertFlag=1;
            return ;
        }   
//    temp_data=temp_data*100;                         //  calculate  frequency     time 10ms
    temp_data=temp_data*20;                            // time 50ms   100% output , Hz
       while(temp_data!=0)
           {
             value[i]=temp_data % 10;
            temp_data=temp_data / 10;
            i++;
        }
       ShowValue(&value[0],i-1);
}

void ShowValue(uchar *p , signed char j)
{
    while(j>=0)
      {
         SendChar(0x30+(*(p+j)));
         if(j==3)
             SendChar('.');   
         j=j-1;
      }
     if(TestAllFlag)
         SendString("  KHz  ");
     else
         SendString("  KHz  \r");
     count=0;     
     ConvertFlag=1;
}

/************************ delayms *****************************************/
void delayms(uint z)
{   
    uint i,j;
      for(i=1;i<z;i++)
      for(j=1;j<(uint)(7.3728*143-2);j++);     // 7.3728 Mhz
}
/************************ interrupt *************************************/
#pragma interrupt_handler Int0: 2  
void Int0(void)
{   
     TimerONFlag=1;
     GIFR |= BIT(INTF0);         // write "1" , clear interrupt  flag bit
     SEI();                     // set global interrupt
       count++;                  // counter rise edge
     if(TimerONFlag)
        TIMSK |= BIT(TOIE1);    // open timer1
}

#pragma interrupt_handler TC1COMPA: 7  
void TC1COMPA(void)
{
    GICR &= ~BIT(INT0);                    // unable INT0
    GIFR |= BIT(INTF0);                   // write "1" ,clear interrupt  flag bit
   
    TIMSK &= ~BIT(TOIE1);                 // unable TC1
    TIFR |= BIT(TOV1);                   // write "1" ,clear interrupt  flag bit
   
    TCNT1 = 0X4BFF ;                     // 50 ms
    TimerONFlag=0;                      // clear flag            
    DisposeValue(count-1);
}

#pragma interrupt_handler UARTReceive: 12  
void UARTReceive(void)
{
      Receive(UDR);
}
搜索更多相关主题的帖子: 频率 单片 
2012-07-13 23:49
快速回复:各位达人,有个 AVR 单片机的问题,想求教一下,麻烦啦。
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.018318 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved