📄 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 + -