刚刚开始上手的时候,从官网上下载了pic24AD的技术文档,看了很久它的寄存器配置,希望知道AD模块所有的功能,手动,自动,定时,中断,,,,然后自己写了一些AD采样的代码,但是运行调试的时候,发现AD1CON1位的DONE位不能被置1,查看技术手册,知道DONE是采样结束以后转换完成时被硬件自动置1 的,自己也在代码中试着将DONE位置1,但是程序还是不行,用while(!_DONE)判断的时候一直在死循环,然后又怀疑是不是采样时间不够转换不够,所以用重新配置寄存器,手动不行,那就自动,自动不行,那就再用中断,这个问题困扰了我好多天,然后又看技术手册,用技术手册上的参考代码运行,还是不行,这下完全崩溃了,快要放弃的时候,最后试一下,就用两一块板子试了一下,突然发现可以了,DONE位也能被自动置1.原来我的板子跟芯片不匹配(这个问题我还没去深究);后来实验就快了。建议学习PIC24AD的同学,先看寄存器配置,然后电气规范也很重要,
提供我的程序希望有帮助 数码管动态扫描 AD转换 VDD=3.2V 采用中断,11次采样取平均值 #include<p24HJ256GP610.h>
unsigned char const Disp_Tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //段码控制 unsigned char const dispbit[]={0X1D,0X1A,0X16,0X0E }; volatile static unsigned int LedNumVal=0,sum=0; int a=1; void lcddelay(unsigned char ms) //(3j+11)*i个指令周期 { unsigned char i,j; // for(i=ms;i>0;i--) for(j=4000;j>0;j--) {;} }
void ADCinit(void) { AD1PCFGL=0XfffF; AD1PCFGH=0XFFFF; AD1PCFGLbits.PCFG3=0; //AN3 TRISBbits.TRISB3=1; AD1CON1=0X00e4; //自动采样 采样以后自动开始转换 AD1CON2=0X0004; //Vadd=3.2V Vss 2个采样产生一个中断 AD1CON3=0X1f09; //9*Tcy=9*1/12us ;Fosc=24M;32*Tad AD1CHS0=0X0003; //AN3 AD1CSSL=0; _AD1IF=0; _AD1IP=7; _AD1IE=1; AD1CON1bits.ADON=1; //开启AD模块 } void __attribute__((__interrupt__)) _ADC1Interrupt(void) {
if(a<=11) { sum=sum+ADC1BUF0; a++; } else { LedNumVal=sum/11; sum=0; PORTD=LedNumVal; a=1 ; } // while(!_DONE); // LedNumVal=ADC1BUF0; _AD1IF=0; }
void main() { unsigned char LedOut[4]; int k; TRISC=0; TRISE=0; TRISD=0; //提供给FPGA的控制信号 ADCinit(); //_SAMP=1; while(1) //进入循环状态 {
if(LedNumVal<=1000) { LedOut[0]=Disp_Tab[LedNumVal%10000/1000+1]; LedOut[1]=Disp_Tab[LedNumVal%1000/100]|0x80; LedOut[2]=Disp_Tab[LedNumVal%100/10]; LedOut[3]=Disp_Tab[LedNumVal%10]; } else { LedOut[0]=Disp_Tab[2]; LedOut[1]=Disp_Tab[0]; LedOut[2]=Disp_Tab[0]; LedOut[3]=Disp_Tab[0]; } for( k=0; k<4; k++) //实现4位动态扫描循环 { PORTC=dispbit[k]&0xff; PORTE= LedOut[k]&0xff; //将字模送到数码管显示 lcddelay(20); } } }
|