⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aaa.c.bak

📁 用51单片机编译成的频率计的源程序
💻 BAK
📖 第 1 页 / 共 2 页
字号:
#include <upsd3300.h>
#include <intrins.h>
#include <string.h>
#include <absacc.h>
//#include "upsd33_adc.h"
//#include <Turbo_adc.h>
//#include <Turbo_timer.h>
//#include <Turbo_PCA-PWM.h>
//#include <test.h>

#define uchar unsigned char
#define uint unsigned int

//#define PSD_REG_ADDR 0x0800		 //PSD寄存器IO基址	 
#define  scan  P3					 //键扫
#define POWK P1_7					 //交流接触器开关,0有效
#define POWZ P4_7					 //电阻短接,0有效
#define ST   P4_6					 //脉冲使能

#define RS  P1_6			         //液晶命令口
#define RW  P1_5
#define  E  P1_4
#define PSD_REG_ADDR 0x0200
   
/*********管脚定义****************/
//#define  lcdport  PSD33_reg.DATAOUT_A  //P4        //P4液晶数据口,必须用双通道IO


xdata PSD_REGS PSD33_reg _at_ PSD_REG_ADDR ;

uchar bdata temp;		    //判忙用字节
sbit busy = temp^7;
uchar  keyv ;
uchar  pinlv[3] = {0,0,0};		   //频率值
uchar  dianya[2] = {0,0};		   //电压值
//uchar  mm[3] = {1,6,0};			   //调制度,30-210
uchar code OK[]={"OK"};

 uchar i;
/******************************************************************************
*                PWM变量定义

******************************************************************************/
/*------------------------------------------------------------------------------
			  Local Variable Declarations
------------------------------------------------------------------------------*/
//时钟周期为30ns,(板上33.1776M晶振)
//固定频率采样,载波频率5K,周期200us,计数值=200us/(30ns*12)=556 
//采样周期 = 1/2载波周期 = 278 



//long Fc;					
long idata F;
long idata F_min;
uint data N;				//载波比
long data M;				//调制系数

						


uint data Ts; 					//采样周期 = 1/2 载波周期
long data Half_Ts;      		//1/2采样周期

long idata K_M;					//调制系数放大倍数
long idata K_F;					//输入频率放大倍数

//uint idata K_sin;				//sin表放大倍数
//uint idata K_coe;				//总放大倍数,K_M * K_sin;
							



//int idata dead_time;		
uint data U_angle;
uint data V_angle;
uint data W_angle;

uint data K;				//采样个数,偶数为顶点采样,奇数为底点采样
uint data U_Toff;			//顶点采样开通延时
uint data U_Ton;         	//底点采样关断延时
uint data V_Toff;
uint data V_Ton;
uint data W_Toff;
uint data W_Ton;

uint Tm;
code uint u36 = 0x125;


unsigned char data P_flag,aa;		 //奇偶采样点标志

static unsigned int idata timer0_tick;
static unsigned int idata timer0_value;

static unsigned int idata timer1_tick;
static unsigned int idata timer1_value;


int data M_angle;

unsigned long idata Fm;


unsigned int data PCA0;


//0--180度正弦表


unsigned char code sin_table[181] = { 0,4,9,13,18,22,27,31,35,40,
                          44,49,53,57,62,66,70,75,79,83,
                          87,91,96,100,104,108,112,116,120,124,
                          128,131,135,139,143,146,150,153,157,160,
                          164,167,171,174,177,180,183,186,190,192,
                          195,198,201,204,206,209,211,214,216,219,
                          221,223,225,227,229,231,233,235,236,238,
                          240,241,243,244,245,246,247,248,249,250,
                          251,252,253,253,254,254,254,255,255,255,
                          255,255,255,255,254,254,254,253,253,252,
                          251,250,249,248,247,246,245,244,243,241,
                          240,238,236,235,233,231,229,227,225,223,
                          221,219,216,214,211,209,206,204,201,198,
                          195,192,190,186,183,180,177,174,171,167,
                          164,160,157,153,150,146,143,139,135,131,
                          128,124,120,116,112,108,104,100,96,91,
                          87,83,79,75,70,66,62,57,53,48,
                          44,40,35,31,27,22,18,13,9,4,0	};

/********************************************************************
*键盘码
********************************************************************/
uchar code key_tab[] =
{
	0x01,0x02,0x03,0x0a,
	0x04,0x05,0x06,0x0b,
	0x07,0x08,0x09,0x0c,
	0x0f,0x00,0x0e,0x0d,
};


/********************************************************************/
/*******************************函数声明*****************************/
/********************************************************************/

/*---------------------------------------------------------------
*          LCD函数声明
*---------------------------------------------------------------*/
void lcdbusytest();
void writelcdcom(uchar com);
void writelcddat(uchar dat);
void mdelay(uchar j);							 //upsd 40M延时
void initlcd();								     //初始化
void clrlcd();								     //清屏
void printchar(uchar xpos,uchar ypos,uchar str); //写一个字符
void printstr(uchar xpos,uchar ypos,uchar *str); //写字符串
/*-------------------------------------------------------------
*        键盘扫描
*-------------------------------------------------------------*/
uchar getkey (void);

/*-------------------------------------------------------------
*    ADC 程序声明
-------------------------------------------------------------*/
void ADC_EnableAll(void) ;
void ADC_Init (unsigned char channel);
unsigned int ADC_Read( unsigned char channel );

/*-------------------------------------------------------------
*    得到电压电压值,并在液晶上显示
-------------------------------------------------------------*/
void getVA (uchar channel);

/*-------------------------------------------------------------
*   得到功率和频率
-------------------------------------------------------------*/
void  getPf  (void);

/*******************************************************************
************************PWM部分声明*********************************
*******************************************************************/

/*-------------------------------------------------------------
//定时器0中断服务程序,PWM
//定时器0用于产生采样周期的定时中断,采样周期Ts	=1/2载波周期 = 278 时钟周期
-------------------------------------------------------------*/
static void timer0_isr (void); //interrupt TF0_VECTOR using 1

/*-------------------------------------------------------------
*    int sin_angle(long angle )
*功能描述:角度换算函数,使角度值控制在180以内
*
-------------------------------------------------------------*/
int sin_angle(long angle );

/*-------------------------------------------------------------
*             void first(void )
*第一个采样点计算函数,在K=0时计算
-------------------------------------------------------------*/
void first(void );

/*-------------------------------------------------------------
*定时器0初始化
-------------------------------------------------------------*/
void timer0_init (void);


/*--------------------------------------------------------------------
*PCA中断服务程序
---------------------------------------------------------------------*/

static void PCA_isr (void); //interrupt PCA_VECTOR using 1   

/*-------------------------------------------------------------------
*  PCA0初始化
--------------------------------------------------------------------*/
void PCA_init() ;
void pwmwork();
/***********************PWM声明结束***********************************/

/*********************************************************************
***************************函数声明结束*******************************
**********************************************************************/


/****************************************************************
*延时子程序,1ms
****************************************************************/

void delay1ms(uint x)
{
    uint i;
    while(x--)   			//((11+7*i)*x+5	)T
      {  i= 450;		
        while((i--)>0);			//i=141,x=1,t=1003T
      }
}
/******************************************************************
*              uchar  keyscan()
*功能:键盘扫描程序
*说明: 4*4键盘,无上拉电阻。P0~P3为行输出,P4~P7为列输入
*返回值:0x(lie)(hang)
******************************************************************/


uchar getkey (void)
{   
     
     static uchar kn;
	 uchar lie=0,hang,x=0;
	 //E = 0;
	 //RS = 0;
	 scan = 0xf0;
	 if((scan & 0xf0) !=0xf0)               
     {  delay1ms(10);                             
        if((scan & 0xf0) !=0xf0)          
          { hang = 0xfe;                     
            for(i=0;i<4;i++ )                
            { scan = hang;
              if((scan & 0xf0) != 0xf0)        
               {
			     lie = ~(scan | 0x0f );        
                 switch (lie)
				  { case 0x10:kn = *(key_tab + i);break;
				    case 0x20:kn = *(key_tab+i+4) ;break;
				    case 0x40:kn = *(key_tab+i+8) ;break;
				    case 0x80:kn = *(key_tab+i+12) ;break;
					default:break;
				   } 
				   return( kn);
               } 
              else hang = (hang<<1)|0x01;
            }
          }   
     }
   return(kn);  
}





/**********延时子程序*************/
void mdelay(uchar j)
{uint i;
for(;j>0;j--)
  { for(i=0;i<200;i++)
  {;}
    }
}

/**********判忙子程序*************/
 void lcdbusytest()
{
  PSD33_reg.DATAOUT_A = 0xff;
 // lcdport=0xff;
  RS=0;
  RW=1;
  E=1;
  PSD33_reg.DIRECTION_A =0;		          //PB为输入模式
  do{temp=PSD33_reg.DATAIN_A;} while(busy);
//do{temp=lcdport;}while(busy);
  E=0;
  PSD33_reg.DIRECTION_A =0xff; 
}


/*********写命令******************/
 void writelcdcom(uchar com)
{
  lcdbusytest();
  RS=0;
  RW=0;
  E=1; 
  PSD33_reg.DATAOUT_A =	com;
  //lcdport=com;
  E=0;
}

/**********写数据****************/
void writelcddat(uchar dat)
{
  lcdbusytest();
  RS=1;
  RW=0;
  E=1;
  PSD33_reg.DATAOUT_A = dat;
  //lcdport=dat;
  E=0;
}

/***********LCD清屏****************/
void clrlcd()
{writelcdcom(0x01);}

/***********LCD初始化**************/
 void init_lcd()
{ mdelay(15);
  RS=0;
  RW=0;
  E=1;
  PSD33_reg.DATAOUT_A = 0x38;
 // lcdport=0x38;
  E=0;
  mdelay(5);
  RS=0;
  RW=0;
  E=1;
  PSD33_reg.DATAOUT_A = 0x38;
  //lcdport=0x38;
  E=0;
  mdelay(5);
  RS=0;
  RW=0;
  E=1;
  PSD33_reg.DATAOUT_A = 0x38;
 // lcdport=0x38;
  E=0;
  writelcdcom(0x38);
  writelcdcom(0x08);
  clrlcd();
  writelcdcom(0x06);
  writelcdcom(0x0c);
}

/*********写一个字符****************/
void printchar(uchar xpos,uchar ypos,uchar str)
{uchar m=0;
switch (ypos)
{ case 0:  xpos|=0x80;break;
  case 1: xpos|=0xc0;break;
  default: break;
  }
writelcdcom(xpos);
writelcddat(str);
}

/*********写字符串函数*************/
void printstr(uchar xpos,uchar ypos,uchar *str)
{ 
 //uchar n;
 uchar m=0;
 switch (ypos)
 { case 0: xpos|=0x80;break;	        //写入显示地址要求D7恒为高电平
   case 1: xpos|=0xc0;break;
   default: break;
  }
 writelcdcom(xpos);                //此处的Xpos已转换为LCM的显示寄存器实际地址
 for(i=0;i<strlen(str);i++)
   {
     writelcddat(str[m++]);
   }

}


/*****************************************************************************
*                         ADC_EnableAll()
*功能:ADC使能,设置P1口通道为ADC输入,选择ADC时钟频率
*参数:无
******************************************************************************/
void ADC_EnableAll(void) 
{
    ACON = 0;                           // 关闭ADC


    ADCPS =(0x08 + 1);                  //使能ADC时钟,设置时钟频率
    _nop_();
    _nop_();
   	P1SFS0 |= 0x07;
	P1SFS1 |= 0x07;                      // 选择P1口相应位为ADC输入

    
    ACON = 0x20;
                        // 使能ADC;Enable ADC

    // 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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -