搜索
您的当前位置:首页直流电机调速控制系统的C语言程序

直流电机调速控制系统的C语言程序

来源:乌哈旅游


//MCU:AT89S51

//晶振:12M

#include \"regX52.H\"

#include \"math.h\"

#include \"intrins.h\"

#define LCDIO P0 //定义P0口与LCD1602的数据口相接

#define ON 1

#define OFF 0

sbit LCD_RS=P2^6;

sbit LCD_RW=P2^5;

sbit LCD_EN=P2^4;

sbit LCD_BUSY=LCDIO^7;

sbit SW4=P2^0; // 速度设置加

sbit SW3=P2^1; // 速度设置减

sbit SW2=P2^2; // 停

sbit SW1=P2^3; // 反转

sbit IN2=P3^4; // 红色的线

sbit PWM=P3^5; // 黄色的线

sbit IN1=P3^6; // 紫色的线

int display;

int flag;

int time;

int a;

int s=25;

unsigned long int p;

unsigned long int xiao;

unsigned long int h;

unsigned long int v;

unsigned char dispbuff[4]; //存放各位数据

/*******1ms延时子程序***********/

void delay_nms(unsigned int n)

{

unsigned int i;

unsigned char j;

for(i=0;ifor(j=0;j<120;j++)

; //空操作

}

/*******1ms延时子程序***********/

/*******0.1ms延时子程序***********/

void control_speed(unsigned int n)

{

unsigned char j;

for(j=0;j; //空操作

}

/*******0.1ms延时子程序***********/

#define uchar unsigned char

#define uint unsigned int

//LCD驱动

void LCD_check_busy(void) //检测LCD状态,看它是不是还在忙呢

{

do

{

LCD_EN=0;

LCD_RS=0;

LCD_RW=1;

LCDIO=0xff;

LCD_EN=1;

}

while(LCD_BUSY==1);

LCD_EN=0;

}

/************LCD1602写命令*******************************/

void LCD_send_command(uchar command,busy1)

{

if(busy1)

LCD_check_busy();

LCD_RS=0;

LCD_RW=0;

LCD_EN=1;

LCDIO=command;

LCD_EN=0;

}

/*****************LCD1602写数据**************************/

void LCD_send_data(uchar dat)

{

LCD_check_busy();

LCD_RS=1;

LCD_RW=0;

LCD_EN=1;

LCDIO=dat;

LCD_EN=0;

}

void LCD_write_char(uchar x,uchar y,uchar dat)

{

unsigned char address;

if (x==0)

address=0x80+y;

else

address=0xc0+y;

LCD_send_command(address,0);

LCD_send_data(dat);

}

/******************LCD1602显示字符串*********************/

void LCD_disp_string(uchar x,uchar y,uchar *Data)

{

if(x==0)

{

if(y<16)

{

LCD_send_command(0x80+y,0);

for(;y<16&&*Data!='\\0';y++)

{

LCD_send_data(*(Data));

Data++;

}

if(*Data!='\\0')

{

y=0;

x=1;

}

}

}

if(x==1)

{

LCD_send_command(0xc0+y,0);

for(;y<16&&*Data!='\\0';y++)

{

LCD_send_data(*(Data));

Data++;

}

}

}

void LCD_init(void)

{

delay_nms(15);

LCD_send_command(0x38,0);

delay_nms(5);

LCD_send_command(0x38,0);

delay_nms(5);

LCD_send_command(0x38,0);

delay_nms(5);

LCD_send_command(0x38,1);//设置lcd1602为每个字符5×7显示

LCD_send_command(0x0f,1); //开显示,光标显示并闪烁

LCD_send_command(0x06,1);//光标移动设置,每写一个数,光标自动加一

LCD_send_command(0x01,1); //清屏

}

/**************LCD1602的初始化完毕***************************/

/***********************初始化函数*********************/

void init()

{

IT1=1; //脉冲触发方式

EA=1; //中断总允许

EX1=1; //允许外部中断1

TMOD=0x91;

TH0=0x3c;

TL0=0xb0; //给定时器赋初值

ET0=1; //允许定时中断

TR0=1; //启动定时器

}

/******定时器,外部中断初始化******/

void main()

{

int mode;

int vs=50; //速度设置参数

int Y= 2;

int

k=0;

init();

LCD_init();

LCD_disp_string(0,0x00,\"set speed:\");

LCD_disp_string(1,0x00,\"V=\");

LCD_disp_string(1,0x05,\"Hz\");

while(1)

{

/***********************按键模式一些控制*********************/

if(SW4==0) //设定速度加

{ xiao++;

if(xiao>100)

{ xiao=0;

vs++;

if(vs>100)

{ vs=100; } }

}

if(SW3==0) { xiao++;

if(xiao>100)

{ xiao=0;

vs--;

if(vs<8)

//设定速度减

{ vs=8; }

}

}

if(SW2==0) //开关键

{ delay_nms(100);

{

if(SW2==0)

{

if(mode!=0)

mode=0;

else

mode=1;

}

}

delay_nms(150);

}

if(SW1==0) //正反转

{ delay_nms(100);

{

if(SW1==0)

{

if(mode==2)

{ mode=1; }

else

{ mode=2; }

}

}

delay_nms(150);

}

/***********************按键模式一些控制*********************/

/***********************电机运行模式选择*********************/

switch(mode)

{

case 0x00: //关闭电机

PWM = OFF;

break;

case 0x01: //正转

IN1 = 0; //p36 紫线

IN2 = 1; //p34 红线

PWM = 1; //p35 黄线 (控制速度)

control_speed(s);

PWM = 0; //p35 黄线

control_speed(100-s);

break;

case 0x02: IN1 = 1; IN2 = 0; //p34 红线

PWM = 1; //p35 黄线

control_speed(s);

PWM = 0; //p35 黄线

control_speed(100-s);

break;

//反转

//p36 紫线

default:break;

}

/***********************电机运行模式选择*********************/

/***********************速度计算显示*********************/

if(display==1)

{

display=0; //一秒钟显示一次

dispbuff[3]=(v/100);

dispbuff[2]=(v/10%10); //

dispbuff[1]=(v%10); //

LCD_write_char(1,0x02,(dispbuff[3])+48); //

LCD_write_char(1,0x03,(dispbuff[2])+48);

LCD_write_char(1,0x04,(dispbuff[1])+48);

LCD_write_char(0,0x0a,(vs/100)+48);

LCD_write_char(0,0x0b,(vs/10)%10+48);

LCD_write_char(0,0x0c,(vs%10)+48);

switch(mode)

{

case 0x00: //关闭电机

LCD_disp_string(1,0x07,\"----stop\");

break;

case 0x01: //正转

LCD_disp_string(1,0x07,\"--->work\");

break;

case 0x02: //反转

LCD_disp_string(1,0x07,\"<---work\");

break;

default:break;

}

/***********************速度计算显示*********************/

/***********************速度自动调节(每一秒调节一次)*********************/

if(v>(vs+Y*2)) //速度过大,快速调节

{

s=s-3;

if(s<8)

{ s=8;}

}

if((v-Y)>=vs>=(v-Y*2)) //速度过大, 慢速调节。

{

s=s-1; // delay_nms(1);

if(s<8)

{ s=8;}

}

if(vs>(v+Y*2)) //速度过大,快速调节

{

s=s+3;

if(s>95)

{ s=95;}

}

if((vs-Y)>=v>=(vs-Y*2)) //速度过大, 慢速调节。

{

s=s+1; // delay_nms(1);

if(s>95)

{ s=95;}

}

else

s=s;

/***********************速度自动调节(每一秒调节一次)*********************/

}

}

}

/***********************频率进入端口*********************/

void inter1() interrupt 2

{

p++;

}

void timer0() interrupt 1 //定时中断入口

{

TH0=0x3c;

TL0=0xb0; // time++;

if(time>=20) {

time=0;

v=p/2;

p=0;

xiao=0;

display=1;

50ms //一秒

//定时器赋值

}

}

因篇幅问题不能全部显示,请点此查看更多更全内容

Top