资源描述
毕业设计(论文)说明书
金属分炼器
学 院 电子信息工程学院
专 业 应用电子技术
指导教师
学生姓名
提交日期 2014年05月03日
摘要:本系统以ATMEL公司的ATmega16芯片为控制核心,采用L298驱动器驱动步进电机控制旋转角度,进而改变转角,在0、45°、-45°,可以由键盘调整电机的初始位置,绝对误差≤5°。系统通过模拟量位移传感器分辨出铁、铝、铜,并回收放到指定的位置。系统利用步进电机旋转的角度对木板偏转角度进行实时测量,并采用LCD1602显示电机偏转角及位移传感器检测的金属。
关键字: ATmega16芯片,L298,位移传感器,LCD1602
目录
一. 系统方案 3
1. 系统组成 3
二.方案论证与比较 3
1.电机控制模块控制选择 3
2. 显示模块选择 4
三.理论分析与计算 5
1.角度控制算法分析与计算 5
四.系统电路设计 5
1. 最小系统电路设计 5
2. 控制之298驱动电路设计 6
3. 总体电路设计 7
五.系统程序设计 8
1.程序功能简介 8
2. 主函数流程图 8
六.测试方案与测试结果 9
1.测试仪器 9
参考文献: 9
附录1:主要元件清单 9
附录2:电路原理图 10
1.1 电路原理图 10
附录3:程序清单 13
系统调试程序 13
/************************************* 18
一. 系统方案
1. 系统组成
根据题目要求,本系统系统设计主要包括三大大部分:显示模块、金属分离模块、金属检测模块。系统构成如图F-1-1,
下面对各部分进行方案论证。
系统构成如图F-1-1
二.方案论证与比较
1.电机控制模块控制选择
通过L298驱动器控制直流风扇的直流电机来实现。L298是一款高压、大电流双全桥式驱动器,可以直接通过电源来调节输出电压,具有输出电压高(最高可达50V),可靠性高,占用空间小等特点。该芯片可以直接受控于单片机IO口提供的信号。因此,电路简单,控制方便,所以我们选择L298来做电机驱动。
2. 显示模块选择
方案一:采用数码管显示。该方案具有程序简单,显示速度快等特点。但数码管显示需要外加驱动芯片,且只能显示数字。
方案二:使用基于ST7920的12864汉子图形点阵液晶显示。LCD12864内置8192个中文汉字(16*16点阵)、128个字符(8*16点阵)及64*256点阵RAM(GDRAM),可采用串并口两种方式传输数据。该方案显示信息量大,可显示汉字及图形,具有驱动电压低;功耗微小等优点。
方案三:采用LCD1602显示。1602内部集成有显示芯片,可以识别英文字母、阿拉伯数字和日语片假名;1602并口传输速度较快。
为方便调试及使用,本设计选用LCD1602液晶显示,在我们这次比赛中,只需要显示字母和角度,就没必要选择12864来显示。
三.理论分析与计算
1.角度控制算法分析与计算
本系统采用了“粗调+微调”纠错调节的方式来完成发挥部分要求的角度设定功能。该方法调节效率高,绝对误差较小。
由于外部环境的干扰及风力与转速的复杂关系,我们不能直接得到转速(或者PWM波占空比)与转角的线性关系。最后,通过测试,我们确定用“粗调+微调”逐步纠错的方法来稳定设定角度。
四.系统电路设计
1. 最小系统电路设计
AVR最小系统由ATmega16单片机,ISP下载端口,晶振,复位电路及电源等组成。ATmega16是基于增强的AVR RISC结构的低功耗8位CMOS微控制器,具有片内振荡器的可编程的看门狗定时器。其数据吞吐率高达 1MIPS/MHz,具有高性能,低功耗的特点。
2. 控制之298驱动电路设计
该电路为L298的接线电路。本电路使能端(EN A和EN B)接高电平,通过控制输入IN1,IN2和IN3,IN4来控制电机。L298可以驱动两个电机,OUT1,OUT2为一个输出组,OUT3,OUT4为另一个输出组。本系统只能驱动一台电机。IN1,IN2和IN3,IN4脚分别是控制OUT1,OUT2和OUT3,OUT4电机的输入电平。输入与电机的运行关系如表1-2所示。本系统将单片机产生的PWM波接L298的IN1输入端,IN2引脚接低电平。当IN1输入为高电平时正转,IN2输入为低电平时被控电机停止。所以,PWM占空比不同,电机转速也就不一样。
表1-2 L298功能模块
电机运转状态
0
ⅹ
ⅹ
停止
1
1
0
正转
1
0
1
反转
1
1
1
立停
1
0
0
停止
3. 总体电路设计
本系统整体电路设计包括的主要模块有:单片机最小系统电路设计,L298驱动电路设计,矩阵按键电路设计,LCD1602液晶接线模块,模拟量位移传感器等。
五.系统程序设计
1.程序功能简介
为方便调试,系统程序分模块进行调试。系统程序设计的主要模块包括:电机驱动模块程序,角度测量模块程序,LCD1602液晶显示模块程序及金属检测分离模块程序等。
2. 主函数流程图
六.测试方案与测试结果
1.测试仪器
铁、铝、铜、1602显示。
参考文献:
[1] 三恒星科技编著.AVR单片机原理与应用实例.北京:电子工业出版社,2009.7
[2] 张军、宋涛编著.AVR单片机C语言程序设计实例精粹.北京:电子工业出版社
附录1:主要元件清单
序号
名称
型号
规格
数量
单位
备注
1
单片机
ATMEGA16L
DIP40
1
片
2
LCD1602液晶
DIP16
1
块
3
电机驱动芯片
L298
1
个
4
模拟量位移传感器
1
块
5
电解电容
10uF
16V
1
个
6
电解电容
220uF
25V
1
个
7
稳压管
7805
1
个
8
稳压管
7812
1
个
9
OPA2234
1
个
10
石英晶振
16MHZ
1
个
11
步进电机
1
个
附录2:电路原理图
1.1 电路原理图
电路原理图为系统整体控制部分原理图和电源部分原理图。
附录3:程序清单
系统调试程序
/******************************************************/
金属分离器
/******************************************************/
#include<avr/io.h>
#include<avr/interrupt.h>
#include"LCD1602.H"
unsigned char CH[]={"0123456789 "};
unsigned char CH0[]={"....! "};
unsigned char CH1[]={"----- "};
unsigned char CH2[]={"_Fe_Just... "};
unsigned char CH3[]={"_Cu_Against..."};
unsigned char spin[]={0x1F,0x20,0x4F,0x8F};
unsigned char spin1[]={0x8F,0x40,0x2F,0x1F};
//#define K1 0x01
//#define K2 0x02
//#define K3 0x04
#define corner 12
int ADtemp,x,y,z,w;
unsigned int MotorFlag,MotorFlag1=0,ADFlag;
/*************************************************/
void initADC(void)
{
ADMUX|=(1<<REFS1)|(1<<REFS0)|(0<<MUX4)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0)|(1<<ADLAR);
ACSR = (1<<ACD); //模数比较器清零
ADCSRA|=(1<<ADEN)|(1<<ADSC)|(1<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(0<<ADPS1)|(1<<ADPS0);
//ADC使能,ADC开始转换,连续转换,中断使能,128分频
}
/*************************************************/
//ADC转换完成中断,ADC读取
/*************************************************/
SIGNAL(SIG_ADC)
{
ADtemp=ADCL;//获取ADC的值
ADtemp=(ADCH<<2)|(ADtemp>>6);
}
/****************************/
// 液晶显示
/****************************/
void LCD_display(unsigned char temp)
{
unsigned int i;
if(temp==0)
{
for(i=0;i<11;i++) LCD_read_com(CH2[i]);
}
if(temp==1)
{
for(i=0;i<11;i++) LCD_read_com(CH3[i]);
}
if(temp==2)
{
for(i=0;i<11;i++) LCD_read_com(CH0[i]);
}
if(temp==3)
{
for(i=0;i<11;i++) LCD_read_com(CH1[i]);
}
}
void LCD_displays(unsigned char temp)
{
x=ADtemp/1000;
y=ADtemp%1000/100;
z=ADtemp%1000%100/10;
w=ADtemp%10;
LCD_write_com(0X80);
LCD_read_com(CH[x]);
LCD_read_com(CH[y]);
LCD_read_com(CH[z]);
LCD_read_com(CH[w]);
LCD_display(temp);
}
/****************************/
// 电机控制
/****************************/
void MT(unsigned int temp)
{
unsigned int i,j,h,l;
if(temp==1)
{
for(j=0;j<corner;j++)
for(i=0;i<4;i++)
{
LCD_displays(ADFlag);
PORTD=spin1[i];
h=j/10;
l=j%10;
LCD_write_com(0x80+0x40);
LCD_read_com(CH[h]);
LCD_read_com(CH[l]);
}
}
if(temp==0)
{
for(j=0;j<corner;j++)
for(i=0;i<4;i++)
{
LCD_displays(ADFlag);
PORTD=spin[i];
h=j/10;
l=j%10;
LCD_write_com(0x80+0x40);
LCD_read_com(CH[h]);
LCD_read_com(CH[l]);
}
}
LCD_write_com(0x80+0x40);
LCD_read_com(CH[10]);
LCD_read_com(CH[10]);
}
void ADcom()
{
int ttp;
ttp=ADtemp;
if(ttp>=0 && ttp<=450) ADFlag=0;
if(ttp>=450 && ttp<=700) ADFlag=1;
if(ttp>=700 && ttp<=900) ADFlag=2;
if(ttp>=900 && ttp<=1024) ADFlag=2;
if(ADFlag==1)
{
MT(ADFlag);
MotorFlag1=1;
}
if(ADFlag==0)
{
MT(ADFlag);
MotorFlag1=2;
}
if(ADFlag==2)
{
LCD_displays(ADFlag);
}
}
void MTcom()
{
unsigned int i,j;
if(MotorFlag1==1)
{
for(j=0;j<corner;j++)
for(i=0;i<4;i++)
{
PORTD=spin[i];
LCD_displays(3);
}
}
if(MotorFlag1==2)
{
for(j=0;j<corner;j++)
for(i=0;i<4;i++)
{
PORTD=spin1[i];
LCD_displays(3);
}
}
delay(10);
MotorFlag1=0;
}
/****************************/
// 按键扫描
/****************************/
/*
void key()
{
signed char temp;
PORTD=0xff;
MotorFlag=0;
LCD_display(MotorFlag);
temp=PIND;
if(temp==~K1)
{
delay(10);
if(temp==~K1)
{
MotorFlag=1;
LCD_display( n);
MT(MotorFlag);
while(temp==~K1)temp=PIND;
MotorFlag1=0;
MotorFlag2=0;
}
}
temp=PIND;
if(temp==~K2)
{
delay(10);
if(temp==~K2)
{
MotorFlag=2;
LCD_display(MotorFlag);
MT(MotorFlag);
while(temp==~K2)temp=PIND;
MotorFlag1=0;
MotorFlag2=1;
}
}
} */
int main(void)
{
LCD_init();
DDRD=0X00;
DDRB=0XFF;
initADC();
sei();
while(1)
{
ADcom();
MTcom();
//delay(10000);
}
}
/*************************************
1602.H文件
************************************/
#include<avr/io.h>
#define RS1 PORTB|=0x01
#define RS0 PORTB&=0x00
#define RW1 PORTB|=0x02
#define RW0 PORTB&=0x00
#define EN1 PORTB|=0x04
#define EN0 PORTB&=0x00
unsigned char zi[]={"_zby:1119013207_"};
void delay(unsigned int x)
{
unsigned int i,j;
for(i=0;i<x;i++)
for(j=0;j<5;j++);
}
void LCD_write_com(unsigned char com)
{
RS0;
delay(5);
PORTC=com;
delay(5);
EN1;
delay(5);
EN0;
}
void LCD_read_com(unsigned char com)
{
RS1;
delay(5);
PORTC=com;
delay(5);
EN1;
delay(5);
EN0;
}
void LCD_init()
{
DDRC=0XFF;
DDRB=0XFF;
PORTC=0X00;
RW0;
LCD_write_com(0x38);
LCD_write_com(0x0c);
LCD_write_com(0x06);
LCD_write_com(0x01);
}
展开阅读全文