久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费
標題:
求解這個單片機程序的PWM周期和采樣周期
[打印本頁]
作者:
九界
時間:
2019-10-31 17:13
標題:
求解這個單片機程序的PWM周期和采樣周期
#include <reg51.h>
#include <intrins.h>
sbit plus_10=P1^3; //對各個按鈕進行位定義
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結構體
{
int SetValue; //設定值
// long SumError; //誤差
double Proportion; //比例系數
double Integral; //積分系數
double Derivative; //微分系數
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 對應數碼
/*****************************************************************************************
*函數名:void delayms(unsigned char x)
*函數功能:簡單延時 支持0~255ms
*函數參數:x 延時時間
*****************************************************************************************/
void delayms(unsigned char x)
{
unsigned char i ;
while(x--)
for(i = 0 ; i < 120 ; i++) ;
}
/*****************************************************************************************
*函數名:void display(void)
*函數功能:顯示函數
*函數參數:無
*****************************************************************************************/
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);
}
}
/*****************************************************************************************
*函數名:void keyscan(void)
*函數功能:按鍵掃描
*函數參數:無
*****************************************************************************************/
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;
}
}
/*****************************************************************************************
*函數名:void timer0(void)
*函數功能:定時器0 中斷函數
*函數參數:無
*****************************************************************************************/
void timer0(void) interrupt 1
{
TH0=0xfc; //定時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周期小于等于采樣周期
}
}
/*****************************************************************************************
*函數名:void EIRQ0(void)
*函數功能:外部中斷0處理函數 記錄脈沖個數
*函數參數:無
*****************************************************************************************/
void EIRQ0(void) interrupt 0
{
count0++;
}
/*****************************************************************************************
*函數名:viod PIDInit(void)
*函數功能:PID參數初始化
*函數參數:無
*****************************************************************************************/
void PIDInit(void)
{
// sptr->SumError = 0;
sptr->LastError = 0; //Error[-1]
sptr->PrevError = 0; //Error[-2]
sptr->Proportion = 2.3; //比例系數
sptr->Integral = 1.2; //積分系數
sptr->Derivative = 0.1; //微分系數
sptr->SetValue = 0;
}
/*****************************************************************************************
*函數名:int PID_Calc(int MeasureValue)
*函數功能:PID算法 調節PWM增量
*函數參數:MeasureValue 測得的速度值 PID_Adjust 返回值 PWM誤差修正值
*****************************************************************************************/
int PID_Calc(int MeasureValue)
{
register int iError, PID_Adjust;
iError = sptr->SetValue - MeasureValue; //計算增加量
PID_Adjust = (int)(sptr->Proportion * iError //E[k]項
- sptr->Integral * sptr->LastError //E[k-1]項
+ sptr->Derivative * sptr->PrevError); //E[k-2]項
//存儲當前誤差以便后面計算
sptr->PrevError = sptr->LastError;
sptr->LastError = iError;
//返回增量值
return (PID_Adjust);
}
/*****************************************************************************************
*函數名:void main(void)
*函數功能:主函數
*函數參數:無
*****************************************************************************************/
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采集一次脈沖數
{
Seep_Measure=count0; //(600/600)*count0
count0=0;
flag_100ms=0;
if(start==1) //調整PWM
{
int PWM_PID;
PWM_PID=PID_Calc(Seep_Measure);
if((PWM+0.5*PWM_PID)<99&&(PWM+0.5*PWM_PID)>1) //防止調節比例過大 造成PWM值超出范圍
PWM=PWM+0.5*PWM_PID; //0.5用于保證速度調整跨度過大時PWM不會過界
}
}
if(flag_10ms)
{
keyscan();
display();
flag_10ms=0;
}
}
}
作者:
man1234567
時間:
2019-11-6 20:20
帶著學習的目的看了一遍,果然沒看懂,但發現這句注釋:“//100ms采集一次脈沖數”...
歡迎光臨 (http://m.zg4o1577.cn/bbs/)
Powered by Discuz! X3.1
主站蜘蛛池模板:
在线观看欧美日韩
|
天天插天天射
|
亚洲国产日韩欧美
|
国产成人97精品免费看片
|
蜜桃视频一区二区
|
超碰免费观看
|
91久久国产综合久久
|
91性高潮久久久久久久久
|
精久久久久
|
欧美久久久久久久
|
日韩在线小视频
|
亚洲成人av
|
国产操操操
|
日韩成人在线播放
|
在线观看91
|
一区二区三区影院
|
午夜性色
|
久久久三级
|
999免费视频
|
手机成人在线视频
|
黄色网在线
|
亚洲激情第一页
|
一级做a爱片性色毛片
|
欧美91
|
黄色日皮视频
|
亚洲精品中文字幕乱码三区91
|
亚洲一区二区三区
|
国产一区二区不卡
|
国产成人区
|
亚洲乱色
|
福利视频二区
|
国产浮力第一页
|
国产一区二区三区久久
|
国语对白做受欧美
|
天天操操操操
|
精品视频免费
|
国产欧美精品
|
中文字幕免费观看
|
中文字幕播放
|
亚洲天堂中文字幕
|
中文字幕黄色片
|