基于单片机的电动机调速实验系统设计

有没有哪位哥哥有这个论文啊,急~救命了……

前言 1
1.总体设计方案 2
(一)方案一:PWM波调速 2
(二)方案二:晶闸管调速 2
2.单元模块设计 3
(一) H桥驱动电路设计方案 3
(二) 调速设计方案 5
(三)系统硬件电路设计 6
1.电源电路 6
2.H桥驱动电路 6
3.基于霍尔传感器的测速模块 7
4.LCD显示模块 8
(四) 调速设计模块 9
1.PWM波软件软件设计 9
2.测速软件设计 12
3.系统功能调试 13
(一)调试软件介绍 13
(二)直流电机的调速功能仿真 14
1.调速前的波形图 14
2.调速后的波形图 14
(三)电机速度的测量并显示功能仿真 15
(四)系统的电路原理图 15
(五)系统的PCB图 16
4.设计总结 17
5.参考文献 17
附录 17
温馨提示:答案为网友推荐,仅供参考
第1个回答  2010-05-09
直接要论文啊?那你不得要去买了?我给你个程序吧
#include<iom16v.h>
#include<macros.h>
#include "Timer0.h"
#include "INT.h"
#include "LCD1602.h"
#include "xianshi.c"

void PORT_INIT(void)
{
DDRA = 0xFF;
//PORTA = 0xFF;
DDRB = 0xFF;
PORTB = 0xFF;
DDRC = 0xFF;
PORTC = 0xFF;
DDRD = 0xF0;
PORTD = 0xFF;
}

//TIMER1 initialize - prescale:1
// WGM: 14) PWM fast, TOP=ICRn
// desired value: 20KHz
// actual value: 20.000KHz (0.0%)
void timer1_init(void)
{
TCCR1B = 0x00; //stop
TCNT1 = 0xFCE1; //setup
ICR1 = 0x031F;
TCCR1A = 0x82;
TCCR1B = 0x99; //start Timer
}

//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
PORT_INIT();
timer0_init();
timer1_init();
INT_INIT();
LCD1602_initial();
SEI(); //re-enable interrupts
//all peripherals are now initialized
}

#define GOHEAD PORTD|=BIT(6);PORTD&=~BIT(7);//正转,刹车位置零
#define GOBACK PORTD&=~BIT(6);PORTD&=~BIT(7);//反转,刹车位置零
#define STOP PORTD|=BIT(6);PORTD|=BIT(7);OCR1A = 0;//正转,刹车位置一

int Sudu = 300; //max = 799,改变此数就可以改变速度
long ii = 0;
void main(void)
{
init_devices();
OCR1A = Sudu;

while(1)
{
LCD1602_xianshi(M,2,6);

if (M<7600)
{
GOHEAD;
}

else if(M<9000 && M>5000)
{
GOBACK;
}
else
{
STOP;
show(123);
}

}
}
#ifndef LCD1602__H__
#define LCD1602__H__

#define uchar unsigned char
#define uint unsigned int
uchar line1[5]={0,0,0,0,'\0'};
#define LCDa_CTRL PORTD //1602控制端口定义
#define LCDa_CTRL_DDR DDRD //控制端口方向寄存器定义
#define LCDa_RS PD5 //定义三个控制引脚
#define LCDa_RW PD6
#define LCDa_E PD7

#define LCDa_L1 0x80 //第一行的地址:0x80+addr ,addr为列数
#define LCDa_L2 0xC0 //第二行的地址:0x80+0x40+addr

#define LCDa_CGRAM_ADDR 0x40 //CGRAM的开始地址
#define LCDa_CGMAX 64 //CGRAM存储的最大字节数

#define LCDa_SET_RS LCDa_CTRL|=BIT(LCDa_RS) //三个控制管脚的控制操作
#define LCDa_SET_RW LCDa_CTRL|=BIT(LCDa_RW)
#define LCDa_SET_E LCDa_CTRL|=BIT(LCDa_E)
#define LCDa_CLR_RS LCDa_CTRL&=~BIT(LCDa_RS)
#define LCDa_CLR_RW LCDa_CTRL&=~BIT(LCDa_RW)
#define LCDa_CLR_E LCDa_CTRL&=~BIT(LCDa_E)

#define LCDa_DO PORTA //输出数据总线端口定义
#define LCDa_DI PINA //输入数据总线端口定义
#define LCDa_DATA_DDR DDRA //数据总线方向寄存器定义

#define LCDa_FUNCTION 0x38 // 液晶模式为8位,2行,5*8字符

#define iDat 1 //数据标志
#define iCmd 0 //指令标志

#define LCDa_CLS 0x01 // 清屏
#define LCDa_HOME 0x02 // 地址返回原点,不改变DDRAM内容
#define LCDa_ENTRY 0x06 // 设定输入模式,光标加,屏幕不移动
#define LCDa_C2L 0x10 // 光标左移
#define LCDa_C2R 0x14 // 光标右移
#define LCDa_D2L 0x18 // 屏幕左移
#define LCDa_D2R 0x1C // 屏幕又移

#define LCDa_ON 0x0C // 打开显示
#define LCDa_OFF 0x08 // 关闭显示
#define LCDa_CURON 0x0E // 显示光标
#define LCDa_CURFLA 0x0F // 打开光标闪烁

void Delayms(uint MS)
{
uint i,j;
for( i=0;i<MS;i++)
for(j=0;j<1141;j++); //1141是在8MHz晶振下,通过软件仿真反复实验得到的数值
}

/*******************************************
*函数名称: LCD1602_initial *
*功 能: 1602液晶初始化 *
*参 数: 无 *
*返回值 : 无 *
********************************************/
void LCD1602_initial(void)
{
Delayms(100); // 等待内部复位
LCDa_CTRL_DDR |= BIT(LCDa_RS)|BIT(LCDa_RW)|BIT(LCDa_E);//配置控制管脚为输出
LCDa_DATA_DDR |= 0xFF;//配置数据管脚为输出

LCD1602_sendbyte(iCmd, LCDa_FUNCTION); // 功能、模式设定
while(LCD1602_readBF());
LCD1602_sendbyte(iCmd, LCDa_ON); //打开显示
while(LCD1602_readBF());
LCD1602_clear(); //清屏
while(LCD1602_readBF());
LCD1602_sendbyte(iCmd, LCDa_ENTRY); // 输入模式设定
}

/*******************************************
函数名称: LCD1602_readbyte
功 能: 从1602液晶读出一个字节数据或者指令
参 数: DatCmd--为iDat时是数据,为iCmd时是指令
返回值 : dByte--读回的数据或者指令
/********************************************/
uchar LCD1602_readbyte(uchar DatCmd)
{
uchar dByte;
if (DatCmd == iCmd) //指令操作
LCDa_CLR_RS;
else
LCDa_SET_RS;

LCDa_SET_RW; //读操作
LCDa_SET_E;
LCDa_DATA_DDR=0x00; //数据总线定义为输入
dByte=LCDa_DI; //读数据或者指令
Delayms(1); //时序调整
LCDa_CLR_E;
LCDa_DATA_DDR|=0xff; //数据总线还原为输出
return dByte;
}
/*******************************************
函数名称: LCD1602_sendbyte
功 能: 向1602液晶写入一个字节数据或者指令
参 数: DatCmd--为iDat时是数据,为iCmd时是指令
dByte--为写入1602的数据或者指令
返回值 : 无
/********************************************/
void LCD1602_sendbyte(uchar DatCmd, uchar dByte)
{
if (DatCmd == iCmd) //指令操作
LCDa_CLR_RS;
else
LCDa_SET_RS;

LCDa_CLR_RW; //写操作
LCDa_SET_E;
LCDa_DO = dByte; //写入数据
Delayms(1);
LCDa_CLR_E;
}
/*******************************************
函数名称: LCD1602_sendstr
功 能: 向1602液晶写入一个字符串
参 数: ptString--字符串指针
返回值 : 无
/********************************************/
void LCD1602_sendstr(uchar *ptString)
{
while((*ptString)!='\0') //字符串未结束
{
LCD1602_sendbyte(iDat, *ptString++);
}
}
/*******************************************
函数名称: LCD1602_clear
功 能: 1602液晶清屏
参 数: 无
返回值 : 无
/********************************************/
void LCD1602_clear(void)
{
LCD1602_sendbyte(iCmd,LCDa_CLS);
Delayms(2);// 清屏指令写入后,2ms 的延时是很必要的!!!
}
/*******************************************
函数名称: LCD1602_readBF
功 能: 1602液晶清屏
参 数: 无
返回值 : busy--为1时忙,为0时可以接收指令
/********************************************/
uchar LCD1602_readBF(void)
{
uchar busy;
busy=LCD1602_readbyte(iCmd); //读回BF标志和地址
if(busy&0x80) //忙
busy=1;
else //不忙,可以写入
busy=0;
return busy;
}
/*******************************************
函数名称: LCD1602_gotoXY
功 能: 移动到指定位置
参 数: Row--指定的行
Col--指定的列
返回值 : 无
/********************************************/
void LCD1602_gotoXY(uchar Row, uchar Col)
{
switch (Row) //选择行
{
case 2:
LCD1602_sendbyte(iCmd, LCDa_L2 + Col); break; //写入第2行的指定列
default:
LCD1602_sendbyte(iCmd, LCDa_L1 + Col); break; //写入第1行的指定列
}
}

void LCD1602_xianshi(uint BCD,uchar i,uchar j)
{
line1[0]=BCD/1000+48;
line1[1]=(BCD%1000)/100+48;
line1[2]=(BCD%100)/10+48;
line1[3]=BCD%10+48;
while(LCD1602_readBF());
LCD1602_gotoXY(i,j);
LCD1602_sendstr(line1);
}

#endif

#ifndef Timer0__H__
#define Timer0__H__
//TIMER0 initialize - prescale:64
// WGM: Normal
// desired value: 1mSec
// actual value: 1.000mSec (0.0%)
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x06; //set count
OCR0 = 0xFA; //set compare
TCCR0 = 0x03; //start timer
TIMSK = 0x01; //timer interrupt sources
}
int count = 0;
#pragma interrupt_handler timer0_ovf_isr:iv_TIM0_OVF
void timer0_ovf_isr(void)
{
TCNT0 = 0x06; //reload counter value
count++;
if (count % 200 == 0)
{
PORTC ^=BIT(7);
}

}

#endif

#include <iom16v.h>
#include <macros.h>

#define uint unsigned int
#define uchar unsigned char
uint tab2[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0X00};//共阴数码管代码表

void delay(long ms)
{
uint i,j;
for(i=0;i<ms;i++)
{
for(j=0;j<1141;j++);
}
}
void show1(uchar j,uchar k)//显示函数
{
PORTB=~BIT(k);
PORTA=tab2[j];
delay(1);
}
void show(uint ada)
{

uint i,ad[4];

for(i=0;i<4;i++)
{
ad[3-i]=ada%10;
ada = ada/10;
}
while(1)
{
for(i=0;i<4;i++)
{
show1((ad[i]),i);
delay(1);
}
}
}

程序时经过我调试过的,绝对正确,有不会Q我:279676738
相似回答