PIC16F690 ADC的转换问题 请大家帮忙看看 内附MPLAB工程和proteus仿真文件

2020-02-06 10:26发布

在proteus仿真里面,下方的电压表显示的值是我要AD转换的电压值,我的程序是想实现1V亮一个LED,LED最下方为最低电量也就是1V,以此类推,0~1V点亮RC7,1~2V点亮RC7 RC6,2~3V点亮RC7 RC6 RC5,3~4V点亮RC7 RC6 RC5 RC4,4~5V点亮RC7 RC6 RC5 RC4 RC3
但是我现在仿真的结果是3~5V时5个LED全亮,然后每降1V灭一个LED,应该是我的条件判断语句有问题,可能我描述的有些乱,仿真看一下就清楚了,希望大家有时间帮忙看看,谢谢
proteus版本是V7.2 SP6,MPLAB版本是V8.53
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
8条回答
pangzi0801
2020-02-06 22:39
我把他的代碼貼上來。呵呵...

#include<pic.h>//包含头文件
#define uchar unsigned char//宏定义
#define uint  unsigned int//宏定义
__CONFIG(INTIO & WDTDIS & PWRTEN & BORDIS & UNPROTECT);
//内置振荡器、引脚为IO功能,关闭看门狗,开电压,关,不保护EEPROM
void init();//系统初始化
void init_adc();//ADC初始化
void delay_ms(uint);//延时xms
uint get_ad();//启动AD转换
//const uchar table[]={0x7f,0x3f,0x1f,0x0f,0x07};
void main()//主函数
{
        uint lednum;//ADC结果暂存
        const uchar dlxs[]={0x7f,0x3f,0x1f,0x0f,0x07};
        //20%:0~203,40%:204~408,60%:409~613,80%:614~818,100%:819~1023
        //uchar a1,a2,a3,a4;
        init();
        init_adc();
        while(1)
        {
                lednum = get_ad();
                //a1=lednum/1000;//2
                //a2=lednum%1000/100;//5
                //a3=lednum%100/10;//0
                //a4=lednum%10;//0
               
                if(lednum>1023)
                {
                        lednum=1023;
                }
                else if(818<lednum && lednum<1024)//>3.9V
                {
                        PORTC = dlxs[5];//PORTC=0b00000111
                }
                else if(613<lednum && lednum<819)//>2.99V
                {
                        PORTC = dlxs[4];//PORTC=0b00001111
                }
                else if(408<lednum && lednum<614)//>1.99V
                {
                        PORTC = dlxs[3];//PORTC=0b00011111
                }
                else if(203<lednum && lednum<409)//>0.99V
                {
                        PORTC = dlxs[2];//PORTC=0b00111111
                }
                else if(0<lednum && lednum<204)//>0
                {
                        PORTC = dlxs[1];//PORTC=0b01111111,lednum<204
                }
                else
                {
                        PORTC = 0xff;
                }

                /*if(lednum>511)
                {
                        PORTC = 0x0f;
                }
                else if(lednum==511)
                {
                        PORTC = 0x1f;
                }
                else
                {
                        PORTC = 0x3f;
                }*/
        }
}
void init_adc()//初始化ADC
{
        ADCON0 = 0xa9;//结果右对齐,基准为VDD,通道选择AN10
        ADCON1 = 0x20;//ADC时钟选择Fosc/32
        ADIE = 0;//禁止ADC中断
        delay_ms(1);
}
uint get_ad()//AD转换
{
        uint adval;//0x000~0x3ff,1024
        //float advalf;
        GODONE = 1;
        while(GODONE);
        adval = ADRESH;//00000000 00000011
        adval = adval << 8 | ADRESL;//00000011 00000000|11111111=00000011 11111111
        //advalf=adval/1023.0*5.0;//==2.5目前advalf为分压后的模拟电压值
        //adval=advalf*1000;//
        //advalf=advalf*124.7/14.7;//目前advalf为分压前的模拟电压值
        //advalf = advalf*1000;//2500
        //float advalf= (uint)adval;
        return (adval);
}
void init()//系统初始化
{
        OSCCON = 0x71;//振荡器控制寄存器配置为内部8MHz
        TRISA = 0x34;//00110100RA2/RA4/RA5为悬空脚
        PORTA = 0xcb;//11001011
        TRISB = 0x50;//01010000RB4为模拟输入(采样电压)RB6为悬空脚
        PORTB = 0xaf;//10101111
        TRISC = 0x07;//00000111RC2为模拟输入(按键中断),RC1/RC0为悬空脚
        PORTC = 0xf8;//11111000
        ANSEL = 0x40;//enable AN6(RC2)
        ANSELH = 0x04;//enable AN10(RB4)
}
void delay_ms(uint xms)//延时xms
{
        uint i,j;
        for(i=xms;i>0;i--)//8MHz晶振下,xms等于几就延时几ms
                for(j=152;j>0;j--);
}

一周热门 更多>