新闻  |   论坛  |   博客  |   在线研讨会
FC-1脉冲发生器 程序 技术指标
0750long | 2009-04-05 16:53:01    阅读:1776   发布文章

FC-1脉冲发生器 程序 技术指标

 

点击开大图点击开大图

点击开大图

点击开大图

 

 

//ICC-AVR application builder : 2008-6-29 16:23:43
// Target : M16
// Crystal: 10.0000Mhz

#include <iom16v.h>
#include <macros.h>
#include <eeprom.h>
#define uchar unsigned char
#define uint unsigned int
#define ulon unsigned long
unsigned char num[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
 0x6f,0x77,0x7c,0x39,0x5e,0x7b,0x71,0x00,0x40}; //0-f
unsigned char num_p[] = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //0.-9.
uchar k_fuction=0;//加减标志
uint add_dec;//增减变量
uchar lu_shu=1;//路数变量
uchar f02_flag,f03_flag,f04_flag;//增加显示变量
uchar flag_jiange,jiange_begin;//开始,间隔标志
uchar time_start_end;//循环标志
uint start,end,jiange,lushu;  //参数EEPROM保存
uint key,star_prior;//键盘数值
uchar light_flag=0;//定义小灯启动停止状态闪烁标志
uchar start_end_flag=0;//手动自动,待机切换
uchar count,count1;//小灯闪烁取反计数,//每隔6秒技术
uint time,count_01min;//开始0.1s时间,0.6s=0.1分时间到标志,
//延时1ms
void delay(uint ms)
{
        uint i,j;
 for(i=0;i<ms;i++)
    {
    for(j=0;j<1141;j++);
       }
}
void port_init(void)//端口初始化,ad口做初始化为高电平输出口
{
 PORTA = 0xff;
 DDRA  = 0xff;
 PORTB = 0xff;
 DDRB  = 0xFF;
 DDRC  = 0x00;//输入口
 DDRC|=BIT(2);//小灯指示口,仿真模式要取消,否则带不动
 PORTC = 0xff;
 PORTD = 0xff;
 DDRD  = 0xff;
}
//TIMER1 initialize - prescale:256//内部晶振不准确,采用外部10M晶振
// WGM: 0) Normal, TOP="0xFFFF"
// desired value: 10Hz
// actual value: 10.000Hz (0.0%)
void timer1_init(void)
{
 TCCR1B = 0x00; //stop
 TCNT1H = 0xC2; //setup
 TCNT1L = 0xF7;
 OCR1AH = 0x3D;
 OCR1AL = 0x09;
 OCR1BH = 0x3D;
 OCR1BL = 0x09;
 ICR1H  = 0x3D;
 ICR1L  = 0x09;
 TCCR1A = 0x00;
 TCCR1B = 0x03; //start Timer
}
///定时器1中断,因为10hz进入一次中断,且考虑到脉冲准确性,做的比较大
#pragma interrupt_handler timer1_ovf_isr:iv_TIM1_OVF
void timer1_ovf_isr(void)
{
 //TIMER1 has overflowed
  TCNT1H = 0xC2; //setup
  TCNT1L = 0xF7;
 count++;
 count1++;
 time++; 
 
  if(count>=3)
  {
   count="0";
   light_flag=~light_flag;
   if(start_end_flag!=1)
     {
     if(light_flag)
     PORTC&=~BIT(2);
     else PORTC|=BIT(2);//利用定时器实现运行灯闪烁。
     }//if
   }//if count3
  if(count1>=60)
  {
  count1=0;
  count_01min++;
  } //if count1
switch(time_start_end)
 {
 case 0x01://初始化定时器,准备发送
 step1:
 time=0;
    if(lu_shu<=8)
      PORTA&=~BIT(lu_shu-1);//第一路输出高电平
    else
      PORTD&=~BIT(lu_shu-9);//第一路输出高电平
    time_start_end=02;//状态机
 f02_flag=0;
 break;
 case 0x02:
      if (time>=start)//查询脉冲高电平时间,并计时显示
      {
      PORTA="0Xff";//与设定时间比较,高电平时间到,初始化低电平计数
      PORTD="0Xff";
   time_start_end=0x03;
      count_01min=0;count1=0;
   if(f02_flag==0)
   f02_flag=1;
   } //end if
   f03_flag=0;
      break;
 case 0x03:    //低电平时间计数,计数时间到清零分技术标志
    if(count_01min>=end)
    {
  if(f03_flag==0)
    f03_flag=1;//第一次低电平时间结束,显示要显示结束数值,
   if(lu_shu<lushu)//没有结束循环,则立马发送
   {
    lu_shu++;
    goto step1;
    }//if
  else   //间隔时间技术开始,清零所有的计数标志,开始计数
   {
    time_start_end=0X04;
    count_01min=0;
     count1=0;
       lu_shu=0;
    f04_flag=0;
   }//else
   }//if
    break;
case 0x04:
 if(count_01min>=jiange)//如果间隔计数数值到,则立马再次重新发送
   {
    if(f04_flag==0)
  f04_flag=1;
  lu_shu=1;
  goto step1;
   }
   break;
default:break;
 }//switch*/
} //end time interupt

////////////////////////////
//SPI initialize
// clock rate: 31250hz
void spi_init(void)
{
 SPCR = 0x50; //setup SPI
 SPSR = 0x01; //setup SPI
}
void spi_send(uchar dd)
    {
      SPDR="dd";
      while(0==(SPSR&0X80));
   SPSR&=0X7f;
   WDR ();
    }
//call this routine to initialize all peripherals
void init_devices(void)
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 port_init();
 spi_init();
 timer1_init();
 MCUCR = 0x00;
 GICR  = 0x00;
 TIMSK = 0x04; //timer interrupt sources
 SEI(); //re-enable interrupts
 //all peripherals are now initialized
}

//eeprom写
void eeprom_write(uchar address,ulon i )//eeprom write
{
 EEPROM_WRITE(address,i);
  WDR();
  SEI();
}
//eeprom读
unsigned long eeprom_read(uchar address1)
{
unsigned long i;

EEPROM_READ(address1,i);          //eepromread
WDR();
return i;
 }
//根据key fuction数值读取相应的eeprom数据
uint eeprom_fuc_read(void)
{  uint value;
   if(k_fuction==1)
  value="eeprom"_read(0x10);
  else if(k_fuction==2)
  value="eeprom"_read(0x20);
  else if(k_fuction==3)
  value="eeprom"_read(0x30);
  else if(k_fuction==4)
  value="eeprom"_read(0x40);
  else if(k_fuction==5)
  value="eeprom"_read(0x50);
  return value;
}
//根据key fuction数值读取相应的eeprom数据
void eeprom_fuc_write(ulon key1)

   if(k_fuction==1)
  eeprom_write(0x10,key1);
  else if(k_fuction==2)
  eeprom_write(0x20,key1);
  else if(k_fuction==3)
  eeprom_write(0x30,key1);
  else if(k_fuction==4)
  eeprom_write(0x40,key1);
  else if(k_fuction==5)
  eeprom_write(0x50,key1);

}
//数码管显示不带点函数
void show_led(uchar data,uchar wei)
{
   switch (wei)
  {
   case 1: PORTB&=0Xf7;break;
   case 2:PORTB&=0Xfb;break;
   case 3:PORTB&=0Xfd;break;
   case 4:PORTB&=0Xfe;break;
   default:break;
   }
 
   PORTB&=~BIT(4);
  PORTB|=BIT(4);
  spi_send(num[data]);
  delay(2);
  PORTB|=0X0f;
  PORTB&=~BIT(4);
  PORTB|=BIT(4);
}
//数码管显示带点函数
void show_led_point(uchar data,uchar wei)
{
   switch (wei)
  {
   case 1: PORTB&=0Xf7;break;
   case 2:PORTB&=0Xfb;break;
   case 3:PORTB&=0Xfd;break;
   case 4:PORTB&=0Xfe;break;
   default:break;
   }
  PORTB&=~BIT(4);
  PORTB|=BIT(4);
  spi_send(num_p[data]);
  delay(2);
  PORTB|=0X0f;
  PORTB&=~BIT(4);
  PORTB|=BIT(4);
}

//主功能中第一位闪烁
void light_1(uchar lu_date)
{
 if(light_flag)
 show_led(lu_date,4);
 else
 show_led(16,4);
}
void show_avr(void)
{
   show_led(k_fuction,4);
     show_led(16,3);
     show_led(16,2);
     show_led(16,1);
}
////////////////根据数据的位数,显示数码管的闪烁状态
void show_led_flash(void)
{
 uchar i,j;
 uint data;
 if(light_flag==0)//定时器闪烁数据显示
 {
  if(k_fuction!=0)
  show_avr();
 }//if 
 else
 {
  data="key";
  if(k_fuction!=0)//显示功能键数值,不显示0
  {
  show_led(k_fuction,4);
  if(data>=100)//是否显示第三位
  show_led(data/100,3);
 
  if((k_fuction==4)|(k_fuction==5))//如果功能键第5次按下,不显示点
  show_led((data%100/10),2);
  else show_led_point((data%100/10),2);//其余功能键值第二位显示点
  show_led(data%10,1);
  }//if
 }//else  
}//end show


///////加减键检测
void key_add_dec(void)
 {
  uchar m,n;
  if((PINC&0X80)!=0X80)
   {
     for(m=0;m<12;m++)
  show_avr();//延时去抖动,并且显示路数
  if((PINC&0X80)!=0X80)
  key++;
  if((k_fuction==4)|(k_fuction==5))//4,5功能键不能超过16
   {
    if(key>16)
    key="0";
   }
  if(key>999) //功能键最大为999
  key="0";//循环显示作为一个延时,防止按键加的过快
  for(m=0;m<30;m++)
  {
   show_led(k_fuction,4);
   if((key/100)!=0)//判断是否显示第三位
   show_led(key/100,3);
  
      if((k_fuction!=4)&(k_fuction!=5))//4,5功能不显示带点的,
      show_led_point(key/10%10,2);
   else
   show_led(key/10%10,2);//其余第二位显示带点
   
      show_led(key%10,1);
  }//for 
  }// end if add
  /////////////////////
 if((PINC&0X01)!=0X01)//判断减按下
   {
  for(n=0;n<12;n++)//延时去抖动,并且显示路数
  show_avr();
  if((PINC&0X01)!=0X01)
  {
   if((k_fuction==4)|(k_fuction==5))
   {
    key--;
    if(key==65535)
    key="16";
   }//if
  else
   { 
    key--;
    if(key==65535)
    key="999";
      }//else
 }//end if
 /////////////////////
    for(m=0;m<30;m++)//延时防止减的过快
  {
   show_led(k_fuction,4);
   if((key/100)!=0)
   show_led(key/100,3);
   if((k_fuction!=4)&(k_fuction!=5))
      show_led_point(key/10%10,2);//4,5功能键不显示带点
   else
   show_led(key/10%10,2);//其余功能键显示带点
  
      show_led(key%10,1);
  }//end for 
   }//end if dec
 }//end key_add_dec

////////////功能键检测
void key_scan(void)
{
  if((PINC&0X02)!=0X02)
   {
  delay(5);
  if((PINC&0X02)!=0X02)
  k_fuction++;
  if(k_fuction>5)
  k_fuction=0;
 while((PINC&0X02)!=0X02);//等待按键抬起
 
   }  
}

////////////////////////启动停止键检测功能函数
void start_end(void)
{
  if((k_fuction==0)|(k_fuction==5))//只有在0,5功能下才可以进入启动健
 {
   if((PINC&0X40)!=0X40)
    {
   delay(2);//延时去抖动
   if((PINC&0X40)!=0X40)
     {
    while((PINC&0X40)!=0X40);//等待键抬起
    start_end_flag++;//数据处理
    time_start_end=0;//初始化数据,构成循环
     TCCR1B = 0x03; //stop
  } //if
 }//if
 }//if
}//end


/////////手动模式处理
void shou_dong(void)
{
    
     while(k_fuction==5)//手动循环
     {
    TCCR1B = 0x00; //stop,不闪烁
    if(start_end_flag!=1)
    key_scan();//查询功能键是否按下,按下则k_fuction=0;跳出循环
    if(k_fuction==0)//如果跳出循环则回复为待机状态
       {start_end_flag=0;TCCR1B=0x03;}
    else
     {
        if(start_end_flag==1)//启动输出高电平
        {
         PORTC&=~BIT(2);//置1工作,因加光耦,实际置0
         if((key<=8)&&(key>=1))
         PORTA&=~BIT(key-1);//第一路输出高电平
               else if ((key>=8)&&(key<=16))
               PORTD&=~BIT(key-9);//第一路输出高电平
     }
    
     start_end();//检测启动
    
    /////////////////////////////////////////
        if(start_end_flag==2)//停止,输出经光耦低电平
        {
         TCCR1B = 0x03; //启动定时器,闪烁状态,并可调按键
         key_add_dec();//仅停止时候可以检测增加键
         PORTA="0Xff";//与设定时间比较,停止
               PORTD="0Xff";
     }//if
     ///////////////////////////////////////
     if(start_end_flag==3)//停止后又马上启动
     start_end_flag=1;
     /////////////////////////////////////
      if(start_end_flag!=2)
      {
      show_led(key%10,1);
         show_led(key/10,2);
         show_led(16,3);
         show_led(5,4);
      }//end if
      else
      {
       if(light_flag==0)//定时器闪烁数据显示
    
       {
    show_led(key%10,1);
          show_led(key/10,2);
          show_led(16,3);
          show_led(5,4);
       }//if
       else
       {
     show_led(16,1);
          show_led(16,2);
          show_led(16,3);
          show_led(5,4);
       }//else
      }//end if
     
   }//else
    }//while
   
}//shou_dong
///////////////////////////////

//待机状态下功能键盘处理函数
void key_function(void)

 ulon i,j,k;
    key_scan();
 if(k_fuction!=0)//在待机状态,加减不起作用,其余功能键下,健起作用
 key_add_dec();
 switch  (k_fuction)
  { 
  case 0:k=k_fuction;
      show_led(15,4);show_led(12,3);
      show_led(17,2);show_led(1,1);break;
  case 1:
  if(k!=k_fuction)
  {
  key=start;k=k_fuction;
  }
  show_led_flash();break;
  
  case 2:
  if(k!=k_fuction)
  {
  eeprom_write(0x10,key);
  start=key;
  k=k_fuction;
  key=end;
  }
  show_led_flash();break;
  
  case 3:
  if(k!=k_fuction)
  {
  eeprom_write(0x20,key);
  end=key;
  k=k_fuction;
  key=jiange;
  }
  show_led_flash(); break;
  
  case 4:
  if(k!=k_fuction)
  {
  eeprom_write(0x30,key);
  jiange=key;
  k=k_fuction;
  key=lushu;
  }
  show_led_flash(); break;
  
  case 5:
  if(k!=k_fuction)
  {
  eeprom_write(0x40,key);
  lushu=key;
  k=k_fuction;
  key=0;
  }
  show_led_flash();
   break;
  default:break;
  } 
}//只有按键回复到待机状态和5状态可以存储,否则不能存储

void show_pulse(void) //自动运行时,显示状态
{   uchar q;
    PORTC&=~BIT(2);//点亮灯指示运行
 /////////////////////////////////////////
 if(lu_shu==16)
 lu_shu=17;
 if(time_start_end==0x00)//第一次按键启动
   {  
 time_start_end=0x01;time=0;
   }//end if
 //////////////////////////////////////////////////////
     if(f03_flag==1)
     {
       for(q=80;q>0;q--)
       {
        show_led_point(end/10%10,2);
        show_led(end%10,1);
        if(end/100)//是否显示第3wei
        show_led(end/100,3);
       }//for
       f03_flag=2;
     }//if
  ////////////////////////
  if(f04_flag==1)//如果间隔时间到,要显示完整间隔时间
   { for(q=80;q>0;q--)
        {
         show_led_point(jiange/10%10,2);
         show_led(jiange%10,1);
         if(jiange/100)//是否显示第3wei
         show_led(jiange/100,3);
        }
     f04_flag=2;
   }
 ///////////////////////////////////////////
 if(time_start_end==0x02)//显示time高电平时间计数
 {
   light_1(lu_shu);//第一位数码管闪烁        
   show_led_point(time/10%10,2);
   show_led(time%10,1);
   if(time/100)//是否显示第3wei
   show_led(time/100,3);
 }//end if;
 
  if(f02_flag==1)//如果正好在沿上,则要显示完整之后显示0
 {
   for(q=80;q>0;q--)
   {
   show_led_point(start/10%10,2);
   show_led(start%10,1);
   if(time/100)//是否显示第3wei
   show_led(start/100,3);
   }
   f02_flag=2;
 }
 //////////////////////////////////////////
 if(time_start_end==0x03)//显示低电平count_01min时间计数
 {

 light_1(lu_shu);//第一位数码管闪烁        
 if(count_01min/100)//是否显示第3wei
 show_led(count_01min/100,3);
 show_led_point(count_01min/10%10,2);
 show_led(count_01min%10,1);

 }
 if(time_start_end==0x04)//显示间隔循环时间
 {
 light_1(lu_shu);//第一位数码管闪烁        
 if(count_01min/100)//是否显示第3wei
 show_led(count_01min/100,3);
 show_led_point(count_01min/10%10,2);
 show_led(count_01min%10,1);
 }//end if
}//end show_pulse


void main(void)
{  uchar i;
  uint end1,jiange1,lushu1;
   init_devices();
  /*/////////////////////////////////////验证使用,已经生成EEPROM文件
  eeprom_write(0x10,10);//写功能键1下初始化数值
  eeprom_write(0x20,1);//写功能键2下初始化数值
  eeprom_write(0x30,1);//写功能键3下初始化数值
  eeprom_write(0x40,2);//写功能键4下初始化数值
  eeprom_write(0x50,0);//写功能键4下初始化数值
  ///////////////////////////////////*/
  start="eeprom"_read(0x10);
  end="eeprom"_read(0x20);
  jiange="eeprom"_read(0x30);
  lushu="eeprom"_read(0x40);
  while(1)
  {
   start_end();     //检测启动按键
   if(start_end_flag==1)   //启动 (下面进行手动自动选择) 
   {
    if(k_fuction==0)
    show_pulse();         //自动循环启动脉冲
    else if(k_fuction==5) //手动启动1路脉冲函数
    {shou_dong();
  
    }
   } 
   else if(start_end_flag==2)//停止脉冲过程,显示待机状态
   {start_end_flag=0;lu_shu=1;}
   else
   key_function();      //start_end_flag=0;待机状态下调整参数函数*/
  }//while(1)
 
}//main

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客