找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

帖子
查看: 3319|回復(fù): 1
收起左側(cè)

求解這個(gè)單片機(jī)程序的PWM周期和采樣周期

[復(fù)制鏈接]
ID:628908 發(fā)表于 2019-10-31 17:13 | 顯示全部樓層 |閱讀模式
1黑幣
#include <reg51.h>
#include <intrins.h>
sbit plus_10=P1^3;       //對(duì)各個(gè)按鈕進(jìn)行位定義
sbit minus_10=P1^4;
sbit plus=P1^5;
sbit minus=P1^6;
sbit enter=P1^7;
sbit PWM_OUT1=P1^1;
sbit PWM_OUT2=P1^0;
sbit dir=P1^2;
struct PID             //定義PID結(jié)構(gòu)體
{
int SetValue;      //設(shè)定值
// long SumError;     //誤差
double Proportion;    //比例系數(shù)
double Integral;    //積分系數(shù)
double Derivative;    //微分系數(shù)
int LastError;
int PrevError;
}sPID,*sptr= &sPID;
int PWM,PWM_temp=1,count0=0,Speed_Set,Seep_Measure,counter_100ms,counter_10ms;
bit flag_100ms,flag_10ms,start,plus_10_lock=1,minus_10_lock=1,plus_lock=1,
    minus_lock=1,enter_lock=1;
char num[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};//0~9 對(duì)應(yīng)數(shù)碼
/*****************************************************************************************
*函數(shù)名:void delayms(unsigned char x)
*函數(shù)功能:簡(jiǎn)單延時(shí) 支持0~255ms
*函數(shù)參數(shù):x 延時(shí)時(shí)間
*****************************************************************************************/
void delayms(unsigned char x)
{
unsigned char i ;
while(x--)
for(i = 0 ; i < 120 ; i++) ;
}
/*****************************************************************************************
*函數(shù)名:void display(void)
*函數(shù)功能:顯示函數(shù)
*函數(shù)參數(shù):無
*****************************************************************************************/
void display(void)
{
P2 =0x7f; P0 = num[Speed_Set/100];delayms(2);   
P2 =0xbf; P0 = num[Speed_Set % 100 / 10];delayms(2);   
P2 =0xdf; P0 = num[Speed_Set % 10];delayms(2);
P2 =0xfb; P0 = num[Seep_Measure / 100];delayms(2);  
P2 =0xfd; P0 = num[Seep_Measure % 100/10];delayms(2);
P2 =0xfe; P0 = num[Seep_Measure % 10]; delayms(2);
if(start&&dir)
{
  P2=0xf7;P0=0x40;delayms(2);
}
}
/*****************************************************************************************
*函數(shù)名:void keyscan(void)
*函數(shù)功能:按鍵掃描
*函數(shù)參數(shù):無
*****************************************************************************************/
void keyscan(void)
{
static unsigned char plus_10_delay,minus_10_delay,plus_delay,minus_delay,enter_delay;
if(plus_10==0)
{
  if(plus_10_lock&&++plus_10_delay>=2)
  {
   plus_10_lock=0;
   if(Speed_Set<170)
   Speed_Set+=10;
   else Speed_Set=10;
  }
}
else
{
  plus_10_lock=1;
  plus_10_delay=0;
}            
if(minus_10==0)
{
  if(minus_10_lock&&++minus_10_delay>=2)
  {
   minus_10_lock=0;
   if(Speed_Set>10)
   Speed_Set-=10;
   else Speed_Set=170;
  }
}
else
{
  minus_10_lock=1;
  minus_10_delay=0;
}
if(plus==0)
{
  if(plus_lock&&++plus_delay>2)
  {
   plus_lock=0;
   if(Speed_Set<170)
   Speed_Set+=1;
   else Speed_Set=0;
  }
}
else
{
  plus_lock=1;
  plus_delay=0;
}
if(minus==0)
{
  if(minus_lock&&++minus_delay>2)
  {
   minus_lock=0;
   if(Speed_Set>0)
   Speed_Set-=1;
   else Speed_Set=170;
  }
}
else
{
  minus_lock=1;
  minus_delay=0;
}
if(enter==0)
{
  if(enter_lock&&++enter_delay>2)
  {
   enter_lock=0;
   sptr->SetValue =Speed_Set;
   start=1;
  }
}
else
{
  enter_lock=1;
  enter_delay=0;
}
}
/*****************************************************************************************
*函數(shù)名:void timer0(void)
*函數(shù)功能:定時(shí)器0 中斷函數(shù)
*函數(shù)參數(shù):無
*****************************************************************************************/
void timer0(void) interrupt 1
{
TH0=0xfc;                    //定時(shí)1ms
TL0=0x18;
if(++counter_100ms>=100)   
{
  counter_100ms=0;
  flag_100ms=1;
}
if(++counter_10ms>=10)
{
  flag_10ms=1;
  counter_10ms=0;
}
if(PWM&&--PWM_temp==0)
{
  PWM_OUT1=!PWM_OUT1;
  if(PWM_OUT1) PWM_temp=PWM;
  else PWM_temp=100-PWM;   //PWM周期小于等于采樣周期
}
}
/*****************************************************************************************
*函數(shù)名:void EIRQ0(void)
*函數(shù)功能:外部中斷0處理函數(shù) 記錄脈沖個(gè)數(shù)
*函數(shù)參數(shù):無
*****************************************************************************************/
void EIRQ0(void) interrupt 0  
{
count0++;
}
/*****************************************************************************************
*函數(shù)名:viod PIDInit(void)
*函數(shù)功能:PID參數(shù)初始化
*函數(shù)參數(shù):無
*****************************************************************************************/
void PIDInit(void)
{
// sptr->SumError = 0;
sptr->LastError = 0; //Error[-1]
sptr->PrevError = 0; //Error[-2]
sptr->Proportion = 2.3; //比例系數(shù)
sptr->Integral = 1.2;   //積分系數(shù)
sptr->Derivative = 0.1; //微分系數(shù)
sptr->SetValue = 0;
}
/*****************************************************************************************
*函數(shù)名:int PID_Calc(int MeasureValue)
*函數(shù)功能:PID算法 調(diào)節(jié)PWM增量
*函數(shù)參數(shù):MeasureValue  測(cè)得的速度值 PID_Adjust 返回值 PWM誤差修正值
*****************************************************************************************/
int PID_Calc(int MeasureValue)
{
register int iError, PID_Adjust;
iError = sptr->SetValue - MeasureValue;   //計(jì)算增加量
PID_Adjust = (int)(sptr->Proportion * iError    //E[k]項(xiàng)
- sptr->Integral * sptr->LastError     //E[k-1]項(xiàng)
+ sptr->Derivative * sptr->PrevError);    //E[k-2]項(xiàng)
//存儲(chǔ)當(dāng)前誤差以便后面計(jì)算
sptr->PrevError = sptr->LastError;
sptr->LastError = iError;
//返回增量值
return (PID_Adjust);
}
/*****************************************************************************************
*函數(shù)名:void main(void)
*函數(shù)功能:主函數(shù)
*函數(shù)參數(shù):無
*****************************************************************************************/
void main(void)   
{
TMOD=0x01;
TH0=0xfc;
TL0=0x18;
IT0=1;
EX0=1;
ET0=1;
TR0=1;
EA=1;
PWM_OUT1=0 ;
PWM_OUT2=0;
PIDInit();
while(1)
{
  if(flag_100ms)      //100ms采集一次脈沖數(shù)
  {
   Seep_Measure=count0;   //(600/600)*count0
   count0=0;
   flag_100ms=0;
   if(start==1)     //調(diào)整PWM
   {
    int PWM_PID;
    PWM_PID=PID_Calc(Seep_Measure);
    if((PWM+0.5*PWM_PID)<99&&(PWM+0.5*PWM_PID)>1) //防止調(diào)節(jié)比例過大 造成PWM值超出范圍
    PWM=PWM+0.5*PWM_PID;              //0.5用于保證速度調(diào)整跨度過大時(shí)PWM不會(huì)過界
   }
  }
  if(flag_10ms)
  {
   keyscan();
   display();
   flag_10ms=0;
  }
}
}

回復(fù)

使用道具 舉報(bào)

ID:584814 發(fā)表于 2019-11-6 20:20 | 顯示全部樓層
帶著學(xué)習(xí)的目的看了一遍,果然沒看懂,但發(fā)現(xiàn)這句注釋:“//100ms采集一次脈沖數(shù)”...
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表