专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

基于AVR单片机的CD纹机的自动控制程序

作者:huqin   来源:本站原创   点击数:  更新时间:2014年02月19日   【字体:



             首先要感谢 反省(网名),给我提供的思路。否则我那个停止按钮估计弄到今年年底都搞不定了。
       再要感谢 天狼星 提供的视屏教程,向你的无私奉献致敬。以下是源代码,欢迎各位高手拍砖。另外还有一个修改版本功能更完善大家可以参考一下 :http://www.51hei.com/mcu/2721.html
 
//环境:编译为ICC AVR6.25A
//硬件:ATMEGA16芯片
//日期:2013年10月20日
//功能:CD纹机控制器
//作者:李亚新
//晶振:内部RC震荡,主频1M
//备注:适合用于 CD纹机的自动控制

#include <iom16v.h>
#include <macros.h>
#define  uchar unsigned char
#define  uint unsigned int
///////以下是宏定义液晶控制线和继电器所用到的IO口////////////
#define  rs_L     PORTD&=~BIT(0)
#define  rs_H     PORTD|=BIT(0)
#define  rs_out   DDRD|=BIT(0)
#define  rw_L     PORTD&=~BIT(1)
#define  rw_H     PORTD|=BIT(1)
#define  rw_out   DDRD|=BIT(1)
#define  en_L     PORTD&=~BIT(2)
#define  en_H     PORTD|=BIT(2)
#define  en_out   DDRD|=BIT(2)
#define  s0L     PORTD&=~BIT(4)
#define  s0H     PORTD|=BIT(4)
#define  s0out   DDRD|=BIT(4)
#define  s1L     PORTD&=~BIT(5)
#define  s1H     PORTD|=BIT(5)
#define  s1out   DDRD|=BIT(5)
#define  s2L     PORTD&=~BIT(6)
#define  s2H     PORTD|=BIT(6)
#define  s2out   DDRD|=BIT(6)
#define  s3L     PORTD&=~BIT(7)
#define  s3H     PORTD|=BIT(7)
#define  s3out   DDRD|=BIT(7)
///////合美特精密五金有限公司的Logo//////////////////////////
uchar table1[]="Himetech v1.0";
////////定义程序中所用到的全局变量///////////////////////////
uchar t1=0,t2=0,t3=0,t4=0,tt1=0,tt2=0,tt3=0,tt4=0;
uchar gg=0,jj=0,xx=0;
uint addata,adc;
/////////延时子程序//////////////////////////////////////////
void delay(uint ms)
{uchar a;uint b;for(a=0;a<ms;a++)for(b=0;b<50;b++);}
/////////液晶写指令函数没有读状态/////////////////////////////
void zhilin(uchar zhi)
{
rs_H; rw_H; en_L;
rs_L; rw_L;
PORTB=zhi;
delay(1);
en_H;
delay(1);
en_L;
}
/////////液晶写数据函数没有读状态////////////////////////////
void shujv (uchar shu)
{
rs_L; rw_H; en_L;
rs_H; rw_L;
PORTB=shu;
delay(1);
en_H;
delay(1);
en_L;
}
/////////液晶写指令和写数据函数//////////////////////////////
void dizhishujv(uchar dizhi,uchar shu)
{zhilin(dizhi);shujv(shu);}
///////////////////////////////////////////////////////////////////////////////
void init_lcd (void)
{
uchar e;
rs_out;  rw_out; en_out;
DDRB=0xff;
rs_out;  en_out;
delay(1);
zhilin(0x38);delay(1);
zhilin(0x38);delay(1);
zhilin(0x38);zhilin(0x38);zhilin(0x08);
zhilin(0x01);zhilin(0x06);zhilin(0x0c); 

zhilin(0x80+1);
for(e=0;e<13;e++){shujv (table1[e]);delay(1);}//写Logo
}
//////////////////ADC单次转换子程序带1个参数,1个返回值/////////////////
int Mega16_ad(uchar chl)
{
 DDRA&=0Xf0;            //转换口设置为输入、无上拉
 PORTA&=0XF0; 
 ADMUX=0;  //采用外部参考电压,输出数据右对齐
 ADMUX|=chl;  //设置指定的通道
 ADCSR=0x80;  //采用单次转换,查询模式,2分频
 ADCSR|=BIT(ADSC);  //启动转换
 while(!(ADCSR&(BIT(ADIF)))); //等待转换结束
 addata=ADCL;  //读取低8位数据
 addata+=ADCH*256;  //读取高2位数据
 adc=addata/10.24;
 return adc;
}
////////切换ADC通道采集四个电位器的值送液晶显示/////////////////////////
void adc_lcd()
{
   uchar shi1=0, ge1=0;  //定义2个局部变量
t1=Mega16_ad(0X40);      //选择PA0为AD通道,将转换结果赋给t1
      shi1=t1/10;        //将t1十位取出赋给shi1
       ge1=t1%10;        //将t1个位取出赋给ge1
     dizhishujv((0x80+0x40+2),(0x30+shi1));//显示十位
     dizhishujv((0x80+0x40+3),(0x30+ge1));//显示个位
t2=Mega16_ad(0X41);
      shi1=t2/10;
       ge1=t2%10;
     dizhishujv((0x80+0x40+5),(0x30+shi1));
     dizhishujv((0x80+0x40+6),(0x30+ge1));
t3=Mega16_ad(0X42);
      shi1=t3/10;
       ge1=t3%10;
     dizhishujv((0x80+0X40+8),(0x30+shi1));
     dizhishujv((0x80+0X40+9),(0x30+ge1));
t4=Mega16_ad(0X43);
      shi1=t4/10;
       ge1=t4%10;
     dizhishujv((0x80+0X40+11),(0x30+shi1));
     dizhishujv((0x80+0X40+12),(0x30+ge1));
}
///////////定时器1初始化子程序/////////////////////////////////////
void init_timer1()
{
  TCCR1B|=0x04;//256分频
  TCNT1H=0xff;//高8位初值
  TCNT1L=0x03;//低8位初值
  TIMSK|=BIT(2);//定时器1的中断使能
}
////////////定时器0初始化子程序/////////////////////////////////////////
void init_timer0()
{
  TCCR0|=0x04;//256分频
  TCNT0=0x00;//初值
  TIMSK|=BIT(0);//定时器0的中断使能
}
//////////以下为主程序////////////////////////////////////////////////
void main()
{
  tt1=0;tt2=0;     //
  tt3=0;tt4=0;     //初始化各变量
  gg=0;jj=0;xx=0;  //
 
  init_lcd();      //初始化液晶
  init_timer0();    //初始化定时器0
  init_timer1();    //初始化定时器1
  SREG|=BIT(7);      //打开总中断

  DDRC|=0xff;
  PORTC|=0xff;    //配置PC口为输入,有上拉电阻
  DDRC&=0x00;
t1=Mega16_ad(0X40);  //启动一次通道0的AD转换
t2=Mega16_ad(0X41);  //启动一次通道1的AD转换
t3=Mega16_ad(0X42);  //启动一次通道2的AD转换
t4=Mega16_ad(0X43);  //启动一次通道3的AD转换
/////////以下while中为按键扫描程序//////////////////////////////////////////////
 while(1)
 {
////////////启动按钮/////////////////////////////////////////////////////////////////////////
  if(!(PINC&BIT(0)))//qidong
   { 
    delay(10);
if(!(PINC&BIT(0)))//qidong
      {
       while(!(PINC&BIT(0)));
  s0out;s0L;gg=1;
      }
  } 
/////////////停止按钮/////////////////////////////////////////////////////////////////////////////     
if(!(PINC&BIT(4)))
     {
     s0out;s0H;
s1out;s1H;
s2out;s2H;
s3out;s3H;
tt1=0;tt2=0;tt3=0;
tt4=0;gg=0;jj=0;xx=0;
      }
/////////工作模式判断///车CD纹///高光/////////////////////////////////////////////
if(t1<tt1)
 {
    if(!(PINC&BIT(2))){ gg=0;tt1=0;s0out;s0H;}
    else if(!(PINC&BIT(3)))
{
if(!(PINC&BIT(1)))  {gg=0;tt1=0;s1out;s1L;}
}
 }
///////////////行程开关/////////////////////////////////////////////////////////////////////////////////
if(!((PINC&BIT(5))|(PINC&BIT(1)))) jj=1;
//////////////////////////////////////////////////////////////////////////////////////////////////////////
if(t2<tt2){jj=0;tt2=0;s0out;s0H;xx=1;}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
if(t3<tt3){xx=0;tt3=0;s1out;s1H;}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
////////////定时器0的中断程序////刷新AD转换的值和刷新液晶屏用///////////
#pragma interrupt_handler timer0:10
void timer0(void)
{
uint ff;
TCNT0=0X00;
ff++;
if(ff==10000);
{ff=0;adc_lcd();}
}
////////////定时器1的中断程序///给继电器定时用////////////////////////////////////////
#pragma interrupt_handler timer1:9
void timer1(void)
{
TCNT1H=0xff;
TCNT1L=0x03;
if(gg)tt1++;
if(jj)tt2++;
if(xx)tt3++;
}


///完成!!!!!

关闭窗口

相关文章