PIC的C语言编程,主函数里的while语句只执行一遍,是为什么?

#include <pic.h>
static volatile bit GODONE @ ((unsigned)&ADCON0*8)+2;

unsigned char a[2];//AD采样寄存数组
unsigned int Vc=0;//采样电压类型存储标志位
unsigned int Vn=0;//采样电压序列存储标志位
unsigned long int Vsrb_sum[3]={0,0,0};//电压采样结果之和
unsigned int Vsrb_average[3]={0,0,0};//电压采样结果平均值

unsigned int Hourx=0;
unsigned int Model=0;

struct{
unsigned :3;
unsigned CHS:3;
}ADCON0X @ 0x1F;

//#define SB2 TRISC,2;

void IO_initialize()
{
TRISB=0B11111101;//PORTB数据方向寄存,将RB1设置为输出
RB1=1;//不放电

ADCON0X.CHS=0;
}

void Timer0_initialize()
{
OPTION=0B11001111;//
T0IF=0;//T0溢出位清零
TMR0=0; //T0状态寄存器设置。
T0IE=1;//T0使能位置1
}

void Timer1_initialize()
{
TMR1IE=1;
TMR1IF=0;
T1CON=0B00110101;
//TMR1H=0;
//TMR1L=0B11;
}

void AD_download()
{
a[0]=ADRESL;
a[1]=ADRESH;
Vsrb_sum[Vc]=(a[1]<<8)+a[0]+Vsrb_sum[Vc];
}

void AD_transfer()
{

ADCON0=0B01000001;//Fosc/8
ADCON0X.CHS=Vc;//选择转通道0-2
ADCON1=0B10000000;//右对齐,AN1口模拟输入 1000 0000
ADIF=0;//PIR1=0x00;//清楚AD转换标志位
ADIE=1;//PIE1的ADIE位置1,A/D转换中断允许
GODONE=1;
}

void interrupt adint()
{

if(T0IF==1)
{
T0IE=0;
T0IF=0;

AD_download();

if(Vn==0)
{
Vsrb_average[Vc]=(Vsrb_sum[Vc])/20;
Vsrb_sum[Vc]=0;
}

Vc++;
if(Vc==3)
{
Vc=0;
Vn++;
if(Vn==20)
Vn=0;
}
AD_transfer();

Timer0_initialize();
}

if(TMR1IF)
{
Hourx++;
TMR1IF=0;
}

}

void PWM_initialize()
{
PR2=0B01111111;//TIMER2周期寄存器0x7F
CCPR1L=0B01100110;//0x66
CCP1CON=0B00001100;//0x0C
//TRISC=0B11111011;//RC2为PWM输出0xfb
T2CON=0B00000111;//t2预分频比1:16,使能T2,开始输出pwm波0x07
}

main()
{
unsigned char m;
INTCON|=0XC0;//禁止所有中断n
IO_initialize();
PWM_initialize();
TRISA=0B00011111;
Timer0_initialize();
Timer1_initialize();

while(1)
{
if(Vsrb_average[0]<600&&Vsrb_average[0]>50)//白天模式,当太阳能板高于某个值时,认为是白天
{
Model=1;
RB1=1;
TRISC2=1;
if(Vsrb_average[1]>600)//当蓄电池低于某个值时,开始充电。
TRISC2=0;
}

if(Vsrb_average[0]>628)//黑夜模式,白天模式和黑夜模式的中间值为微光状态。twilight model
{
Model=2;
RB1=1;
TRISC2=1;
if(Vsrb_average[1]<650)//当蓄电池高于某个值时,开始放电。放电和充电之间的状态为报警状态。
RB1=0;
}
}
}

为什么while里面的程序只执行一遍?是哪些设置影响到了。
作为标志位的Model始终为0。如果将T0初始化屏蔽掉,while语句就可以循环执行。用的是PIC16f876 4M晶振。

你怎么判断它只执行了一次呢???

补充:首先不清楚你的芯片具体是什么型号的,从程序上看应该是PIC16或者pic18系列的。也不清楚晶振频率是多少。
我提出我的怀疑及其推论:首先我怀疑while不是没有循环,而是一直循环了,但是Vsrb_average[0]并没有被赋值超过50以上的数值。(你可以加一条语句,在wihile大括号里,但不在任何if语句内的:loop++;让一个自定义变量自加,运行一两秒后看loop的数数值肯定很大)
因此怀疑AD采集过程并不准确。而为什么AD采集不准确呢,一般设置好并开启AD后采样和保持需要时间的(PIC单片机的数据手册里也提到)但你的程序设置是T0定时溢出后在中断里执行AD采集。这时候问题来了,你的TO的option_org寄存器等于0B11001111,也就是说设置T0定时器使用内部指令周期时钟(就是用单片机晶振所输入的频率定时)但PSA=0,预分频器不用于T0,所以当你的晶振是4M的时候,定时器0从计数到溢出只需要256uS。也就是说程序从WHILE开始到采集AD信号这段时间才比256us大不了多少,这根本不符合PIC单片机规定的采集时间。所以采集到的数据很小,根本不足进入while循环内部的哪两个if语句(一个IF语句是判断[50,600]这个区间,另一个是判断大于680这个范围)。
但当你屏蔽掉T0的初始化程序后,注意,这时候0PTION_REG寄存器等于0B11111111,如果TRCKI这个引脚是有脉冲充输入的话,T0定时器是会自动计数的,当溢出之后是会自动置位T0IF的(虽然没有设置T0IE,但T0IF满足条件后是会置位的),而你的总中断开关在主函数里INTCON|=0XC0;所以当T1定时器溢出之后,程序会在中断子函数里进行对T0的操作。
还有你的程序有些逻辑错误,AD结果应该是10位的,但你接收AD结果的数组a[2]却是8位的,那就丢失了两个位了。
如果还有问题,给我留言。
温馨提示:内容为网友见解,仅供参考
第1个回答  2010-05-13
建议先学一下MCU的执行方式

PIC C语言的函数问题
PICC库函数里并没有这几个函数。从命名方式来看,属于自定义的那种。你看看程序能否在MPLAB上编译通过。有的书本为了方便阅读,在整本书里都简化了某些程序的定义,全书里的程序看到有这些函数都是告诉你们在编译的时候需要把他的声明加上。补充:我看过PICC 8.2 0和 9.60里的include都没有这个文件...

在pic中如何用C语言编写程序?
}while(--x); }\/\/其指令时间为:7+(3*(Y-1)+7)*(X-1)如果再加上函数调用的call 指令、页面设定、传递参数花掉的7 个指令。\/\/则是:14+(3*(Y-1)+7)*(X-1)。\/\/***\/\/初始化ds18b20void ds18b20_init(){ char presence=1; while(presence) { TRISA0=0; \/\/主机拉至低电平 DQ=0; dela...

请问用C语言编写四则运算的问题
1、你如果不加break的话,后面的case还会执行判断的,如果加了,就只执行其中的一个 2、你应该连续输入,不要敲回车键或者其它无关的字符 这样你就会看到正确的结果(注:不知道你用的是什么编译器,为什么主函数不写返回值类型,虽然默认是int型的,但是最好不要使程序有警告)...

c51主函数只执行一次if语句请高手帮忙分析下
应该是程序死在display(i);中 for(;m>=0;m\/10)\/\/有问题 { 改为for(;m>0;m\/=10){

pic编程问题
烧写的又是什么型号的单片机??如果在MPLAB软件里设置的PIC单片机型号和烧写的实际PIC单片机信号不一样,就可能出现错误。而且设置时候CONFIG位没有设置好也可能出错。PIC的8位单片机有上百种型号,虽然内部结构大同小异,但每种单片机都有不同的CONFIG配置位,没设置好的话,烧不进去的。

pic系列单片机用c语言编程时,让他执行A\/D转换的指令是什么?
while(1){NOP();for (i=0;i<3;i++)\/\/延时时间大约20us NOP();ADGO=1;\/\/开始AD while(ADGO==1);\/\/等待AD转换完成 ADIF=0;X=ADRESH;\/\/读取AD结果高字节至C口 PORTC=X;Y=ADRESL;\/\/读取AD结果低字节至D口 PORTD=Y;};} 参考资料:北航出版社:PIC16单片机C程序设计与PROTEUS仿真...

关于PIC单片机C语言编程
1:第一个问号:是; 第二个问号:不一定;2:一些C30有多种类型版本,你说的30C和36可能不是指同一种类型。3:没破解的编译器过期就不能编译程序了。想用就需要重装(貌似它会在系统内记录的,所以应该是重装操作系统才行)。4:肯定不可靠。我有过编译经历,破解的编译出来的在逻辑上就会有问题...

谁有pic的c语言编程软件下载地址
PIC C 语言编程软件下载可以到microchip官网下载,最新的MPLAB IDE自带PICC并提供LITE版本使用。参考资料:吃

atan2函数在PIC单片机C语言中如何使用?
建议不要在中断中处理函数,最好在中断中返回个标志位,然后在主函数中执行函数。如果一定要在中断中执行函数,这个函数最好在其他地方不使用,否则容易出错哦。你说的RXIF我不知道,我只知道RCIF。

一般8位PIC单片机使用C语言还是汇编语言编程,好像编译器不是支持所有...
PIC单片机的C语言编译器是分类支持各类PIC单片机的。一般做工业产品的公司大多用汇编来编写程序,原因有:1:pic的8位单片机一般ROM和RAM都相对较小,而现在的PIC的C编译器在优化方面做的不是很好,简单的一个C语句编译器能编出很多行汇编代码。所以有些开发人员认为用c还不如直接用汇编写。2:因为PIC...

相似回答