求助!如何将pwm测速程序与syn6288播音程序结合,让喇叭播放速度?
时间:10-02
整理:3721RD
点击:
这是电机PWM驱动程序:#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
void displaym();
sbit en=P2^7; //1602 6管脚
sbit rs=P2^5; //1602端口 4管脚
sbit rw=P2^6;//lcd1602控制端口 5管脚
sbit num1=P1^0; //占空比加1
sbit num2=P1^1; //占空比减一
sbit num3=P1^2; //正传
sbit num4=P1^3; //反转
sbit num5=P1^4; //开始停止切换
sbit out=P3^4; //PWM输出用于正传
sbit out1=P3^7; //PWM输出用于反转
uint zhuansu,flag,z1,z2,m,flag_1,zheng,fan,kai;
void delay(uint z)//延时1ms函数
{
uint x,y;
for(x=0;x<z;x++)
for(y=0;y<110;y++);
}
void write_com(uchar com)//向1602写一字节(控制指令)
{
rs=0;
P0=com;
delay(5);
en=1;
delay(10);
en=0;
}
void write_data(uchar date)//向1602写一字节(数据)
{
rs=1;
P0=date;
delay(5);
en=1;
delay(5);
en=0;
}
void init()//初始化函数
{
en=0;
rw=0;
write_com(0x38); //5X7显示
write_com(0x0c); //关闭光标
write_com(0x01); //lcd初始化
TMOD=0x11; //定时器方式1
TH0=0xdc;
TL0=0x00; //定时器装入初值
EA=1; //开总中断
ET0=1; //定时器0开中断
TR0=1;
EX1=1;
IT1=1; //定时器启动
TH1=0xfc;
TL1=0x66;//定时100us
ET1=1; //定时器1开中断
TR1=1;
write_com(0x80);
write_data('V');
write_data(':');
write_com(0x87); //第一行显示转速
write_data('r');
write_data('p');
write_data('m');
write_com(0xc0);
write_data('z');
write_data('h');
write_data('a');
write_data('n');
write_data('k');
write_data('o');
write_data('n');
write_data('g');
write_data('b');
write_data('i'); //在第二行显示zhankongbi:
write_data(':');
write_com(0x80+14);
write_data('R');
displaym();
}
void keyscan() //键盘扫描函数
{
if(num1==0)
{
delay(5); //消除抖动
if(num1==0)
{
if(m<=199)
m++;
displaym(); //设定占空比加一
}
}
if(num2==0)
{
delay(5);
if(num2==0)
{
if(m>=1)
m--;
displaym(); //设定占空比减一
}
}
if(num3==0)
{
delay(5);
if(num3==0)
{
zheng=1; //正传标志置1
write_com(0x80+14);
write_data('R');
fan=0; // 反转标志置0
}
}
if(num4==0)
{
delay(5);
if(num4==0)
{
write_com(0x80+14);
write_data('L');
zheng=0; //正传标志置0
fan=1; // 反转标志置1
}
}
if(num5==0)
{
delay(5);
if(num5==0)
{
while(num5==0) ;
kai=1-kai;
}
}
}
void display()
{
write_com(0x82);
zhuansu=zhuansu*10; //将两秒内的计数乘以20得到转每分 *30/2 =*15 因为一圈2个磁铁
if(zhuansu/10000!=0)
write_data(zhuansu/10000+0x30); //如果转速的万位不为0 正常显示否则显示空格
else
write_data(' ');
if(zhuansu/10000==0&&zhuansu%10000/1000==0) //万位是0 千位也是0 写空格
write_data(' ');
else
write_data(zhuansu%10000/1000+0x30); //如果转速小于1000 千位为空格 否则正常显示
if(zhuansu/10000==0&&zhuansu%10000/1000==0&&zhuansu%1000/100==0) //万位 0 千位 0 百位是0 写空格
write_data(' ');
else
write_data(zhuansu%1000/100+0x30); //如果转速小于100 百位为空格 否则正常显示
if(zhuansu/10000==0&&zhuansu%10000/1000==0&&zhuansu%1000/100==0&&zhuansu%100/10==0) //万千百十位都是0 写空格
write_data(' ');
else
write_data(zhuansu%100/10+0x30); //如果转速小于10 十位为空格 否则正常显示
write_data(zhuansu%10+0x30);
write_com(0xd0);
}
void displaym()
{
write_com(0xcb);
if(m/200%10!=0)
write_data(m/200%10+0x30); //如果占空比百位不为0则显示百位否则显示空格
else
write_data(' ');
if(m/200%10==0&&m/20%10==0)
write_data(' ');
else
write_data(m/20%10+0x30); //如果占空比小于10 十位正常显示 否则显示空格
write_data(m/2%10+0x30); //显示个位
}
void main()
{
flag_1=0;
m=100; //占空比为100
zhuansu=0; //转速初值0
flag=0;
zheng=1; //初始化电机正转动
fan=0;
init(); //初始化
while(1)
{
keyscan(); //键盘扫描程序
}
}
void int1()interrupt 2 //外部中断1脉冲技术记录电机的转速 电机转一圈zhuansu加一
{
zhuansu++;
}
void int2()interrupt 1 //定时器0显示转速
{
TH0=0xdc;
TL0=0x00;//定时10ms
flag++;
if(flag==300) //计时到达2s
{
display(); //显示转速
zhuansu=0; //转速置0
flag=0;
}
}
void int3()interrupt 3 //产生PWM
{
TH1=0xff;
TL1=0x00;//定时100us
flag_1++;
if(flag_1>199)
flag_1=1;
if(kai==1) //如果kai==1电机启动
{
if(zheng==1) //电机正转
{
if(flag_1<m) //小于占空比m输出PWM=0输出电压为1
{out=0;
out1=1;}
else
{
out=1;
out1=1;
}
}
if(fan==1) //电机反转
{
if(flag_1<m) //小于占空比m输出PWM=0输出电压为1
{
out=1;
out1=0;
}
else //大于m输出PWM=1输出电压为0
{
out=1;
out1=1;
}
}
}
if(kai==0) //kai=0电机停止转动
{
out=1;
out1=1;
}
}
这个是syn6288播音程序:
#include<reg52.h>
#include<string.h>
#define uchar unsigned char
#define uint unsigned int
//需要发送的文本
char code text[]={"欢迎使用宇音天下播放"};
unsigned char headOfFrame[5];
unsigned char length;
unsigned char ecc = 0; //定义校验字节
unsigned char i=0;
void Delay1ms(uchar n)
{
uchar i=112;
while(n--)
{
while(i--);
}
}
void main(void)
{
length=strlen(text); //需要发送文本的长度
//串口的初始化
TL1=0xFA; //在11.0592MHz下,设置波特率9600bps,工作方式2
TH1=0xFA;
TMOD=0x20; //定时器工作方式2
SCON=0x50; //串口工作方式1,允许接收
PCON=0x80; //波特率正常 0x00-----波特率加倍
EA=0; //关总中断
REN=1; //允许穿行接收
TI=0; //发送中断标志位置零
RI=0; //接收中断标志位置零
TR1=1; //定时器1用作波特率发生
//发送过程
headOfFrame[0]=0xFD; //构造帧头FD
headOfFrame[1]=0x00; //构造数据区长度的高字节
headOfFrame[2]=length + 3; //构造数据区长度的低字节
headOfFrame[3]=0x01; //构造命令字:合成播放命令
headOfFrame[4]=0x00; //构造命令参数:编码格式为GBK
while(1)
{
for(i=0;i<5;i++) //一次发送构造好的5个帧头字节
{
ecc=ecc^(headOfFrame[i]); //对发送的字节进行异或校验
SBUF=headOfFrame[i];
while(TI==0);
TI=0; //发送中断标志位清零
}
for(i=0;i<length;i++) //依次发送呆合成的文本数据
{
ecc=ecc^(text[i]); //对发送的字节进行异或校验
SBUF=text[i];
while(TI==0);
TI=0;
Delay1ms(2);
}
SBUF=ecc; //最后发送校验字节
while(TI==0);
TI=0;
Delay1ms(100);
ecc=0;
}
}
两个程序单独使用都是可以的,问题是怎样让它结合起来使用?
#define uchar unsigned char
#define uint unsigned int
void displaym();
sbit en=P2^7; //1602 6管脚
sbit rs=P2^5; //1602端口 4管脚
sbit rw=P2^6;//lcd1602控制端口 5管脚
sbit num1=P1^0; //占空比加1
sbit num2=P1^1; //占空比减一
sbit num3=P1^2; //正传
sbit num4=P1^3; //反转
sbit num5=P1^4; //开始停止切换
sbit out=P3^4; //PWM输出用于正传
sbit out1=P3^7; //PWM输出用于反转
uint zhuansu,flag,z1,z2,m,flag_1,zheng,fan,kai;
void delay(uint z)//延时1ms函数
{
uint x,y;
for(x=0;x<z;x++)
for(y=0;y<110;y++);
}
void write_com(uchar com)//向1602写一字节(控制指令)
{
rs=0;
P0=com;
delay(5);
en=1;
delay(10);
en=0;
}
void write_data(uchar date)//向1602写一字节(数据)
{
rs=1;
P0=date;
delay(5);
en=1;
delay(5);
en=0;
}
void init()//初始化函数
{
en=0;
rw=0;
write_com(0x38); //5X7显示
write_com(0x0c); //关闭光标
write_com(0x01); //lcd初始化
TMOD=0x11; //定时器方式1
TH0=0xdc;
TL0=0x00; //定时器装入初值
EA=1; //开总中断
ET0=1; //定时器0开中断
TR0=1;
EX1=1;
IT1=1; //定时器启动
TH1=0xfc;
TL1=0x66;//定时100us
ET1=1; //定时器1开中断
TR1=1;
write_com(0x80);
write_data('V');
write_data(':');
write_com(0x87); //第一行显示转速
write_data('r');
write_data('p');
write_data('m');
write_com(0xc0);
write_data('z');
write_data('h');
write_data('a');
write_data('n');
write_data('k');
write_data('o');
write_data('n');
write_data('g');
write_data('b');
write_data('i'); //在第二行显示zhankongbi:
write_data(':');
write_com(0x80+14);
write_data('R');
displaym();
}
void keyscan() //键盘扫描函数
{
if(num1==0)
{
delay(5); //消除抖动
if(num1==0)
{
if(m<=199)
m++;
displaym(); //设定占空比加一
}
}
if(num2==0)
{
delay(5);
if(num2==0)
{
if(m>=1)
m--;
displaym(); //设定占空比减一
}
}
if(num3==0)
{
delay(5);
if(num3==0)
{
zheng=1; //正传标志置1
write_com(0x80+14);
write_data('R');
fan=0; // 反转标志置0
}
}
if(num4==0)
{
delay(5);
if(num4==0)
{
write_com(0x80+14);
write_data('L');
zheng=0; //正传标志置0
fan=1; // 反转标志置1
}
}
if(num5==0)
{
delay(5);
if(num5==0)
{
while(num5==0) ;
kai=1-kai;
}
}
}
void display()
{
write_com(0x82);
zhuansu=zhuansu*10; //将两秒内的计数乘以20得到转每分 *30/2 =*15 因为一圈2个磁铁
if(zhuansu/10000!=0)
write_data(zhuansu/10000+0x30); //如果转速的万位不为0 正常显示否则显示空格
else
write_data(' ');
if(zhuansu/10000==0&&zhuansu%10000/1000==0) //万位是0 千位也是0 写空格
write_data(' ');
else
write_data(zhuansu%10000/1000+0x30); //如果转速小于1000 千位为空格 否则正常显示
if(zhuansu/10000==0&&zhuansu%10000/1000==0&&zhuansu%1000/100==0) //万位 0 千位 0 百位是0 写空格
write_data(' ');
else
write_data(zhuansu%1000/100+0x30); //如果转速小于100 百位为空格 否则正常显示
if(zhuansu/10000==0&&zhuansu%10000/1000==0&&zhuansu%1000/100==0&&zhuansu%100/10==0) //万千百十位都是0 写空格
write_data(' ');
else
write_data(zhuansu%100/10+0x30); //如果转速小于10 十位为空格 否则正常显示
write_data(zhuansu%10+0x30);
write_com(0xd0);
}
void displaym()
{
write_com(0xcb);
if(m/200%10!=0)
write_data(m/200%10+0x30); //如果占空比百位不为0则显示百位否则显示空格
else
write_data(' ');
if(m/200%10==0&&m/20%10==0)
write_data(' ');
else
write_data(m/20%10+0x30); //如果占空比小于10 十位正常显示 否则显示空格
write_data(m/2%10+0x30); //显示个位
}
void main()
{
flag_1=0;
m=100; //占空比为100
zhuansu=0; //转速初值0
flag=0;
zheng=1; //初始化电机正转动
fan=0;
init(); //初始化
while(1)
{
keyscan(); //键盘扫描程序
}
}
void int1()interrupt 2 //外部中断1脉冲技术记录电机的转速 电机转一圈zhuansu加一
{
zhuansu++;
}
void int2()interrupt 1 //定时器0显示转速
{
TH0=0xdc;
TL0=0x00;//定时10ms
flag++;
if(flag==300) //计时到达2s
{
display(); //显示转速
zhuansu=0; //转速置0
flag=0;
}
}
void int3()interrupt 3 //产生PWM
{
TH1=0xff;
TL1=0x00;//定时100us
flag_1++;
if(flag_1>199)
flag_1=1;
if(kai==1) //如果kai==1电机启动
{
if(zheng==1) //电机正转
{
if(flag_1<m) //小于占空比m输出PWM=0输出电压为1
{out=0;
out1=1;}
else
{
out=1;
out1=1;
}
}
if(fan==1) //电机反转
{
if(flag_1<m) //小于占空比m输出PWM=0输出电压为1
{
out=1;
out1=0;
}
else //大于m输出PWM=1输出电压为0
{
out=1;
out1=1;
}
}
}
if(kai==0) //kai=0电机停止转动
{
out=1;
out1=1;
}
}
这个是syn6288播音程序:
#include<reg52.h>
#include<string.h>
#define uchar unsigned char
#define uint unsigned int
//需要发送的文本
char code text[]={"欢迎使用宇音天下播放"};
unsigned char headOfFrame[5];
unsigned char length;
unsigned char ecc = 0; //定义校验字节
unsigned char i=0;
void Delay1ms(uchar n)
{
uchar i=112;
while(n--)
{
while(i--);
}
}
void main(void)
{
length=strlen(text); //需要发送文本的长度
//串口的初始化
TL1=0xFA; //在11.0592MHz下,设置波特率9600bps,工作方式2
TH1=0xFA;
TMOD=0x20; //定时器工作方式2
SCON=0x50; //串口工作方式1,允许接收
PCON=0x80; //波特率正常 0x00-----波特率加倍
EA=0; //关总中断
REN=1; //允许穿行接收
TI=0; //发送中断标志位置零
RI=0; //接收中断标志位置零
TR1=1; //定时器1用作波特率发生
//发送过程
headOfFrame[0]=0xFD; //构造帧头FD
headOfFrame[1]=0x00; //构造数据区长度的高字节
headOfFrame[2]=length + 3; //构造数据区长度的低字节
headOfFrame[3]=0x01; //构造命令字:合成播放命令
headOfFrame[4]=0x00; //构造命令参数:编码格式为GBK
while(1)
{
for(i=0;i<5;i++) //一次发送构造好的5个帧头字节
{
ecc=ecc^(headOfFrame[i]); //对发送的字节进行异或校验
SBUF=headOfFrame[i];
while(TI==0);
TI=0; //发送中断标志位清零
}
for(i=0;i<length;i++) //依次发送呆合成的文本数据
{
ecc=ecc^(text[i]); //对发送的字节进行异或校验
SBUF=text[i];
while(TI==0);
TI=0;
Delay1ms(2);
}
SBUF=ecc; //最后发送校验字节
while(TI==0);
TI=0;
Delay1ms(100);
ecc=0;
}
}
两个程序单独使用都是可以的,问题是怎样让它结合起来使用?
各位大神,请支支招!
