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

📄 340_i2c.c

📁 新华龙C8051F340单片机I2C总线的程序 保证可以用
💻 C
字号:


#include <c8051f340.h> 
#define uchar unsigned char
#define uint unsiged int                     
#define  SYSCLK         12000000             // 12M内部时钟
#define  SMB_FREQUENCY  50000                //SMBUS目标时钟频率

#define  WRITE          0x00                 // SMBus 写命令                          
#define  READ           0x01                 // SMBus 读命令
#define  EEPROM_ADDR    0xA0                 // 铁电存储器的地址
#define  SMB_BUFF_SIZE  0x08                 // 定义传输地址


#define  SMB_MTSTA      0xE0                 // 开始传输
#define  SMB_MTDB       0xC0                 // 数据传输
#define  SMB_MRDB       0x80                 // 数据接收


uchar* pSMB_DATA_IN;                 // 定义全局变量
uchar SMB_SINGLEBYTE_OUT;            // 定义握手信号

uchar* pSMB_DATA_OUT;                // 数据存储变量
unsigned long q;                           
uchar SMB_DATA_LEN;                  // SMBUS传输数据长度

uchar WORD_ADDR;                     // 数据地址

uchar TARGET;                        //目标从地址
uchar temp_char; 
uchar retval;
bit SMB_BUSY = 0;                            // 定义SMBUS忙标志位

bit SMB_RW;                                  // 传输标志

bit SMB_SENDWORDADDR;                        // 传输地址位


bit SMB_RANDOMREAD;                          // 传输开始信号发出后

bit SMB_ACKPOLL;                             // 设置应答

 

sfr16    TMR3RL   = 0x92;                    
sfr16    TMR3     = 0x94;                   

void SMBus_Init (void);						 //SMBUS初始化函数
void Timer1_Init (void);					 //定时器1初始化函数
void Timer3_Init (void);					 //定时器3初始化函数
void Port_Init (void);
void SMBus_ISR (void);
void Timer3_ISR (void);

void EEPROM_ByteWrite(uchar addr, uchar dat);
void EEPROM_WriteArray (uchar dest_addr, uchar* src_addr,
                        uchar len);
uchar EEPROM_ByteRead(uchar addr);
void EEPROM_ReadArray (uchar* dest_addr, uchar src_addr,
                       uchar len);



void main (void)
{
   char in_buff[9] ;                    
   char out_buff[8] = "ABCDEFG2";            



   PCA0MD &= ~0x40;                          // 关看门狗定时器

   OSCICN |= 0x03;                           // 初始化内部12M系统时钟
   Port_Init ();                             // 端口初始化

   Timer1_Init ();                           

   Timer3_Init ();                           

   SMBus_Init ();                            // 初始化SMBUS

   EIE1 |= 1;                                // SMBus 中断允许
   IE |= 0x20;                               // Timer2 中断允许
   EA = 1;                                  
   while(1){
  
   EEPROM_ByteWrite(0x25, 0xAA);			 //写数据0XAA到地址0X25

  
   temp_char = EEPROM_ByteRead(0x25);		 //读数据从地址0X25			 此处设断点观察值变化

  
   EEPROM_ByteWrite(0x20, 0xBB);			 //写数据0Xbb到地址0X20

  
   EEPROM_ByteWrite(0x38, 0xCC);			 //写数据0Xcc到地址0X38

  
   temp_char = EEPROM_ByteRead(0x20);	     //读数据从地址0X20		   此处设断点观察值变化

   
   temp_char = EEPROM_ByteRead(0x38);	     //读数据从地址0X38		   此处设断点观察值变化

  
   EEPROM_WriteArray(0x100, out_buff, sizeof(out_buff));   	 //写数组数据到地址0X100

  
   EEPROM_ReadArray(in_buff, 0x100, sizeof(in_buff));}		//读数据从地址0X100	 此处设断点观察值变化

}

/*******************************************************************************
铁电存储器写字节函数
参数:addr 目标地址
     dat  要写数据
*******************************************************************************/
void EEPROM_ByteWrite( uchar addr, uchar dat )
{
   while (SMB_BUSY);                         
   SMB_BUSY = 1;                            
         
   TARGET = EEPROM_ADDR;                     
   SMB_RW = WRITE;                          
   SMB_SENDWORDADDR = 1;                    
   SMB_RANDOMREAD = 0;                      
                                  
   SMB_ACKPOLL = 1;                          
                                   
   WORD_ADDR = addr;                         

   SMB_SINGLEBYTE_OUT = dat;               

   pSMB_DATA_OUT = &SMB_SINGLEBYTE_OUT;      

   SMB_DATA_LEN = 1;                         
   STA = 1;

}
/**********************************************************************
连续向铁电存储器写入多个字节
参数:
 dest_addr  目标地址
 src_addr   目标数据
 len		数据长度
***********************************************************************/
void EEPROM_WriteArray (uchar dest_addr, uchar* src_addr,
                        uchar len)
{
   uchar i;
   uchar* pData = (uchar*) src_addr;
   for( i = 0; i <= len; i++ )
   {
    EEPROM_ByteWrite(dest_addr++, *pData++);
   }

}

/**************************************************************************
函数功能:从目标地址读数据
参数:addr 目标地址
***************************************************************************/
uchar EEPROM_ByteRead( uchar addr)
{
   while (SMB_BUSY);                         
   SMB_BUSY = 1;                            
   TARGET = EEPROM_ADDR;                   
   SMB_RW = WRITE;                          
   SMB_SENDWORDADDR = 1;                     
   SMB_RANDOMREAD = 1;                       
   SMB_ACKPOLL = 1;                          
   WORD_ADDR = addr;                         
   pSMB_DATA_IN = &retval;                  
   SMB_DATA_LEN = 1;                      
   STA = 1;
   while(SMB_BUSY);                         
   return retval;

}

/***************************************************************************
函数功能:从目标地址连续读出数据
参数: dest_addr	保存数据的数组
      src_addr	目标地址
	  len		数据长度
****************************************************************************/
void EEPROM_ReadArray (uchar* dest_addr, uchar src_addr,
                       uchar len)
{
   while (SMB_BUSY);                         
   SMB_BUSY = 1;                             
   TARGET = EEPROM_ADDR;                   
   SMB_RW = WRITE;                         
   SMB_SENDWORDADDR = 1;                    
   SMB_RANDOMREAD = 1;                       
   SMB_ACKPOLL = 1;                         
   WORD_ADDR = src_addr;                     
    pSMB_DATA_IN = (unsigned char*) dest_addr;

   SMB_DATA_LEN = len;                      
   STA = 1;
   while(SMB_BUSY);                         
}
/*******************************************************************************
函数功能:SMBUS初始化
*******************************************************************************/
void SMBus_Init (void)
{
   SMB0CF = 0x5D;                           
                            

   SMB0CF |= 0x80;                           
}

/*******************************************************************************
函数功能:定时器3初始化
*******************************************************************************/
void Timer3_Init (void)
{
   TMR3CN = 0x00;                           
   TMR3 = -(SYSCLK/12/40);                  
   TMR3RL = -(SYSCLK/12/40);                
   CKCON &= ~0x40;                         
   TMR3 |= 0x04;                             
}

/*******************************************************************************
函数功能:定时器1初始化
*******************************************************************************/
void Timer1_Init (void)
{
   CKCON &= ~0x0B;                          
   TMOD = 0x20;                             

   TH1 = -(SYSCLK/SMB_FREQUENCY/12/3);      

   TL1 = -(SYSCLK/SMB_FREQUENCY/12/3);      

   TR1 = 1;                                 
}

/*******************************************************************************
函数功能:端口初始化
*******************************************************************************/
void Port_Init (void)
{  P0SKIP    = 0xff;
   P1SKIP    =0x07;
   XBR0 = 0x04;                
   XBR1 = 0x40;                              

   P0MDIN = 0xFF;                            

   P0MDOUT = 0x00;                          
   P0 = 0xFF;                                

   P1MDOUT = 0x00;                         

}

/*******************************************************************************
函数功能:SMBUS处理函数,这部分函数按照SMBUS通讯协议进行判断处理.具体请参见F340数
         据手册SMBUS通讯部分.
*******************************************************************************/
void SMBus_ISR (void) interrupt 7
{
   bit FAIL = 0;                           
   static char i;                           

   static bit SEND_START = 0;                
   switch (SMB0CN & 0xF0)                   
   {
     
      case SMB_MTSTA:

         SMB0DAT = TARGET;                  
         SMB0DAT |= SMB_RW;                  
         STA = 0;                            
         i = 0; 

	              
         break;

       case SMB_MTDB:
         if (ACK)                            
         {                                   
            if (SEND_START)
            {
               STA = 1;
               SEND_START = 0;
               break;
            }
            if(SMB_SENDWORDADDR)            
            {
               SMB_SENDWORDADDR = 0;         
               SMB0DAT = WORD_ADDR;         

               if (SMB_RANDOMREAD)
               {
                  SEND_START = 1;           
                  SMB_RW = READ;
               }

               break;
            }

            if (SMB_RW==WRITE)               
            {

               if (i < SMB_DATA_LEN)         
               {
                  SMB0DAT = *pSMB_DATA_OUT;  
                  pSMB_DATA_OUT++;           
                  i++;                       
               }
               else
               {
                 STO = 1;                    
                 SMB_BUSY = 0;               
               }
            }
            else {}                         
         }
         else                                
         {
            if(SMB_ACKPOLL)
            {
               STA = 1;                      
            }
            else
            {
               FAIL = 1;                     
            }                                
         }
         break;

    
      case SMB_MRDB:
         if ( i < SMB_DATA_LEN )             
         {
            *pSMB_DATA_IN = SMB0DAT;         
            pSMB_DATA_IN++;                  
            i++;                             
            ACK = 1;                         
                                             

         }

         if (i == SMB_DATA_LEN)             
         {
            SMB_BUSY = 0;                  
            ACK = 0;                        
            STO = 1;                         
         }

         break;

      default:
         FAIL = 1;                           
                                             
         break;
   }

   if (FAIL)                                 
   {
      SMB0CN &= ~0x40;                       
      SMB0CN |= 0x40;
      SMB_BUSY = 0;                          
   }

   SI=0;                                     
}

/*******************************************************************************
函数功能:25MS后对SMBUS重新初始化
*******************************************************************************/
void Timer3_ISR (void) interrupt 14
{  
   SMB0CN &= ~0x40;                          
   SMB0CN |= 0x40;                          
   TMR3CN &= ~0x80;                          
   

}

⌨️ 快捷键说明

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