📄 工频参数测试.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 + -