标题:
单片机接收PWM显示转速问题
[打印本页]
作者:
时间煮雨我煮鱼
时间:
2023-7-30 15:12
标题:
单片机接收PWM显示转速问题
下面有两块板,绿色的数码管是显示转速的,红色的数码管是显示clock信号的,也就是显示频率的,比如当红色的数码管手动调到200Hz时,绿色数码管就要显示800转速,这是个假设,不一定只显示800转,看电机是几对极来计算,现在绿色数码管的板子上引了一根通讯线与红色数码管的PWM线相连,打算用这根线来接收红色数码管通讯线的脉冲,然后将他转换得到转速显示在绿色数码管上,目前我需要知道一个思路,因为我写出来的没有实现出来,请大伙给个思路或函数框架。
51hei图片_20230730151138.jpg
(2.97 MB, 下载次数: 71)
下载附件
2023-7-30 15:11 上传
作者:
wulin
时间:
2023-7-30 21:56
适用于1000转/分钟以内
#include <reg51.H>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define DASE 60000
//全局变量声明
// 数据头 方向位 高位 低位 验证 数据尾
uchar data dis_buf[6]={ 0xaa, 0x00, 0x00, 0x00, 0xff, 0x55 };
uint D_num; //定时器中断计数变量
uint speed=0; //转速
uint temp=0; //T0中断计数临时变量
uint count=0; //主循环计数变量
uchar flag_Z=0; //外部中断标志
bit flag_D=0; //T0中断标志
//---本地函数声明---//
void Timer0Init(); //定时器T0初始化
void UartInit(); //定时器T1初始化波特率
void Delay_ms(uint t); //延时函数
//主函数
void main()
{
uchar k;
Timer0Init(); //初始化定时器0
UartInit(); //初始化定时器1波特率发生器
Delay_ms(100); //长延时100ms
IE0 = 0; //INT0中断请求标志清0
IT0 = 1; //设置外部下降沿中断
EX0 = 1; //开INT0中断
ET0 = 1; //开T0中断
EA = 1; //开总中断
Delay_ms(100); //长延时100ms
flag_Z=0; //外部中断标志初始0,消除加电时外部中断的一次触发
while(1)
{
if(flag_D==1) //定时器中断250ms
{
flag_D=0; //定时器中断标志清0
count++; //250ms计数++
if(flag_Z==3) //外部中断标志
{
flag_Z=2; //外部中断标志复位
speed=DASE/D_num; //计算转速 r/min
dis_buf[2]=speed>>8; //转速高8位
dis_buf[3]=speed; //转速低8位
count=0; //250ms计数清0
}
else if(count>24) //否则 如果持续6秒收不到外部中断信号清一次所有信息
{
count=0;
speed=0; //转速清0
dis_buf[2]=0x00; //转速高位缓存清0
dis_buf[3]=0x00; //转速低位缓存清0
D_num=0; //定时器中断缓存清0
temp=0; //定时器中断变量清0
flag_Z=0; //外部中断标志清0
}
dis_buf[4]=dis_buf[0]+dis_buf[1]+dis_buf[2]+dis_buf[3]+dis_buf[5];//计算验证码
for(k=0;k<6;k++)
{
SBUF = dis_buf[k]; //串口发送数据串
while(!TI); //等待串口发送中断请求标志位为1
TI=0; //串口发送中断请求标志清0
}
}
}
}
//T0中断服务函数 周期1ms
void Timer0Interrupt() interrupt 1
{
static uint i;
temp++;
i++;
if(i>=250) //250ms
{
i=0;
flag_D=1; //T0中断标志
}
}
//INT0中断服务函数
void INT0_Isr() interrupt 0
{
TR0=0; //关定时器0
D_num=temp; //读取定时器1ms中断计数值
temp=0; //定时器1ms中断计数值清0
TL0 = 0x66; //设置定时初始值
TH0 = 0xfc; //设置定时初始值
TR0=1; //开定时器0
if(++flag_Z>=3) //判断外部(霍尔)中断,用于起步消除错误计数
flag_Z=3;
}
//延时函数
void Delay_ms(uint t) //@11.0592MHz
{
uint i,j;
for(i=t;i>0;i--)
for(j=110;j>0;j--);
}
//初始化定时器T0
void Timer0Init() //1毫秒@11.0592MHz
{
TMOD|= 0x01; //设置定时器16位自动重载模式
TL0 = 0x66; //设置定时初始值
TH0 = 0xfc; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
//初始化串口T1
void UartInit() //9600bps@11.0592MHz
{
SCON = 0x50; //8位数据,可变波特率
TMOD|= 0x20; //设置定时器模式
TL1 = 0xfd; //设置定时初始值
TH1 = 0xfd; //设置定时初始值
ET1 = 0; //禁止定时器中断
TR1 = 1; //定时器1开始计时
}
复制代码
作者:
zsyzdx
时间:
2023-7-31 09:20
你需要把控制电机的PWM信号变成频率信号调节电机的速度 频率是不变的,所以你目前应该不行,要么用程序,采集占空比输出频率也可以!要么就直接用单片机驱动两个数码管显示,然后单片机输出PWM控制最简单。
作者:
yzwzfyz
时间:
2023-7-31 16:20
这是硬件问题。需要一个PWM电压与转速的对应关系。这个关系与硬件相关,你能找出这个关系吗。
认真读相关硬件的手册吧。尤其是电机。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1