本帖最后由 figureout 于 2015-8-6 14:12 编辑
(第一次在这里发帖,不知道有没有选对地方。)
通过zlg读取按键输入电压值,经过da转换(tlc5615), 之后再经过ad转换(tlc2543),然后把电压值(0~5V)显示在数码管(zlg7289)上。
单片机是Atmega64
现在的问题是:万用表测5615处的电压是正确的,而数码管显示的是上一次按键输入的电压值,不知道为什么。
麻烦大家帮我看下>3< 先谢过了!!
这是代码:
/*
* GccApplica
tion2.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 ;
}
// ****************************************************************