⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 twi372.c

📁 此程序是AVR的时钟372的TWI程序,已调试完成
💻 C
字号:
#include <iom88v.h>                         
#include <macros.h>  
//#include"TWI.H" 
#define rd_device_add 0x65 
#define wr_device_add 0x64 
//#define wr_device_add 0x26
/***************************************************/
//TWI状态定义 
//MT 主方式传输  MR 主方式接收 
#define START 0x08 
#define RE_START 0x10 
//#define MT_SLA_ACK 0x38 
#define MT_SLA_ACK 0x18 
#define MT_SLA_NOACK 0x20 
#define MT_DATA_ACK  0x28 
#define MT_DATA_NOACK 0x30 
//////////////////////////////////
#define MR_SLA_ACK  0x40 
#define MR_SLA_NOACK 0x48 
#define MR_DATA_ACK 0x50 
#define MR_DATA_NOACK 0x58 
//////////////////////////////////
#define SCL_1 PORTC |= BIT(PC5)
#define SCL_0 PORTC &= ~BIT(PC5)  
#define SDA_1 PORTC |= BIT(PC4)
#define SDA_0 PORTC &= ~BIT(PC4) 
//常用TWI操作(主模式写和主模式读) 
//TWCR TWI控制寄存器;TWINT BIT7;TWSTA BIT5 ;TWEN BIT 2;TWSTO BIT4;TWEA BIT 6
#define Start()         (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)) 
#define Stop()          (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)) 
#define Wait()          {while(!(TWCR&(1<<TWINT)));} 
#define TestAck()       (TWSR&0xf8) //检验TWI的状态寄存器屏蔽预分频器 ,当状态字 不是MT——DATA——ACK转出错处理 和初值f8与
#define SetAck()        (TWCR|=(1<<TWEA)) 
#define SetNoAck()      (TWCR&=~(1<<TWEA)) 
#define Twi()           (TWCR=(1<<TWINT)|(1<<TWEN)) //装入SLA-W到TWDR 寄存器TWINT位清零启动发送地址
#define Write8Bit(x)    {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);}  
/***************************************************/
 unsigned char R_datyy[8];
 unsigned char R_datyyb[8];
/***************************************************/
struct date
     { 
	 unsigned char year;
	 unsigned char month;
	 unsigned char day;
	 unsigned char week;
	 unsigned char hour;
	 unsigned char minute;
	 unsigned char second;
	 };//datyy;
/***************************************************/
 struct date datyy={05,05,0x21,06,0x11,0x38,0x10};//全局变量,包含年月日 星期 时分秒            
/******************************************/ 
void delay_1ms(void)                 //1ms延时函数
  {
   unsigned int i;
   for (i=0;i<1140;i++);
  }
/******************************************/  
void delay_ms(unsigned int n)       //N ms延时函数
  {
   unsigned int i=0;
   for (i=0;i<n;i++)
   delay_1ms();
  }
/****************************************** 
             twi总线写一个字节 
             返回0:写成功 
             返回非0:写失败 
*******************************************/ 
unsigned char twi_Write(unsigned int RomAddress,unsigned char Wdata)  
{    
     //unsigned char ADDR=0;
	 
     unsigned char ACK_A=0;
	 unsigned char ACK_B=0;
	 unsigned char ACK_C=0;
     Start();//twi启动 
     Wait(); 
     if(TestAck()!=START) return 1;//ACK 0x08
	 //delay_ms(10);/////hhhh
	 //ADDR=wr_device_add;
     Write8Bit(wr_device_add);//起动372从器件地址和写方式 0x64
	 //Write8Bit(ADDR);//起动372从器件地址和写方式 0x64
	 //delay_ms(10);
	 //SDA_0;///hhhhh
     Wait(); 
	 
	 ACK_A=TestAck();//hhhhhh
	 //if(TestAck()!=MT_SLA_NOACK) return 1;//hhhhh
     if(TestAck()!=MT_SLA_ACK) return 1;//ACK MT_SLA_ACK 0x18 已发送从机地址和写方式主机已接受则续 
	 Write8Bit(RomAddress);  //向 TWDR写入数据
     Wait(); 
	 ACK_B=TestAck();//hhhhhh
     if(TestAck()!=MT_DATA_ACK) return 1;//ACK 
     Write8Bit(Wdata);//写数据到372
     Wait(); 
	 ACK_C=TestAck();//hhhhhh
     if(TestAck()!=MT_DATA_ACK) return 1;//ACK    
     Stop();//twi停止 
     delay_ms(20);//延时等EEPROM写完 
     return 0; 
} 
/****************************************** 
               twi总线读一个字节 
               如果读失败也返回0 
*******************************************/ 

unsigned char twi_Read(unsigned int RomAddress)//,unsigned char addr_len
{     
      unsigned char ACK_R1=0;
	  unsigned char ACK_R2=0;
	  unsigned char ACK_R3=0;
	  unsigned char ACK_R4=0;
      unsigned char temp; 
	  unsigned char ADDR;
      Start();    //twi启动 
      Wait(); 
      if (TestAck()!=START) return 0;//ACK             
      Write8Bit(wr_device_add);//起动372从器件地址和写方式    
      Wait();    
      if (TestAck()!=MT_SLA_ACK) return 0;//ACK 
	  Write8Bit(RomAddress);	
      Wait(); 
	  ACK_R1=TestAck();//////////HHHH
      if (TestAck()!=MT_DATA_ACK) return 0; 
       
      Start();//twi重新启动 
      Wait(); 
	  ACK_R2=TestAck();////////HHHH
      if (TestAck()!=RE_START)  return 0;  
      Write8Bit(rd_device_add);//写twi从器件地址和读方式   
      Wait(); 
	  ACK_R3=TestAck();////////HHHH
      if(TestAck()!=MR_SLA_ACK)  return 0;//ACK     
      Twi();//启动主twi读方式 
      Wait(); 
	  ACK_R4=TestAck();////////HHHH
      if(TestAck()!=MR_DATA_NOACK) return 0;//ACK  MR_DATA_NOACK 0x58   
      temp=TWDR;//读取twi接收数据 TWDR twi数据寄存器      
      Stop();//twi停止 
      return temp; 
} 
/******************************************/ 
void init372(void)
{
  twi_Write(0x70,0);
  twi_Write(0xe0,0x23);
 //twi_Write(0xe0,0);
  twi_Write(0xf0,0x28);//24h
 //twi_Write(0xf0,0x38);//24h
}
/******************************************/ 
void Init_TWI(void) 
{      
	 (PRR&=~(1<<PRTWI));//启动两串行线 置能TWI 
     TWBR=0x16;   //TWBR=0x16;TWBR=0x12;bps rigister
     TWSR=00;     //设置TWI时钟50K twi 状态寄存器    	 
} 
/******************************************/
/*
void Bcd2asc(void) 
{
    uchar i,j;
 
    for (j=0,i=0; i<7; i++)
    {
        asc[j++] =(trdata[i]&0xf0)>>4|0x30  ;	
        asc[j++] =trdata[i]&0x0f|0x30; 
    }
}
*/
/******************************************/ 
void main(void) 
{ 
	PORTB = 0x0F; //00101111B
    DDRB  = 0x30; //00110000B
	PORTC = 0x3F;//置TWI管脚上拉 
    DDRC  = 0x0E;
	PORTD = 0x40; //00000000B
    //DDRD  = 0x50; //01110010B
	//MCUCR = 0x00;
    //EICRA = 0x00; //extended ext ints
    //EIMSK = 0x01;
	Init_TWI();
	init372();
	twi_Write(0,datyy.second);
    twi_Write(0x10,datyy.minute);
    twi_Write(0x20,datyy.hour);
    twi_Write(0x30,datyy.week);
    twi_Write(0x40,datyy.day);
    twi_Write(0x50,datyy.month);
    twi_Write(0x60,datyy.year);
	while(1)
	{
	R_datyy[0]=twi_Read(0x60);//Y
	R_datyyb[0]=((R_datyy[0]>>4) & 0x7)*10+(R_datyy[0] & 0xf);
	R_datyy[1]=twi_Read(0x50);//MO
	R_datyyb[1]=((R_datyy[1]>>4) & 0x7)*10+(R_datyy[1] & 0xf);
	R_datyy[2]=twi_Read(0x40);//D
	R_datyyb[2]=((R_datyy[2]>>4) & 0x3)*10+(R_datyy[2] & 0xf);
	R_datyy[3]=twi_Read(0x30);//W
	R_datyyb[3]=((R_datyy[3]>>4) & 0x1)*10+(R_datyy[3] & 0xf);
	R_datyy[4]=twi_Read(0x20);//H
	R_datyyb[4]=((R_datyy[4]>>4) & 0x1)*10+(R_datyy[4] & 0xf);
	R_datyy[5]=twi_Read(0x10);//MI
	R_datyyb[5]=((R_datyy[5]>>4) & 0xf)*10+(R_datyy[5] & 0xf);
	R_datyy[6]=twi_Read(0x00);//S
	R_datyyb[6]=((R_datyy[6]>>4) & 0x7)*10+(R_datyy[6] & 0xf);
	delay_ms(20);
	/*
	datyy.second=((datyy.second >> 4) & 0x7)*10+(datyy.second & 0xf);
	datyy.minute=((datyy.minute>>4) & 0x7)*10+(datyy.minute & 0xf);
	datyy.hour=((datyy.hour>>4) & 0x3)*10+(datyy.hour & 0xf);
	datyy.day=((datyy.day>>4) & 0x3)*10+(datyy.day & 0xf);
	datyy.month=((datyy.month>>4) & 0x1)*10+(datyy.month & 0xf);
	datyy.year=((datyy.year>>4) & 0xf)*10+(datyy.year & 0xf);
	
	R_datyy[0]=((R_datyy[0]>>4) & 0x7)*10+(R_datyy[0] & 0xf);
	R_datyy[1]=((R_datyy[1]>>4) & 0x7)*10+(R_datyy[1] & 0xf);
	R_datyy[2]=((R_datyy[2]>>4) & 0x3)*10+(R_datyy[2] & 0xf);
	R_datyy[3]=((R_datyy[3]>>4) & 0x3)*10+(R_datyy[3] & 0xf);
	R_datyy[4]=((R_datyy[4]>>4) & 0x1)*10+(R_datyy[4] & 0xf);
	R_datyy[5]=((R_datyy[5]>>4) & 0xf)*10+(R_datyy[5] & 0xf);
	R_datyy[6]=((R_datyy[6]>>4) & 0x7)*10+(R_datyy[6] & 0xf);
	*/
	}
} 






⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -