⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 digitalvoltmeter.c

📁 《dsPIC通用数字信号控制器原理及应用》源码
💻 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 + -