PIC编程中发现俩个问题 提醒新人 1,中断变量注意再注意 2 if语句关系表达式的写法

2020-02-09 09:28发布

关于第一个问题 我自己也不太清楚  语句是别人帮我改的 他大概说是因为中断变量如果占用了通用寄存器RO(类似) 为了提高速度 往往单片机这么做  那么你原先函数中的变量在通用寄存器的值可能在被中断打断后  他原来的值就回不来了。


我的事例:、
我在AD中断中
原来的语句

AD_Result_power=(ADRES*300)/256;

经过同事改后:
AD_Result_power=ADRES;       {ADRES是AD结果寄存器}
AD_Result_power=(AD_Result_power*300)/256;

这样结果就正确了   请高人指点  (可能需要清楚编译器原理,不同编译器还不一样)



关于第二点:



我的
if(120>a>0)   这样是完全错误的 反正我在PIC中不行

但是我改为if(a>0&a<120)   这样就行了
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
12条回答
joychainleo
2020-02-10 17:31
贴一下我调试完的程序吧  应该有许多可以优化
AD双通道中断里面切换




#include <htc.h>
  __CONFIG(0x3BA4);//设置配置位

#define uint8 unsigned char
#define uint16 unsigned int
#define uint32  long
#define  clk1  RB4
#define  RX12  RB5
#define  clk2  RB1
#define  RX21  RB2
#define  redfive                  25
#define  redfour                 50
#define  redthree                  75
#define  redtwo                  100
#define  redone                        128
#define  greenone                  150
#define  greentwo                  175
#define  greenthree          200
#define  greenfour                  225





uint8 shumanum[]={0x0a,0x7b,0x4c,0x58,0x39,0x98,0x88,0x3a,0x08,0x18,0xf7};//0 1 2 3 4 5 6 7 8 9 点
uint16 volge,volfen,volshi;
uint32 AD_Result_power,AD_Result_speed;
/*******************************************************************************
* 函 数 名        :        ADinit()
* 函数功能:         AD初始化
* 入口参数:        无
* 返    回:                 无
*******************************************************************************/
void ADinit()
{
ADCON1=0X50;        //选择AD参考电压 转换频率内部FOS/16   
ADCON0=0X01;        //选择ADC通道     启动ADC   转换模块
ADIF = 0;                //中断标志清零
ADIE = 1;                //ADC中断使能       


}

/*******************************************************************************
* 函 数 名        :        port_init()
* 函数功能:         端口初始化
* 入口参数:        无
* 返    回:                 无
*******************************************************************************/
void Portinit()
{
TRISA=0X03;
TRISB=0X00;
PORTA=0Xc0;
}

/*******************************************************************************
* 函 数 名        :        init()
* 函数功能:         函数初始 包括端口初始化和AD 初始化
* 入口参数:        无
* 返    回:                 无
*******************************************************************************/
void init()
{
Portinit();
ADinit();
}

/*******************************************************************************
* 函 数 名: DelayMS(uint16 delay)
* 函数功能: 毫秒延时        for20MHZ
* 入口参数: delay
* 返    回: 无
*******************************************************************************/

void DelayMS(uint16 delay)
{
    uint16 i;
    for(;delay>0;delay--)
        for(i=0;i<453;i++);
}



/*******************************************************************************
* 函 数 名        :        AD_get()
* 函数功能:         AD采集数据
* 入口参数:        无
* 返    回:                 无
*******************************************************************************/
void AD_get()
{

init();
PEIE = 1;                //ADC中断使能(外设中断的其中一种)
GIE=1;             //全局中断允许位
ADGO = 1;                //启动ADC转换

}


/*******************************************************************************
* 函 数 名        :        TxLs164(unsigned char data)
* 函数功能:         串行数据输出并行数据
* 入口参数:                8位数据
* 返    回:                 无
*******************************************************************************/

void TxLs164(unsigned char data)
{
     uint8 i;
     
     i = 8;                                                
  

     do
      {
       RX12 = 0;                                            //先高后低

       if (data & 0x80) RX12 = 1;                           

       clk1 = 1;                                            //时钟置位
       data <<= 1;                                         //数据左移
       clk1 = 0;                                            //时钟清零
      }
     while (--i);                                          //循环发送                              

}

/*******************************************************************************
* 函 数 名        :        TxLs164_2(unsigned char data)
* 函数功能:         串行数据输出并行数据
* 入口参数:                8位数据
* 返    回:                 无
*******************************************************************************/

void TxLs164_2(unsigned char data)
{
     uint8 i;
     
     i = 8;                                                
  

     do
      {
       RX21 = 0;                                            //先高后低

       if (data & 0x80) RX21 = 1;                           

       clk2 = 1;                                            //时钟置位
       data <<= 1;                                         //数据左移
       clk2 = 0;                                            //时钟清零
      }
     while (--i);                                          //循环发送                              

}


/*******************************************************************************
* 函 数 名    :            shumashow()
* 函数功能:             将AD寄存器RES中的值返给数码管显示
* 入口参数:       
* 返    回:                 无
*******************************************************************************/
void shumashow()
{

TxLs164(shumanum[volshi]);
DelayMS(1);
PORTA=0XC0|0X08;
DelayMS(1);
PORTA=0XC0;
TxLs164(shumanum[volge]);
DelayMS(1);
PORTA=0XC0|0X10;
DelayMS(1);
PORTA=0XC0;
TxLs164(shumanum[volfen]);
DelayMS(1);
PORTA=0XC0|0X20;
DelayMS(1);
PORTA=0XC0;
}



/*******************************************************************************
* 函 数 名        :        ADinterrupt()
* 函数功能:         AD中断服务子程序
* 入口参数:        无
* 返    回:                 无
*******************************************************************************/
void interrupt ADinterrupt()
{
                             //定义AD采样值的个位 十位
        if(ADIF == 1)
        {
                ADIF = 0;                                                       //AD中断标志清零
                switch(ADCON0)
                        {

case 0x01:        AD_Result_power=ADRES;                                                     
                     AD_Result_power=(AD_Result_power*300)/256;                             //读取ADC采样结果
                     volshi= AD_Result_power/100;                                                 //十位数据
                        volge= AD_Result_power%100/10;                                                 //个位数据  
                        volfen=(AD_Result_power%100)%10;                                                 // 小数位
                        shumashow();
                        ADCON0=0X05;                                                                                       //实现通道切换
                        break;

                       
case 0x05:        AD_Result_speed=ADRES;               


                  if(AD_Result_speed>=0&&AD_Result_speed<redfive)
                        {
                        PORTA=0XC0        ;
                        TxLs164_2(0Xa2);
                        DelayMS(1);
                        }
            if(AD_Result_speed>=redfive&&AD_Result_speed<redfour)
                        {
                       
                        PORTA=0XC0        ;
                        TxLs164_2(0Xaa);
                        DelayMS(1);
                        }
            if(AD_Result_speed>=redfour&&AD_Result_speed<redthree)
                        {
                        PORTA=0XC0        ;
                        TxLs164_2(0Xae);
                        DelayMS(1);
                        }
            if(AD_Result_speed>=redthree&&AD_Result_speed<redtwo)
                        {
                        PORTA=0XC0        ;
                        TxLs164_2(0XaF)        ;
                        DelayMS(1)        ;
                        }
                    if(AD_Result_speed>=redtwo&&AD_Result_speed<redone)
                        {
                        PORTA=0XC0        ;
                        TxLs164_2(0Xef)        ;
                        DelayMS(1)        ;
                        }
            if(AD_Result_speed==128)
                        {
                        PORTA=0XC0        ;
                        TxLs164_2(0XFF);
                        DelayMS(1);
                        }
            if(AD_Result_speed>128&&AD_Result_speed<greenone)
                        {
                        PORTA=0XC0        ;
                        TxLs164_2(0Xdf);
                        DelayMS(1);
                        }
                    if(AD_Result_speed>=greenone&&AD_Result_speed<greentwo)
                    {       
                        PORTA=0XC0        ;
                        TxLs164_2(0X5f);
                        DelayMS(1);
                        }
                        if(AD_Result_speed>=greentwo&&AD_Result_speed<greenthree)       
                        {
                        PORTA=0XC0 ;
                        TxLs164_2(0X5d);
                        DelayMS(1);
                        }
                        if(AD_Result_speed>=greenthree&&AD_Result_speed<greenfour)       
                        {
                        PORTA=0X80 ;
                        TxLs164_2(0X5d);
                        DelayMS(1);
                        }
                        if(AD_Result_speed>=greenfour&&AD_Result_speed<256)       
                        {
                        PORTA=0X00 ;
                        TxLs164_2(0X5d);
                        DelayMS(1);
                        }


               
                        ADCON0=0X01;                                                                                      //实现通道切换
                        break;

default:        break;       

                        }
                }


ADGO=1;


}




/*******************************************************************************
* 函 数 名        :        main()
* 函数功能:         实现AD 采集并且在数码管上显示
* 入口参数:        无
* 返    回:                 无
*******************************************************************************/


void main()
{
AD_get();
while(1);
}

一周热门 更多>