一路差分输入用数码管显示拦樱卖 p0段p1位没简逗用锁存器。不一样话显示部分可自己编译 ,其他无需改动
#include <reg52.h>
#include <intrins.h>
#define AddWr 0x90 //写数据地址
#define AddRd 0x91 //读数据地址
#define _Nop() _nop_() //定义空指令
bit ack //应答标志位
#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换
#define CtrlPort P1
sbit SDA=P2^5
sbit SCL=P2^4
unsigned char code DuanMa[10]={0xc0,0xf9,0xa4,0xb0, 0x99,0x92,0x82,0xf8,0x80,0x90}// 显示段码值0~9
unsigned char code WeiMa[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}//分别对应相应的数码管点亮,即位码
unsigned char TempData[8]//存储显示值的全局变量
extern bit ack
unsigned char ReadADC(unsigned char Chl)
bit WriteDAC(unsigned char dat)
/*------------------------------------------------
主程序
------------------------------------------------*/颂核
void DelayUs2x(unsigned char t)
{
while(--t)
}
/*------------------------------------------------
mS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t)
{
while(t--)
{
//大致延时1mS
DelayUs2x(245)
DelayUs2x(245)
}
}
void Display(unsigned char FirstBit,unsigned char Num)
{
static unsigned char i=0
DataPort=0 //清空数据,防止有交替重影
CtrlPort=WeiMa[i+FirstBit]//取位码
DataPort=TempData[i]//取显示数据,段码
i++
if(i==Num)
i=0
}
/*------------------------------------------------
定时器初始化子程序
------------------------------------------------*/
void Init_Timer0(void)
{
TMOD |= 0x01 //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
//TH0=0x00 //给定初值
//TL0=0x00
EA=1 //总中断打开
ET0=1 //定时器中断打开
TR0=1 //定时器开关打开
}
/*------------------------------------------------
定时器中断子程序
------------------------------------------------*/
void Timer0_isr(void) interrupt 1
{
TH0=(65536-2000)/256 //重新赋值 2ms
TL0=(65536-2000)%256
Display(0,3)
}
void Start_I2c()
{
SDA=1 //发送起始条件的数据信号
_Nop()
SCL=1
_Nop() //起始条件建立时间大于4.7us,延时
_Nop()
_Nop()
_Nop()
_Nop()
SDA=0//发送起始信号
_Nop() //起始条件锁定时间大于4μ
_Nop()
_Nop()
_Nop()
_Nop()
SCL=0 //钳住I2C总线,准备发送或接收数据
_Nop()
_Nop()
}
/*------------------------------------------------
结束总线
------------------------------------------------*/
void Stop_I2c()
{
SDA=0 //发送结束条件的数据信号
_Nop() //发送结束条件的时钟信号
SCL=1 //结束条件建立时间大于4μ
_Nop()
_Nop()
_Nop()
_Nop()
_Nop()
SDA=1 //发送I2C总线结束信号
_Nop()
_Nop()
_Nop()
_Nop()
}
/*----------------------------------------------------------------
字节数据传送函数
函数原型: void SendByte(unsigned char c)
功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
此状态位进行 *** 作.(不应答或非应答都使ack=0 假)
发送数据正常,ack=1ack=0表示被控器无应答或损坏。
------------------------------------------------------------------*/
void SendByte(unsigned char c)
{
unsigned char BitCnt
for(BitCnt=0BitCnt<8BitCnt++) //要传送的数据长度为8位
{
if((c<<BitCnt)&0x80)SDA=1 //判断发送位
else SDA=0
_Nop()
SCL=1 //置时钟线为高,通知被控器开始接收数据位
_Nop()
_Nop()//保证时钟高电平周期大于4μ
_Nop()
_Nop()
_Nop()
SCL=0
}
_Nop()
_Nop()
SDA=1 //8位发送完后释放数据线,准备接收应答位
_Nop()
_Nop()
SCL=1
_Nop()
_Nop()
_Nop()
if(SDA==1)ack=0
else ack=1 //判断是否接收到应答信号
SCL=0
_Nop()
_Nop()
}
/*----------------------------------------------------------------
字节数据传送函数
函数原型: unsigned char RcvByte()
功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),
发完后请用应答函数。
------------------------------------------------------------------*/
unsigned char RcvByte()
{
unsigned char retc
unsigned char BitCnt
retc=0
SDA=1//置数据线为输入方式
for(BitCnt=0BitCnt<8BitCnt++)
{
_Nop()
SCL=0 //置时钟线为低,准备接收数据位
_Nop()
_Nop() //时钟低电平周期大于4.7us
_Nop()
_Nop()
_Nop()
SCL=1 //置时钟线为高使数据线上数据有效
_Nop()
_Nop()
retc=retc<<1
if(SDA==1)retc=retc+1//读数据位,接收的数据位放入retc中
_Nop()
_Nop()
}
SCL=0
_Nop()
_Nop()
return(retc)
}
/*----------------------------------------------------------------
应答子函数
原型: void Ack_I2c(void)
----------------------------------------------------------------*/
/*void Ack_I2c(void)
{
SDA=0
_Nop()
_Nop()
_Nop()
SCL=1
_Nop()
_Nop() //时钟低电平周期大于4μ
_Nop()
_Nop()
_Nop()
SCL=0 //清时钟线,钳住I2C总线以便继续接收
_Nop()
_Nop()
}*/
/*----------------------------------------------------------------
非应答子函数
原型: void NoAck_I2c(void)
----------------------------------------------------------------*/
void NoAck_I2c(void)
{
SDA=1
_Nop()
_Nop()
_Nop()
SCL=1
_Nop()
_Nop() //时钟低电平周期大于4μ
_Nop()
_Nop()
_Nop()
SCL=0 //清时钟线,钳住I2C总线以便继续接收
_Nop()
_Nop()
}
main()
{
unsigned char num=0
Init_Timer0()
while (1) //主循环
{
num=ReadADC(0)
TempData[2]=DuanMa[num/100]
TempData[1]=DuanMa[(num%100)/10]
TempData[0]=DuanMa[(num%100)%10]
//主循环中添加其他需要一直工作的程序
DelayMs(100)
}
}
/*------------------------------------------------
读AD转值程序
输入参数 Chl 表示需要转换的通道,范围从0-3
返回值范围0-255
------------------------------------------------*/
unsigned char ReadADC(unsigned char Chl)
{
unsigned char Val
Start_I2c() //启动总线
SendByte(AddWr)//发送器件地址
if(ack==0)return(0)
SendByte(0x62|Chl) //发送器件子地址 0x62控制字节可自行更改,可参考资料的图五 部分更改《8591中文资料》
if(ack==0)return(0)
Start_I2c()
SendByte(AddWr+1)
if(ack==0)return(0)
Val=RcvByte()
NoAck_I2c()//发送非应位
Stop_I2c() //结束总线
return(Val)
}
#include<reg51.h>#include <intrins.h>
#include <absacc.h>
#include<历指stddef.h>
#define uchar unsigned char
#define uint unsigned int
#define LCD1602_PORT P0
uchar code ledtab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff} //显示段码共阳
uchar keyval=0,time=0,mode
uchar disdat[16],num=0
uint adchg=0
uchar adval[4]
uchar code alarml[4]={10,20,30,40}
uchar code alarmh[4]={200,200,200,200}
uchar code disp[]="Four channels DC"
sbit lcd1602_rs=P2^0
sbit lcd1602_rw=P2^1
sbit lcd1602_e=P2^2
sbit lcd1602_busy=P0^7
sbit SDA=P1^7
sbit SCL=P1^6
sbit sound=P1^5
sbit led1=P1^0
sbit led2=P1^1
sbit led3=P1^2
sbit led4=P1^3
sbit key=P3^2
//--------------------------------
void i2c_start( void )
void i2c_stop( void )
void i2c_ack( void )
void master_notAck()
void i2c_writeByte( unsigned char byte)
unsigned char i2c_readByte( void )
void PCF8591_wirteCommand( unsigned char addr, unsigned char command )
unsigned char i2c_readADResult( void )
void PCF8591_displayADResult( unsigned int ADResult)
void i2c_delay( void )
void delay_xms(unsigned int )
/********************************************************
** 函数名: void i2c_start( void ),i2c起余配始信号
**输入参数:无
**返回参数:无
********************************************************/
void i2c_start( void )
{
SCL = 1
SDA = 1
i2c_delay()
SDA = 0
i2c_delay()
SCL = 0
i2c_delay()
}
/********************************************************
** 函数名: void i2c_stop( void ),i2c停止信号
**输入参数:无
**返回参数:无
********************************************************/
void i2c_stop( void )
{
SDA = 0
i2c_delay()
SCL = 1
i2c_delay()
SDA = 1
i2c_delay()
}
/********************************************************
** 函数名: void i2c_ack( void ),i2c应答信号(从机)
**输入参数:无
**返回参数:无
********************************************************/
void i2c_ack( void )
{
int i = 0
SCL = 0
i2c_delay()
SDA = 1
i2c_delay()
SCL = 1
i2c_delay()
while(SDA == 1)
/*while((SDA == 1) && ((i++) < 10))
{
_nop_()
}*/
}
竖烂指
/********************************************************
** 函数名: void master_notAck( void ),主机非应答信号,在读取数据时
**输入参数:无
**返回参数:无
********************************************************/
void master_notAck( void )
{
SCL = 0
i2c_delay()
SDA = 1
i2c_delay()
SCL = 1
i2c_delay() // 没下面四句程序读取不正常
SCL = 0 //
i2c_delay() //
SDA = 0 //
}
/********************************************************
** 函数名: void i2c_writeByte,i2c写一个字节
**输入参数:unsigned char byte
**返回参数:无
********************************************************/
void i2c_writeByte( unsigned char byte )
{
char loop
for(loop = 0 loop < 8 loop++)
{
SCL = 0
i2c_delay()
if((byte<<loop)&0x80) //数据是从高位到低位传输
{
SDA = 1
}
else
{
SDA = 0
}
i2c_delay()
SCL = 1
i2c_delay()
}
}
unsigned char i2c_readByte( void )
{
int loop = 0
unsigned char temp = 0
unsigned char tempData = 0
//SDA = 0
for(loop = 7 loop >= 0 loop--)
{
SCL = 0
i2c_delay()
temp = SDA
i2c_delay()
SCL = 1
i2c_delay()
tempData += (temp<<loop)
temp = 0
}
return tempData
}
/********************************************************
** 函数名: void PCF8591_wirteCommand( unsigned char addr, unsigned char command ),PCF8591写控制指令
**输入参数:unsigned char addr, unsigned char command
**返回参数:无
********************************************************/
void PCF8591_wirteCommand( unsigned char addr, unsigned char command )
{
i2c_start()
i2c_writeByte(addr)
i2c_ack()
i2c_writeByte(command)
i2c_ack()
i2c_delay()
i2c_stop()
}
/********************************************************
** 函数名: unsigned char i2c_readADResult( void ),i2c读出一个字节
**输入参数:无
**返回参数:unsigned char
********************************************************/
unsigned char i2c_readADResult( void )
{
unsigned char temp = 0
i2c_start()
i2c_writeByte(0x91)
i2c_ack()
temp = i2c_readByte()
master_notAck()
i2c_stop()
return temp
}
/************************************************************************
**函数名:void i2c_delay( void ),i2c专用延时
** 功能:无
** 参数: 无
*************************************************************************/
void i2c_delay( void )
{
char loop
for(loop = 0 loop < 5 loop++)
{
_nop_()
}
}
/************************************************************************
**函数名:void delay_xms( unsigned int x )
** 功能:延时xms
** 参数: 无
*************************************************************************/
void delay_xms( unsigned int x )
{
unsigned char j = 0
while( x-- )
{
while( (j++) < 100 )
j = 0
}
}
/************************************
* 函数名称:lcd1602_CheckBusy()
* 函数功能:状态查询
************************************
*/
void lcd1602_CheckBusy()
{
do
{
lcd1602_busy=1
lcd1602_rs=0
lcd1602_rw=1
lcd1602_e=0
lcd1602_e=1
}
while(lcd1602_busy)
}
/*
***************************************
* 函数名称: lcd1602_WriteCmd()
* 函数功能:写命令
* 入口参数:命令字
* 出口参数:无
***************************************
*/
void lcd1602_WriteCmd(uchar cmd)
{
lcd1602_CheckBusy()
lcd1602_rs=0
lcd1602_rw=0
lcd1602_e=1
LCD1602_PORT=cmd
lcd1602_e=0
}
/*
*******************************************
* 函数名称:lcd1602_WriteData()
* 函数功能:写数据
* 入口参数:c--待写数据
* 出口参数:无
*********************************************
*/
void lcd1602_WriteData(uchar c)
{
lcd1602_CheckBusy()
lcd1602_rs=1
lcd1602_rw=0
lcd1602_e=1
LCD1602_PORT=c
lcd1602_e=0
}
/*
***********************************************
* 函数名称:lcd1602_Init()
* 函数功能:初始化LCD
* 入口参数:无
* 出口参数:无
***********************************************
*/
void lcd1602_Init()
{
lcd1602_WriteCmd(0x38) //显示模式为8位2行5*7点阵
lcd1602_WriteCmd(0x0f) //display enable,flag enable,flash enable,
lcd1602_WriteCmd(0x06) //flag move to right,screen don't move
lcd1602_WriteCmd(0x01) //clear screen
}
/*
************************************************
* 函数名称:lcd1602_Display()
* 函数功能: 字符显示
* 入口参数:ptr--字符或字符串指针
* 出口参数:无
* 说 明:用户可通过以下方式来调用:
* 1)lcd1602_Display("Hello,world!")
* 2) INT8U 存储类型 txt[]="要显示的字符串"
* 或者 INT8U 存储类型 txt[]={'t','x','t',..,'\0'}
* INT8U *ptr
* ptr=&txt
* lcd1602_Display(ptr)
* 或 lcd1602_Display(txt)
* 或 lcd1602_Display(&txt)
************************************************
*/
void lcd1602_Display(uchar *ptr,uchar ln)
{
uchar data i=0
uchar *data q
q=ptr
switch(ln)
{
case 0:
lcd1602_WriteCmd(0x80)
while(q!=NULL && (*q!='\0'))
{
lcd1602_WriteData(*q)
q++
i++
}
break
case 1:
lcd1602_WriteCmd(0xc0)
while(q!=NULL && (*q!='\0'))
{
lcd1602_WriteData(*q)
q++
i++
}
}
}
//--------------------------------
void dischg(uchar a)
{
uint x
disdat[0]='H'
disdat[1]=2*a+0x30
disdat[2]=' '
x=(int)(100.0*(float)adval[2*a]/51.0)
disdat[3]=(x/100)%10+0x30
disdat[4]='.'
disdat[5]=(x/10)%10+0x30
disdat[6]=x%10+0x30
disdat[7]=' '
disdat[8]=' '
disdat[9]='H'
disdat[10]=2*a+0x31
disdat[11]=' '
x=(int)(100.0*(float)adval[2*a+1]/51.0)
disdat[12]=(x/100)%10+0x30
disdat[13]='.'
disdat[14]=(x/10)%10+0x30
disdat[15]=x%10+0x30
}
void ext0() interrupt 0
{
while(key==0)
if(mode==0 && keyval==0)mode=1
else keyval++
keyval%=5
if(keyval<4)mode=1
else mode=0
}
void t0isr() interrupt 1
{
TH0=0x3c
TL0=0xb0
time++
if(time>=10)
{
time=0
if(adval[0]<alarml[0] || adval[0]>alarmh[0])led1=~led1
else led1=1
if(adval[1]<alarml[1] || adval[1]>alarmh[1])led2=~led2
else led2=1
if(adval[2]<alarml[2] || adval[2]>alarmh[2])led3=~led3
else led3=1
if(adval[3]<alarml[3] || adval[3]>alarmh[3])led4=~led4
else led4=1
}
}
main()
{
uchar i=0
uint tmp
TMOD=0x01
TH0=0x3c
TL0=0xb0
TR0=1
ET0=1
EX0=1
IT0=1
EA=1
sound=1
lcd1602_Init()
mode=0
while(1)
{
PCF8591_wirteCommand(0x90, i)
i2c_readADResult()
i2c_readADResult()
i2c_readADResult()
adval[i]=i2c_readADResult()
i++
i%=4
switch(mode)
{
case 0:
dischg(0)
lcd1602_Display(disdat,0)
dischg(1)
lcd1602_Display(disdat,1)
break
case 1:
lcd1602_Display(disp,0)
disdat[0]='C'
disdat[1]='H'
disdat[2]=keyval+0x30
disdat[3]=' '
tmp=(int)(100.0*(float)adval[keyval]/51.0)
disdat[4]=(tmp/100)%10+0x30
disdat[5]='.'
disdat[6]=(tmp/10)%10+0x30
disdat[7]=tmp%10+0x30
disdat[8]=' '
if(adval[keyval]<alarml[keyval])
{
disdat[9]='L'
disdat[10]='O'
disdat[11]='W'
disdat[12]='E'
disdat[13]='R'
disdat[14]=' '
}
else if(adval[keyval]>alarmh[keyval])
{
disdat[9]='O'
disdat[10]='V'
disdat[11]='E'
disdat[12]='R'
disdat[13]=' '
disdat[14]=' '
}
else {
disdat[9]='N'
disdat[10]='O'
disdat[11]='R'
disdat[12]='M'
disdat[13]='A'
disdat[14]='L'
}
disdat[15]=' '
lcd1602_Display(disdat,1)
default:break
}
delay_xms(100)
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)