//===============功能描述 //该程序实现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) { ; } }
|