📄 adc_scan_10.c
字号:
//*****************************************************************
//*ADC_scan_in.C *
//*****************************************************************
// *
// 晶振为7.3728MHz *
// 它做的事情是: *
// 1. 采用AD扫描输入,对电位计R13(RB2/AN2)采样,每次采样/转换完成后产生中断,在ISR中比较电位计电压-当它达到参考电压的一半以上,RD4亮起 *
//*****************************************************************
#include <p30f6010A.h>
#include<adc10.h>
#include <dsp.h>
/*********************************************************************/
// 配置位
_FOSC(CSW_FSCM_OFF & XT_PLL4);
_FWDT(WDT_OFF);
_FBORPOR(PBOR_ON & BORV_20 & PWRT_64 & MCLR_EN);
#define LED1 PORTDbits.RD4 // LED1连到RD4
#define LED2 PORTDbits.RD5 // LED1连到RD5
#define LED3 PORTDbits.RD6 // LED1连到RD6
#define FCY 7378200 // 7.37Mhz晶振(且系统时钟PPL为4倍频,后分频比为默认值1:1),
// 即单片机指令频率Fcy=7378200Hz
#define MILLISEC FCY/7378 // 1ms延时常数,1000
//---------------------------------------------------------------------
// 子程序和中断矢量声明 开头的void表示无返回值
void InitADC10(void);
void DelayNmSec(unsigned int N);
void SetupPorts(void);
void __attribute__((__interrupt__)) _ADCInterrupt(void);
unsigned int ADCValue1;
unsigned int ADCValue2;
unsigned int ADCValue3;
unsigned int ADRU[10][5]; //结果矩阵10行5列
unsigned int ADG; //组号
unsigned int ADH; //行号
unsigned int ADFRU[10]; //最终平均数
//---------------------------------------------------------------------
int main(void)
{
InitADC10();
SetupPorts(); // 初始化I/O
volatile unsigned int * AD16ptr;
while(1)
{
for(ADG=0;ADG<5;ADG++) //一共转换5次5组数据
{
AD16ptr = &ADCBUF0; //初始化指针
ADCON1bits.ASAM = 1; // 开始开启采样
if(IFS0bits.ADIF=0);
else ADCON1bits.ASAM = 0; // 关闭自动采样
for(ADH=0;ADH<10;ADH++)
{
ADRU[ADH][ADG]=*AD16ptr++; //以此存入矩阵
}
// IFS0bits.ADIF=0 ; // AD中断标志位清0
}
unsigned int h,j; //排序计数
unsigned int ADTemp; //转移暂存字
for(ADH=0;ADH<9;ADH++) //10行循环排序
{
//ADH = 0;
for(h=4;h>0;h--) //冒泡法外循环
{
for(j=0;j<h;j++) //冒泡法内循环
{
if(ADRU[ADH][ADG+j]>ADRU[ADH][ADG+j+1]) //大值往后排
{
ADTemp=ADRU[ADH][ADG+j];
ADRU[ADH][ADG+j]=ADRU[ADH][ADG+j+1];
ADRU[ADH][ADG+j+1]=ADTemp;
}
}
}
ADFRU[ADH]=ADRU[ADH][1]+ADRU[ADH][2]+ADRU[ADH][3]; //去头去尾就平均
ADFRU[ADH]=ADFRU[ADH]/3;
}
ADH = 9; //不知名原因,不能进行10次赋值循环,故进行9次后对最后一组数据补充处理。
for(h=4;h>0;h--) //冒泡法外循环
{
for(j=0;j<h;j++) //冒泡法内循环
{
if(ADRU[ADH][ADG+j]>ADRU[ADH][ADG+j+1]) //大值往后排
{
ADTemp=ADRU[ADH][ADG+j];
ADRU[ADH][ADG+j]=ADRU[ADH][ADG+j+1];
ADRU[ADH][ADG+j+1]=ADTemp;
}
}
}
ADFRU[ADH]=ADRU[ADH][1]+ADRU[ADH][2]+ADRU[ADH][3]; //去头去尾就平均
ADFRU[ADH]=ADFRU[ADH]/3;
IFS0bits.ADIF=0 ; // AD中断标志位清0
//ADCValue1 = ADCBUF9; // 转换好了得到ADC value,为加数据处理用这行
ADCValue1 = ADFRU[9]; //处理完用这行
if(ADCValue1>0x01FF)
LED1 = 1;
else LED1 = 0;
//ADCValue2 = ADFRU[9]; //处理完用这行
// if(ADCValue2>0x01FF)
// LED2 = 1;
// else LED2 = 0;
//ADCValue3 = ADFRU[4]; //处理完用这行
// if(ADCValue3>0x01FF)
// LED3 = 1;
// else LED3 = 0;
//DelayNmSec(100); // 延时100ms
}
} // 主函数结束
//---------------------------------------------------------------------
void SetupPorts(void)
{
PORTD = 0;
TRISD = 0xFF0F; // Set 设置RD7 to RD4 as outputs为0(输出)
}
//---------------------------------------------------------------------
void InitADC10(void)
{
ADPCFG = 0xF003; // 设置RB口
ADCON1 = 0x00E0; // SSRC=111,通过内部计数器结束采样并开始转换
ADCHS = 0x0000; // 连接RB2/AN2到CH0正输入选择位,CH0负输入选择Vref-
ADCSSL = 0x0FFC; // 选择RB2/AN2为唯一的扫描输入通道
ADCON3 = 0x030D; // 3Tad,Tad=Tcy/2
ADCON2 = 0x0428; // 单AN扫描输入,每10次采样/转换过程后产生中断
//ConfigIntADC10(ADC_INT_PRI_3 &
// ADC_INT_ENABLE); // 使能AD中断,且中断优先级是3
ADCON1bits.ADON = 1; // 开启ADC模块
}
//以下是一个简单的1ms到65.5秒的延时程序,当N=1,延时1ms,当N=65535,延时65535ms
// 注意FCY在这里被用于计算.
void DelayNmSec(unsigned int N)
{
unsigned int j;
while(N--)
for(j=0;j < MILLISEC;j++);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -