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

📄 工频参数测试.c

📁 工频参数测量 megal128 单片机 iccavr开发环境
💻 C
字号:
//系统晶振为8Mhz
#include <iom128v.h>
#include <math.h>
#define data_port PORTA
//ASK=PORTE.6
#define ask (PINE&0x40)
//ANSWER=PORTE.7
#define set_answer asm("sbi 0x03,7")
#define clr_answer asm("cbi 0x03,7")
//RESTE=PORTC.3
#define set_reset asm("sbi 0x15,3")
#define clr_reset asm("cbi 0x15,3") 
#define wait  asm("nop\n nop")
#define ICP1 PIND4
const unsigned char table[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
                             0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46};
/**********************************/
float maxu,maxu0,maxi,maxi0,P,Q,G;
#define ICP1 PIND4
#define uchar unsigned char 
#define uint  unsigned int
uchar flag=0;//标志位
uint rise1,rise2;
uchar ov,k=0;
float t0;
unsigned char lcd_buff[6]={0,0,0,0,0,0};
/*********************************/				
unsigned char t1;
unsigned long  temp,j;
unsigned long  max;
unsigned long  mem[90];
/*********************************/
void delay_ms(unsigned char x)
{  
   unsigned char i,m,n,t;
   for(i=0;i<=x;i++)
     for(m=0;m<10;m++)
        for(n=0;n<10;n++) 
		  for(t=0;t<50;t++);
}
	

void ocmj_init(void)
{
 MCUCR=0;
 DDRA=0xff;
 PORTA=0xff;
 DDRE=0b10000000;
 PORTE=0xff;
 clr_reset;//LCD
 delay_ms(1);
 set_reset;
 clr_answer;
 delay_ms(1);
}
/**********************************************/
	 /*LCD  */
/**********************************************/
void ocmj_write(unsigned char data)
{
 while(ask!=0)
  ;
 data_port=data;
 wait;
 set_answer;
 wait;
 while(ask==0)
  ;		
 clr_answer;
}
/**********************************************/
	 /* ASCII*/
/**********************************************/
void write_ASCII(unsigned type,unsigned xx,unsigned yy,unsigned data)
{
    ocmj_write(type);
    ocmj_write(xx+4);
    ocmj_write(yy);
    ocmj_write(data);
}

/**********************************************
	          写汉字到LCD        
**********************************************/
 void hz_tran(unsigned char x,unsigned char y,unsigned char *hz_p)
    {
	 x+=2;
     while((*hz_p)!=0)
	    {
		 ocmj_write(0xf0);
		 ocmj_write(x);
		 ocmj_write(y);
		 ocmj_write(*hz_p-0xa0);
		 hz_p++;
		 ocmj_write(*hz_p-0xa0);
		 hz_p++;
		 if(x<0x09)
 		    x++;
		 else
		    {
			 x=0x02;
			 y++;
			}	
		}
	}
 void lcd_display(void)
{  
   write_ASCII(0xf9,5,32,table[lcd_buff[5]]);
   write_ASCII(0xf9,6,32,table[lcd_buff[4]]);
   write_ASCII(0xf9,7,32,0x2e);
   write_ASCII(0xf9,8,32,table[lcd_buff[3]]);
   write_ASCII(0xf9,9,32,table[lcd_buff[2]]);
   write_ASCII(0xf9,10,32,table[lcd_buff[1]]);
 }
 void zhuanhuan(float y1)
 {
     unsigned int y;
     y1=y1*5/1024;
	 y=(unsigned int)(y1*10000);
     lcd_buff[5]=y/100000;
	 lcd_buff[4]=y%100000/10000;
	 lcd_buff[3]=y%10000/1000;
     lcd_buff[2]=y%1000/100;
     lcd_buff[1]=y%100/10;
     lcd_buff[0]=y%10;
 }
/**********************************************/
	 /*           测相位        */
/**********************************************/
#pragma interrupt_handler time1_ov:15
void time1_ov(void)
    {
       ov++;
	}
#pragma interrupt_handler time1_capt:12
void time1_capt(void)
{    
    if(ICP1)
   { 
	  if(PING=0x02)
      { 
	    rise1=ICR1;
		PING=0x03;     //多路开关
      }
	  else if(PING=0x03)   //电流
      { 
	    rise2=ICR1;
	    t0=(float)((unsigned long)rise2-(unsigned long)rise1+ov*65535);//计算结果
             t0=(float)(0.0025133*t0);
             PING=0x00;   //多路开关复位
			 ov=0;	
	  }
  }
}	
 void capt_unit(void)
  { 
    DDRD=~(1<<4);
    TCNT1=0;
	TIMSK=0X24;//TC1捕获中断允许
    TCCR1B=0x43;//TC1初始化,64分频,上升沿触发
 }
/***************************************
          数据采集
***************************************/

void timer0_init(void)
{
  SREG=0x80;
  TCCR0 = 0x00; //stop
  ASSR = 0x00; //set async mode同步方式
  TCNT0 = 0x90; //set count
  TCCR0 = 0x02; //start timer 8分频 
  TIMSK=0x01; 
}
#pragma interrupt_handler timer0_ovf_isr:17
void timer0_ovf_isr(void)
 {
	ADCSRA|=(1<<ADSC);
	t1++;	
 }
void adc_init(void)
{
    SREG=0x80;
	ADCSRA=0x88;     //16分频   
    ADMUX=0x03;
}
#pragma interrupt_handler adc:22
void adc(void)
 {
	if(j<90)
	{ 
	  mem[j]=ADC&0x03ff;
      j++;
	}
	else 
	{
	  TIMSK=0x00;
	  j=0;
	}
 }
void comp()
 {
   unsigned char i;
   if(t1==90)
   { 
    max=mem[0];
    for(i=0;i<90;i++)
     {
      if(max<mem[i])
	     max=mem[i];
     }
	t1=0;
   }
}
void shujucaiji(void)
{ 
   unsigned char i; 
   ADCSRA|=(1<<ADSC);//控制和状态寄存器,使能ADC,关闭转换 中断允许 32分频  
   while(1)
   {
      comp();
      TIMSK=0x01;
	  if(t1==0) break;
   } 
 }
/***************************************
          键盘子程序
***************************************/
unsigned char scan_key(void)
   {
    unsigned char i,temp;
    DDRB=0x0f;	
	PORTB=0xff;	  
    for (i=0;i<4;i++)
        {
         PORTB=~(1<<i); //键盘线扫描
         delay_ms(1);   //等待低电平稳定
         temp=PINB&0xf0;//读取键盘扫描信号,屏蔽低四位
         if (temp!=0xf0)//如果有键按下,延时10ms消抖
            {           //本程序用display代替10ms延时,
             delay_ms(1); //可消除显示抖动
             temp=PINB&0xf0;//再读键盘
             if (temp!=0xf0)
                {
                 temp&=0xf0;
                 switch (temp) //计算键值
                     {
				      case 0x70:temp=15-(3-i)*4;break;
                      case 0xb0:temp=14-(3-i)*4;break;
                      case 0xd0:temp=13-(3-i)*4;break;
                      case 0xe0:temp=12-(3-i)*4;break;
                      default:break;				 
                     }
                 return temp;
                }		 
       	     }
        }
    return 0xff;			 
    }

/********************************/
void controlcmd_ocmj(unsigned char key11)
   {  unsigned char i; 
     // if(key11==5)
	 // {
	    PING=0x00;
	    if(PING=0x00)
        { shujucaiji();
	      maxu=maxu0=max;
		  PING=0x01;
		}
	    else if(PING=0x01)  //多路开关转换
	    {
	      shujucaiji();
	      maxi=maxi0=max;
	      PING=0x00;    //多路开关回电压位
        }
	  // }
      switch (key11)
	   {
	    case 0:
		   ocmj_write(0xf4);
		   //shujucaiji();
		   hz_tran(3,1,"电压");
		   zhuanhuan(maxu);
		   lcd_display();
           break;
	    case 1:
		   ocmj_write(0xf4);
		   //shujucaiji();               
		   hz_tran(3,1,"电流");
		   zhuanhuan(maxi);
		   lcd_display();
           break; 
        case 2:
		   ocmj_write(0xf4);
	       P=maxu0*maxi0*5*(float)cos(t0)/1024;
		   hz_tran(2,1,"有功功率");
		   zhuanhuan(P);
		   lcd_display();
           break; 
        case 3:	
		   ocmj_write(0xf4);
		   Q=maxu0*maxi0*5*(float)sin(t0)/1024;
		   hz_tran(2,1,"无功功率");
		   zhuanhuan(Q);
		   lcd_display();
           break; 
	    case 4:	
		   ocmj_write(0xf4);
		   G=(float)(cos(t0));
		   hz_tran(2,1,"功率因数");
		   zhuanhuan(G);
		   lcd_display();
		   break;
        default :break;
	   }
   }
	
/***************************************
          开机界面子程序
***************************************/	
void jiemian(void)
 {
	  ocmj_write(0xf4);
	  hz_tran(1,0,"工频参数测试");
	  hz_tran(0,1,"课题组成员");
	  write_ASCII(0xf9,10,16,0x3a);
	  hz_tran(1,2,"石梦军");
	  hz_tran(5,2,"张达敏");
	  hz_tran(0,3,"指导老师");
	  write_ASCII(0xf9,8,48,0x3a);
	  hz_tran(5,3,"张一斌");
	  delay_ms(200);
	  delay_ms(200);
	  ocmj_write(0xf4);
	  hz_tran(1,0,"按键功能说明");
	  hz_tran(0,1,"电压");
	  write_ASCII(0xf9,4,16,0x20);
	  write_ASCII(0xf9,5,16,0x30);
	  hz_tran(3,1,"有效功率");
	  write_ASCII(0xf9,14,16,0x20);
	  write_ASCII(0xf9,15,16,0x32);
	  hz_tran(0,2,"电流");
	  write_ASCII(0xf9,4,32,0x20);
	  write_ASCII(0xf9,5,32,0x31);
	  hz_tran(3,2,"无功功率");
	  write_ASCII(0xf9,14,32,0x20);
	  write_ASCII(0xf9,15,32,0x33);
	  hz_tran(3,3,"功率因数");
	  write_ASCII(0xf9,14,48,0x20);
	  write_ASCII(0xf9,15,48,0x34);
	  hz_tran(0,3,"复位");
	  write_ASCII(0xf9,4,48,0x20);
	  write_ASCII(0xf9,5,48,0x35);
 }	
void main(void)
{ 
	unsigned char key;
	DDRG=0xff;                //多路开关用G口控制
	PING=0x02; 
    SREG=0x80;
	clr_answer;
	ocmj_init();
	capt_unit();
	timer0_init();
	adc_init();
	jiemian();
	ADCSRA|=(1<<ADSC);//控制和状态寄存器,使能ADC,关闭转换 中断允许 32分频  
	while(1)
	{	
	  key=scan_key();
	  PING=0x02; 
      controlcmd_ocmj(key);
	 } 
}
	  

⌨️ 快捷键说明

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