msp430——软件模拟II2C实例



运行代码  复制代码
  1.  
  2. #include <msp430x22x4.h>  
  3. #define   SDA              BIT1  
  4. #define   SCL              BIT2  
  5.      
  6. #define  SEG_A  0xA0   //0x0200---0x027F    
  7. #define  SEG_B  0xB0   //0x0280---0x02FF  
  8. #define  SEG_C  0xC0   //0x0300---0x037F  
  9.  
  10. //0x0380---0x0400  
  11. __no_init char wokao@0x243;  
  12. //=============================  
  13.  char *send_ptr;  
  14.  char  DEVICE_ADR=0;  
  15.  char WORD_ADR=0;  
  16.  char  REC_DATA=0;  
  17.  char START_flag = 0;  
  18.  char STOP_flag = 0;  
  19.  char PreState = 0;  
  20.  char NowState = 0;  
  21. //*********************函数声明*************************************  
  22. void ACK(void);  
  23.  
  24. //****************************************************************  
  25. void main( void )  
  26. {  
  27.   // Stop watchdog timer to prevent time out reset  
  28.   WDTCTL = WDTPW + WDTHOLD;  
  29.    
  30.   //======================MCLK=16MHz=====================================  
  31.   DCOCTL = CALDCO_16MHZ;  
  32.   BCSCTL1 = CALBC1_16MHZ;    //MCLK=DCO=16MHz  
  33.  P3DIR &= ~(SDA+SCL);  
  34.   while(1)  
  35.   {  
  36.     NN=10;  
  37.     PreState = READ_SDA;  
  38.     while(READ_SCL && NN--)  
  39.     {      
  40.       NowState = READ_SDA;  
  41.       if(PreState && !NowState)  
  42.       {  
  43.         START_flag = 1;  
  44.         _DINT();  
  45.       }  
  46.       if(!PreState && NowState)  
  47.       {  
  48.         STOP_flag = 1;  
  49.         _EINT();  
  50.       }    
  51.       PreState = NowState;  
  52.       if(START_flag)  
  53.       {  
  54.         START_flag=0;  
  55.         while(READ_SCL);          //START时的SCL高电平状态就等待  
  56.         for(gg=8;gg>0;gg--)       //接收器件地址  
  57.         {  
  58.           while(!READ_SCL);       //SCL低电平状态就等待  
  59.            
  60.           DEVICE_ADR<<=1;  
  61.           if(READ_SDA)            //数据的第一个CLK高电平来临  
  62.             DEVICE_ADR |= 0x01;  
  63.            
  64.           while(READ_SCL);        //SCL高电平状态就等待  
  65.         }  
  66.         ACK();                    //对设备地址ACK应答信  
  67.         //-----------以上收到了设备地址,并知晓主机要对从机进行读还是写操作---  
  68.           
  69.         for(gg=8;gg>0;gg--)       //接收内存单元地址  
  70.         {  
  71.           while(!READ_SCL);  
  72.            
  73.           WORD_ADR<<=1;  
  74.           if(READ_SDA)  
  75.             WORD_ADR |= 0x01;  
  76.            
  77.           while(READ_SCL);  
  78.         }      
  79.         //-----------以上就已经接收到内存单元地址------------  
  80.         ACK();                  //对内存单元ACK应答信号  
  81.           
  82.           
  83.         if(DEVICE_ADR & 0x01)     //从机发数据给主机  R/W=1  
  84.         {  
  85.           if(DEVICE_ADR==SEG_A+0x01)  
  86.           {  
  87.             send_ptr =(char*)(0x0200 + WORD_ADR);  
  88.           }  
  89.           else if(DEVICE_ADR==SEG_B+0x01)  
  90.           {  
  91.             send_ptr =(char*)(0x0280 + WORD_ADR);  
  92.           }  
  93.           else if(DEVICE_ADR==SEG_C+0x01)  
  94.           {  
  95.             send_ptr =(char*)(0x0300 + WORD_ADR);  
  96.           }  
  97.            
  98.           //--------以上是判断出为主机读从机,要把要读的地址单元赋给指针---  
  99.            
  100.           for(gg=8;gg>0;gg--)  
  101.           {  
  102.             while(!READ_SCL);  
  103.             if( *send_ptr & 0x80)  
  104.               _NOP();  
  105.             else  
  106.             {  
  107.               P3DIR |= SDA;     //输出0  
  108.             }  
  109.             while(READ_SCL);    //SCL为1,就保持SDA输出不变  
  110.             P3DIR &= ~SDA;      //SCL为0,就把SDA从新切换到接收状态  
  111.             *send_ptr <<=1;  
  112.           }  
  113.           ACK();                //从机数据发送完毕,应答信号  
  114.           _NOP();  
  115.           //------------------以上是从机发数据给主机-----------------  
  116.         }  
  117.         else  //主机写从机  R/W=0  
  118.         {  
  119.           for(gg=8;gg>0;gg--)     //接收主机要写到该器件内存单元的数据  
  120.           {  
  121.             while(!READ_SCL);  
  122.              
  123.             REC_DATA <<=1;  
  124.             if(READ_SDA)  
  125.               REC_DATA |= 0x01;  
  126.              
  127.             while(READ_SCL);  
  128.           }  
  129.           if(DEVICE_ADR==SEG_A)  
  130.           {  
  131.             send_ptr =(char*)(0x0200 + WORD_ADR);  
  132.             *send_ptr = REC_DATA;  
  133.           }  
  134.           else if(DEVICE_ADR==SEG_B)  
  135.           {  
  136.             send_ptr =(char*)(0x0280 + WORD_ADR);  
  137.             *send_ptr = REC_DATA;  
  138.           }  
  139.           else if(DEVICE_ADR==SEG_C)  
  140.           {  
  141.             send_ptr =(char*)(0x0300 + WORD_ADR);  
  142.             *send_ptr = REC_DATA;  
  143.           }  
  144.           ACK();    
  145.           _NOP();  
  146.           while(!READ_SCL);  
  147.         }  
  148.       }// if(START_flag)  
  149.        
  150.     }//while(NN--)  
  151.     _EINT();  
  152.     _NOP();  
  153.   }//while(1)  
  154. }  
  155. //****************************************************  
  156. void ACK(void)  
  157. {  
  158.   // while(READ_SCL);  
  159.   while(!READ_SCL);  
  160.   P3DIR |= SDA;        //第9个CLK变高的情况下,SDA输出0  
  161.   while(READ_SCL);    
  162.   P3DIR &= ~SDA;       //第9个CLK变低的情况下,SDA输出1  
  163. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值