📄 digitalvoltmeter.c
字号:
/***************************************************
文件名 :DigitalVoltmeter.c **
功能描述:数字式电压表,在四个发光二极管上显示AN15**
通道的电压采样值采样和显示精度为0.001V **
***************************************************/
#include "p30f6014.h"
#include "DigitalVoltmeter.h"
void InitializeSys()
{
INTCON1 = 0x0000; //关中断
INTCON2 = 0x0000;
IEC0 = 0x0000; //IECx中断禁止
IEC1 = 0x0000;
IEC2 = 0x0000;
}
void InitializeSPIOut()
{
TRISF = TRISF&0xfebf; //SCK(RF6)、SDO(RF8)输出
TRISG = TRISG&0xfdff; //LACK(RG9)输出
SPI1CON = 0x0379; // CKP=1,CKE=1,FOSC/32,时钟上升沿发送数据
SPI1STATbits.SPIEN = 1; //SPI1EN=1
IFS0bits.SPI1IF = 0; //清除SPI1IF中断标志
}
void InitializeTMR3()
{
TMR3 = 0; //定时器3计数寄存器TMR3=0
T3CON = 0x8000; //起动定时器,使用内部时钟,预分频比为1:1
PR1 = 0x4e20; //定时器Timer3周期寄存器PR1=0x4e20,10ms初值
IFS0bits.T3IF = 0; //清除TMR1的中断标志
IPC1bits.T3IP = 6; //中断优先级为6
IEC0bits.T3IE = 1; //使能中断
}
void InitializeADC()
{
ADPCFG = 0x7fff; //RB15引脚处于模拟模式,禁止端口读取输入,A/D采样引脚电压
ADCON1 = 0x0044; //ADC结果为无符号整数格式,SSRC<2:0>=010:timer3定时器比较结束采样开始转换,
//使能自动采样模式
ADCHS = 0x000f; //通道0负输入是Vref-,通道0正输入是AN15
ADCSSL = 0x0000; //不对输入引脚进行扫描
ADCON2 = 0x0000; //参考电压配置AVDD,AVSS;一个采样/转换完成后产生中断
ADCON3 = 0x1f03; //使用系统时钟,相邻两次采样之间的时间间隔为31Tad,Tad=2Tcy
IFS0bits.ADIF = 0; //清AD转换中断标志位
IPC2bits.ADIP = 7; //设置AD转换中断优先级为7
IEC0bits.ADIE = 1; //使能AD转换完成中断
ADCON1bits.ADON = 1; //启动ADC
}
void FormatADCResult()
{
unsigned int ADCResult = 0;
unsigned long int ADCResultTemp = 0;
int i = 0;
//ADCResult = ADCBUF0 + ADCBUF1;
//ADCResult = ADCResult>>1; //取两次采样值的平均值
//ADCResult = (ADCResult*5000)>>12; //将无量纲的采样值转换为有量纲的电压值并放大1000倍
//防止在运算过程中,小数部分被舍去。
ADCResultTemp = ADCBUF0;
ADCResultTemp = (ADCResultTemp*5000)>>12;
ADCResult = ADCResultTemp;
for(i=3; i>=0; i--)
{
ADCData[i] = ADCResult%10;
ADCResult = ADCResult/10;
} //将四位电压值分离存储于四个数组单元中,方便在数码管上显示
}
void DisplayOnLED()
{
int i,j,k;
PORTGbits.RG9 = 0;
for(i=0; i<4; i++) //在前四个数码管上显示电压值
{
if(i == 0)
SPI1BUF = Table1[ADCData[i]];
else
SPI1BUF = Table0[ADCData[i]];
while(SPI1STATbits.SPITBF == 1);
}
for(j=0; j<4; j++) //熄灭后四个数码管
{
SPI1BUF = 0xff;
while(SPI1STATbits.SPITBF == 1);
}
SPI1BUF = 0xff;
while(SPI1STATbits.SPITBF == 1);
PORTGbits.RG9 = 1;
}
void __attribute__((__interrupt__))_T3Interrupt(void)
{
TMR3 = 0;
IFS0bits.T3IF = 0; //清定时器中断标志
}
void __attribute__((__interrupt__))_ADCInterrupt(void)
{
FormatADCResult();
DisplayOnLED();
IFS0bits.ADIF=0; //清AD转换中断标志位
}
int main()
{
InitializeSys();
InitializeTMR3();
InitializeADC();
InitializeSPIOut();
DisplayOnLED();
while(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -