单片机/MCUwilliam hill官网
直播中

figureout

9年用户 3经验值
擅长:控制/MCU
私信 关注
[问答]

通过按键读取电压值并用数码管显示电压值,显示是上一次的按键值

本帖最后由 figureout 于 2015-8-6 14:12 编辑

(第一次在这里发帖,不知道有没有选对地方。)

通过zlg读取按键输入电压值,经过da转换(tlc5615), 之后再经过ad转换(tlc2543),然后把电压值(0~5V)显示在数码管(zlg7289)上。单片机是Atmega64
现在的问题是:万用表测5615处的电压是正确的,而数码管显示的是上一次按键输入的电压值,不知道为什么。
麻烦大家帮我看下>3< 先谢过了!!

这是代码:
/*
* GccApplication2.c
*
* Created: 2015-7-30 14:52:02
*  Author: Administrator
*/

#include
#include

// ****************************************************************
/*位操作宏定义*/
#define SETB(bit) (1 << (bit))
#define    CLRB(bit) ~(1 << (bit))
//****LCD******记得修改端口配置函数
#define    ZLG7289_CS_H    PORTE|=SETB(PIN7) //高电平置1
#define    ZLG7289_CS_L    PORTE&=CLRB(PIN7) //低电平置0

#define    ZLG7289_SCK_H    PORTE|=SETB(PIN6)
#define    ZLG7289_SCK_L    PORTE&=CLRB(PIN6)

#define    ZLG7289_SDA_PIN    (PINE&SETB(PIN5))
#define    ZLG7289_SDA_IN    DDRE&=CLRB(DD5)
#define    ZLG7289_SDA_OUT    DDRE|=SETB(DD5)
#define    ZLG7289_SDA_H    PORTE|=SETB(PIN5)
#define    ZLG7289_SDA_L    PORTE&=CLRB(PIN5)

#define    ZLG7289_KEY_PIN    (PINE&SETB(PIN4))

#define ZLG_INIT_COMM    0xA4
#define ZLG_TEST_COMM    0xBF
#define ZLG_READ_KEY_COMM    0x15   

//*****************************************************
//**接着宏定义TLC5615端口的含义  ***
//使用工作方式一 -> 12位数据系列

#define    TLC5615_CS_H    PORTA|=SETB(PIN2)
#define    TLC5615_CS_L    PORTA&=CLRB(PIN2)

#define    TLC5615_SCK_H    PORTA|=SETB(PIN1)
#define    TLC5615_SCK_L    PORTA&=CLRB(PIN1)

//TLC5615 PORT1代表IN
#define    TLC5615_SDA_H    PORTA|=SETB(PIN0)
#define    TLC5615_SDA_L    PORTA&=CLRB(PIN0)

//*****************************************************
//**接着宏定义TLC2543端口的含义  ***
#define    TLC2543_SCK_H    PORTB|=SETB(PIN4)
#define    TLC2543_SCK_L    PORTB&=CLRB(PIN4)

#define    TLC2543_SDA_IN_H    PORTB|=SETB(PIN5)
#define    TLC2543_SDA_IN_L    PORTB&=CLRB(PIN5)

#define    TLC2543_SDA_PIN    (PINB&SETB(PIN6))
#define    TLC2543_SDA_OUT_H    PORTB|=SETB(PIN6)
#define    TLC2543_SDA_OUT_L    PORTB&=CLRB(PIN6)

#define TLC2543_CS_H    PORTB|=SETB(PIN7)    //高电平置1
#define    TLC2543_CS_L    PORTB&=CLRB(PIN7)    //低电平置0

// ****************************************************************
void    initPort();
void    delayS(int x);

//*****************************************************
// *** 功能描述: zlg读取按键为电压值  ***
double Read_Key();

//*****************************************************
// *** 功能描述: 向TLC中一次写入12bit数据  ***
void    TLC5615_Write_12Bits(unsigned int dacDat);
//********************************************************
//***  功能描述: 将十进制电压值转换为对应二进制 ***
void TLC5615_DAC( double data);

//*****************************************************
// *** 功能描述: 向TLC2543中一次写入转换后的模拟电压值  ***
unsigned int Read_TLC2543();

//*****************************************************
//**功能描述:从ZLG7289接收一个字节  ***
unsigned char zlg7289ReceiveByte();
//*****************************************************
//**功能描述:发送一个字节到ZLG7289 ***
void zlg7289SendByte(unsigned char byteData);
// ****************************************************************

void main()
{
    initPort();
    // *配置引脚*
    DDRE  = 0xE0;
    PORTE = 0xFD;
   
    DDRA  = 0x0F;
    PORTA = 0x0F;
   
    DDRB = 0xB0;
    PORTB = 0xF0;
   
    double digital;
    double sum;   
    int adata = 0;
   
    while(1){   
         digital = Read_Key();  //读取按键值(4位)
        
        TLC5615_DAC(digital);//进行DA(5615)转换                                                                  
        sum = (Read_TLC2543()*5.0)/4095.0;
        adata = sum*1000;
        //zlg7289显示
        zlg7289SendByte(0x80);
             zlg7289SendByte(adata%10);
             ZLG7289_CS_H;   
            
             zlg7289SendByte(0x81);
             zlg7289SendByte(adata%1000%100/10);
             ZLG7289_CS_H;
            
             zlg7289SendByte(0x82);
             zlg7289SendByte((adata%1000)/100);
             ZLG7289_CS_H;   
            
              //0x80最高位小数点显示
             zlg7289SendByte(0x83);
             zlg7289SendByte(0x80+(adata/1000));
             ZLG7289_CS_H;   
             PORTG ^= (1<<4);
              delayS(1);
    }
}
        
//*****************************************************
// *** 功能描述: zlg读取按键为电压值  ***
double Read_Key()
{
    double data = 0.0;
    int j;
    unsigned char num_key[4]; //按键按四下,精度为小数点后三位
   
   
    // *复位*
//     zlg7289SendByte(ZLG_INIT_COMM);
//     ZLG7289_CS_H;
    for(j=0;j<4;j++)
    {
        while(ZLG7289_KEY_PIN){;}//触发按键处理
            
        // *如果有按键,来个指示灯取反*
        PORTG ^= (1<<0);

        // *读取按键*
        zlg7289SendByte(ZLG_READ_KEY_COMM);
        num_key[j] = zlg7289ReceiveByte();
        ZLG7289_CS_H;
            
        //*第七位显示键盘输入值*
        zlg7289SendByte(0x87);
        zlg7289SendByte(num_key[j]);
        ZLG7289_CS_H;
        _delay_us(10);
        
        //*第六位显示键盘输入次数*
        zlg7289SendByte(0x86);
        zlg7289SendByte(j+1);
        ZLG7289_CS_H;
        _delay_us(10);
        
        while(!ZLG7289_KEY_PIN){;}

    }        
    data = num_key[0]+num_key[1]*0.1+num_key[2]*0.01+num_key[3]*0.001;   
    return data;
}   

//*****************************************************
// *** 功能描述: 向TLC2543中一次写入转换后的模拟电压值  ***
unsigned int Read_TLC2543()
{
    unsigned int angDat = 0; //用来存放采集的数据
    unsigned char i;
    unsigned int port;
    port = 0x10; //12位数据 以二进制形式高位先送出
    TLC2543_CS_H;
    TLC2543_SCK_L;
    _delay_us(10);
    TLC2543_CS_L;  //CS下降沿 使能
    for(i = 0; i < 12; i++)
    {
        PORTG ^= (1<<0);
        angDat <<= 1;
        
        if(TLC2543_SDA_PIN){
            angDat++;
        }
        if(port&0x80){
            TLC2543_SDA_IN_H;
        }
        else{
            TLC2543_SDA_IN_L;
        }
        
        TLC2543_SCK_H;
        _delay_us(10);
        TLC2543_SCK_L;
        _delay_us(10);
        port <<= 1;
    }
    TLC2543_CS_H;
//    angDat = angDat & 0x0fff;
    return angDat;
   
}

//*****************************************************
// *** 功能描述: 向TLC5615中一次写入12bits数据;  ***
void TLC5615_Write_12Bits(unsigned int dacDat)
{
    int i;
   
    dacDat <<= 4;
    TLC5615_SCK_L; //CLK置为低电平,为写bit做准备
    TLC5615_CS_L;
    _delay_us(50);
    //**循环发送12位**
    for(i=0;i<12;i++)
    {
        if(dacDat&0x8000){
            TLC5615_SDA_H;
        }else{
            TLC5615_SDA_L;
        }
        TLC5615_SCK_H;
        _delay_us(10);
        dacDat<<=1;
        TLC5615_SCK_L;
        _delay_us(10);
        
    }
    TLC5615_CS_H;
    TLC5615_SCK_L;
}

// ********************************************************
// *** 功能描述: 将十进制电压值转换为对应二进制 ***
void TLC5615_DAC( double data)
{
     unsigned int dacDat;
     dacDat = (0x0FFF*data)/(5);
     TLC5615_Write_12Bits(dacDat);
}

//*****************************************************
//**功能描述:从ZLG7289接收一个字节  ***
unsigned char zlg7289ReceiveByte()
{
    unsigned char i,val=0;

    ZLG7289_SDA_IN;
//    ZLG7289_SDA_H;
   
    _delay_us(50);

    for(i=0;i<8;i++){
        ZLG7289_SCK_H;
        _delay_us(10);

        val<<=1;
        if(ZLG7289_SDA_PIN){
            val++;
        }
        ZLG7289_SCK_L;
        _delay_us(10);
    }
   
    // **空闲为output**
    ZLG7289_SDA_OUT;

    return(val);
}
//*****************************************************
//**功能描述:发送一个字节到ZLG7289 ***
void zlg7289SendByte(unsigned char byteData)
{
    unsigned char i;
   
    ZLG7289_SCK_L;
    ZLG7289_CS_L;
    _delay_us(50);

    //**循环发送八位**
     for(i=0;i<8;i++){
        if(byteData&0x80){
             ZLG7289_SDA_H;
        }else{
            ZLG7289_SDA_L;
        }
        ZLG7289_SCK_H;
        _delay_us(10);
        byteData<<=1;
        ZLG7289_SCK_L;
        _delay_us(10);
    }
   
    return;
}
// ****************************************************************
void    delayS(int x)
{
    int    i,j;
   
    for(j=0;j         // *100ms循环10次*
        for(i=0;i<10;i++){
            _delay_ms(33);
            _delay_ms(33);
            _delay_ms(34);
        }
    }
}
// ****************************************************************
void    initPort()
{
    DDRA  = 0x00;
    PORTA = 0xFF;

    DDRB  = 0x00;
    PORTB = 0xFF;

    DDRC  = 0x00;
    PORTC = 0xFF;

    DDRD  = 0x00;
    PORTD = 0xFF;

    DDRE  = 0x00;
    PORTE = 0xFF;

    DDRF  = 0x00;
    PORTF = 0xFF;
   
    DDRG  = 0x1F;
    PORTG = 0x1F;

    return ;
}
// ****************************************************************

更多回帖

发帖
×
20
完善资料,
赚取积分