搜索
bottom↓
回复: 8

ZLG7290 的WinAVR 驱动代码

[复制链接]

出0入0汤圆

发表于 2006-4-19 09:02:15 | 显示全部楼层 |阅读模式
看到有兄弟要,就发上来了。以前我朋友用WinAVR写的,改的是ZLG的C51代码,用WinAVR20040404可以正常编译运行。



//#####################---文件信息-----############################

//文   件   名        :        7290.c

//创   建   人        :        www.fcdpj.com

//建  立 时 间        :        2004-2-17

//版  本 描 述        :        V1.0

//功  能 描 述        :        ZLG7290使用代码 ,使用模拟I2C

//备                注        :        调试环境为AVRGCC 3.3.1,MCU为Mega8 晶振为3.6864MHZ

//                                        由于ZLG7290的速度很慢,换晶振时注意延时程序的调整.实际测试中

//                                        死机现象比较严重,建议使用控制ZLG7290的复位

//最后修改时间        :        2004-2-19

//##################################################################



#include "7290.h"



//0到9

//const u08 LED_Font[10] = {0xCF,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6}; //正

const u08 LED_Font[10] = {0xfc,0x0c,0xda,0x9e,0x2e,0xb6,0xf6,0x1c,0xfe,0xbe}; //反



//----------------------------------------------------------------

void I2c_Send_Byte(u08 data);

u08 I2c_Rev_Byte(void);



//*****************************************************************

//函   数   名        :        _Nop       

//建 立 时  间        :        2004-2-17

//功 能 描  述        :        延时函数,最大值为0xff

//备                注        :        没有返回值

//最后修改时间        :        2004-2-18

//*****************************************************************

void  _Nop(u08 dly)  

{

        u08 i;

        for(i=0;i<dly;i++)

        {

                asm("nop");

        }

}



//==============================================

//I2C通讯协议实现部分

//==============================================



//*****************************************************************

//函   数   名        :        Start_I2c       

//建 立 时  间        :        2004-2-17

//功 能 描  述        :        启动模拟I2C通讯

//备                注        :        没有返回值

//最后修改时间        :        2004-2-17

//*****************************************************************

void Start_I2c(void)

{

  SDA_1;   //发送起始条件的数据信号

  _Nop(1);

  SCL_1;

  _Nop(5);    //起始条件建立时间大于4.7us,延时   

  SDA_0;   //发送起始信号

  _Nop(5);    // 起始条件锁定时间大于4μs

      

  SCL_0;   //钳住I2C总线,准备发送或接收数据

  _Nop(5);

}



//*****************************************************************

//函   数   名        :        Stop_I2c       

//建 立 时  间        :        2004-2-17

//功 能 描  述        :        停止模拟I2C通讯

//备                注        :        没有返回值

//最后修改时间        :        2004-2-17

//*****************************************************************

void Stop_I2c(void)

{

  SDA_0  //发送结束条件的数据信号

  _Nop(1);

  SCL_1  //结束条件建立时间大于4μs

  _Nop(5);

  SDA_1  //发送I2C总线结束信号

  _Nop(5);

}



//*****************************************************************

//函   数   名        :        I2c_Send_Byte       

//建 立 时  间        :        2004-2-17

//功 能 描  述        :        向I2c总线发送1个字节的数据/命令

//备                注        :        没有返回值

//最后修改时间        :        2004-2-18

//*****************************************************************

void I2c_Send_Byte(u08 data)

{

        u08 BitCnt;



        for(BitCnt=0;BitCnt<8;BitCnt++)  //要传送的数据长度为8位

    {

     if((data<<BitCnt)&0x80)

             SDA_1                  //判断发送位

      else  

       SDA_0               

     _Nop(15);

     SCL_1                       //置时钟线为高,通知被控器开始接收数据位

      _Nop(15);        

     SCL_0

    }

   

    _Nop(15);

    SDA_1               //8位发送完后释放数据线,准备接收应答位

    _Nop(15);

    SCL_1

    _Nop(15);

    if(bit_is_set(I2C_PIN,SDA))ack=0;     

       else ack=1;        //判断是否接收到应答信号

    SCL_0

    _Nop(15);

}



//*****************************************************************

//函   数   名        :        Stop_I2c       

//建 立 时  间        :        2004-2-17

//功 能 描  述        :        从I2c总线接收1个字节的数据/命令

//备                注        :        返回接收到的数据/命令

//最后修改时间        :        2004-2-18

//*****************************************************************

u08 I2c_Rev_Byte(void)

{

  u08 retc;

  u08 BitCnt;

  

  retc=0;

  SDA_1             //置数据线为输入方式

  for(BitCnt=0;BitCnt<8;BitCnt++)

      {

        _Nop(15);           

        SCL_0       //置时钟线为低,准备接收数据位

        _Nop(20);

        SCL_1       //置时钟线为高使数据线上数据有效

        _Nop(20);

        retc=retc<<1;

        if(bit_is_set(I2C_PIN,SDA))retc=retc+1; //读数据位,接收的数据位放入retc中

        _Nop(20);

      }

  SCL_0   

  _Nop(20);

  return(retc);

}



//*****************************************************************

//函   数   名        :        Ack_I2c       

//建 立 时  间        :        2004-2-17

//功 能 描  述        :        主机的发送应答信号

//备                注        :        没有返回值

//最后修改时间        :        2004-2-17

//*****************************************************************

void Ack_I2c(u08 a)

{

  

  if(a==0)SDA_0     //在此发出应答或非应答信号

        else SDA_1

  _Nop(5);  

  SCL_1

    _Nop(5);

SCL_0               //清时钟线,钳住I2C总线以便继续接收

    _Nop(5);

}



//*****************************************************************

//函   数   名        :        I2c_Read

//建 立 时  间        :        2004-2-18

//功 能 描  述        :        从I2C总线上读取数据/命令,icadder是从器件地址,adder

//                                        是从器件的寄存器(如果有的话),count是一次读取的的数量

//                                        *buff读取的数据存放地址

//备                注        :        没有返回值

//最后修改时间        :        2004-2-18

//*****************************************************************

void I2c_Read(u08 icadder, u08 adder, u08 count, u08 *buff)

{       

        u08 i;

        Start_I2c();

        _Nop(5);

        I2c_Send_Byte(icadder);        //写入IC的地址

        _Nop(10);

        I2c_Send_Byte(adder);        //写入寄存器地址

        _Nop(10);

       

        Stop_I2c();                                //可查看I2C标准

        _Nop(5);



        Start_I2c();

        _Nop(5);

        I2c_Send_Byte(icadder+1);

        _Nop(10);



         for (i=0;i<count;i++)

         {

                 *buff=I2c_Rev_Byte();

                 if (i!=count-1) Ack_I2c(0);//除最后一个字节外,其他都要从MASTER发应答。

                 buff++;

         }

        //SendAck();//除最后一个字节外,其他都要从MASTER发应答。



        Ack_I2c(1);

        Stop_I2c();

       

}



//*****************************************************************

//函   数   名        :        I2c_Send

//建 立 时  间        :        2004-2-18

//功 能 描  述        :        从I2C总线上读取数据/命令,icadder是从器件地址,adder

//                                        是从器件的寄存器(如果有的话),value要写入的值

//备                注        :        有返回值

//最后修改时间        :        2004-2-18

//*****************************************************************

u08 I2c_Send(u08 icadder, u08 adder, u08 value)

{

        if (adder >0x17)

                return False;

               

        Start_I2c();

        I2c_Send_Byte(icadder);  //写入IC地址

        _Nop(15);

        I2c_Send_Byte(adder);         //写入寄存器地址

        _Nop(15);

        I2c_Send_Byte(value);        //写入值

        _Nop(30);

       

        Stop_I2c();



        return True;

}



//==============================================

//ZLG7290接口部分

//==============================================



//*****************************************************************

//函   数   名        :        ZLG_Get_Key

//建 立 时  间        :        2004-2-18

//功 能 描  述        :        从ZLG7290里读取键盘数值

//备                注        :        有返回值,返回的为读取的按键值,如果是0则是没有按键读回

//最后修改时间        :        2004-2-19

//*****************************************************************

u08 ZLG_Get_Key(void)

{

        u08 tmp;

        tmp = 0;

        I2c_Read(zlg7290, 0x01, 0x01, &tmp);

        _Nop(1);

        return tmp;

}



//*****************************************************************

//函   数   名        :        ZLG_Disp_Cnt

//建 立 时  间        :        2004-2-18

//功 能 描  述        :        向ZLG7290写入要显示的数码管的数量(0--7)

//备                注        :        有返回值,成功写入数据返回True,注意ZLG7290扫描位数寄存器的设置

//最后修改时间        :        2004-2-19

//*****************************************************************

u08 ZLG_Disp_Cnt(u08 Count)

{

        u08 tmp;

        tmp = 0;

        if (Count > 0x07)

                return False;

               

        I2c_Send(zlg7290,0x0D,Count);

        _Nop(1);

        I2c_Read(zlg7290,0x0D,0x01,&tmp);

        asm("nop");

        if (tmp == Count)

                return True;

        else

                return False;

}



//*****************************************************************

//函   数   名        :        ZLG_Disp_LED

//建 立 时  间        :        2004-2-18

//功 能 描  述        :        向ZLG7290写入要显示的数码管和内容.

//备                注        :        有返回值,成功写入数据返回True,注意ZLG7290扫描位数寄存器的设置

//最后修改时间        :        2004-2-19

//*****************************************************************

u08 ZLG_Disp_LED(u08 Led_Index,u08 Led_Num)

{

        u08 tmp;

        tmp = 0;

        if ((Led_Index < 0x10) || (Led_Index > 0x17))

                return False;

       

        I2c_Send(zlg7290,Led_Index,Led_Num);

        asm("nop");

        I2c_Read(zlg7290,Led_Index,0x01,&tmp);

        asm("nop");

        if (tmp == Led_Num)

                return True;

        else

                return False;

}



//*****************************************************************

//函   数   名        :        ZLG_Cls

//建 立 时  间        :        2004-2-18

//功 能 描  述        :        清LED显示,Type =0 全部清除显示为0,Type=1 全部不显示,默认为1

//备                注        :        有返回值,成功则返回True,失败返回False

//最后修改时间        :        2004-2-18

//*****************************************************************

u08 ZLG_Cls(u08 Type)

{

        u08 tmp,i;

        u08 Num;

        tmp = 0;

       

        Num = 0x00;

       

        if (Type == 0x00)

                Num = 0xFC;

               

        for(i=0;i<8;i++)

        {

                I2c_Send(zlg7290,SubDpRam+i,Num);

                asm("nop");

                asm("nop");

        }

        _Nop(1);

        for(i=0;i<8;i++)

        {

                I2c_Read(zlg7290,SubDpRam+i,0x01,&tmp);

                if(tmp != Num)

                        return False;

        }

       

        _Nop(1);

        return True;



}

#ifndef USE_INT

//*****************************************************************

//函   数   名        :        ZLG_Check_Key

//建 立 时  间        :        2004-2-19

//功 能 描  述        :        检查是否有按键,只有在没有定义过USE_INT后才能使用

//备                注        :        有返回值 ,如果返回True表示有按键产生

//最后修改时间        :        2004-2-19

//*****************************************************************

        u08 ZLG_Check_Key(void)

        {

                u08 tmp;

                I2c_Read(zlg7290,0x00,0x01,&tmp);

                if ((tmp & 0x01) == 0x01 )

                        return True;

                else

                        return False;

        }

#endif



//*****************************************************************

//函   数   名        :        ZLG_Read_Reg

//建 立 时  间        :        2004-2-19

//功 能 描  述        :        读取指定寄存器,作为I2c的读取数据的API使用,扩展功能用

//备                注        :        有返回值

//最后修改时间        :        2004-2-19

//*****************************************************************

u08 ZLG_Read_Reg(u08 reg)

{

        u08 tmp;

        tmp = 0;

        I2c_Read(zlg7290,reg,0x01,&tmp);

        return tmp;

}



//*****************************************************************

//函   数   名        :        ZLG_Write_reg

//建 立 时  间        :        2004-2-19

//功 能 描  述        :        向指定寄存器写入数据,作为I2c的写入数据的API使用,扩展功能用

//备                注        :        有返回值

//最后修改时间        :        2004-2-19

//*****************************************************************

u08 ZLG_Write_reg(u08 reg, u08 value)

{

        u08 tmp;

        tmp = 0;

        I2c_Send(zlg7290,reg,value);

        _Nop(1);

        I2c_Read(zlg7290,reg,0x01,&tmp);

       

        if (tmp == value)

                return True;

        else

                return False;

}



//*****************************************************************

//函   数   名        :        RST_ZLG

//建 立 时  间        :        2004-2-19

//功 能 描  述        :        由于ZLG的不稳定,控制它的复位,达到整个系统的健壮

//备                注        :        有返回值,此函数未经实际测试

//最后修改时间        :        2004-2-19

//*****************************************************************

#ifdef USE_RST

        void delay(u16 dly_Time)

        {

                u16 i,t;

                t = dly_Time;

                while(t--)

                        for(i=0;i<6300;i++);

        }

        u08 RST_ZLG(void)

        {

                u08 tmp;

                tmp = 0x00;

                RST_0;

                delay(400);        //延时100未经实际测试

                _Nop(2);

                RST_1;

                I2c_Send(zlg7290,0x00,0xF0);

                _Nop(10);

                I2c_Read(zlg7290,0x00,0x01,&tmp);

                if(tmp == 0xF0)

                        return True;

                else

                        return False;

        }

#endif



//##################程序结束

出0入0汤圆

 楼主| 发表于 2006-4-19 09:03:15 | 显示全部楼层
下面是头文件

//#####################---文件信息-----############################

//文   件   名        :        7290.h

//创   建   人        :        www.fcdpj.com

//建  立 时 间        :        2004-2-17

//版  本 描 述        :        V1.0

//功  能 描 述        :        ZLG7290使用代码 7290.c的头文件

//备                注        :        调试环境为AVRGCC 3.3.1,MCU为Mega8

//最后修改时间        :        2004-2-19

//##################################################################



#ifndef _7290_H_

#define _7290_H_



#include <avr/io.h>

#include <avr/interrupt.h>

#include <avr/signal.h>

#include <avr/eeprom.h>

//-----------------------

//I2C定义,可根据具体情况配置

//相应的管脚

//-----------------------

#define SDA PB1

#define SCL PB0

#define        I2C_PORT         DDRB

#define I2C_PIN                PINB



#define        SCL_1        cbi(I2C_PORT, SCL);

#define        SCL_0        sbi(I2C_PORT, SCL);

#define        SDA_1        cbi(I2C_PORT, SDA);

#define        SDA_0        sbi(I2C_PORT, SDA);



//------------------------

//数据类型重新定义

//------------------------

#ifndef u08

        #define u08 unsigned char

#endif



#ifndef u16

        #define u16 unsigned int

#endif

#define True        0x01

#define False        0x00



u08 ack;                 //应答标志位



//-------------------------------

//ZLG7290相应的声明

//-------------------------------

#define zlg7290         0x70 //ZLG7290的IIC地址



#define SubKey          0x01

#define SubCmdBuf         0x07

#define SubDpRam         0x10

//#define USE_INT        //声明使用中断方式检测有按键

#define USE_RST        //声明使用控制ZLG7290的复位

#ifdef USE_RST

        #define ZLG_RST_DDR                DDRB

        #define ZLG_RST_PORT        PORTB

        #define ZLG_RST                        PB2

        #define RST_INIT                sbi(ZLG_RST_DDR,ZLG_RST)

        #define        RST_0                        cbi(ZLG_RST_PORT,ZLG_RST)

        #define RST_1                        sbi(ZLG_RST_PORT,ZLG_RST)

#endif



//---------------------------------

//LED显示字码,如果要显示小数点,则加上 pd

//---------------------------------

#define pd 0x01;

extern const u08 LED_Font[10];



//I2C函数声明

void Start_I2c(void);

void Stop_I2c(void);

void Ack_I2c(u08 a);

void I2c_Read(u08 icadder, u08 adder, u08 count, u08 *buff);

u08 I2c_Send(u08 icadder, u08 adder, u08 value);

//控制ZLG7290

u08 ZLG_Get_Key(void); //读取ZLG7290中点键值,地址是0x01

u08 ZLG_Disp_Cnt(u08 Count); //设置要显示的LED数量

u08 ZLG_Disp_LED(u08 Led_Index,u08 Led_Num); //显示特定的LED

u08 ZLG_Cls(u08 Type); //清LED显示



#ifndef USE_INT  //使用中断函数暂无

        u08 ZLG_Check_Key(void); //检查是否有按键

#endif



u08 ZLG_Read_Reg(u08 reg);  //读取指定寄存器

u08 ZLG_Write_reg(u08 reg, u08 value); //向指定寄存器写入数据

#ifdef USE_RST

        u08 RST_ZLG(void);        //复位ZLG7290

#endif



#endif

/////////////////// END

出0入0汤圆

发表于 2006-4-21 23:22:41 | 显示全部楼层
太好,对我好有用,马上保存读下,谢谢,

是软件模拟的,有TWI驱动吗?谢啊,我就是这个驱动不了啊,
-----此内容被kinggink888于2006-04-21,23:28:22编辑过

出0入0汤圆

发表于 2006-4-22 11:01:50 | 显示全部楼层
谢谢共享

出0入0汤圆

发表于 2007-4-15 01:05:17 | 显示全部楼层
我最近都开始学一下用7290,真是多谢啊!

出0入0汤圆

发表于 2009-8-9 13:03:22 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-3-10 17:20:14 | 显示全部楼层
为什么没有SDA脚输入输出脚的控制转换的。SDA一直是输出吗?你的程序可以过吗?

出0入0汤圆

发表于 2010-4-21 20:00:36 | 显示全部楼层
我也觉得奇怪,不过楼主开头就说了的  只是能编译通过  呵呵

出0入0汤圆

发表于 2010-7-23 11:32:46 | 显示全部楼层
点上
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-7 18:46

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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