//------------------------------------------------------------
// spwm信號調制
//------------------------------------------------------------
//PIC單片機PIC16F716,包含PWM調制,AD采樣,PI控制算法
#include <pic16f716.h>
#include<pic.h>
#include<string.h>
#include<stdio.h>
//------------------------------------------------------------
//系統配置
__CONFIG(0xfff6);
//-------------------------------------------
#define Reference 0.5;//給定參考值,即PID中的Setpoint
const unsigned char sin_[]={0,8,16,23,31,38,46,53,60,67,74,81,87,93,99,105,111,116,121,126,130,134,138,142,145,147,150,152,154,155,156,156,//正半周
156,
156,156,155,154,152,150,147,145,142,138,134,130,126,121,116,111,105,99,93,87,81,74,67,60,53,46,38,31,23,16,8,1//負半周
};
unsigned char sin_num;//SIN函數表查表變量
bank1 float sin_am,sin_l,sin_d;//浮點數,幅值變量,臨時變量,臨時變量
bit direction;//控制方向
unsigned char AD_result;//存放AD轉換結果
typedef struct PID {
double Setpoint; //設定目標
double Proportion;//比例常數
double Integral;//積分常數
double Derivative;//微分常數
double LastError;//Error【-1】,使用差分方程
double PrevError;//Error【-2】
double SumError;
}PID;//定義PID相關數據類型
/*************************************************************************************************/
//***************PID計算函數*****************
double PID_calc(PID *pp,double NextPoint)
{
double dError,
Error;
Error=pp->Setpoint-NextPoint; //偏差
pp->SumError+=Error; //積分
dError=pp->LastError-pp->PrevError; //當前微分
pp->PrevError=pp->LastError;
pp->LastError=Error;
return(pp->Proportion*Error //比例項
+ pp->Integral*pp->SumError//積分項
+ pp->Derivative*dError); //微分項
}
//**************PID初始化函數***************
void INIT_pid(PID *pp)
{
memset(pp,0,sizeof(PID));
}
//**************PID執行函數*****************
void actuator(double rDelta)
{
}
//*************軟件延時子程序***************
void DELAY()
{
unsigned int i;
for(i=200;i>0;i--);
}
//******************中斷服務程序*************************************
void interrupt ISR()
{
//-------PWM中斷函數-------------------
if(TMR2IF&TMR2IE)
{
CLRWDT();//清除看門狗
TMR2IF=0;//清零中斷標志位
sin_d=sin_am*sin_[sin_num];
if(sin_d>=156)sin_l=156;//限幅
sin_l=(unsigned char)sin_d;
CCPR1L=sin_l;
sin_num++;
if(65==sin_num)
{
sin_num=0;
direction=~direction;//換向
P1M1=direction;
}
}
}
//*********************開始AD轉換**********************************
unsigned char START_A2D()
{
DELAY();//采樣延時
GO=1;//開始AD轉換
while(GO);//等待轉化完成
AD_result=ADRES;
return(AD_result);
}
//*********************pwm初始化函數*******************************
void INIT_CCP()
{
PR2=0x9C; //十進制156
CCP1CON=0b11001100;// 1100 1100四輸出全橋驅動,占空比低2位暫時清零,
//PWM 模式。P1A,P1C高電平有效;P1B, P1D 高電平有效;
CCPR1L=0x00;//占空比清零
TMR2IF=0; //Timer2 中斷標志位清零
T2CON=0b00000100; //0010 0100預分頻1,后分頻1:1,使能timer2
TMR2IE=1; //允許TMR2 和 PR2 匹配中斷
}
//********************AD初始化**************************************
void INIT_A2D()
{
//--------------ADCON0----------------
ADCS1=0;ADCS0=1;//Fosc/8,外接16M晶振時采樣時間約為600ns
CHS2=0;CHS1=1;CHS0=0;//RA2作為輸入通道
//--------------ADCON1----------------
PCFG2=0;PCFG1=0;PCFG0=0;//AN3:0都為模擬輸入
ADON=1;//打開AD模塊
}
//******************初始化端口*************************************
void INIT_PORT()
{
//---------端口B初始化---------------
TRISB=0;//B端口為輸出
PORTB=0X00;
//---------端口A初始化---------------
TRISA=1;//A端口為輸入
}
//****************************主函數*********************************************
void main(void)
{
PID sPID;
double rOut;
double rIn;
INIT_pid(&sPID);
sPID.Proportion=0.5;
sPID.Integral=0.5;
sPID.Derivative=0.0;
sPID.Setpoint=1.0;
INIT_CCP();
INIT_PORT();
direction=0;
sin_num=0;
sin_am=Reference;//調節AC幅度
PEIE=1;
GIE=1;
while(1)
{
rIn=START_A2D();
rOut=PID_calc(&sPID,rIn);
actuator(double rOut);
}
}
本人在編譯這個程序的時候遇到的問題如下:
1、編譯器為picc9.83,源碼復制張貼編譯報錯很多actuator(double rOut);此處也報錯,刪double后沒有報錯了,但是出現了以下報錯:
Executing: "d:\Program Files (x86)\HI-TECH Software\PICC\9.83\bin\picc.exe" --pass1 C:\Users\WanChen\Desktop\PICPWM\pwm16\pwm.c -q --chip=16F716 -P --runtime=default --opt=default -D__DEBUG=1 -g --asmlist "--errformat=Error [%n] %f; %l.%c %s" "--msgformat=Advisory[%n] %s" "--warnformat=Warning [%n] %f; %l.%c %s"
Warning [162] d:\Program Files (x86)\HI-TECH Software\PICC\9.83\include\pic16f716.h; 3.81 #warning: Header file pic16f716.h included directly. Use #include <htc.h> instead.
Warning [356] C:\Users\WanChen\Desktop\PICPWM\pwm16\pwm.c; 78.13 implicit conversion of float to integer
Executing: "d:\Program Files (x86)\HI-TECH Software\PICC\9.83\bin\picc.exe" -opwm.cof -mpwm.map --summary=default --output=default pwm.p1 --chip=16F716 -P --runtime=default --opt=default -D__DEBUG=1 -g --asmlist "--errformat=Error [%n] %f; %l.%c %s" "--msgformat=Advisory[%n] %s" "--warnformat=Warning [%n] %f; %l.%c %s"
HI-TECH C Compiler for PIC10/12/16 MCUs (PRO Mode) V9.83
Copyright (C) 2011 Microchip Technology Inc.
Serial number: HCPICP-11111 (PRO)
Error [1360] C:\Users\WanChen\Desktop\PICPWM\pwm16\pwm.c; 87. no space for auto/param main@sPID
當這行代碼:bank1 float sin_am,sin_l,sin_d;變量類型改為int 型或者char型的時候編譯成功,但是燒寫后,只有兩路互補146hz方波輸出,沒有spwm調制波輸出,還望論壇里的大神指。
|