?? setup.c
字號:
/**********************************************************************
* 程序說明
*
* 該文件包含所有的dsPIC外圍設備設置子程序,此外還有WriteConfig()函數,
* 該函數可以在運行時間配置芯片的位,尤其是WriteConfig()還可以反轉PWM
* 輸出信號的極性;在PWM運行周期的結束點,PWM用于觸發A/D轉換。這樣可以
* 保證AD能夠及時被觸發,不管PWM的占空比如何,要完成這項功能,用戶必須
* 把占空比值寫入PDC寄存器。
* ADC在此點觸發
* |
* PWM1 _____ _______________
* |________________| |_______
*
* PWM2 _____ _______________________
* |________| |_______
*
* PWM3 _____ _________
* |______________________| |_______
*
*
**********************************************************************/
#include "general.h"
#include "hardware.h"
#include "defs.h"
#include "extern_globals.h"
void setup_ports(void);
void setup_motor_pwms(void);
void setup_adc(void);
void setup_qei(void);
void setup_timers(void);
unsigned int ReadConfig(int);
void WriteConfig(int,int);
#ifdef DEVELOPMODE
void setup_uart(void);
#endif
//設置端口子程序
void setup_ports(void)
{
//清所有的端口
PORTB=0;
PORTC=0;
PORTD=0;
PORTE=0;
//確保禁止點火
DISABLE_FIRING;
//設定端口方向
TRISB = 0xFFFF; // RB15:輸出比較錯誤 -> 輸入
// RB14-0:模擬端口 -> 輸入
TRISC = 0x6000; // RC14: S2起始/停止開關 -> 輸入
// RC13: S3 后退/前進開關 -> 輸入
// 其余的C端口設定為輸出
TRISD = 0x0003; // RD0-1:調試EMUC2/EMUD2 -> 輸入
// 其余的D端口設定為輸出
TRISE = 0x0100; // RE8: PWM出錯按鈕 -> 輸入
// RE5-0:PWM信號 -> 輸出
return;
}
//設置馬達PWM子程序
void setup_motor_pwms(void)
{
unsigned int config_value,temp;
//時基控制
PTCON = 0x8000; //時基開,運行與空閑模式,無預置或后置,自由運行
//周期寄存器 :自由運行時PWM周期為(PTER+1) * Tcy * Prescaler
PTPER = FULL_DUTY/2; //7.3728MHz指令頻率,無預置
//當FULL_DUTY= 922時,PWM為16kHz
//特定事件觸發控制
SEVTCMP = FULL_DUTY/2; // 開關關之前立即觸發
//PWM控制寄存器#1
PWMCON1 = 0x0700; // 第4項點火信號不用,其余的獨立
//PWM控制寄存器#2
PWMCON2 = 0x0000; //無特殊事件預置,快速超越,使能更新
//停滯時間控制寄存器
DTCON1 = 0x0000; // 禁止停滯時間
//錯誤A輸入控制寄存器
FLTACON = 0xFF0F; //鎖存FLTA所有引腳激活
//改寫控制寄存器
OVDCON = 0x3FFF; // 所有輸出產生PWM,所有超越狀態激活
// PDC1-4 - PWM#1-4 占空比寄存器
PDC1=FULL_DUTY; //在此種情況下占空比滿值
PDC2=FULL_DUTY;
PDC3=FULL_DUTY;
config_value=ReadConfig(4);
temp=config_value;
temp=(temp & 0x0700)>>8;
//如果PWM極性和復位定義位正確設置,temp=4
if (temp != 4)
{
config_value &= 0xF0FF;
config_value |= 0x0400;
//寫新值到F80004
WriteConfig(4,config_value);
}
IFS2bits.PWMIF = 0;
IFS2bits.FLTAIF =0;
return;
}
//設置ADC子程序
void setup_adc(void)
{
// ADC控制寄存器#1
ADCON1 = 0x006F; //采用PWM觸發,連續同時采樣
// ADC控制寄存器#2
ADCON2 = 0x0200; //參考電壓采用Avdd/Avss, 轉換CH0、CH1、CH2 和CH3共4個通道,不掃描
//完成每個采樣/ 轉換過程后產生中斷,總是使用MUX A 輸入多路開關設置
// ADC控制寄存器#3
ADCON3 = 0x0003; // 不采用自動采樣,A/D時鐘由系統時鐘產生(2Tcy),
// 轉換時間大約3us,7.3728Mhz X4 PLL時給出271ns Tad
// A/D輸入選擇寄存器
ADCHS = VPH_RED; //MUXB不用, MUXA-ve=Vss,對CH1-3通道+ve=AN0-2
//對CH0 -ve=Vss,+ve=AN12
// ADC端口配置寄存器
ADPCFG = 0x8000; //AN15引腳:模擬輸入引腳處于數字模式,使能端口讀取輸入, A/D 輸入多路開關輸入連接到AVSS
//所有其他端口:模擬輸入引腳處于模擬模式,禁止端口讀取輸入, A/D 采樣引腳電壓
// A/D 輸入掃描選擇寄存器
ADCSSL = 0x7020; //選擇對AN5, AN12-14 輸入進行掃描
// 清A/D中斷
IFS0bits.ADIF = 0;
// 打開ADC模塊
ADCON1bits.ADON=1;
return;
}
//設置QEI子程序
void setup_qei(void)
{
//QEI控制寄存器
QEICON = 0x0910; //在空閑模式下,模塊繼續工作,位置計數器方向為正(+), 啟動16 位定時器,
//相位A 和相位B 輸入已交換,位置計數器方向狀態輸出為正常的I/O 引腳,定時器輸入時鐘預分頻比1:64(7372800/64 = 115.2kHz )
//數字濾波器控制寄存器
DFLTCON = 0x0000;//數字濾波器輸出為正常的引腳,數字濾波器時鐘分頻1:1,數字濾波器輸出禁止
MAXCNT = 0xffff; //最大計數寄存器設為滿值
IFS2bits.QEIIF=0; //清QEI中斷
return;
}
//設置定時器子程序
void setup_timers(void)
{
// Timer 1為守護時間,用于捕捉丟失的過零事件,以防止過流。
// Timer 2用于記時換向事件的時間間隔
// Timer 3用于準時關閉閘刀開關,
//時基寄存器#1
T1CON= 0x8020; //定時器開, 在空閑模式定時器繼續工作,定時器輸入時鐘預分頻為1:64
//時鐘預分頻與T2 和 QEI匹配
PR1=0xFFFF; //設置周期匹配寄存器為滿值
IFS0bits.T1IF=0; //清T1中斷標志
//時基寄存器#2
T2CON=0x8020; //定時器開, 在空閑模式定時器繼續工作,定時器輸入時鐘預分頻為1:64
//時鐘預分頻與QEI匹配,用作“輸入捕捉”
PR2=0xFFFF; //設置周期匹配寄存器為滿值
IFS0bits.T2IF=0; //清T2中斷標志
//時基寄存器#3
T3CON=0x8020; //定時器開, 在空閑模式定時器繼續工作,定時器輸入時鐘預分頻為1:64
PR3=0xFFFF;
IFS0bits.T3IF=0; //清T3中斷標志
return;
}
//在指定地址讀值子程序
unsigned int ReadConfig(int address)
{
//表頁指向配置頁
asm(" mov.w #0x00F8,w2");
asm(" mov.w w2,TBLPAG");
//讀值
asm(" tblrdl [w0],w0");
//返回所讀的值
return WREG0;
}
//在指定地址寫值子程序
void WriteConfig(int address, int value)
{
//表頁指向配置頁
asm(" mov.w #0x00F8,w2");
asm(" mov.w w2,TBLPAG");
// 設定NVMCON值,開始寫
asm(" mov.w #0x4008,w2");
asm(" mov.w w2,NVMCON");
// 寫值
asm(" tblwtl W1,[W0]");
asm(" bset NVMCON,#14");
asm(" mov #0x55,W2 ");
asm(" mov W2,NVMKEY ");
asm(" mov #0xaa,W2 ");
asm(" mov W2,NVMKEY ");
asm(" bset NVMCON,#15");
while(NVMCONbits.WR);
}
#ifdef DEVELOPMODE
//設定UART子程序
void setup_uart(void)
{
U1MODE = 0x8000;
U1STA = 0x0000;
U1BRG = ((CLOCK_FREQ/16)/BAUD) - 1; //設定波特率
IEC0bits.U1RXIE = 1;
RXPtr = &InData[0]; //指向接收字符串的首字符
control_flags2.CheckRX = 0;
control_flags2.SendTX = 0;
U1STAbits.UTXEN = 1; //初始化數據傳輸
}
#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -