使用proteus进行仿真:运用单片机(AT89C52、STM32、MSP430等)控制实现PWM输出经驱动芯片后驱动电机,(驱动自选) 需实现以下功能: 1、pwm频率为1KHz,初始占空比50% 2、PWM输出占空比可调 3、可控制两个电机同时正转、反转、一正一反; (可实物,提供所需器材)
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include<reg52.h> // 引入STC89C52头文件
- #define uint unsigned int // 定义无符号整型变量
- #define uchar unsigned char // 定义无符号字符型变量
- uchar time, count = 50, flag1 = 1, flag2 = 1; // 定义变量
- uchar seg[] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39}; // 数码管显示字符
- sbit PWM1 = P3^0; // PWM 输出引脚 1
- sbit PWM2 = P3^1; // PWM 输出引脚 2
- sbit PWM3 = P3^2; // PWM 输出引脚 3
- sbit PWM4 = P3^3; // PWM 输出引脚 4
- sbit key_add = P2^3; // 增加按键
- sbit key_dec = P2^4; // 减少按键
- sbit key_turn1 = P2^5; // 旋转按键 1
- sbit key_turn2 = P2^6; // 旋转按键 2
- sbit RS = P3^5; // LCD 控制引脚 RS
- sbit RW = P3^6; // LCD 控制引脚 RW
- sbit E = P3^7; // LCD 控制引脚 E
- // 延时函数
- void delayxms(uint z);
- // 旋转按键1的处理函数
- void Motor_turn1();
- // 旋转按键2的处理函数
- void Motor_turn2();
- // 增加按键的处理函数
- void Motor_add();
- // 减少按键的处理函数
- void Motor_dec();
- // 定时器0的初始化函数
- void timer0_init();
- // 定时器1的初始化函数
- void timer1_init();
- // 向LCD发送命令
- void w_com(uchar j);
- // 向LCD发送数据
- void w_dat(uchar j);
- // 初始化LCD
- void lcd_init();
- void main()
- {
- uint mm, nn;
- lcd_init();
- timer0_init();
- timer1_init();
- while (1)
- {
- Motor_turn1();
- Motor_turn2();
- Motor_add();
- Motor_dec();
- w_com(0x80);
- w_dat('d');
- w_dat('u');
- w_dat('t');
- w_dat('y');
- w_dat(' ');
- w_dat('r');
- w_dat('a');
- w_dat('t');
- w_dat('i');
- w_dat('o');
- w_dat(':');
- w_com(0xc7);
- mm = seg[count/10];
- nn = seg[count%10];
- w_dat(mm);
- w_dat(nn);
- w_dat('%');
- }
- }
- // 延时函数,延时z毫秒
- void delayxms(uint z)
- {
- uint x, y;
- for (y = z; y > 0; y--)
- for (x = 110; x > 0; x--);
- }
- // 处理旋转按键1
- void Motor_turn1()
- {
- if (key_turn1 == 0)
- {
- delayxms(2);
- if (key_turn1 == 0)
- {
- flag1 = ~flag1;
- }
- while (!key_turn1);
- }
- }
- // 处理旋转按键2
- void Motor_turn2()
- {
- if (key_turn2 == 0)
- {
- delayxms(2);
- if (key_turn2 == 0)
- {
- flag2 = ~flag2;
- }
- while (!key_turn2);
- }
- }
- // 处理增加按键
- void Motor_add()
- {
- if (key_add == 0)
- {
- delayxms(2);
- if (key_add == 0)
- {
- count += 5;
- if (count >= 100)
- {
- count = 0;
- }
- }
- while (!key_add);
- }
- }
- // 处理减少按键
- void Motor_dec()
- {
- if (key_dec == 0)
- {
- delayxms(2);
- if (key_dec == 0)
- {
- count -= 5;
- if (count >= 100)
- {
- count = 0;
- }
- }
- while (!key_dec);
- }
- }
- // 定时器0初始化
- void timer0_init()
- {
- TMOD = 0x01;
- TH0 = (65536 - 10) / 256;
- TL0 = (65536 - 10) % 256;
- TR0 = 1;
- ET0 = 1;
- EA = 1;
- }
- // 定时器0中断处理函数
- void timer0_int() interrupt 1
- {
- TR0 = 0;
- TH0 = (65536 - 10) / 256;
- TL0 = (65536 - 10) % 256;
- TR0 = 1;
- if (flag1 == 1)
- {
- PWM1 = 0;
- time++;
- if (time < count)
- PWM2 = 1;
- else
- PWM2 = 0;
- if (time >= 100)
- time = 0;
- }
- else
- {
- PWM2 = 0;
- time++;
- if (time < count)
- PWM1 = 1;
- else
- PWM1 = 0;
- if (time >= 100)
- time = 0;
- }
- }
- // 定时器1初始化
- void timer1_init()
- {
- TMOD = 0x10;
- TH1 = (65536 - 10) / 256;
- TL1 = (65536 - 10) % 256;
- TR1 = 1;
- ET1 = 1;
- EA = 1;
- }
- // 定时器1中断处理函数
- void timer1_int() interrupt 3
- {
- TR1 = 0;
- TH1 = (65536 - 10) / 256;
- TL1 = (65536 - 10) % 256;
- TR1 = 1;
- if (flag2 == 1)
- {
- PWM3 = 0;
- time++;
- if (time < count)
- PWM4 = 1;
- else
- PWM4 = 0;
- if (time >= 100)
- time = 0;
- }
- else
- {
- PWM4 = 0;
- time++;
- if (time < count)
- PWM3 = 1;
- else
- PWM3 = 0;
- if (time >= 100)
- time = 0;
- }
- }
- // 向LCD发送命令
- void w_com(uchar j) {
- RS = 0;
- RW = 0;
- E = 1;
- P1 = j;
- E = 0;
- delayxms(3);
- }
- // 向LCD发送数据
- void w_dat(uchar j) {
- RS = 1;
- RW = 0;
- E = 1;
- P1 = j;
- E = 0;
- delayxms(2);
- }
- // 初始化LCD
- void lcd_init() {
- delayxms(10);
- w_com(0x38);
- delayxms(10);
- w_com(0x0c);
- delayxms(10);
- w_com(0x06);
- delayxms(10);
- w_com(0x01);
- delayxms(10);
- w_com(0x38);
- delayxms(10);
- }
复制代码
Keil代码与Proteus仿真下载:
仿真程序.7z
(65.19 KB, 下载次数: 19)
|