本帖最后由 yxx85 于 2016-8-21 15:23 编辑
为什么程序不能在AVR Studio中模拟仿真?仿真时进入不了主循环?定时器0也没反应?
程序如下:
/*****************************************************
This program was produced by the
CodeWizardAVR V2.05.0 Professional
Automatic Program Generator
Copyright 1998-2010 Pavel Haiduc, HP InfoTech s.r.l.
Project : AC源
Chip type : ATmega16
Program type : Application
AVR Core Clock frequency: 16.000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*****************************************************/
#include <mega16.h>
#include <delay.h>
#include <mega16_bits.h>
#include <math.h>
bit READ_SHOW_Flag;
unsigned char i,k;
unsigned int Iv,Vadj,voltage,current,power,cosa; // 因在math.h中已占用cos,所以用cosa代替cos
unsigned long int VOL,CUR,POW;
flash unsigned char DIG[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00}; // 共阴数码管
unsigned char DISP[4];
#define V_CH 0 // 电压ADC通道
#define I_CH 1 // 电流ADC通道
#define IV_CH 2 // 过流ADC通道
#define VAJ_CH 3 // 电压调节ADC通道
#define BEEP PORTA.7 // 声音报警
#define LED PORTA.6 // 报警指示灯
#define LIE0 PORTA.4 // 第一位数码管
#define LIE1 PORTA.5 // 第二位数码管
#define LIE2 PORTB.0 // 第三位数码管
#define LIE3 PORTB.1 // 第四位数码管
#define LIE4 PORTB.2 // 第五位数码管
#define LIE5 PORTB.3 // 第六位数码管
#define LIE6 PORTB.4 // 第七位数码管
#define LIE7 PORTB.5 // 第八位数码管
#define LIE8 PORTB.6 // 第九位数码管
#define LIE9 PORTB.7 // 第十位数码管
#define LIE10 PORTD.0 // 第11位数码管
#define LIE11 PORTD.1 // 第12位数码管
#define LIE12 PORTD.3 // 第13位数码管
#define LIE13 PORTD.5 // 第14位数码管
#define LIE14 PORTD.6 // 第15位数码管
#define LIE15 PORTD.7 // 第16位数码管
#define PWM PORTD.4 // OCR1B输出PWM
#define V_DB 4352 // 分压系数与ADC转换系数之积。
#define I_DB 14142 // 分流系数、分压系数与ADC转换系数之积。
// Standard Input/Output functions
void io_init(void)
{
DDRA=0xF0; // PA0~3 ADC输入 PA6-7 报警输出(高电平有效)
PORTA=0x30; // 数码管位码输出高电平使其灭
DDRB=0xFF; // 数码管位码输出
PORTB=0xFF; // 高电平使其灭
DDRC=0xFF; // 输出段码
PORTC=0x00; // 共阴数码管
DDRD=0xFB; // PD2中断0保护输入 PD4(OC1B)输出PWM 其余数码管位输出
PORTD=0xFB; // INT0输入置1 数码管位码输出高电平使其灭
}
void EXT_init(void)
{
GICR=0x40; // 外部中断0 使能
MCUCR=0x00; // 外部中断0 低电平触发
GIFR=0x40; // 外部中断0 标志位允许
}
void TIMER0_init(void) // 625us定时器 用于测量
{
TCCR0=0x03; // 普通模式 64分频 (16M/64=250k)
TCNT0=0x63; // 初值99=255-0.000625/(1/250k) 延时156*(1/250k)=624us
TIMSK=0x01; // 允许定时器0 溢出中断
}
void PWM_init(void)
{ // 快速PWM
TCCR1A=0X63; // 比较匹配时OC1A取反 匹配时清0 TOP时置位 模式15
TCCR1B=0X19; // 模式15 预分频系数N=1
OCR1A=799; // PWM频率设为20kHz 799=(16M/20k)-1 OCR1A定f OCR1B定脉宽
OCR1B=0; // OC1B(PD4)上得PWM
}
// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{ // 过流 过载保护程序
PWM=0; // PWM=0
LED=1; // 打开报警
BEEP=1;
delay_ms(1000);// 延时1s
}
unsigned int ADC(unsigned char CH) // ADC程序
{
ADCSRA=0x00; // 关闭ADC
ADMUX|=CH; // 选择输入
// Delay needed for the stabilization of the ADC input voltage
delay_us(3);
// ADCSRA|=0x40; // ADC使能并启动
ADCSRA=0xC7; // ADC使能并启动,预分频128(16M/128=125k)
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10; // ADCIF清0
// Start the AD conversion agen
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10; // ADCIF清0
return ADCW;
}
void SHOW(void)
{
if(i/2==0)
{
DISP[0]=voltage/1000;
DISP[1]=(voltage%1000)/100;
DISP[2]=(voltage%100)/10;
DISP[3]=voltage%10;
k=0;
if(DISP[0]==0)
{
DISP[0]=10;
if(DISP[1]==0) DISP[1]=10;
}
}
if(i/2==4)
{
DISP[0]=current/1000;
DISP[1]=(current%1000)/100;
DISP[2]=(current%100)/10;
DISP[3]=current%10;
k=4;
}
if(i/2==8)
{
DISP[0]=power/1000;
DISP[1]=(power%1000)/100;
DISP[2]=(power%100)/10;
DISP[3]=power%10;
k=8;
if(DISP[0]==0)
{
DISP[0]=10;
if(DISP[1]==0) DISP[1]=10;
}
}
if(i/2==12)
{
DISP[0]=cosa/1000;
DISP[1]=(cosa%1000)/100;
DISP[2]=(cosa%100)/10;
DISP[3]=cosa%10;
k=12;
}
switch(i/2) // 关闭位码
{
case 0:
LIE15=1;
break;
case 1:
LIE0=1;
break;
case 2:
LIE1=1;
break;
case 3:
LIE2=1;
break;
case 4:
LIE3=1;
break;
case 5:
LIE4=1;
break;
case 6:
LIE5=1;
break;
case 7:
LIE6=1;
break;
case 8:
LIE7=1;
break;
case 9:
LIE8=1;
break;
case 10:
LIE9=1;
break;
case 11:
LIE10=1;
break;
case 12:
LIE11=1;
break;
case 13:
LIE12=1;
break;
case 14:
LIE13=1;
break;
case 15:
LIE14=1;
break;
}
PORTC=DIG[DISP[i/2-k]]; // 段码赋值
switch(i/2) // 打开位码
{
case 0:
LIE0=0;
break;
case 1:
LIE1=0;
break;
case 2:
LIE2=0;
break;
case 3:
LIE3=0;
break;
case 4:
LIE4=0;
break;
case 5:
LIE5=0;
break;
case 6:
LIE6=0;
break;
case 7:
LIE7=0;
break;
case 8:
LIE8=0;
break;
case 9:
LIE9=0;
break;
case 10:
LIE10=0;
break;
case 11:
LIE11=0;
break;
case 12:
LIE12=0;
break;
case 13:
LIE13=0;
break;
case 14:
LIE14=0;
break;
case 15:
LIE15=0;
break;
}
}
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Reinitialize Timer 0 value
unsigned int V1,I1; // 定义瞬时值
TCNT0=0x63; // 装入初值
if(i%2)
{
SHOW();
}
else
{
if(!READ_SHOW_Flag)
{
V1=ADC(V_CH)*V_DB/1024;
VOL+=(unsigned long int)V1*V1;
I1=ADC(I_CH)*I_DB/1024;
CUR+=(unsigned long int)I1*I1;
POW+=(unsigned long int)V1*I1;
}
else
{
switch(i/2)
{
case 1:
voltage=(unsigned int)lsqrt(VOL/16);
break;
case 3:
current=(unsigned int)lsqrt(CUR/16);
break;
case 5:
power=(unsigned int)POW/1000/16;
break;
case 7:
if(voltage*current==0) cosa=0;
else cosa=power*1000/(voltage*current);
break;
case 15:
VOL=0;
CUR=0;
POW=0;
break;
default: break;
}
}
if(++i>31)
{
i=0;
READ_SHOW_Flag=~READ_SHOW_Flag;
}
}
}
void main(void)
{
io_init();
EXT_init();
ACSR=0x80;
PWM_init();
TIMER0_init();
delay_us(4);
// Global enable interrupts
#asm("sei")
while (1)
{
if(READ_SHOW_Flag)
{
LED=0; // 关闭报警
BEEP=0;
Iv=ADC(IV_CH);
if(Iv>1000)
{
LED=1;
if(Iv>1022) PORTD.2=0;
}
Vadj=ADC(VAJ_CH);
OCR1B=25*Vadj/32;
}
}
}
|