第5节 GP32 MCU A/D转换编程实例
本节给出的A/D转换程序,包含了中值滤波与平均值滤波的复合滤波方式,因为不含软件滤波的A/D转换程序很少能够实际应用的。本程序中的中值滤波,就是对三次采样值比较大小,取中间的一个。所谓平均值滤波,就是N个采样值求平均。而中值滤波与平均值滤波的复合滤波方式,就是先进行中值滤波,再进行平均值滤波。
10.5.1 A/D转换08C语言编程实例
以下给出GP32的A/D模块编程实例。表10-1列出了该例程的所有程序文件,下面逐一介绍这些程序。
(1) A/D转换有关头文件ADC.h
//[ADC.h]A/D转换头文件------------------------------------------------------
//头文件
#include "GP32C.h" //GP32 MCU映像寄存器名定义
#include "Type.h" //类型别名定义
//转换完成标志位宏定义
#define COCOBit 7
//函数声明
void ADCinit(void); //A/D转换初始化
INT8U ADCvalue(INT8U channel); //1路A/D转换函数
INT8U ADCmid(INT8U channel); //1路A/D转换函数(中值滤波)
INT8U ADCave(INT8U channel, INT8U n); //1路A/D转换函数(均值滤波)
(2) A/D转换有关C语言子函数ADC.C
//[ADC.c]A/D转换-----------------------------------------------------------*
//本文件包含: *
// (1)ADCinit:A/D转换初始化 *
// (2)ADCvalue:获取1路A/D转换结果 *
// (3)ADCmid:获取中值滤波后的A/D转换结果 *
// (4)ADCave:获取均值滤波后的A/D转换结果 *
//硬件连接: *
// PTB0/AD0 接模拟量输入端 *
//-------------------------------------------------------------------------*
//头文件
#include "ADC.h"
//ADCinit:A/D转换初始化----------------------------------------------------*
//功能:设置A/D转换时钟频率为1MHz *
//参数:无 *
//返回:无 *
//-------------------------------------------------------------------------*
void ADCinit(void)
{
ADCLK = 0b00110000;
//||||||||_______不用
//||||___________选择内部总线时钟
//|||____________分频系数为2
}
//ADCave:1路A/D转换函数(均值滤波)------------------------------------------*
//功能:通道channel进行n次中值滤波,求和再作均值,得出均值滤波结果 *
//参数:channel = 通道号,n = 中值滤波次数 *
//返回:该通道均值滤波后的A/D转换结果 *
//内部调用:ADCmid *
//-------------------------------------------------------------------------*
INT8U ADCave(INT8U channel, INT8U n)
{
INT8U i;
INT16U j;
j = 0;
for (i = 0; i < n; i++)
j += ADCmid(channel);
j = j/n;
return (INT8U)j;
}
//ADCmid:1路A/D转换函数(中值滤波)------------------------------------------*
//功能:获取通道channel中值滤波后的A/D转换结果 *
//参数:channel = 通道号 *
//返回:该通道中值滤波后的A/D转换结果 *
//内部调用:ADCvalue *
//-------------------------------------------------------------------------*
INT8U ADCmid(INT8U channel)
{
INT8U i,j,k,tmp;
//1.取三次A/D转换结果
i = ADCvalue(channel);
j = ADCvalue(channel);
k = ADCvalue(channel);
//2.从三次A/D转换结果中取中值
if (i > j)
{
tmp = i;
i = j;
j = tmp;
}
if (k > i)
{
if (k > j)
{
tmp = j;
}
else
{
tmp = k;
}
}
else
{
tmp = i;
}
return tmp;
}
//ADCvalue:1路A/D转换函数--------------------------------------------------*
//功能:获取通道channel的A/D转换结果 *
//参数:channel = 通道号 *
//返回:该通道的A/D转换结果 *
//-------------------------------------------------------------------------*
INT8U ADCvalue(INT8U channel)
{
INT8U tmp;
//1. 选取通道号ADch4-ADch0 = 00000-00111:AD0引脚 - AD7引脚
channel &= 0b00011111; //取通道号变量的低五位(实际通道号)
tmp = ADSCR & 0b11100000; //取ADSCR的高三位(取上电复位默认值000)
ADSCR = tmp | channel; //合并上述8位
//2. 取A/D转换结果
while ((ADSCR & (1<<COCOBit)) == 0);
return ADR;
}
(3) A/D转换08C测试实例主函数main.c
//-------------------------------------------------------------------------*
//工 程 名:ADC.prj *
//硬件连接: *
// (1)PTB0/AD0 接模拟量输入端(见"ADC.c"文件) *
// (2)MCU的串口与PC方的串口相连(见"SCI.c"文件) *
//程序描述:获取1路A/D转换结果,并滤波,通过串口发送出去 *
//目 的:掌握A/D转换的基本编程方法 *
//注 意:用MD-IDE实验板测试时,把液晶拔出,否则可能影响结果 *
//------------------清华2007版《嵌入式技术基础与实践》实例-----------------*
//总头文件
#include "Includes.h"
//主程序
void main(void)
{
DisableMCUint(); //禁止总中断
//1. 芯片初始化
MCUinit();
//2. 模块初始化
SCIinit(); //(1) 串行口初始化
ADCinit(); //(2) A/D转换初始化
while (1)
{
//在通道0做A/D转换,200次中值滤波,串口发送均值滤波结果
SCIsend1(ADCave(0, 200));
}
}
10.5.2 A/D转换汇编语言编程实例
A/D转换汇编程序和08C程序相似,这里仅给出工程列表,如表10-2所示,具体内容参见程序文件夹。
10.5.1 A/D转换08C语言编程实例
以下给出GP32的A/D模块编程实例。表10-1列出了该例程的所有程序文件,下面逐一介绍这些程序。

(1) A/D转换有关头文件ADC.h
//[ADC.h]A/D转换头文件------------------------------------------------------
//头文件
#include "GP32C.h" //GP32 MCU映像寄存器名定义
#include "Type.h" //类型别名定义
//转换完成标志位宏定义
#define COCOBit 7
//函数声明
void ADCinit(void); //A/D转换初始化
INT8U ADCvalue(INT8U channel); //1路A/D转换函数
INT8U ADCmid(INT8U channel); //1路A/D转换函数(中值滤波)
INT8U ADCave(INT8U channel, INT8U n); //1路A/D转换函数(均值滤波)
(2) A/D转换有关C语言子函数ADC.C
//[ADC.c]A/D转换-----------------------------------------------------------*
//本文件包含: *
// (1)ADCinit:A/D转换初始化 *
// (2)ADCvalue:获取1路A/D转换结果 *
// (3)ADCmid:获取中值滤波后的A/D转换结果 *
// (4)ADCave:获取均值滤波后的A/D转换结果 *
//硬件连接: *
// PTB0/AD0 接模拟量输入端 *
//-------------------------------------------------------------------------*
//头文件
#include "ADC.h"
//ADCinit:A/D转换初始化----------------------------------------------------*
//功能:设置A/D转换时钟频率为1MHz *
//参数:无 *
//返回:无 *
//-------------------------------------------------------------------------*
void ADCinit(void)
{
ADCLK = 0b00110000;
//||||||||_______不用
//||||___________选择内部总线时钟
//|||____________分频系数为2
}
//ADCave:1路A/D转换函数(均值滤波)------------------------------------------*
//功能:通道channel进行n次中值滤波,求和再作均值,得出均值滤波结果 *
//参数:channel = 通道号,n = 中值滤波次数 *
//返回:该通道均值滤波后的A/D转换结果 *
//内部调用:ADCmid *
//-------------------------------------------------------------------------*
INT8U ADCave(INT8U channel, INT8U n)
{
INT8U i;
INT16U j;
j = 0;
for (i = 0; i < n; i++)
j += ADCmid(channel);
j = j/n;
return (INT8U)j;
}
//ADCmid:1路A/D转换函数(中值滤波)------------------------------------------*
//功能:获取通道channel中值滤波后的A/D转换结果 *
//参数:channel = 通道号 *
//返回:该通道中值滤波后的A/D转换结果 *
//内部调用:ADCvalue *
//-------------------------------------------------------------------------*
INT8U ADCmid(INT8U channel)
{
INT8U i,j,k,tmp;
//1.取三次A/D转换结果
i = ADCvalue(channel);
j = ADCvalue(channel);
k = ADCvalue(channel);
//2.从三次A/D转换结果中取中值
if (i > j)
{
tmp = i;
i = j;
j = tmp;
}
if (k > i)
{
if (k > j)
{
tmp = j;
}
else
{
tmp = k;
}
}
else
{
tmp = i;
}
return tmp;
}
//ADCvalue:1路A/D转换函数--------------------------------------------------*
//功能:获取通道channel的A/D转换结果 *
//参数:channel = 通道号 *
//返回:该通道的A/D转换结果 *
//-------------------------------------------------------------------------*
INT8U ADCvalue(INT8U channel)
{
INT8U tmp;
//1. 选取通道号ADch4-ADch0 = 00000-00111:AD0引脚 - AD7引脚
channel &= 0b00011111; //取通道号变量的低五位(实际通道号)
tmp = ADSCR & 0b11100000; //取ADSCR的高三位(取上电复位默认值000)
ADSCR = tmp | channel; //合并上述8位
//2. 取A/D转换结果
while ((ADSCR & (1<<COCOBit)) == 0);
return ADR;
}
(3) A/D转换08C测试实例主函数main.c
//-------------------------------------------------------------------------*
//工 程 名:ADC.prj *
//硬件连接: *
// (1)PTB0/AD0 接模拟量输入端(见"ADC.c"文件) *
// (2)MCU的串口与PC方的串口相连(见"SCI.c"文件) *
//程序描述:获取1路A/D转换结果,并滤波,通过串口发送出去 *
//目 的:掌握A/D转换的基本编程方法 *
//注 意:用MD-IDE实验板测试时,把液晶拔出,否则可能影响结果 *
//------------------清华2007版《嵌入式技术基础与实践》实例-----------------*
//总头文件
#include "Includes.h"
//主程序
void main(void)
{
DisableMCUint(); //禁止总中断
//1. 芯片初始化
MCUinit();
//2. 模块初始化
SCIinit(); //(1) 串行口初始化
ADCinit(); //(2) A/D转换初始化
while (1)
{
//在通道0做A/D转换,200次中值滤波,串口发送均值滤波结果
SCIsend1(ADCave(0, 200));
}
}
10.5.2 A/D转换汇编语言编程实例
A/D转换汇编程序和08C程序相似,这里仅给出工程列表,如表10-2所示,具体内容参见程序文件夹。



