欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
關于單片機直流電機轉速測量與控制的請教
[打印本頁]
作者:
swx想去cityu
時間:
2020-5-4 21:53
標題:
關于單片機直流電機轉速測量與控制的請教
各位大佬好,我有幾個問題想請教大家。
為什么我在proteus仿真中直流電機最大轉速只能是166r/m。請問這是和占空比有關系嗎?我的占空比設置的是0~100,或者是和代碼中哪一部分有關呢?
當我預設速度是(setspeed)是155r/m是,通過INT0輸入脈沖計算的轉速是(nowspeed)是150r/m或者165r/m。請問這是和我使用的是頻率法計算有關嗎?
轉速n=60M/TP. (在規定時間T內,測量輸入脈沖個數M,P是指對于每轉有P個脈沖)。Proteus中我選擇的是motor-encoder 每圈輸出P=2個脈沖,規定時間T=2s。所以我個人的理解是60*M/2.0*2.0。因為頻率法導致的
起始時間與轉速信號脈沖的不完全一致
,
造成的±1個脈沖的丟失。
(比如60*5/4-60*4/4=15)所以導致轉速是150r/m和165r/m。
所以頻率法更適合高速運轉的電機。但是為啥我的proteus中直流電機最高只能是166r/m呢?
1.PNG
(142.69 KB, 下載次數: 24)
下載附件
2020-5-4 21:43 上傳
2.PNG
(147.18 KB, 下載次數: 16)
下載附件
2020-5-4 21:43 上傳
我表達的可能不是特清楚,還請大家賜教~,別噴我,謝謝。代碼有借鑒大家的。
#include<reg51.h>
sbit Motor_ENA=P1^4; //L298N驅動引腳
sbit Motor_IN1=P1^0;
sbit Motor_IN2=P1^2;
sbit LCD_RS=P3^6;
sbit LCD_EN=P3^7;
sbit LCD_RW=P3^5;
sbit S1=P2^0;
sbit S2=P2^1;
sbit S3=P2^2;
sbit S4=P2^3;
sbit S5=P2^4;
#define uchar unsigned char
#define uint unsigned int
uint AA,count=0,flag; //AA:定時器0中斷次數;count:INT0中斷次數
void timer(); //定時器初始化
void InitLCD(); //顯示屏初始化
void KeyDown(); //按鍵程序
unsigned int PID();
void SendCommandToLCD(unsigned char LCDCommand);
void SendDataToLCD(unsigned char LCDData);
void delay1(unsigned int i);
void Display();
void LCD1602DisplayString(unsigned char Disposition,unsigned char *pointer);
void DisplayNumber(unsigned int DisplayData,unsigned char StartPosition,unsigned char Longth_Number);
void DisplayNumber1(unsigned int DisplayData1,unsigned char StartPosition1,unsigned char Longth_Number1);
float kp=0.30,ki=0.05,kd=0.01; //PI
unsigned int SpeedSet=115; //初始轉速
uint CurrentSpeed; //當前轉速
unsigned char pid_val_mid; //占空比調整
unsigned int lastError=0;
long int sumError=0; //sumError偏差和
/**************************************************************
延遲函數
**************************************************************/
void delay1(unsigned int i)
{
unsigned int j;
for(;i>0;i--)
for(j=0;j<20;j++);
}
/**************************************************************
main
**************************************************************/
void main()
{
timer(); //定時器初始化
InitLCD(); //LCD初始化
while(1)
{
KeyDown(); //按鍵控制程序
Display(); //LCD顯示程序
}
}
/*****************************************************************
void timer() 定時器,中斷初始化
定時器0:計時 定時器1:PWM控制
*****************************************************************/
void timer()
{
TMOD=0x11; //定時器0 ,定時器1 工作方式1
TH0=(65536-50000)/256; //50ms初值
TL0=(65536-50000)%256;
TH1=0xfc; //1ms PWM控制
TL1=0x66;
//TH1=(65536-50)/256;
//TL1=(65536-50)%256;
TR1=1; //????????1
ET1=1; //????????1?ж????
IT0=1; //???ж?0????????
EX0=1; //?????ж?INT0????
TR0=1; //????????0
ET0=1; //????????0?ж????
EA=1; //
}
/*****************************************************************
InitLCD() LCD初始化
*****************************************************************/
void InitLCD()
{
LCD_RW=0;
SendCommandToLCD(0x38);
SendCommandToLCD(0x0c);
SendCommandToLCD(0x06);
SendCommandToLCD(0x01);
LCD1602DisplayString(0x80,"SetSpeed");
LCD1602DisplayString(0xC0,"NowSpeed");
}
/*****************************************************************************
LCD1602DisplayStr
******************************************************************************/
void LCD1602DisplayString(unsigned char Disposition,unsigned char *pointer)
{
SendCommandToLCD(Disposition);
while(*pointer!='\0')
{
SendDataToLCD(*pointer++);
}
}
/******************************************************************
void Timer0_isr() interrupt 1
定時器0中斷
*******************************************************************/
void Timer0() interrupt 1
{
AA++;
//TH0=0x4b;
//TL0=0xfe;
TH0=(65536-50000)/256;
TL1=(65536-50000)%256;
if(AA==39)
{
CurrentSpeed=(count*60.0)/(2.0*2.0); //一分鐘的轉速,2.0:一轉有兩個脈沖,AA==39是2秒
count=0;
AA=0;
PID();
}
}
/*******************************************************************
void key_int() interrupt0
外部中斷INT0
********************************************************************/
void key_int() interrupt 0
{
count++;
}
/********************************************************************
void Timer1() interrupt 3
定時器1中斷
*********************************************************************/
void Timer1() interrupt 3
{
static int c=0;
TH1=0xfc;
TL1=0x66;
//TH1=(65536-50)/256;
//TL1=(65536-50)%256;
c++;
if(c<=pid_val_mid) Motor_ENA=1;
if(c>pid_val_mid) Motor_ENA=0;
if(c>=100) c=0;
}
/******************************************************************
void KeyDown
電機控制程序
******************************************************************/
void KeyDown()
{
if(S1==0) //正轉
{
delay1(2);
if(S1==0)
{
Motor_IN1=1;
Motor_IN2=0;
}
}
if(S2==0) //反轉
{
delay1(2);
if(S2==0)
{
Motor_IN1=0;
Motor_IN2=1;
}
}
if(S3==0) //停車
{
delay1(2);
if(S3==0)
{
Motor_IN1=0;
Motor_IN2=0;
}
}
if(S4==0)
{
delay1(2);
if(S4==0)
{
SpeedSet+=10; //設定速度+10
}
}
if(S5==0)
{
delay1(2);
if(S5==0)
{
SpeedSet-=10; //設定速度-10
}
}
}
/**************************************************************
PID控制
**************************************************************/
unsigned int PID()
{
int dError=0,Error=0,B;
Error=SpeedSet-CurrentSpeed; //當前誤差
sumError=Error+sumError; //誤差和
dError=Error-lastError; //誤差偏差
lastError=Error;
B=kp*Error+ki*sumError+kd*dError;
if(B>100) pid_val_mid=100;
if(B<0) pid_val_mid=0;
if(B>=0&&B<=100) pid_val_mid=B;
return(0);
}
/***************************************************************
LCD1602
寫命令函數
*****************************************************************/
void SendCommandToLCD(unsigned char LCDCommand)
{
P0=LCDCommand;
LCD_RS=0;
delay1(2);
LCD_EN=1;
delay1(2);
LCD_EN=0;
delay1(2);
}
/*****************************************************************
LCD1602
寫數據函數
******************************************************************/
void SendDataToLCD(unsigned char LCDData)
{
P0=LCDData;
LCD_RS=1;
delay1(2);
LCD_EN=1;
delay1(2);
LCD_EN=0;
delay1(2);
}
/********************************************************************
void display
*********************************************************************/
void Display()
{
DisplayNumber(SpeedSet*10,8,5);
DisplayNumber1(CurrentSpeed*10,8,5); //因為要精確到小數點后一位,所以我先*10
}
/*********************************************************************
void DisplayNumber() 預設轉速顯示 Setspeed
**********************************************************************/
void DisplayNumber(unsigned int DisplayData,unsigned char StartPosition,unsigned char Longth_Number)
{
unsigned char i=0;
SendCommandToLCD(0x80+StartPosition+7); //小數位
SendDataToLCD(DisplayData%10+0x30);
DisplayData=DisplayData/10;
SendCommandToLCD(0x80+StartPosition+6); //0x2E顯示小數點
SendDataToLCD(0x2e);
for(i=Longth_Number;i>0;i--)
{
SendCommandToLCD(0x80+StartPosition+i);
SendDataToLCD(DisplayData%10+0x30);
DisplayData=DisplayData/10;
}
}
/**********************************************************************
void DisplayNumber2() 實時轉速顯示CurrentSpeed
***********************************************************************/
void DisplayNumber1(unsigned int DisplayData1,unsigned char StartPosition1,unsigned char Longth_Number1)
{
unsigned char a=0;
SendCommandToLCD(0xC0+StartPosition1+7); //小數位
SendDataToLCD(DisplayData1%10+0x30);
DisplayData1=DisplayData1/10;
SendCommandToLCD(0xC0+StartPosition1+6); //0x2E
SendDataToLCD(0x2e);
for(a=Longth_Number1;a>0;a--)
{
SendCommandToLCD(0xC0+StartPosition1+a);
SendDataToLCD(DisplayData1%10+0x30);
DisplayData1=DisplayData1/10;
}
}
作者:
LOVE008
時間:
2020-5-7 16:05
樓主你好,我現在也在做這方面的的設計,想需要你的資料參考一下
歡迎光臨 (http://m.raoushi.com/bbs/)
Powered by Discuz! X3.1