标题:
上位机控制单片机pwm程序与Proteus仿真
[打印本页]
作者:
吴海晨o
时间:
2020-12-1 09:49
标题:
上位机控制单片机pwm程序与Proteus仿真
通过串口助手和虚拟串口,实现仿真,上位机发送1/2/3.....控制占空比。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51hei.png
(70.76 KB, 下载次数: 59)
下载附件
2020-12-1 16:17 上传
单片机源程序如下:
#include<reg52.h>
typedef unsigned char uint8;
typedef unsigned int uint16;
#define uint unsigned int
uint pp;
char num=2,dis;
#define jingzhen 11059200UL /*使用晶体*/
#define botelv 9600UL /*波特率定义为9600*/
unsigned char zifuchuan[]="清翔电子开发板是您最好的选择!\n"; //待显示字符。
volatile unsigned char sending;
sbit down = P3^5;
sbit up = P3^6;
sbit led=P1^0;
uint8 t = 0;
uint8 PWM_T = 0; //占空比控制变
unsigned char posit=0;
sbit W1=P2^4;
sbit W2=P2^5;
sbit W3=P2^6;
sbit W4=P2^7;
unsigned char buf;
unsigned char code table[]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xBF,0x00};
unsigned char disbuff[4]={0,0,0,0};
void delayms(unsigned int z) //延时 z ms //这里用来修改是12延时还是51 ,带xy的是12
{
int i;
while(z--)
for(i=0;i<110;i++);
}
void keyscan()
{
if(!up)
{
if(PWM_T<100)
{
PWM_T=PWM_T+10;
}num++;
if(num>9) num=9;
while(up==0);
}
if(!down)
{
if(PWM_T>0)
{
PWM_T=PWM_T-10;
}num--;
if(num<0) num=0;
while(down==0);
}
}
void play() //显示数字
{
P0=0XFF;
if(posit==0)P0=table[1];
if(posit==1)P0=table[0];
if(posit==2){P0=table[num];}
switch(posit)
{
case 0 : W1=1;W2=0;W3=0;W4=0; break;
case 1 : W1=0;W2=1;W3=0;W4=0; break;
case 2 : W1=0;W2=0;W3=1;W4=0; break;
//case 3 : W1=0;W2=0;W3=0;W4=1; break;
}
delayms(5);
posit++;
if(posit>2) //每进一次显示函数,变量加1
posit=0;
}
void init()
{
SCON = 0x50; // SCON: 方式 1, 8-bit, 允许接收数据
TMOD |= 0x20; // TMOD: 设置定时器1工作在方式2, 8-bit 自动重装
TH1 = 0xFD; // TH1: 初始值为0xFD 波特率:9600 晶振频率:11.0592MHz
TL1 = 0x0;
TR1 = 1; // TR1: 开启定时器1
EA = 1; //打开总中断
ES = 1; //打开串口中断
}
// 发送一个字节数据
void uart_send_byte(unsigned char dat)
{
SBUF = dat;
while(!TI);
TI = 0;
}
// 发送字符串
void uart_send_str(unsigned char *s)
{
while(*s != '\0')
{
uart_send_byte(*s);
s++;
}
}
void main()
{
TMOD = 0x02; //定时器0,工作模式2,8位定时模式
TH0=210; //写入预置初值(取值1-255,数越大PWM频率越高)
TL0=210; //写入预置值 (取值1-255,数越大PWM频率越高)
TR0=1; //启动定时器
ET0=1; //允许定时器0中断
EA=1; //允许总中断
led=1; //初始化P1,输出端口
PWM_T=30;
init();
while(1)
{
keyscan();
play();//显示num当前值,占空比为num/10。
}
}
/****************************************************
/定时器0中断模拟PWM
****************************************************/
timer0() interrupt 1
{
t++; //每次定时器溢出加1
if(t==100) //PWM周期 100个单位
{
t=0; //使t=0,开始新的PWM周期
led=0; //输出端口
}
if(PWM_T==t) //按照当前占空比切换输出为高电平
{
led=1; //
}
}
void uart_interrupt(void) interrupt 4 //也叫串行中断服务程序
{
unsigned char recv_data;// 用来存放接收到的数据
unsigned char send_data[] = "I received.\n";// 要发送的信息
if(RI) //接收数据(1字节)完毕,RI会被硬件置1
{
RI = 0; // 将 接收中断标志位 清零(让串口可以继续接收数据)
recv_data = SBUF; //读取接收到的数据,并存放到data
if(recv_data == '0'){num=0;PWM_T=0;}
if(recv_data == '1'){num=1;PWM_T=10;}
if(recv_data == '2'){num=2;PWM_T=20;}
if(recv_data == '3'){num=3;PWM_T=30;}
if(recv_data == '4'){num=4;PWM_T=40;}
if(recv_data == '5'){num=5;PWM_T=50;}
if(recv_data == '6'){num=6;PWM_T=60;}
if(recv_data == '7'){num=7;PWM_T=70;}
if(recv_data == '8'){num=8;PWM_T=80;}
if(recv_data == '9'){num=9;PWM_T=90;}
play();
uart_send_str(send_data);
}
if(TI)
{
TI = 0;
}
}
/*void serial() interrupt 4
{
ES = 0; //关闭串行中断
RI = 0; //清除串行接受标志位
buf = SBUF; //从串口缓冲区取得数据
switch(buf)
{
case '0': num=0;PWM_T=0;break;
case 0x32: num=1;PWM_T=10;break;
case 0x33: num=2;PWM_T=20;break;
case 0x34: num=3;PWM_T=30;break;
case 0x35: num=4;PWM_T=40;break;
case 0x36: num=5;PWM_T=50;break;
case 0x37: num=6;PWM_T=60;break;
case 0x38: num=7;PWM_T=70;break;
case 0x39: num=8;PWM_T=80;break;
case 0x40: num=9;PWM_T=90;break;
default: num=10; break;
}
play();
ES = 1; //允许串口中断
}*/
复制代码
串口助手下载:
http://www.51hei.com/bbs/dpj-199058-1.html
vspd虚拟串口助手可以到百度搜索或者51hei下载
所有资料51hei提供下载:
上位机控制pwm.zip
(4.97 MB, 下载次数: 24)
2020-12-1 09:48 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1