Zigbee基础实验之ADC

/******************************************************************************* * *功能描述:通过ADC采样, 实现五向开关操作LED等亮灭 *演示时,上左下右分别使一个LED亮 *按中间 4个LED一起亮 * *作者:Rfstorm studio QQ群:51109148 * *时间:2010-12-7 * ********************************************************************************/ #include typedef signedcharint8; typedef unsigned charuint8; typedef signedshortint16; typedef unsigned shortuint16; typedef signedlongint32; typedef unsigned longuint32; #define uint unsigned int #define uchar unsigned char// macro will also start the conversion. #define st(x)x //do { x } while (__LINE__ == -1) #define ADC_SINGLE_CONVERSION(settings) st( ADCCON3 = (settings); )//D1~D4 #define D1 P1_0 //定义LED1为P10口控制 #define D2 P1_1 //定义LED2为P11口控制 #define D3 P1_4 //定义LED3为P14口控制 #define D4 P0_1 //定义LED4为P01口控制// Input channel: #define ADC_AIN00x00// single ended P0_0 #define ADC_AIN10x01// single ended P0_1 #define ADC_AIN20x02// single ended P0_2 #define ADC_AIN30x03// single ended P0_3 #define ADC_AIN40x04// single ended P0_4 #define ADC_AIN50x05// single ended P0_5 #define ADC_AIN60x06// single ended P0_6 #define ADC_AIN70x07// single ended P0_7 #define ADC_GND0x0C// Ground #define ADC_TEMP_SENS0x0E// on-chip temperature sensor #define ADC_VDD_30x0F// (vdd/3)// Macro for setting/clearing a channel as input of the ADC #define ADC_ENABLE_CHANNEL(ch)ADCCFG |=(0x01 << ch) #define ADC_DISABLE_CHANNEL(ch)ADCCFG &= ~(0x01 << ch)int16 adcSampleSingle(uint reference, uint resolution, uint channel); void Initial(void); /**************************** //初始化程序 ***************************/ void Initial(void) { P1SEL &= ~0x13; //GPIO P1DIR |= 0X13; //OUTPUT P0SEL &= ~0x02; //GPIO P0DIR |= 0x02; //OUTPUTD1 = 0; D2 = 0; D3 = 0; D4 = 0; } /***************************************** //主函数 *****************************************/ void main( ) { int16 aa; int MOVE=0; APCFG |= 0X40; //配置P0.6为ADC INPUT//APCFG :模拟外设I/O 配置 //configured the 4LED P1SEL &= ~0x13; //GPIO P1DIR |= 0X13; //OUTPUT P0SEL &= ~0x02; //GPIO P0DIR |= 0X02; //OUTPUT P2SEL &= ~0x01; //GPIO P2DIR &= ~0X01; //INPUTInitial(); while(1) { aa=adcSampleSingle(0x80,0x00,ADC_AIN6); MOVE = P2_0; if(MOVE == 1) { MOVE = 0; if(aa<0x2000) { D1=1; D2=0; D3=0; D4=0; } if(aa>0x2000) if(aa<0x4000) { D1=0; D2=1; D3=0; D4=0; } if(aa>0x4000) if(aa<0x4a00) { D1=0; D2=0; D3=1; D4=0; } if(aa>0x4a00) if(aa<0x4f00) { D1=0; D2=0; D3=0; D4=1; } if(aa>0x4f00) { D1=1; D2=1; D3=1; D4=1; } } }}int16 adcSampleSingle(uint reference, uint resolution, uint channel) { int value; ADC_ENABLE_CHANNEL(channel); ADCIF = 0; ADC_SINGLE_CONVERSION(reference | resolution | channel);

while(!ADCIF); //等待转化结束 value= https://www.it610.com/article/(ADCH << 8) & 0xff00; value |= ADCL; ADC_DISABLE_CHANNEL(channel); return value; }

【Zigbee基础实验之ADC】代码分析:
1、#define st(x)do { x } while (__LINE__ == -1)
__LINE__ 是个宏,它代表当前代码在源文件的行号,它是大于0的,所以__LINE__ == -1 等同于0,化简为:
#define st(x)do { x } while (0)

2,do {} while (0)通常用于宏中, 为的是避免如下情况:

#define st(x) x

那么我们在调用 if (0) st(a = b; b = c; ) 时会被解释成

if(0)
a = b;
b = c;

可见 if 只对a = b;起作用。
2、
单个通道选择。选择写ADCCON3 触发的单个转换所在的通道号码。
当单个转换完成,该位自动清除。
0000: AIN0
0001: AIN1
0010: AIN2
0011: AIN3
0100: AIN4
0101: AIN5
0110: AIN6
0111: AIN7
1000: AIN0-AIN1
1001: AIN2-AIN3
1010: AIN4-AIN5
1011: AIN6-AIN7
1100: GND
1101: 正电压参考
1110: 温度传感器
1111: VDD/3
3、什么是 ADC模块的转换分辨率?
分辨率是指ADC能够分辨量化的最小信号的能力。
分辨率用二进制位数表示。
例如对一个10位的ADC,其所能分辨的最小量化电平为参考电平(满量程)的2的10次方分之一。也就是说分辨率越高,就能把满量程里的电平分出更多的份数(10bit就是把满量程分成了2^10份),得到的转换结果就越精确,得到的数字信号再用DAC转换回去就越接近原输入的模拟值。
4、
ADCIF : ADC中断标志。ADC中断发生时设为1且CPU指向中断向量例程时清除。
0: 无中断未决
1: 中断未决
5、
SFR寄存器:特殊功能寄存器(SFR)
6、
ADC_SINGLE_CONVERSION(reference | resolution | channel); 即ADCCON3 = (reference | resolution | channel);
其中ADCCON3 (0xB6)–ADC 控制3
ADCCON3[7:6]表示参考电压,ADCCON3[5:4]抽取率,ADCCON3[3:0]单个通道选择,详见手册。
10: AVDD5 引脚00: 64 抽取率(7 位ENOB)0110: AIN6
aa=?以及后面的判断不懂!

    推荐阅读