?? aaa.c
字號:
// NOTE: USER CODE MUST WAIT AT LEAST 20 MS before calling ADC_Read (Using the ADC)
}
/******************************************************************************
* ADC_Init(channel)
*功能描述:ADC初始化,選擇模擬通道輸入,初始化時鐘,關閉ADC中斷
*參 數:channel - uchar 選擇ADC通道
*注 意:當ADC通道改變得時候,此子程序一定要被調用
*****************************************************************************/
void ADC_Init (unsigned char channel)
{
unsigned char temp;
ACON = 0;
temp = (0x01) << channel; // 選擇通道
P1SFS0 |= temp;
P1SFS1 |= temp; // 設置P1口相應位為ADC輸入
ADCPS =(0x08 + 1); // 使能ADC時鐘,設置時鐘頻率
_nop_();
ACON = 0x20; // 允許ADC轉換
// NOTE: USER CODE MUST WAIT AT LEAST 20 MS before calling ADC_Read (Using the ADC)
}
/******************************************************************************
* uint ADC_Read(channel)
*功能描述:讀A/D轉換后的數據
*參 數:channel,初始化程序中選擇的通道
*返 回 值:ADC轉換結果,12位
*注 意:該子程序調用前,ADC_Init()必須先被調用
*******************************************************************************/
unsigned int ADC_Read( unsigned char channel )
{
unsigned int temp_ADC_result;
ACON &= 0xE0; //清除輸入通路 ~(00101110B) = (11010001B)
ACON |= (channel<<2); //選擇通路
_nop_ ();
_nop_ ();
ACON |= 0x02; //開始ADC轉換
_nop_ (); //延時一個機器周期: ADST: 1->0
while( (ACON & 0x01) != 1 ); //等待轉換結束
// Note: For increased ADC accuracy, the while loop above should be
// replaced with code that puts the MCU into Idle mode via PCON
// and makes use of the ADC interrupt to exit the Idle mode.
// The user would need to enable the ADC int and define the ADC ISR.
temp_ADC_result = (ADAT1<<8)+ADAT0; //Calculate ADC conversion result
return (temp_ADC_result);
}
/*******************************************************************************
* int sin_angle(long angle )
*功能描述:角度換算函數,使角度值控制在180以內
*
********************************************************************************/
int sin_angle(long angle )
{
int Mod_data;
Mod_data = (int)angle/180;
switch (Mod_data )
{
case 0:
M_angle = sin_table[angle];
break;
case 1:
M_angle = -sin_table[angle - 180];
break;
case 2:
M_angle = sin_table[angle - 360];
break;
case 3:
M_angle = -sin_table[angle - 540];
break;
}
return(M_angle);
}
/*******************************************************************************
* void first(void )
*第一個采樣點計算函數,在K=0時計算
*******************************************************************************/
void first(void )
{
U_angle = K*180/N; //U相在K=0時計算
V_angle = U_angle + 120;
W_angle = U_angle + 240;
U_Toff = ((Half_Ts * (0xffff - M*(sin_angle(U_angle))))>>16);
V_Toff = ((Half_Ts * (0xffff - M*(sin_angle(V_angle))))>>16);
W_Toff = ((Half_Ts * (0xffff - M*(sin_angle(W_angle))))>>16);
P_flag = 0;
}
/*------------------------------------------------------------------------------
timer0_isr()
This function is an interrupt service routine for TIMER 0. It should never
be called by a C or assembly function. It will be executed automatically
when TIMER 0 overflows.
This ISR stops timer0, adjusts the counter so that another interrupt occurs in
10ms, and then restarts the timer.
------------------------------------------------------------------------------*/
//定時器0中斷服務程序
//定時器0用于產生采樣周期的定時中斷,采樣周期Ts =1/2載波周期 = 278 時鐘周期
static void timer0_isr (void) interrupt TF0_VECTOR using 1
{
TR0 = 0; /* stop timer 0 */
TL0 = (timer0_value & 0x00FF);
TH0 = (timer0_value >> 8);
TR0 = 1; /* start timer 0 */
////////////////////////////////////////////
////將上一次定時器中斷計算的延時值送入TCM0,TCM1,TCM2的比較寄存器
//
//
////取當前PCA0的計數值
PCA0 = PCACL0 + (PCACH0 << 8 );
//
////實際延時時間應加上PCA0的當前計數值
//
U_Toff += PCA0;
V_Toff += PCA0;
W_Toff += PCA0;
U_Ton += PCA0;
V_Ton += PCA0;
W_Ton += PCA0;
//
//
////偶數頂點采樣使用Toff,奇數底點采樣使用Ton
if ( P_flag==0)
{
CAPCOML0 = (U_Toff & 0x00FF);
CAPCOMH0 = (U_Toff >> 8);
CAPCOML1 = (V_Toff & 0x00FF);
CAPCOMH1 = (V_Toff >> 8);
CAPCOML2 = (W_Toff & 0x00FF);
CAPCOMH2 = (W_Toff >> 8);
}
else
{
CAPCOML0 = (U_Ton & 0x00FF);
CAPCOMH0 = (U_Ton >> 8);
CAPCOML1 = (V_Ton & 0x00FF);
CAPCOMH1 = (V_Ton >> 8);
CAPCOML2 = (W_Ton & 0x00FF);
CAPCOMH2 = (W_Ton >> 8);
} //66
////////////////////////////////////////////
//下一個采樣點
P_flag = ~P_flag; //奇偶點變換
K++; //下一個采樣點值
Tm++;
U_angle = K*180/N;
V_angle = U_angle + 120;
W_angle = U_angle + 240;
if (P_flag == 0)
{
// U_Toff =k1* ((Half_Ts * (0xffff - M*(sin_angle(U_angle))))>>16);
// V_Toff =k1* ((Half_Ts * (0xffff - M*(sin_angle(V_angle))))>>16);
// W_Toff =k1* ((Half_Ts * (0xffff - M*(sin_angle(W_angle))))>>16);
U_Toff =((Half_Ts * (0xffff - M*(sin_angle(U_angle))))>>16);
V_Toff =((Half_Ts * (0xffff - M*(sin_angle(V_angle))))>>16);
W_Toff =((Half_Ts * (0xffff - M*(sin_angle(W_angle))))>>16);
}
else
{
U_Ton =((Half_Ts * (0xffff + M*(sin_angle(U_angle))))>>16);
V_Ton =((Half_Ts * (0xffff + M*(sin_angle(V_angle))))>>16);
W_Ton =((Half_Ts * (0xffff + M*(sin_angle(W_angle))))>>16);
}
// if (P_flag == 0)
// {
// U_Toff = (417 * (0x400000 - M*(sin_angle(U_angle))))>>22;
// V_Toff = (417 * (0x400000 - M*(sin_angle(V_angle))))>>22;
// W_Toff = (417 * (0x400000 - M*(sin_angle(W_angle))))>>22;
// }
// else
// {
// U_Ton = (417 * (0x400000 + M*(sin_angle(U_angle))))>>22;
// V_Ton = (417 * (0x400000 + M*(sin_angle(V_angle))))>>22;
// W_Ton = (417 * (0x400000 + M*(sin_angle(W_angle))))>>22;
//
//
// }
// aa=0;
if ( K==2*N )
{ K=0;
// P_flag = 0;
}
}
/****************************************************************************
*死區指令延時,應實測,要考慮中斷影響
* 10個temp 延時約6us
****************************************************************************/
void delay1()
{
char temp;
EA=0;
temp = 0;
temp = 0;
temp = 0;
temp = 0;
temp = 0;
temp = 0;
temp = 0;
temp = 0;
temp = 0;
temp = 0;
temp = 0;
temp = 0;
temp = 0;
temp = 0;
temp = 0;
temp = 0;
temp = 0;
temp = 0;
EA=1;
}
/***************************************************************************
*定時器0初始化
***************************************************************************/
void timer0_init (void)
{
EA = 0; /* disable interrupts */
TR0 = 0; /* stop timer 0 */
TMOD &= 0xF0; /* clear timer 0 mode bits - bottom 4 bits */
TMOD |= 0x01; /* put timer 0 into 16-bit no prescale */
timer0_value = 0x10000-Ts; //采樣周期=1/2載波周期
TL0 = (timer0_value & 0x00FF);
TH0 = (timer0_value >> 8);
// PT0 = 1; /* set high priority interrupt for timer 0 */
PT0 = 0;
ET0 = 1; /* enable timer 0 interrupt */
TR0 = 1; /* start timer 0 */
EA = 1; /* enable interrupts */
}
/***************************************************************************
*PCA中斷服務程序
***************************************************************************/
static void PCA_isr (void) interrupt PCA_VECTOR using 1
{
unsigned char PCA_status;
PCA_status = PCASTA; //讀PCA中斷狀態
if ( PCA_status & 0x01) //TCM0中斷,U相
{
if (P_flag==0)
{
P4_3 = 1; //偶數采樣中斷到,關V4 延時 開V1
delay1();
P4_0 = 0;
}
else
{
P4_0 = 1; //奇數采樣中斷到,關V1 延時 開V4
delay1();
P4_3 = 0;
}
PCASTA &= 0xFE;
}
if ( PCA_status & 0x02) //TCM1中斷,V相
{
if (P_flag==0)
{
P4_5 = 1; //偶數采樣中斷到,關V6 延時 開V3
delay1();
P4_2 = 0;
}
else
{
P4_2 = 1; //奇數采樣中斷到,關V3 延時 開V6
delay1();
P4_5 = 0;
}
PCASTA &= 0xFD;
}
if ( PCA_status & 0x04) //TCM2中斷,W相
{
if (P_flag==0)
{
P4_4 = 1; //偶數采樣中斷到,關V5 延時 開V2
delay1();
P4_1 = 0;
}
else
{
P4_1 = 1; //奇數采樣中斷到,關V2 延時 開V5
delay1();
P4_4 = 0;
}
PCASTA &= 0xFB;
}
// PCASTA &= 0x00; //清PCA中斷狀態
}
//PCA0初始化
void PCA_init()
{
unsigned int PCA0;
//0.1 Configure pins as PCA function
// P4SFS0=0xff;
// P4SFS1=0;
//0.2 initialize PCA0 counter
PCACL0=PCACH0=0;
PCACL1=PCACH1=0;
//1.2 select PCA0CLK as PCA0 clock source
//PCA0時鐘為fosc,timer0_isr中Toff,Ton計數值*12 再寫入比較寄存器
// CCON2=0x10;
CCON2=0x12; //fosc/4
//Stop PCA0 counter
PCACON0=0x00;
//3. Set TCM0 operationg mode,16bit soft timer , enable softimer interrupt
// TCMMODE0=0x48;
TCMMODE0=0xC8;
TCMMODE1=0xC8;
TCMMODE2=0xC8;
CAPCOML0 = (PCA0 & 0x00FF);
CAPCOMH0 = (PCA0 >> 8);
// 開PCA中斷
IEA |= 0x20;
IPA |= 0X20; // set high priority interrupt for PCA0
//5. Start PCA0 counter
PCACON0|=0x40;
}
/******************************************************************************
* uint getVA(channel)
*功能描述:讀取輸出電壓,電流值
*參 數:channel,選擇讀取通道
*****************************************************/
void getVA (uchar channel)
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -