现在采用HR6P61L芯片搞个项目 大家谁有ADC的模块程序啊
如题,C语言和汇编都有最好了。多谢! 请版主上传个应用历程吧!{:tongue:} 流浪飞鸟 发表于 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;
} 汇编的程序供参考
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]