GalaxyMan 发表于 2013-4-11 16:51:33

现在采用HR6P61L芯片搞个项目 大家谁有ADC的模块程序啊

如题,C语言和汇编都有最好了。多谢!

流浪飞鸟 发表于 2013-4-11 17:05:48

请版主上传个应用历程吧!{:tongue:}

海尔_小海 发表于 2013-4-11 17:51:37

流浪飞鸟 发表于 2013-4-11 17:05 static/image/common/back.gif
请版主上传个应用历程吧!

#include <HR6P61L.H>
#define ucharunsigned char
#define uint   unsigned int


section1 ucharADC_Time_CNT;
section1 ucharPA_Buf;
section1 ucharPB_Buf;
section1 uint   ADC_One_Time_BUF;
section1 sbit   ADC_Display_ok;


union
{
       uint   temp;
        struct {
       uchartemp_L;                        //低8位
       uchar       temp_H;                         //高8位
                               }ADC_Result;
}ADC;







voidint_IO_RAM(void);
voidADC_Work_PRO(void);
voidADC_Result_Arrange(void);
void        ADC_Result_Display(void);




main()
{
        int_IO_RAM();
        while(1)
        {
                ADC_Work_PRO();
                if(ADC_Display_ok==1)
                        {
                                ADC_Display_ok=0;
                                ADC_Result_Arrange();
                                ADC_Result_Display();       
                        }
        }
}

void int_IO_RAM()
{
        __asm{               
                movi 0b00000001                        // 1010 1111    PA0-USB接口输出电压检测 PA1-
                                                                tris PA
                movi 0b11110000
                                                                tris PB
                       };       
      PA = 0x00;
      PAWPUC = 0b11111111;//无弱上拉使能
                                PB = 0x00;
      PBWPUC = 0b11111111;//无弱上拉使能
      ADCRL=0;
      ADCRH=0;
      ADC.ADC_Result.temp_L=0;
      ADC.ADC_Result.temp_H=0;
      ADC.temp=0;
      ADC_Time_CNT=0;
      
      
//初始化ADC模块PA0/AN0通道设为ADC CHANNEL
      ADCC2=0b00000001;
      //ADC模块时钟设置寄存器 ADCS<7-5> 011=FOSC/8100=FOSC/16 101=FOSC/32ADIE=中断使能位 0=禁止 1=使能<3-0>=未用
      ADCC1=0b10001111; //16分频   ADCC1=0b01101111;// 8分频      ADCC1=0b10001111; 16分频
      // 右对齐ADFM=1VCFG-VREF参考电压设置0-VDD 1-VREF ADIF=中断标志位 CHS<4-2>--000=通道0 001=通道1 GO/DONE=使能ADC转换 ADON=工作模块使能位
                        ADCC0=0b10000001;//通道0    通道1ADCC0=0b10000101;      
}


void ADC_Work_PRO()
{
        //初始化ADC模块PA0/AN0通道设为ADC CHANNEL
ADCC2=0b00000001;
        GO_DONE = 1;
        while(GO_DONE);
        ADC_One_Time_BUF=ADCRH;
        ADC_One_Time_BUF=ADC_One_Time_BUF<<8;
        ADC_One_Time_BUF+= ADCRL;
        ADC.temp+=ADC_One_Time_BUF;
        ADC_One_Time_BUF=0;
        ADC_Time_CNT++;
        if(ADC_Time_CNT>=8)
                {
                        ADC_Time_CNT=0;
                        ADC_Display_ok=1;
                        //初始化ADC模块PA0/AN0通道设为ADC CHANNEL
      ADCC2=0b00000000;
                }
}

void ADC_Result_Arrange()
{
        //8次ADC累加和 除以8求平均值
        ADC.temp=ADC.temp>>3;
        //用于调整显示IO口 低8位为PB1 PB0 PA7 PA6 PA5 PA4 PA3 PA2   高2位为 PB3 PB2
        ADC.temp=ADC.temp<<1;
        PA_Buf=ADC.ADC_Result.temp_L;
                ADC.temp=ADC.temp<<1;
                PA_Buf&=0b00111111;
        PA_Buf|=(ADC.ADC_Result.temp_L&0b11000000);
        PB_Buf=ADC.ADC_Result.temp_H;
}


void ADC_Result_Display()
{
        PA=PA_Buf;
        PB=PB_Buf;
        ADC.temp=0;
}

海尔_小海 发表于 2013-4-11 18:01:06

汇编的程序供参考
ADC模块初始化:
BANK    2
      MOVI    0x1F                  ;设置AN0,AN1,AN2,AN3,AN4为模拟I/O口,AN5为数字I/O口
      MOVA    ADCC2                   ;
      CLR   ADCC0                   ;参考电压VDD,转换结果格式左对齐
      MOVI    0X80                  ;AD中断禁止,ADC时钟FOSC/16
      MOVA    ADCC1      

;AD采样子程序
;***********************************************************      
AD_SAMPLE      
      BANK    2                     ;取按键采集值,连续采6次,去掉最大最小,除以4
      CLR   ad_acc_l                ;清采样值累加寄存器
      CLR   ad_acc_h
      CLR   ad_count                ;清采样次数
FIRST_SAMPLE
      BSS   ADCC0,GO_DONE         ;启动第一次AD转换
      JBC   ADCC0,GO_DONE         ;检测启动位,转换完成该位自动清零,跳过下条指令
      JUMP    $-1                     ;转换没有完成返回上一条继续检测
      MOV   ADCRH,0               ;第一次采样把结果赋给ad_max、ad_min和ad_acc_l
      MOVA    ad_max   
      MOVA    ad_min
      MOVA    ad_acc_l
LATTER_SAMPLE      
        BSS   ADCC0,GO_DONE         ;启动第2~6次AD转换
      JBC   ADCC0,GO_DONE         ;检测启动位,转换完成该位自动清零,跳过下条指令
      JUMP    $-1                     ;转换没有完成返回上一条继续检测
      MOV   ADCRH,0               ;第二次采样把结果累加到ad_acc_l
      ADD   ad_acc_l,1
      JBC   PSW,C
      INC   ad_acc_h,1
COMPARE_MAX
      MOV   ad_max,0                ;如果此次采样值大于原来的ad_max,则取代原来的ad_max
      SUB   ADCRH,0
      JBS   PSW,C
      JUMP    COMPARE_MIN
      MOV   ADCRH,0
      MOVA    ad_max
COMPARE_MIN
      MOV   ADCRH,0               ;如果此次采样值小于原来的ad_min,则取代原来的ad_min
      SUB   ad_min,0
      JBS   PSW,C
      JUMP    AD_RESULT
      MOV   ADCRH,0
      MOVA    ad_min
AD_RESULT
      INC   ad_count,1            ;记录AD采样的次数
      MOVI    .5
      SUB   ad_count,0            ;ad_count=9时结束AD采样
      JBS   PSW,Z
      JUMP    LATTER_SAMPLE         ;没到6次,继续采
                                        ;到6次,计算采样结果
        MOV   ad_max,0                ;从累加的结果中减去最大值和最小值
      SUB   ad_acc_l,1
      JBS   PSW,C
      DEC   ad_acc_h
      MOV   ad_min,0
      SUB   ad_acc_l,1
      JBS   PSW,C
      DEC   ad_acc_h
                                        ;<ad_acc_h:ad_acc_l>右移2次,即除以4
        BCC   PSW,C
      RR      ad_acc_h,1
      RR      ad_acc_l,1
        BCC   PSW,C
      RR      ad_acc_h,1
      RR      ad_acc_l,1
      
      MOV   ad_acc_l,0
      BANK    0
      MOVA    ad_resultbuf               ;最后采样的结果保存在ad_resultbuf里
      BANK    1
        MOVA    ad_resultbuf1               ;最后采样的结果保存在ad_resultbuf1里
      RETIA   0X00
页: [1]
查看完整版本: 现在采用HR6P61L芯片搞个项目 大家谁有ADC的模块程序啊