微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 新手求助,c8051f340的多通道adc输出问题

新手求助,c8051f340的多通道adc输出问题

时间:10-02 整理:3721RD 点击:
全程序已贴出,在void ADC0ISR (void) interrupt 10(倒数第二个片段)里输出的result数组两个值是一样的,不知应该怎么改?求教。Thanks?(?ω?)?

#include "main.h"
#include "lcd.h"

#define        BAUDRATE 115200
#define SYSCLK 22118400UL        //采用外部晶振时,系统的时钟频率为22118400hz
#define INPUTS 2

bit uartPrintFlag=0;
uint32 voltageData=0;
uint32 currentData=0;
uchar vol[5];
uchar cur[5];
uchar idata PIN_MUX_TABLE[INPUTS] = {4,5};
uint8 input=0;
uint32 result[INPUTS];
void InitUart0(void)
{
        if (SYSCLK/BAUDRATE/2/256 < 1) {
                TH1 = -(SYSCLK/BAUDRATE/2);
                CKCON &= ~0x0B;                  // T1M = 1; SCA1:0 = xx
                CKCON |=  0x08;
        } else if (SYSCLK/BAUDRATE/2/256 < 4) {
                TH1 = -(SYSCLK/BAUDRATE/2/4);
                CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 01
                CKCON |=  0x01;
        } else if (SYSCLK/BAUDRATE/2/256 < 12) {
                TH1 = -(SYSCLK/BAUDRATE/2/12);
                CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 00
        } else {
                TH1 = -(SYSCLK/BAUDRATE/2/48);
                CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 10
                CKCON |=  0x02;
        }

        /*初始化定时器1*/
        TMOD|=0x20;                        //定时器1工作在8位自动重装方式
        TL1=0;
        TR1=1;
       
        /*初始化串口*/
        S0MODE=0;                        //8位的UART工作方式
        REN0=1;                                //接收允许
        PS0=1;                                //为了在中断里输出串口打印,串口的优先级设为最高
        ES0=1;                                //打开串口中断

        /*配置引脚*/
        P0MDOUT |= 0x10;        //串口TXD引脚配置为推挽输出方式,用于UART发送端
        XBR0|=0x01;                        //在外设连接寄存器0上把UART0连接到引脚P0.4和P0.5
}

/********************************************************************
函数功能:将外部晶振配置为系统时钟。
入口参数:无。
返    回:无。
备    注:无。
********************************************************************/
void InitOSC(void)
{
        P0MDIN &= ~0xC0;                //P0.6, P0.7配置为模拟输入,用作外部晶振
        P0SKIP |=  0xC0;                //交叉开关跳过P0.6, P0.7脚,用作外部晶振

        OSCXCN = (0x60 | 7);        //配置为外部晶体不分频,配置晶体频率为10M~30M
        delay(1024);            //等待外部晶振开始工作,不可省略一定要做的步骤
        while (!(OSCXCN & 0x80));        //一直读取标志位,直到外部晶体稳定
        RSTSRC = 0x06;                        // Enable missing clock detector and VDD Monitor reset

        CLKSEL = 0x01;                        //选择外部晶体为时钟
        OSCICN = 0x00;                        //关闭内部晶振
}
/********************************************************************
函数功能:初始化定时器3,每5ms产生一个中断。
入口参数:无。
返    回:无。
备    注:无。
********************************************************************/
void InitTimer3(void)
{
        /*22.1184M/12分频/200=9216,即5ms*/
        TMR3RLL=(65536-9216)%256;        //计数到0xFFFF再计一次发生溢出。(0xFFFF=65535)
        TMR3RLH=(65536-9216)/256;
        TMR3L=(65536-9216)%256;
        TMR3H=(65536-9216)/256;
        EIE1|=0x80;                        //允许T3中断
        TMR3CN|=0x04;                //启动定时器3,默认为16位自动重装方式,sysclk/12分频
}
/********************************************************************
函数功能:初始化初始化ADC0。
入口参数:无。
返    回:无。
备    注:无。
********************************************************************/
void InitADC0(void)
{
        P2MDIN&=~0x60;                                                //P2.5、P2.6配置为模拟输入,用作AD转换输入
        P2SKIP|=0x60;                                                //跳过P2.5、P2.6脚,用作AD转换输入
        ADC0CN = 0x05;                      // 关闭ADC0, 设置正常跟踪方式, 由定时器3触发
        REF0CN = 0x08;                      // 选择使用VCC作为电压基准
        AMX0P = PIN_MUX_TABLE[0];           // ADC0正极输入选择
           AMX0N = 0x1F;                       // ADC0负极输入选择为GND,即工作在单端模式
        ADC0CF=((SYSCLK/3000000)-1)<<3;                // SAR clock是供给ADC转换器的时钟,根据数据手册,SAR clock最快为3MHz
        ADC0CF |= 0x00;                     // 转换结果右对齐
        EIE1 |= 0x08;                       // 使能ADC0转换完成中断
        AD0EN = 1;                          // 开启ADC0
}

char *itoa(int num, char *str, int radix)             //itoa
{
    char  string[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    char* ptr = str;
    int i;
    int j;

    while (num)
    {
        *ptr++  = string[num % radix];
        num    /= radix;

        if (num < radix)
        {
            *ptr++  = string[num];
            *ptr    = '\0';
            break;
        }
    }

    j = ptr - str - 1;

    for (i = 0; i < (ptr - str) / 2; i++)
    {
        int temp = str;
        str   = str[j];
        str[j--] = temp;
    }

    return str;
}
/********************************************************************
函数功能:主函数。
入口参数:无。
返    回:无。
备    注:无。
********************************************************************/
void main (void)
{
        PCA0MD &= ~0x40;        //WDTE = 0 关闭看门狗,上电默认打开
        XBR1= 0x60;                        //打开交叉开关,使能弱上拉,要使GPIO生效,必须打开交叉开关
        P2MDOUT=0x0D;                //P2.2,P2.3配置为推挽方式,LED2,LED3
        P1MDOUT=0xE0;                //1.5,1.6,1.7,配置为推挽方式,NUM_SER,NUM_SCK,NUM_RCK
        P3MDOUT=0x1F;
        InitOSC();                        //初始化晶振
        InitTimer3();                //初始化定时器3
        InitADC0();                        //初始化ADC0
        InitUart0();                //初始化串口

        EA=1;                                //允许所有中断
        LED2=0;
        LED3=0;

        NUM_SCK=0;                        //上升沿数据移位,下降沿不变
        NUM_RCK=0;                        //上升沿移位寄存器数据进入数据存储器,下降沿不变
       
        while(1){
                initial_lcd();   
                clear_screen();
                if(uartPrintFlag){
                        uartPrintFlag=0;
                        itoa(voltageData,vol,10);
                        itoa(currentData,cur,10);
                        display_graphic_16x16(1,1,dian1);
                        display_graphic_16x16(1,1+16,ya1);
                        display_graphic_8x16(1,1+16*2,maohao);
                        display_string_8x16(1,41,vol);
                        display_string_8x16(1,1+16*5,"mV.");
                        display_graphic_16x16(3,1,dian1);
                        display_graphic_16x16(3,1+16,liu1);
                        display_graphic_8x16(3,1+16*2,maohao);
                        display_string_8x16(3,41,cur);
                        display_string_8x16(3,1+16*5,"mA.");
//                        Prints("Voltage = ");
//                        PrintLongDecimal(voltageData);
//                        Prints(" mV.\r\n");
                        delay(1000);
                }
        }
}



/********************************************************************
函数功能:ADC0的中断服务程序。
入口参数:无。
返    回:无。
备    注:注意手动清除标志位。
********************************************************************/
void ADC0ISR (void) interrupt 10
{
        static uint32 accumulator[INPUTS]=0;         //AD转换结果累加和
//        static unsigned int measurement=0;        //AD转换次数计数
        uint8 i=0;
        for(i=0;i<INPUTS;i++)
        {
                AD0INT=0;
                AMX0P=PIN_MUX_TABLE;
                delay(50);
                accumulator +=ADC0;
                result=accumulator;
                accumulator=0;       
        }
        voltageData =  result[0] * 3300/1023;                  //计算出以mV为单位的转换结果,写入numData
        currentData = (result[1] * 3300/1023-2410)*5;//计算出以mA为单位的转换结果,写入numData
        uartPrintFlag=1;                //设置更新数码管显示标志位
}
/********************************************************************
函数功能:定时器3的中断服务程序。
入口参数:无。
返    回:无。
备    注:注意手动清除标志位。
********************************************************************/
void Timer3_ISR (void) interrupt 14
{
        static unsigned int count=0;
        TMR3CN&=(~0x80);        //手动清除标志位
        count++;
        if(count==100){                //5ms一次中断,接收到100次*2中断即为1秒
                count=0;
                LED2=!LED2;}                //每1秒闪烁一次LED
}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top