找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2814|回复: 0
打印 上一主题 下一主题
收起左侧

51单片机驱动74hc164的程序

[复制链接]
跳转到指定楼层
楼主
ID:115908 发表于 2016-5-8 20:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*#include"reg51.h"
#define uchar unsigned char
#define uint unsigned int
sbit PWM=P1^0;
sbit DEC=P1^1;
sbit INC=P1^2;
sbit seg=P1^3;
sbit cp=P1^4;
sbit DAT=P1^5;
uint high;
bit stop;

uchar tab[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

void delayms(uchar n)
{   uchar i,j,k;
        for(i=0;i<n;i++)
          for(j=0;j<100;j++)
            for(k=0;k<5;k++);
}

void delay(uint N)
{        while(--N);
}

void writebyte_164(uchar Dat)
{        uchar temp,i;
        temp=Dat;
        for(i=0;i<8;i++)
        { cp=0;
          if(temp&0x80) DAT=1;
          else DAT=0;
          cp=1;
          temp<<=1;
        }
}



void main()
{   PWM=0;
        seg=0;
        EX0=1;
        IT0=1;
        EA=1;
        writebyte_164(tab[0]);
        writebyte_164(tab[0]);
        writebyte_164(tab[0]);
        seg=1;
        while(!stop);
        while(1)
        { PWM=1;
          delay(high);
          PWM=0;
          delay(300-high);
        }
}

void int0()interrupt 0
{        PWM=0;
        if(!stop) stop=1;
        if(!DEC) high-=10;
        if(!INC) high+=10;
        seg=0;
        writebyte_164(tab[high/2%10]);
        writebyte_164(tab[high/2%100/10]|0x80);
        writebyte_164(tab[high/2/100]);
        seg=1;
        delayms(255);
}        */
#include"reg51.h"
#include"intrins.h"     //_nop_();延时函数用
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
sbit PWM=P1^0;
sbit DEC=P1^1;
sbit INC=P1^2;
sbit seg=P1^3;
sbit cp=P1^4;
sbit DAT=P1^5;

sbit sda=P2^0;          //数据线
sbit scl=P2^1;          //时钟线

uint high;
bit flag;

uchar tab[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};


void delayms(uchar n)
{   uchar i,j,k;
        for(i=0;i<n;i++)
          for(j=0;j<100;j++)
            for(k=0;k<5;k++);
}

void delay(uint N)
{        while(--N);
}

//**************************************************************************************************
//启动(SCL为高,SDA由高变为低是一个开始条件)
//**************************************************************************************************
void start()  
{        
        sda=1;    //数据线置高,
        _nop_();  //延时
        scl=1;    //时钟线置高
        _nop_();  //延时
        sda=0;    //数据线置低,由高变低
        _nop_();  //延时
        scl=0;    //时钟线置低,准备发送或接收数据,总线进入忙状态(I2C总线在空闲状态时,SDA与SCL均被置高)
        _nop_();  //延时
}
//**************************************************************************************************
//停止(SCL为高,SDA由低变为高是一个结束条件)
//**************************************************************************************************
void stop()   
{
        sda=0;                   //数据线置低
        _nop_();                 //延时
        scl=1;                   //时钟线置高
        _nop_();                 //延时
        sda=1;                   //数据线置高,由低变高
        _nop_();                 //延时
}
//**************************************************************************************************
//检测应答(所有的地址和数据字都是以8bit,在第9个时钟周期,从器件发出"0"信号来作为收到一个字的应答信号)
//**************************************************************************************************
void checkACK()                   //主器件检测从器件是否返回应答
{
        scl=1;                        //时钟线置高
        _nop_();                      //延时
        while(sda==1);                //等待第9个时钟周期器件发出的响应信号"0"
        scl=0;                        //时钟线置低
        _nop_();                      //延时
}
//**************************************************************************************************
//发送应答(发送方为主器件,接收方为从器件,控制器作为从器件接收完1数据时,发送应答信号
//**************************************************************************************************
void sendACK(bit ACK)                  
{
    if(ACK)sda=1;            //如果i位为1则发送1,即发送"非应答信号"
      else sda=0;            //如果i位为0则发送0,即发送"应答信号"        
    scl=1;                   //时钟线置高,给一个脉冲
        _nop_();                 //延时
        scl=0;                   //时钟线置低
        _nop_();                 //延时
}
//**************************************************************************************************
//写一字节
//**************************************************************************************************
void send_byte(uchar date)       //写一个8位字
{
        uchar i,temp;                //定义局部变量
        temp=date;                   //待发8位数据赋予temp
        for(i=0;i<8;i++)             //循环8次,每次写入1位,从最高位开始发送
        {
        if(temp&0x80)sda=1;      //如果temp最高位为1则发送1
          else sda=0;            //如果temp最高位为0则发送0
            _nop_();                 //延时
                scl=1;                   //给一个脉冲,发送sda当前这位数据
                _nop_();                 //延时,需大于4us(参考数据手册时序图)
                _nop_();              
                _nop_();                 
                _nop_();                 
                _nop_();               
                scl=0;                   //时钟线置低,准备下一脉冲
            _nop_();                 //延时,需大于4.7us(参考数据手册时序图)
                _nop_();              
                _nop_();                 
                _nop_();                 
                _nop_();  
                temp=temp<<1;            //左移1位,准备好下1位待发送的数据
        }
        checkACK();                  //查询是否返回应答信号
}
//**************************************************************************************************
//读一字节
//**************************************************************************************************
uchar receive_byte()         //读一个8位字
{
        uchar i,temp;            //定义局部变量
        sda=1;                   //设置数据线为输入
        _nop_();                 //延时
        for(i=0;i<8;i++)         //循环8次,每次读取1位,从最高位开始接收
        {
                scl=1;               //给一脉冲,准备发送1位数据            
                _nop_();             //延时,需大于4us(参考数据手册时序图)
                _nop_();              
                _nop_();                 
                _nop_();                 
                _nop_();
                temp=(temp<<1)|sda;  //读取1位数据,放在temp最低位
                scl=0;               //准备给下1个脉冲
            _nop_();             //延时,需大于4.7us(参考数据手册时序图)
                _nop_();              
                _nop_();                 
                _nop_();                 
                _nop_();      
        }
        return temp;             //返回读取的8位数据
}
//**************************************************************************************************
//向某I2C器件的某字地址写一字节数据
//**************************************************************************************************
void write_word(uchar device_add,uchar word_add,uchar date)  //写进去一个存储数据
{
        start();                  //启动
        send_byte(device_add);    //选择从器件地址,RW位为0,即选择写命令
        send_byte(word_add);      //写字地址
        send_byte(date);          //写数据
        stop();                   //停止        
}
//**************************************************************************************************
//向某I2C器件的某字地址读一字节数据
//**************************************************************************************************
uchar read_word(uchar device_add,uchar word_add)   //读出一个存储的数据
{
        uchar date;
        start();                 //启动
        send_byte(device_add);   //选择从器件地址,RW位为0,即选择写命令
        send_byte(word_add);     //写字地址
        start();                 //启动
        send_byte(device_add+1); //选择从器件地址,RW位为1,即选择读命令
        date=receive_byte();     //读数据
    sendACK(1);              //发送非应答信号
        stop();                  //停止
        return date;             //返回读取结果数据
}

void writebyte_164(uchar Dat)
{        uchar temp,i;
        temp=Dat;
        for(i=0;i<8;i++)
        { cp=0;
          if(temp&0x80) DAT=1;
          else DAT=0;
          cp=1;
          temp<<=1;
        }
}

void main()
{   PWM=0;
        seg=0;
        EX0=1;
        IT0=1;
        EA=1;
/*        write_word(0xa0,0,0);
        delayms(5); */
        high=(uint)read_word(0xa0,0)*2;
        writebyte_164(tab[high/2%10]);
        writebyte_164(tab[high/2%100/10]|0x80);
        writebyte_164(tab[high/2/100]);
        seg=1;
        if(high==0) while(!flag);
        while(1)
        { PWM=1;
          delay(high);
          PWM=0;
          delay(300-high);
        }
}

void int0()interrupt 0
{        PWM=0;
        if(!flag) flag=1;
        if(!DEC) high-=10;
        if(!INC) high+=10;
        if(high>=300) high=290;
        if(high<=0)        high=10;
        write_word(0xa0,0,(high/2));  
        seg=0;
        writebyte_164(tab[high/2%10]);
        writebyte_164(tab[high/2%100/10]|0x80);
        writebyte_164(tab[high/2/100]);
        seg=1;
        delayms(255);
}

评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表