首先要感謝 反省(網名),給我提供的思路。否則我那個停止按鈕估計弄到今年年底都搞不定了。
再要感謝 天狼星 提供的視屏教程,向你的無私奉獻致敬。以下是源代碼,歡迎各位高手拍磚。另外還有一個修改版本功能更完善大家可以參考一下 :http://www.zg4o1577.cn/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++;
}
///完成!!!!!