第一節 知識點
1.ADC
(1)10 位模數轉換器(A/D)模塊:28 引腳器件的模數(Analog-to-DigitalA/D)轉換器具有10 路輸入,而40/44 引腳器件的模數轉換器則具有13 路輸入。A/D 模塊能將一個模擬輸入信號轉換成相應的10 位數字信號。
(2)此模塊有五個寄存器:
? A/D 轉換結果高位寄存器(ADRESH)
? A/D 轉換結果低位寄存器(ADRESL)
? A/D 轉換控制寄存器0 (ADCON0):A/D 模塊的工作方式由ADCON0寄存器控制。
? A/D 轉換控制寄存器1 (ADCON1):端口引腳的功能由ADCON1 寄存器配置。
? A/D 轉換控制寄存器2 (ADCON2):由ADCON2 寄存器配置A/D 時鐘源,編程采集時間和對齊方式。
(3)執行A/D 轉換時應該遵循以下步驟:
- 配置A/D 模塊:
? 配置模擬引腳、參考電壓和數字I/O (通過ADCON1 寄存器)
? 選擇A/D 輸入通道(通過ADCON0 寄存器)
? 選擇A/D 采集時間(通過ADCON2 寄存器)
? 選擇A/D 轉換時鐘(通過ADCON2 寄存器)
? 使能A/D 模塊(通過ADCON0 寄存器) - 需要時,配置A/D 中斷:
? 清零ADIF 位
? 將ADIE 位置1
? 將GIE 位置1 - 如果需要,等待所需的采集時間。
- 啟動轉換:
? 將GO/DONE 位置1 (ADCON0 寄存器) - 等待A/D 轉換完成,通過以下兩種方法之一判斷轉換是否完成:
? 查詢GO/DONE 位是否被清零或 等待A/D 中斷 - 讀取A/D 結果寄存器(ADRESH:ADRESL),需要時將ADIF 位清零。
- 如需再次進行A/D 轉換,返回步驟1 或步驟2。將每位的A/D 轉換時間定義為TAD,在下一次采集開始前至少需要等待2 個TAD。
(4)A/D 采集要求
為了使A/D 轉換器達到規定精度,必須使充電保持電容(CHOLD)充滿至輸入通道的電平。圖19-3 給出了模擬輸入的電路模型。電源阻抗(RS)和內部采樣開關阻抗(RSS)直接影響電容CHOLD 充電的時間。采樣開關(RSS)阻抗值隨器件電壓(VDD)不同而改變。電源阻抗將影響模擬輸入的偏移電壓(由于引腳泄漏電流的原因)。模擬信號源的最大阻抗推薦值為2.5 kΩ。在選擇(改變)了模擬輸入通道之后,必須對通道進行采樣才能啟動轉換,采樣時間必須大于最小采集時間。
(5) 采樣時間計算:
1.ADC的原理框圖:
2.與ADC相關的寄存器:
我們設置VCFG1=0,采用BSS作為參考電壓VREF-;
設置VCFG0=0,采用VDD作為VREF+的參考電壓。
配置PCFG3:PCFG0 進行采集模擬量的端口配置。
配置ADFM,ADC轉化結構的格式是左對齊還是右對齊,這是因為ADC轉化結果是10位的需要兩個8位寄存器存儲。
ACQT2:ACQT0:A/D 采集時間選擇位;
ADCS2:ADCS0:A/D 轉換時鐘選擇位。
3.比如我們在實際中要采集電壓,典型的電路圖如下:
02第二節 代碼設計
1.我們新建兩個文件:
(1) adc_sample.h
/* Microchip Technology Inc. and its subsidiaries. You may use this software
* and any derivatives exclusively with Microchip products.
* File: adc_sample.h
* Author: Greg
* Comments:
* Revision history: 2018-06-21
*/
// This is a guard condition so that contents of this file are not included
// more than once.
#ifndef _ADC_SAMPLE_H_
#define _ADC_SAMPLE_H_
#include // include processor files - each processor file is guarded.
#define Channel_0_ON 0b0000
#define Channel_1_ON 0b0001
#define Channel_2_ON 0b0010
#define Channel_3_ON 0b0011
#define Channel_4_ON 0b0100
#define Channel_5_ON 0b0101
#define Channel_6_ON 0b0110
#define Channel_7_ON 0b0111
#define ADC_Channel_select ADCON0bits.CHS
#define ADC_ENABLE ADCON0bits.ADON=1
#define ADC_DISABLE ADCON0bits.ADON=0
#define ADC_STATUS ADCON0bits.GODONE
#define ADC_START ADCON0bits.GO=1
#define ADC_PORT_DIR TRISA
void ADC_Channel_config(void);
double ADC_Converter_Ddecimal(unsigned int ADC_data);
double ADC_Process_show(unsigned char Channel_selected );
double ADC_Process_Select_work(unsigned char Channel_selected);
#endif /* XC_HEADER_TEMPLATE_H */
(2)adc_sample.c
#include
#include "adc_sample.h"
static unsigned int ADC_Data[8]=0;
void ADC_Channel_config(void)
{
ADC_PORT_DIR=0xFF;
ADCON1bits.PCFG=0b0111; //select An0-An7 Channel to A_D converter
ADCON1bits.VCFG=0b00; //voltage reference for Vss,Vdd.
ADCON2bits.ADFM=1; // reslut right justed
ADCON2bits.ACQT=0b001;
ADCON2bits.ADCS=0b000;
}
/*
this fucntion is to converter result of ADC to decimal result.
*/
double ADC_Converter_Ddecimal(unsigned int ADC_data)
{ double temp;
temp=(double) ADC_data*5.0;
return temp/1023.0;
}
/*
* This is first way to get ADC sample Result.
*/
double ADC_Process_show(unsigned char Channel_selected)
{
double ADC_temp0=0;
switch (Channel_selected){
case 0:
ADC_Channel_select=Channel_0_ON;
break;
case 1:
ADC_Channel_select=Channel_1_ON;
break;
case 2:
ADC_Channel_select=Channel_2_ON;
break;
case 3:
ADC_Channel_select=Channel_3_ON;
break;
case 4:
ADC_Channel_select=Channel_4_ON;
break;
case 5:
ADC_Channel_select=Channel_5_ON;
break;
case 6:
ADC_Channel_select=Channel_6_ON;
break;
case 7:
ADC_Channel_select=Channel_7_ON;
break;}
ADC_ENABLE;
ADC_START;
while(ADC_STATUS);
// ADC_Data[0]=0x00FF&ADRESL;
// ADC_Data[0]|=ADRESH< 8;< span="" >
ADC_Data[0]=ADRES;
ADC_temp0=ADC_Converter_Ddecimal(ADC_Data[Channel_selected]);
return ADC_temp0;
}
/*
* This is second way to get ADC sample Result.
*/
double ADC_Process_Select_work(unsigned char Channel_selected)
{ double ADC_temp0=0;
ADC_Channel_select=Channel_selected;
ADC_ENABLE;
ADC_START;
while(ADC_STATUS);
// ADC_Data[0]=0x00FF&ADRESL;
// ADC_Data[0]|=ADRESH< 8;< span="" >
ADC_Data[0]=ADRES;
ADC_temp0=ADC_Converter_Ddecimal(ADC_Data[0]);
return ADC_temp0;
}
(3)main.C
// PIC18F4520 Configuration Bit Settings
// 'C' source line config statements
// Author:Greg
// Title:ADC 采樣
// CONFIG1H
#pragma config OSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
// CONFIG2L
#pragma config PWRT = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = SBORDIS // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 3 // Brown Out Reset Voltage bits (Minimum setting)
// CONFIG2H
#pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)
// CONFIG3H
#pragma config CCP2MX = PORTC // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = ON // PORTB A/D Enable bit (PORTB< 4:0 >pins are configured as analog input channels on Reset)
#pragma config LPT1OSC = OFF // Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = OFF // MCLR Pin Enable bit (RE3 input pin enabled; MCLR disabled)
// CONFIG4L
#pragma config STVREN = OFF // Stack Full/Underflow Reset Enable bit (Stack full/underflow will not cause Reset)
#pragma config LVP = OFF // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))
// CONFIG5L
#pragma config CP0 = OFF // Code Protection bit (Block 0 (000800-001FFFh) not code-protected)
#pragma config CP1 = OFF // Code Protection bit (Block 1 (002000-003FFFh) not code-protected)
#pragma config CP2 = OFF // Code Protection bit (Block 2 (004000-005FFFh) not code-protected)
#pragma config CP3 = OFF // Code Protection bit (Block 3 (006000-007FFFh) not code-protected)
// CONFIG5H
#pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code-protected)
// CONFIG6L
#pragma config WRT0 = OFF // Write Protection bit (Block 0 (000800-001FFFh) not write-protected)
#pragma config WRT1 = OFF // Write Protection bit (Block 1 (002000-003FFFh) not write-protected)
#pragma config WRT2 = OFF // Write Protection bit (Block 2 (004000-005FFFh) not write-protected)
#pragma config WRT3 = OFF // Write Protection bit (Block 3 (006000-007FFFh) not write-protected)
// CONFIG6H
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot block (000000-0007FFh) not write-protected)
#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)
// CONFIG7L
#pragma config EBTR0 = OFF // Table Read Protection bit (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF // Table Read Protection bit (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF // Table Read Protection bit (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks)
// CONFIG7H
#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) not protected from table reads executed in other blocks)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include
#include "adc_sample.h"
#include
#include "usart_dr.h"
//#include"plib/adc.h"
//#include "delays.h"
int main(void)
{
unsigned char Channel_select=0;
double ADC_temp0;
ADC_Channel_config();
usart_port_dir_init();
usart_Config_init();
printf("test for printf functionrtn"); // printf 函數實現成功!
printf("ADC 采樣實現rtn"); // printf 函數實現成功!
while(1)
{
ADC_temp0=ADC_Process_show(Channel_select);
printf("ADC var:%frtn",ADC_temp0);
ADC_temp0=ADC_Process_Select_work(Channel_0_ON);
printf("ADC var:%frtn",ADC_temp0);
}
return 0;
}
下載到開發板中看效果吧,代碼的注釋很清楚我就不解釋了。
評論
查看更多