关于第一个问题 我自己也不太清楚 语句是别人帮我改的 他大概说是因为中断变量如果占用了通用寄存器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) 这样就行了
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
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);
}
一周热门 更多>