电压检测系统的设计与制作

更新时间:2024-06-24 05:41:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

姓名: 学号: 专业:

电压检测系统的设计与制作

项目实施过程及步骤

(一)中断模式下的AD转换器

1、启动PROTEUS软件绘制项目原理图(如图1)

109811413765432RA5/AN4/SSRA4/T0CKIRA3/AN3/VREF+RA2/AN2/VREF-RA1/AN1RA0/AN0RE2/AN7/CSRE1/AN6/WRRE0/AN5/RDPIC16F877AU2RC7/RX/DTRC6/TX/CKRC5/SDORC4/SDI/SDARC3/SCK/SCLRC2/CCP1RC1/T1OSI/CCP2RC0/T1OSO/T1CKIRD7/PSP7RD6/PSP6RD5/PSP5RD4/PSP4RD3/PSP3RD2/PSP2RD1/PSP1RD0/PSP03029282722212019262524231817161510987654321+5VU1RV211121314151617181920LED-BARGRAPH-GRN5k4039383736353433RB7/PGDRB6/PGCRB5RB4RB3/PGMRB2RB1RB0/INTRA0R15k50%MCLR/Vpp/THVOSC2/CLKOUTOSC1/CLKIN 图1 AD转换器的外部电路

2、参考程序

// 采用中断方式把模拟通道AN0的10位A/D转换结果送D口,C口显示 #include \

__CONFIG(XT & WDTDIS & LVPDIS); // ICD2 调试配置字 interrupt ISR(void) {

if(ADIE==1 && ADIF==1) {

ADIF=0; // A/D标志位清零 PORTC=ADRESL; // 低两位送PORTC PORTD=ADRESH; // 高八位送PORTD ADGO=1; // 启动下一次A/D转换 } else {

while(1); // 调试程序用,若有其它意外中断产生才会走的此处。 } }

电压检测系统设计

第1页 共9页

姓名: 学号: 专业:

void main(void) {

char i=0;

TRISA0=1; // AN0是RA0,所以要把A口置为输入 TRISD=0; // D口用做输出控制LED TRISC=0; // C口用做输出控制LED ADFM=0; //左对齐,ADRESH保存高八位 PCFG3=0; PCFG2=0; PCFG1=0;

PCFG0=0; // PCFG3:PCFG0=0000,全为模拟引脚,参考电压为VDD和VSS

// 以上5条语句可以用一条语句表达:ADCON1=0b00000000; 分开写的目的是易于理解 ADCS1=1;

ADCS0=1; // 使用A/D转换模块内部RC振荡器作为时钟 CHS2=0; CHS1=0;

CHS0=0; // CHS2:CHS0=000, 选择通道0进行A/D转换 ADON=1; // 开启A/D转换模块

// 以上6条语句可以用一条语句表达:ADCON0=0b11000001; ADIE=1; // 允许A/D转换产生中断 ADIF=0; // A/D标志位清零 PEIE=1; // 允许外设中断 GIE=1; // 打开总中断使能位

for(i=0;i<25;i++) ; // 为了采样保持电路充电的延时,超过25us即可 ADGO=1; // 启动一次A/D转换 while(1) ; //等待A/D转换结束 }

电位器阻值测量仪设计

1、启动PROTEUS软件绘制项目原理图(如图1)

电压检测系统设计

第2页 共9页

姓名: 学号: 专业:

W1RA07SEG-MPX4-CA-BLUE-WR1U2131412345678910OSC1/CLKINOSC2/CLKOUTMCLR/Vpp/THVRB0/INTRB1RB2RB3/PGMRB4RB5RB6/PGCRB7/PGD3334353637383940151617182324252619202122272829305K+88.8Volts92%RA0/AN0RA1/AN1RA2/AN2/VREF-RA3/AN3/VREF+RA4/T0CKIRA5/AN4/SSRC0/T1OSO/T1CKIRC1/T1OSI/CCP2RE0/AN5/RDRC2/CCP1RE1/AN6/WRRC3/SCK/SCLRE2/AN7/CSRC4/SDI/SDARC5/SDORC6/TX/CKCLOCK=4MHzRC7/RX/DT5kRV2PIC16F877ARD0/PSP0RD1/PSP1RD2/PSP2RD3/PSP3RD4/PSP4RD5/PSP5RD6/PSP6RD7/PSP7 图2 电位器阻值测量电路原理图

2、参考程序

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // myfuncs.c

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include \

void delayms(int ms) //定义延时函数 { int i=0,j=0;

for(i=0;i

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // myfuncs.h

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #ifndef _MYFUNCS_H_ // 防止重复编译本头文件 #define _MYFUNCS_H_

#define DLY_MS 67 //设置延时时间常数。不同主频时需要修改 void delayms(int ms); //声明延时函数 #endif // _MYFUNCS_H_

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // seg74.c

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include \

#include \#include \

const char Seg7TableN[]={0b11000000,0b11111001,0b10100100, 0b10110000,0b10011001,0b10010010,

电压检测系统设计

第3页 共9页

姓名: 学号: 专业:

0b10000010, 0b11111000,0b10000000,0b10010000}; //字形码数组 void DisplayData(unsigned int iData) { char i=0,j=0,k=0,NumStr[5]={0,0,0,0,0}; //NumbStr[0]未用 NumStr[1]=iData/1000; // 千位 NumStr[2]=(iData00)/100; // 百位 NumStr[3]=iData0/10; // 十位 NumStr[4]=iData; // 个位

//用NumStr[1]到NumStr[4]的目的是与电路图上的序号匹配,这样不易弄错 for(i=0;i<10;i++) { SEG_BITSEL_PORT=k=0x01; // 每次循环不要忘记k赋初始值 for(j=1;j<=4;j++) // 共需要刷新四个数码管位置 { SEG_BITSEL_PORT=k; //设置要点亮的位置 SEG_FONT_PORT=Seg7TableN[NumStr[j]]; //设置字形 delayms(5); // 延时显示字形,造成视觉暂留现象 k=k<<1; // 左移为显示下一位置做准备 } } }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // seg74.h

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #ifndef _SEGMENT74_H_ // 防止重复编译本头文件 #define _SEGMENT74_H_

#define SEG_BITSEL_PORT PORTD // 位选端口

#define SEG_BITSEL_PORT_DIR TRISD // 位选端口的方向寄存器 #define SEG_FONT_PORT PORTC // 字形输出端口

#define SEG_FONT_PORT_DIR TRISC // 字形端口的方向寄存器 void DisplayData(unsigned int iData); #endif // _SEGMENT74_H_

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // main.c

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 测量电位器RV2对地阻值并显示在四位数码管上。 #include \#include \#include \#include \

__CONFIG(XT & WDTDIS & LVPDIS); // ICD2 调试配置字 void main(void) {

char i=0; // 用来计数超过25us的变量

电压检测系统设计

第4页 共9页

姓名: 学号: 专业:

int adres=0; // 存放A/D转换10位结果

TRISA0=1; // AN0是RA0,所以要把A口置为输入 SEG_BITSEL_PORT_DIR=0x00; //位选端口置为输出 SEG_FONT_PORT_DIR=0x00; // 字形端口置为输出 ADFM=1; //右对齐,ADRESL保存低八位 PCFG3=0; PCFG2=0; PCFG1=0;

PCFG0=0; // PCFG3:PCFG0=0000,全为模拟引脚,参考电压为VDD和VSS

// 以上5条语句可以用一条语句表达:ADCON1=0b00000000;分开写的目的是易于理解 ADCS1=1;

ADCS0=1; // 使用A/D转换模块内部RC振荡器作为时钟 CHS2=0; CHS1=0;

CHS0=0; // CHS2:CHS0=000, 选择通道0进行A/D转换 ADON=1; // 开启A/D转换模块

// 以上6条语句可以用一条语句表达:ADCON0=0b11000001;

for(i=0;i<25;i++) ; 为了采样保持电路充电的延时,超过25us即可 ADGO=1; // 启动一次A/D转换 while(1) {

while(ADGO) ; // 采用查询方式进行A/D转换

adres=( ((unsigned int)ADRESH) << 8)+ADRESL; //获得10位结果 adres=((long)adres*5000/1023); //获得电阻值

DisplayData(adres); // 显示一次的时间远远大于25us ADGO=1; // 启动下一次A/D转换 } }

5、参考程序(带有软件滤波的电位器阻值测量仪)

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // myfuncs.c

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include \

void delayms(int ms) //定义延时函数 { int i=0,j=0;

for(i=0;i

电压检测系统设计

第5页 共9页

姓名: 学号: 专业:

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // myfuncs.h

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #ifndef _MYFUNCS_H_ // 防止重复编译本头文件 #define _MYFUNCS_H_

#define DLY_MS 67 //设置延时时间常数。不同主频时需要修改 void delayms(int ms); //声明延时函数 #endif // _MYFUNCS_H_

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // seg74.c

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include \

#include \#include \

const char Seg7TableN[]={0b11000000,0b11111001,0b10100100, 0b10110000,0b10011001,0b10010010, 0b10000010,0b11111000,0b10000000,0b10010000}; //字形码数组 void DisplayData(unsigned int iData) { char i=0,j=0,k=0,NumStr[5]={0,0,0,0,0}; //NumbStr[0]未用 NumStr[1]=iData/1000; // 千位 NumStr[2]=(iData00)/100; // 百位 NumStr[3]=iData0/10; // 十位 NumStr[4]=iData; // 个位

//用NumStr[1]到NumStr[4]的目的是与电路图上的序号匹配,这样不易弄错 for(i=0;i<10;i++) { SEG_BITSEL_PORT=k=0x01; // 每次循环不要忘记k赋初始值 for(j=1;j<=4;j++) // 共需要刷新四个数码管位置 { SEG_BITSEL_PORT=k; //设置要点亮的位置 if(j==1) {

SEG_FONT_PORT=Seg7TableN[NumStr[j]] &0b01111111; //设置千位显示小数点的字形 } } else { SEG_FONT_PORT=Seg7TableN[NumStr[j]]; //设置其它位字形 } delayms(5); // 延时显示字形,造成视觉暂留现象 k=k<<1; // 左移为显示下一位置做准备 } } }

电压检测系统设计

第6页 共9页

姓名: 学号: 专业:

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // seg74.h

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #ifndef _SEGMENT74_H_ // 防止重复编译本头文件 #define _SEGMENT74_H_

#define SEG_BITSEL_PORT PORTD // 位选端口

#define SEG_BITSEL_PORT_DIR TRISD // 位选端口的方向寄存器 #define SEG_FONT_PORT PORTC // 字形输出端口

#define SEG_FONT_PORT_DIR TRISC // 字形端口的方向寄存器 void DisplayData(unsigned int iData); #endif // _SEGMENT74_H_

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // main.c

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 采用中断方式+软件滤波测量电位器RV2对地阻电压值并显示在四位数码管上。 #include \#include \#include \#include \

__CONFIG(XT & WDTDIS & LVPDIS); // ICD2 调试配置字 unsigned int g_ADRTable[12]={0}; //保存12次转换结果 unsigned char g_Count=0; // 记录当前采集数据的存放位置

bit OverFlag=0; // 12次转换完成标志位,初学者注意标志位的使用方法 interrupt ISR(void) {

if(ADIE && ADIF) {

ADIF=0; // A/D标志位清零

g_ADRTable[g_Count]=( ((unsigned int)ADRESH) << 8)+ADRESL; //获得10位结果 g_Count++; if(g_Count==12) {

g_Count=0; OverFlag=1; } else

{ ADGO=1; // 启动下一次A/D转换 } } else {

while(1); // 调试程序用,若有其它意外中断产生才会走的此处。 } }

void main(void)

电压检测系统设计

第7页 共9页

姓名: 学号: 专业:

{

char i=0,j=0; // i用来计数超过25us的变量,i,j用来做排序算法循环变量 int tmp=0; // 存放数组元素或数组元素和的临时变量 int adc_v=0; // 存放多次A/D转换10位结果的平均值 TRISA0=1; // AN0是RA0,所以要把A口置为输入 SEG_BITSEL_PORT_DIR=0x00; //位选端口置为输出 SEG_FONT_PORT_DIR=0x00; // 字形端口置为输出 ADFM=1; //右对齐,ADRESL保存低八位 PCFG3=0; PCFG2=0; PCFG1=0;

PCFG0=0; // PCFG3:PCFG0=0000,全为模拟引脚,参考电压为VDD和VSS

// 以上5条语句可以用一条语句表达:ADCON1=0b00000000; 分开写的目的是易于理解 ADCS1=1;

ADCS0=1; // 使用A/D转换模块内部RC振荡器作为时钟 CHS2=0; CHS1=0;

CHS0=0; // CHS2:CHS0=000, 选择通道0进行A/D转换 ADON=1; // 开启A/D转换模块

// 以上6条语句可以用一条语句表达:ADCON0=0b11000001; ADIE=1; // 允许A/D转换产生中断 ADIF=0; // A/D标志位清零 PEIE=1; // 允许外设中断

GIE=1; // 打开总中断使能位

for(i=0;i<25;i++) ; // 为了采样保持电路充电的延时,超过25us即可 ADGO=1; // 启动一次A/D转换 while(1) {

if(OverFlag==1) // 12次转换完成 { // 简单的冒泡排序算法 for(i=0;i<12;i++) {

for(j=i+1;j<12;j++) {

if(g_ADRTable[i]>g_ADRTable[j]) {

tmp=g_ADRTable[i];

g_ADRTable[i]=g_ADRTable[j]; g_ADRTable[j]=tmp; } } }

// 计算g_ADRTable[2]到g_ADRTable[10]之间的平均值 tmp=0;

电压检测系统设计

第8页 共9页

姓名: 学号: 专业:

for(i=2;i<10;i++) //求排序后中间八个数的和 { // 最高的两个值和最低的两个值除外 tmp=tmp+g_ADRTable[i]; }

tmp=tmp>>3; //整数右移三位等价于除以八 adc_v=tmp; // 保存平均值

adc_v=((long)adc_v*5000/1023); //获得电阻值 OverFlag=0; // 清空标志位

ADGO=1; // 启动下一次A/D转换 }

DisplayData(adc_v); //显示平均值 } }

电压检测系统设计

第9页 共9页

本文来源:https://www.bwwdw.com/article/y1t3.html

Top