用TAmega128和TLC2543测电压 请大家帮忙看看哪里问题
#include<macros.h>
#define uchar unsigned char
#define uint unsigned int
/*********************
管脚定义
*********************/
#define CS PG2 /***片选信号rs***/
#define SID PG3 /***数据信号rw***/
#define SCLK PG4 /***时钟信号en***/
#define LCD_PSB PG1 // 串/并方式控制
#define TLC2543_CLK_H PORTD|=BIT(4) //2543时钟输入端
#define TLC2543_CLK_L PORTD&=~(BIT(4))
#define TLC2543_ADIN_H PORTD|= BIT(6) //2543数据输入端
#define TLC2543_ADIN_L PORTD&=~(BIT(6))
#define TLC2543_DOUT (PIND&0x10) //2543数据输出端
#define TLC2543_CS_H PORTD|= BIT(5) //2543片选端
#define TLC2543_CS_L PORTD&=~(BIT(5))
/*********************
延时函数
*********************/
void delay_ms(uint ms)
{
uint i,j;
for(i=ms;i>0;i--)
for(j=1141;j>0;j--);
}
/************************************************************
TLC2543数据转换函数
D7~D4为通道选择,D3、D2为数据长度
************************************************************/
uint Read_TLC2543(uchar port) //uchar为8位
{
uint i; //定义循环变量
uint ad_value=0; //AD转换的值
TLC2543_CLK_L; //开始时时钟输入端为低
TLC2543_CS_L; //片选信号为低
port<<=4; //左移四位,以便用一位十进制数表示所选的模拟通道
for(i=0;i<12;i++ ) //循环十二次,输出十二位数据
{
if(TLC2543_DOUT) //如果输出端为高
ad_value |=0x01; //则ad_val赋1,否则赋0
if(port&0x80) //将地址按位发送出去
TLC2543_ADIN_H;
else
TLC2543_ADIN_L;
TLC2543_CLK_H; //时钟拉高,上升沿送入数据
delay_ms(3);
TLC2543_CLK_L; //拉低,为下次上升沿送数据做准备
delay_ms(3);
port=port<<1; //左移一位
ad_value=ad_value<<1; //左移一位,逐渐移到高位
}
TLC2543_CS_H;
ad_value=ad_value>>1; //出去一位就要进来一位
return ad_value;
}
///******12864液晶程序******///
//////以串行协议发送数据///////
void send_bit(uchar byte)
{
uchar x;
for(x=0;x<8;x++) //八位数据,一位一位发送//
{
if((byte<<x)&0x80) //如果最高位为1,则发送1//
{
PORTG|=(1<<SID);
}
else
{
PORTG&=~(1<<SID); //如果最高位为0,则发送0//
}
PORTG&=~(1<<SCLK);
PORTG|=(1<<SCLK); //每发送一位,SCLK跳变一次,上升沿有效//
}
delay_ms(5);
}
//////写串口命令函数////////
void write_com(uchar com)
{
PORTG|=(1<<CS); //每次传数据前把CS端拉高//
send_bit(0xf8); //串行发送命令前必发0xf8识别命令//
send_bit(com&0xf0); //0xf0为1111 0000,送高四位
send_bit((com<<4)&0xf0); //0xf0为1111 0000,送低四位
delay_ms(5);
PORTG&=~(1<<CS);
}
//////写串口数据函数////////
void write_dat(uchar date)
{
PORTG|=(1<<CS); //每次传数据前把CS端拉高//
send_bit(0xfa); //串行发送数据前必发0xfa识别数据//
send_bit(date&0xf0); //0xf0为1111 0000,送高四位//
send_bit((date<<4)&0xf0); //0xf0为1111 0000,送低四位//
delay_ms(10);
PORTG&=~(1<<CS);
}
////设定在液晶上显示的位置/////
void Lcd_pos(uchar X,uchar Y)
{
uchar pos;
if(X==0)
{X=0x80;} //第一行
else if(X==1)
{X=0x90;}
else if(X==2)
{X=0x88;}
else if(X==3)
{X=0x98;}
pos=X+Y;
write_com(pos); //显示地址
}
//////////显示字符串和汉字///////////
void Lcd_str(uchar X,uchar Y,uchar *str)
{
Lcd_pos(X,Y);
while(*str!='\0')
{
write_dat(*str);
str++;
}
}
/***********************************************
函数名:void init()
功能: 液晶初始化函数
参数: 无
返回值:无
************************************************/
void init(void)
{
DDRG=0xff; //设置PG口为输出
PORTG&=~(1<<LCD_PSB); //选择串口方式0
delay_ms(5);
write_com(0x30); //基本指令操作
delay_ms(5);
write_com(0x06); //地址归位
delay_ms(5);
write_com(0x0c); //开显示,关光标
delay_ms(5);
write_com(0x01); //清除液晶显示内容
delay_ms(5);
}
/***********************主函数***************************************/
void main(void)
{
uint ge,x1,x2,x3,x4;
uint ad_val,ad;
init();
Lcd_str(1,1,"电压:");
DDRD=0XD0; //定义为输出
ad = Read_TLC2543(0x01); //通道1
ad_val = (uint)(((ad*5.0)/4096.0)*10000);
//数据处理
while(1)
{
delay_ms(10);
ge = ad_val/10000;
x1 = ad_val%10000/1000;
x2 = ad_val%1000/100;
x3 = ad_val%100/10;
x4 = ad_val%10;
//液晶显示数据
write_com(0x94);
write_dat(0x30+ge);
write_dat(0x2e);
write_dat(0x30+x1);
write_dat(0x30+x2);
write_dat(0x30+x3);
write_dat(0x30+x4);
ad_val = (uint)(((Read_TLC2543(0x01)*5.0)/4096.0)*10000);//不断扫描
}
}
我是用MSP430f5438改的 没有电压显示 显示为0.0000 也不懂哪出了问题 ATmega128我也是刚学不久,请各位大神帮帮忙 拜托拜托!
已经解决 下面是完整的程序
#include<iom128v.h>
#include<macros.h>
#define uchar unsigned char
#define uint unsigned int
/*********************
管脚定义
*********************/
#define CS PG2 /***片选信号rs***/
#define SID PG3 /***数据信号rw***/
#define SCLK PG4 /***时钟信号en***/
#define LCD_PSB PG1 // 串/并方式控制
#define TLC2543_CLK_H PORTD|=BIT(4) //2543时钟输入端
#define TLC2543_CLK_L PORTD&=~(BIT(4))
#define TLC2543_ADIN_H PORTD|= BIT(6) //2543数据输入端
#define TLC2543_ADIN_L PORTD&=~(BIT(6))
#define TLC2543_DOUT (PIND&0x10) //2543数据输出端
#define TLC2543_CS_H PORTD|= BIT(5) //2543片选端
#define TLC2543_CS_L PORTD&=~(BIT(5))
/*********************
延时函数
*********************/
void delay_ms(uint ms)
{
uint i,j;
for(i=ms;i>0;i--)
for(j=1141;j>0;j--);
}
/************************************************************
TLC2543数据转换函数
D7~D4为通道选择,D3、D2为数据长度
************************************************************/
uint Read_TLC2543(uchar port) //uchar为8位
{
uint i; //定义循环变量
uint ad_value=0; //AD转换的值
TLC2543_CLK_L; //开始时时钟输入端为低
TLC2543_CS_L; //片选信号为低
port<<=4; //左移四位,以便用一位十进制数表示所选的模拟通道
for(i=0;i<12;i++ ) //循环十二次,输出十二位数据
{
if(TLC2543_DOUT) //如果输出端为高
ad_value |=0x01; //则ad_val赋1,否则赋0
if(port&0x80) //将地址按位发送出去
TLC2543_ADIN_H;
else
TLC2543_ADIN_L;
TLC2543_CLK_H; //时钟拉高,上升沿送入数据
delay_ms(3);
TLC2543_CLK_L; //拉低,为下次上升沿送数据做准备
delay_ms(3);
port=port<<1; //左移一位
ad_value=ad_value<<1; //左移一位,逐渐移到高位
}
TLC2543_CS_H;
ad_value=ad_value>>1; //出去一位就要进来一位
return ad_value;
}
///******12864液晶程序******///
//////以串行协议发送数据///////
void send_bit(uchar byte)
{
uchar x;
for(x=0;x<8;x++) //八位数据,一位一位发送//
{
if((byte<<x)&0x80) //如果最高位为1,则发送1//
{
PORTG|=(1<<SID);
}
else
{
PORTG&=~(1<<SID); //如果最高位为0,则发送0//
}
PORTG&=~(1<<SCLK);
PORTG|=(1<<SCLK); //每发送一位,SCLK跳变一次,上升沿有效//
}
delay_ms(5);
}
//////写串口命令函数////////
void write_com(uchar com)
{
PORTG|=(1<<CS); //每次传数据前把CS端拉高//
send_bit(0xf8); //串行发送命令前必发0xf8识别命令//
send_bit(com&0xf0); //0xf0为1111 0000,送高四位
send_bit((com<<4)&0xf0); //0xf0为1111 0000,送低四位
delay_ms(5);
PORTG&=~(1<<CS);
}
//////写串口数据函数////////
void write_dat(uchar date)
{
PORTG|=(1<<CS); //每次传数据前把CS端拉高//
send_bit(0xfa); //串行发送数据前必发0xfa识别数据//
send_bit(date&0xf0); //0xf0为1111 0000,送高四位//
send_bit((date<<4)&0xf0); //0xf0为1111 0000,送低四位//
delay_ms(10);
PORTG&=~(1<<CS);
}
////设定在液晶上显示的位置/////
void Lcd_pos(uchar X,uchar Y)
{
uchar pos;
if(X==0)
{X=0x80;} //第一行
else if(X==1)
{X=0x90;}
else if(X==2)
{X=0x88;}
else if(X==3)
{X=0x98;}
pos=X+Y;
write_com(pos); //显示地址
}
//////////显示字符串和汉字///////////
void Lcd_str(uchar X,uchar Y,uchar *str)
{
Lcd_pos(X,Y);
while(*str!='\0')
{
write_dat(*str);
str++;
}
}
/***********************************************
函数名:void init()
功能: 液晶初始化函数
参数: 无
返回值:无
************************************************/
void init(void)
{
DDRG=0xff; //设置PG口为输出
PORTG&=~(1<<LCD_PSB); //选择串口方式0
delay_ms(5);
write_com(0x30); //基本指令操作
delay_ms(5);
write_com(0x06); //地址归位
delay_ms(5);
write_com(0x0c); //开显示,关光标
delay_ms(5);
write_com(0x01); //清除液晶显示内容
delay_ms(5);
}
/***********************主函数***************************************/
void main(void)
{
uint ge,x1,x2,x3,x4;
uint ad_val,ad;
init();
Lcd_str(1,1,"电压:");
DDRD=0X70; //定义为输出
ad = Read_TLC2543(0x01); //通道1
ad_val = (uint)(((ad*5.0)/4096.0)*10000);
//数据处理
while(1)
{
delay_ms(10);
ge = ad_val/10000;
x1 = ad_val%10000/1000;
x2 = ad_val%1000/100;
x3 = ad_val%100/10;
x4 = ad_val%10;
//液晶显示数据
write_com(0x94);
write_dat(0x30+ge);
write_dat(0x2e);
write_dat(0x30+x1);
write_dat(0x30+x2);
write_dat(0x30+x3);
write_dat(0x30+x4);
ad_val = (uint)(((Read_TLC2543(0x01)*5.0)/4096.0)*10000);//不断扫描
}
}