打印
[AVR单片机]

ATmega128单片机IIC控制ZLG7290 键盘源程序

[复制链接]
2738|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hvcb_hlj|  楼主 | 2009-7-16 15:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
//===============功能描述
//该程序实现ZLG7290的控制,显示全8,连续闪烁6次后
//按下按键即可显示键值在数码管上
//======================================================
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <avr/delay.h>
#include <avr/pgmspace.h>

#ifndef cbi 
        #define cbi(reg,bit)        reg &= ~_BV(bit)
#endif 

#ifndef sbi 
        #define sbi(reg,bit)        reg |= _BV(bit)
#endif

uint8_t Num[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
uint8_t key[17]={1,9,11,13,15,1,3,5,7,10,12,14,16,2,4,6,8};
//---------------延时子程序
void delay_1ms(uint8_t xtal)
{
    uint8_t i;
    for(i=1;i<(uint8_t)(xtal*143-2);i++)
    {;}
}

void delay_ms(uint8_t m, uint8_t fosc)
{
    uint8_t i;
    i=0;
    while(i<m)
    {
        delay_1ms(fosc);
        i++;
    }
}

//-----------------------------IIC操作子程序-------------------------------
//IIC写操作
//address_reg1为寄存器地址1
//data_package为写的数据
void twi_write(uint8_t address_reg1, uint8_t data_package)
{    
    //TWI预分频为4分频
    sbi(TWSR,TWPS0);
    cbi(TWSR,TWPS1);
    TWBR=0x20;//SCL频率92160HZ
begin:
    TWCR=_BV(TWEN)|_BV(TWSTA)|_BV(TWINT);
    while(!(TWCR&_BV(TWINT)))//等待TWINT置位,TWINT置位表示开始信号发送完毕
        ;
    if(((TWSR&0xF8)!=0x08)&((TWSR&0xF8)!=0x10))//检查状态寄存器,如果状态字不是START或RESTART,重新发送开始信号
        goto begin;
    TWDR=0x70;//将器件地址写入到TWDR寄存器,TWINT位清零,启动发送地址
    TWDR=0x70;//%%%%%%%%%%%%%%%

    TWCR=_BV(TWEN)|_BV(TWINT);
    while(!(TWCR&_BV(TWINT)))//等待TWINT置位,TWINT置位表示总线命令SLA+W已发出,及收到应答信号ACK/NACK
        ;
    if((TWSR&0xF8)!=0x18)//检查TWI状态寄存器,如果状态字不是地址ACK,重新发送开始信号
        goto begin;    
    //---发送寄存器地址
    TWDR=address_reg1;//写寄存器地址
    TWDR=address_reg1;//%%%%%%%%%%%%%%%
    TWCR=_BV(TWEN)|_BV(TWINT);
    while(!(TWCR&_BV(TWINT)))//等待TWINT置位,TWINT置位表示总线命令SLA+W已发出,及收到应答信号ACK/NACK
        ;
    if((TWSR&0xF8)!=0x28)//检查TWI状态寄存器,如果状态字不是地址ACK,重新发送开始信号
        goto begin;
        
    //---写入数据
    TWDR=data_package;//将数据载入到TWDR寄存器,TWINT位清零,启动发送地址
    TWDR=data_package;//%%%%%%%%%%%%%%%

    TWCR=_BV(TWINT)|_BV(TWEN);    
    while(!(TWCR&_BV(TWINT)))//等待TWINT置位,TWINT置位表示总线数据已发出,及收到应答信号ACK/NACK
        ;        
    if((TWSR&0xF8)!=0x28)//检查TWI状态寄存器,如果状态字不是数据ACK,重新发送开始信号
        goto begin;    
    TWCR=_BV(TWINT)|_BV(TWSTO)|_BV(TWEN);//发送STOP信号
    
    delay_ms(2,8);    
    delay_ms(2,8);    
    delay_ms(2,8);
}
//-------------------------------------------
//IIC读操作
//address_reg1为寄存器地址
uint8_t twi_read(uint8_t address_reg1)
{
    uint8_t result1=0;
    
    sbi(TWSR,TWPS0);//TWI预分频为4分频
    cbi(TWSR,TWPS1);
    TWBR=0x20;//SCL频率92160HZ
    
begin:
    delay_ms(2,8);
    
    TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);//发送开始信号
    while(!(TWCR&(1<<TWINT)))//等待开始信号发送完毕
        ;
    if(((TWSR&0xF8)!=0x08)&((TWSR&0xF8)!=0x10))//检查TWI状态寄存器,如果状态字不是START或RESTART,重新发送开始信号
        goto begin;
    //---发送器件地址
    TWDR=0x70;//发器件写地址,TWINT位清零,启动发送%%%%%%%%%%%%%%
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)))//等待TWINT置位,TWINT置位表示总线命令SLA+W已发出,及收到应答信号ACK/NACK
        ;
    if((TWSR&0xF8)!=0x18)//检查TWI状态寄存器,如果状态字不是地址ACK,重新发送开始信号
        goto begin;
    //---发送寄存器地址
    TWDR=address_reg1;//写寄存器地址,TWINT位清零,启动发送%%%%%%%%%%%%%%%%%%
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)))//等待TWINT置位,TWINT置位表示总线数据已发出,及收到应答信号ACK/NACK
        ;
    if((TWSR&0xF8)!=0x28)//检查TWI状态寄存器,如果状态字不是数据ACK,重新发送开始信号
        goto begin;    
        
    //---发送起始信号
    TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);//发送开始信号
    while(!(TWCR&(1<<TWINT)))//等待TWINT置位,TWINT置位表示开始信号发送完毕
        ;    
    if(((TWSR&0xF8)!=0x08)&((TWSR&0xF8)!=0x10))//检查TWI状态寄存器,如果状态字不是START或RESTART,重新发送开始信号
        goto begin;    
    //---发送读命令
    TWDR=0x70+1;//读器件地址写入到TWDR寄存器,TWINT位清零,启动发送
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)))//等待TWINT置位,TWINT置位表示总线命令SLA+W已发出,及收到应答信号ACK/NACK
        ;    
    if((TWSR&0xF8)!=0x40)//检查TWI状态寄存器,如果状态字不是地址ACK,重新发送开始信号
        goto begin;    
    TWCR=(1<<TWINT)|(1<<TWEN);//发送NACK信号
    while(!(TWCR&(1<<TWINT)))
        ;
    if((TWSR&0xF8)!=0x58)
        goto begin;    
    TWCR=(1<<TWSTO)|(1<<TWEN);//发送STOP信号
    result1=TWDR;//将TWDR寄存器的数据读入    
    delay_ms(2,8);    
    delay_ms(2,8);    
    delay_ms(2,8);
    return result1;

//---------------按键中断子程序
SIGNAL(SIG_INTERRUPT7)
{
    uint8_t i;    
    i=twi_read(0x01);    
    num_disp(key);
}

//=================多位数据显示
void num_disp(uint8_t num)
{
    uint8_t bai,shi,ge;
    bai=num/100;
    shi=(num%100)/10;
    ge=(num%100)%10;
    twi_write(0x10,Num[ge]);
    if((shi!=0)||(bai!=0))
    {
        twi_write(0x10+1,Num[shi]);
    }
    else
    {
        twi_write(0x10+1,0);
    }
    if(bai!=0)
    {
        twi_write(0x10+2,Num[bai]);
    }
    else
    {
        twi_write(0x10+2,0);
    }
}

//==================================================================  
void main()
{
    int i,j;
    for(j=0;j<6;j++)//循环显示,闪烁8次
    {
        for(i=0;i<=7;i++)
        {
            twi_write(0x10+i,Num[8]);//全部显示8
        }
        delay_ms(250,8);
        delay_ms(250,8);
        delay_ms(250,8);
        for(i=0;i<=7;i++)
        {
            twi_write(0x10+i,0);//清除显示
        }
        delay_ms(250,8);
        delay_ms(250,8);
        delay_ms(250,8);
    }    
    cbi(DDRE,PE7);//开中断
    cbi(EICRB,ISC71);
    cbi(EICRB,ISC70);
    sbi(EIMSK,INT7);
    sei();    
    while(1)
    {
        ;
    }
}

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

4

帖子

0

粉丝