分享

CD纹机控制器单片机程序

 共同成长888 2015-07-19

CD纹机控制器单片机程序 

 ////////////////////////////////////////////////////////////////////////////////
////环境:编译为ICCAVR 6.25A
////单片机:ATMEGA 8A
////日期:2014年2月11日 
////功能:CD纹机控制器
////作者:夜猫子(QQ610027265)
////晶振:外部有源晶振,主频10M
////备注:适合用于 恒源隆的CD纹机的自动控制
////////////////////////////////////////////////////////////////////////////////
//包含头文件////////////////////////////////////////////////////////////////////
#include<iom16v.h>
#include<macros.h>
//定义数据类型//////////////////////////////////////////////////////////////////
#define uchar unsigned char
#define uint unsigned int
//定义输出io口//////////////////////////////////////////////////////////////////
#define Y1_OUT DDRC|=BIT(5);
#define Y1_H PORTC|=BIT(5);   
#define Y1_L PORTC&=~BIT(5);
#define Y2_OUT DDRD|=BIT(6);
#define Y2_H PORTD|=BIT(6);   
#define Y2_L PORTD&=~BIT(6);  
#define Y3_OUT DDRD|=BIT(7);
#define Y3_H PORTD|=BIT(7);   
#define Y3_L PORTD&=~BIT(7); 
#define Y4_OUT DDRB|=BIT(0);
#define Y4_H PORTB|=BIT(0);   
#define Y4_L PORTB&=~BIT(0); 
#define Y5_OUT DDRC|=BIT(4);
#define Y5_H PORTC|=BIT(4);   
#define Y5_L PORTC&=~BIT(4); 
#define Y6_OUT DDRB|=BIT(1);
#define Y6_H PORTB|=BIT(1);   
#define Y6_L PORTB&=~BIT(1); 
//ad求平均的个数(N的值越大ad越准)///////////////////////////////////////////////
#define N  3  
//数码管亮度调节0x00-0xff
#define P  0x01 
//定时器的初值//////////////////////////////////////////////////////////////////
#define TEMERH  0xf0
#define TEMERL  0x00 
//全局变量//////////////////////////////////////////////////////////////////////
 uint  addata,adc,i,q=1,t1,t2,t3,tt1,tt2,tt3;
 uchar g1,g2,g3;
//io初始化//////////////////////////////////////////////////////////////////////
void port_init()
{
   DDRC&=BIT(0)&BIT(1)&BIT(2)&BIT(3); //AD转换口设置为输入
   PORTC&=BIT(0)&BIT(1)&BIT(2)&BIT(3);   //AD转换口设置为无上拉
     
   DDRD|=0x3f;
   PORTD|=0x3f;          //配置PD口为输入,有上拉电阻
   DDRD&=0xC0;
   
   Y1_H;Y2_H;Y3_H;Y4_H;Y5_H;Y6_H;              //输出为高电平
   Y1_OUT;Y2_OUT;Y3_OUT;Y4_OUT;Y5_OUT;Y6_OUT;  //配置成输出
  
}
//spi初始化/////////////////////////////////////////////////////////////////////
void spi_init()
{
        DDRB|=BIT(2)|BIT(3)|BIT(5);//置spi数据口为输出
        SPCR=0x51;
        PORTB|=BIT(2);
        SPSR&=0x7f;
}
//初始化max7219数码管模块////////////////////////////////////////////////////////
void initmax7219()
{
        spi_init();
        max7219(0x0c,0x00);   //掉电模式:0,普通模式:1
        max7219(0x09,0xff);   //译码方式:BCD码
        max7219(0x0a,P);      //亮度调节
        max7219(0x0b,0x07);   //扫描界限;4个数码管显示
        max7219(0x0c,0x01);   //掉电模式:0,普通模式:1
        max7219(0x0f,0x00);   //显示测试:1;测试结束,正常显示:0
max7219(3,10); max7219(6,10); //显示横杠
        delay_ms(2);
}
//定时器1初始化子程序///////////////////////////////////////////////////////////
void init_timer1()
{
  TCCR1B|=0x04;//256分频
  TCNT1H=TEMERH;//高8位初值
  TCNT1L=TEMERL;//低8位初值
  TIMSK|=BIT(2);//定时器1的中断使能
}
//延时函数//////////////////////////////////////////////////////////////////////
void delay_ms(uint i)
{
    while(i--)
    {                          
   uint j;                
        for(j=1;j<=1332;j++);               
    } 
}
//向max7219写入地址和数据///////////////////////////////////////////////////////
void max7219(uchar add,uchar date)
{
  PORTB&=~BIT(2);
  SPDR=add;
  while(!(SPSR&0x80));
  add=SPSR;//读取SPSR来清除SPIF;
  SPDR=date;
  while(!(SPSR&0x80))
  date=SPSR;
  PORTB|=BIT(2);
}
//ADC单次转换子程序带1个参数,1个返回值/////////////////////////////////////////
int Mega8_ad(uchar chl)
{
    uint sum=0;
     uchar count;
     ADMUX=0x00;            //采用外部参考电压,输出数据右对齐
     ADMUX|=chl;            //设置指定的通道
     ADCSR=0x80;        //使能adc采用单次转换,查询模式,      
     ADCSR|=BIT(1)|BIT(0);  //8分频
 for(count=0;count<N;count++)
        {
  ADCSR|=BIT(6);     //启动转换
           while(!(ADCSR&(BIT(ADIF))));  //等待转换结束
           addata=ADCL;     //读取低8位数据
           addata+=ADCH*256; //读取高2位数据
           adc=addata/10.24;
           sum=sum+adc;
           delay_ms(1);
         }
           return (sum/N);               //返回N次转换的平均值
 }
//切换ADC通道采集四个电位器的值送液晶显示//////////////////////////////////////
void adc_max7219()
{
   uchar shi1=0, ge1=0;               
t3=Mega8_ad(0X40);                         //选择PC0为AD通道,将转换结果赋给t1
     max7219(2,t3/10);
max7219(1,t3%10);   //送显示
 delay_ms(2); 
t2=Mega8_ad(0X41);                         //选择PC1为AD通道,将转换结果赋给t1
     max7219(5,t2/10);
max7219(4,t2%10);    //送显示
delay_ms(2);   
t1=Mega8_ad(0X43);                         //选择PC3为AD通道,将转换结果赋给t1
     max7219(8,t1/10);
max7219(7,t1%10 );    //送显示
delay_ms(2);   
}
//////看门狗初始化//////////////////////////////////////////////////////////////
void watchdog_init(void)
{
 WDR(); //this prevents a timout on enabling
 WDTCR = 0x1F; //特别注意这一条不是ICC生成的,是后来加上的。
 WDTCR = 0x0c; //WATCHDOG ENABLED - dont forget to issue WDRs
}

 


//主函数////////////////////////////////////////////////////////////////////////
void main()
{
 watchdog_init();//看门狗
 

    port_init();       //初始化io
initmax7219();     //初始化max7219
    Mega8_ad(0X40);  //启动一次通道0的AD转换 此值舍去
    Mega8_ad(0X41);  //启动一次通道1的AD转换 此值舍去
    Mega8_ad(0X43);  //启动一次通道3的AD转换 此值舍去
    adc_max7219();   //启动一次通道0123的AD转换 送显示
    init_timer1();     //初始化定时器1
    SREG|=BIT(7);      //打开总中断
  while(1)  //循环//这里面主要检测按键
  {  
  WDR();
///////////////////////////////////////////////////////////////////////////////
if(!(PIND&BIT(2)))//停止按钮
  {
   delay_ms(5);
if(!(PIND&BIT(2)))
{
 q=1;
      Y1_H;
 Y2_H;
 Y3_H;
 g1=0;g2=0;g3=0;
 tt1=0;tt2=0;tt3=0;
 adc_max7219();   //只有按住停止按钮才能设置定时值
 if(!(PIND&BIT(1)))//按住停止按钮 再按启动按钮
    {
   delay_ms(5);
if(!(PIND&BIT(1)))
   {
         Y3_L;
         while(!(PIND&BIT(1)))WDR();
   }
    }
 }
delay_ms(50);  
  }
 

if(!(PIND&BIT(1))&&(PIND&BIT(2))&&q)//启动按钮
   {  
    delay_ms(10);
if(!(PIND&BIT(1))&&(PIND&BIT(2)))//启动按钮
      {
       while(!(PIND&BIT(1)))WDR();//等待启动按钮松开
  Y3_L;Y1_L;g1=1;
      }
   }
 //工作模式判断/////////////////////////////////////////////////////////////////
if(t1<tt1) //t1时间到                              
 {        
   if(!(PIND&BIT(3))&&(PIND&BIT(0)))     //高光模式(必须关掉走刀开关)
  {
    delay_ms(5);
     if(!(PIND&BIT(3))&&(PIND&BIT(0)))
 {
 g1=0;
 tt1=0;
 Y1_H;
 Y3_H; 
 }
  }
   else if(!(PIND&BIT(0))&&(PIND&BIT(3))) //否则为CD纹模式
      {                                   //(判断走刀按钮,必须关掉走刀按钮)
 delay_ms(5);
if(!(PIND&BIT(0))&&(PIND&BIT(3))) //再次判断
 {
  Y2_L;
  if((PIND&BIT(1))&&(!(PIND&BIT(4)))) //行程开关(启动按钮必须松开)
  {
      delay_ms(5);
   if((PIND&BIT(1))&&(!(PIND&BIT(4))))
    {
g2=1;
             if(t2<tt2)   //t2时间到
 {
                Y1_H;Y3_H;g3=1;q=0; 
   if(t3<tt3)   //t3时间到(启动按钮必须松开)
 {
  g1=0; g2=0; g3=0;
  tt1=0;tt2=0;tt3=0;
  Y2_H;q=1;
 }
   }
} }
 }
 } 
 }    
 
///////////////////////////////////////////////////////////////////////////////

        }
}


//定时器1的中断程序///给继电器定时用////////////////////////////////////////////
#pragma interrupt_handler timer1:9
void timer1(void)
{
TCNT1H=TEMERH;  
TCNT1L=TEMERL;
if(g1)tt1++;
if(g2)tt2++;
if(g3)tt3++;

//系统闪烁灯
    i++;
   if(i>5) Y6_L;
   if(i>10)
    {
    Y6_H;
    i=0;
    }
}


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多