| 
 
| 本帖最后由 denvice 于 2011-7-13 12:11 编辑 
 看多了大家奉献的帖子,这里我也奉献一帖,虽然新唐单片机的IIC够多,但是我实在是无聊呵呵写了一个GPIO模拟IIC的程序,和大家一起来学习学习。
 /************************************
 函数功能:通过PA.0,PA.2向2404写入和
 读出单字节数据。写入以后将数据读出来,
 如果写进去的数据和读出来的数据相等,
 则让PB.0的LED闪烁起来
 *************************************/
 #include <stdio.h>
 #include "NUC1xx.h"
 #include "DrvGPIO.h"
 #include "DrvSYS.h"
 
 void start(void) //起始信号
 {
 DrvGPIO_SetBit(E_GPA, 0);         //sda=1
 DrvSYS_Delay(5);                    //延时5us
 DrvGPIO_SetBit(E_GPA, 2);          //scl=1
 DrvSYS_Delay(5);                         //延时5us
 DrvGPIO_ClrBit(E_GPA, 0);          //sda=0
 DrvSYS_Delay(5);                           //延时5us
 }
 
 void stop(void) //停止信号
 {
 DrvGPIO_ClrBit(E_GPA, 0);         //sda=0
 DrvSYS_Delay(5);                           //延时5us
 DrvGPIO_SetBit(E_GPA, 2);          //scl=1
 DrvSYS_Delay(5);                           //延时5us
 DrvGPIO_SetBit(E_GPA, 0);          //sda=1
 DrvSYS_Delay(5);                            //延时5us
 }
 
 void waitack(void)//等待应答信号
 {
 int i;
 DrvGPIO_SetBit(E_GPA, 2);          //scl=1
 DrvSYS_Delay(5);                            //延时5us
 DrvGPIO_Open(E_GPA,0, E_IO_INPUT); //将sda置为输入
 while(DrvGPIO_GetBit(E_GPA,0)&&i<255)
 i++;
 DrvGPIO_Open(E_GPA,0, E_IO_OUTPUT);//将sda置为输出
 DrvGPIO_ClrBit(E_GPA, 2);          //scl=0
 DrvSYS_Delay(5);                                 //延时5us
 
 }
 
 void noack(void) //非应答信号
 {
 DrvGPIO_SetBit(E_GPA, 0);          //sda=1
 DrvSYS_Delay(5);                            //延时5us
 DrvGPIO_SetBit(E_GPA, 2);          //scl=1
 DrvSYS_Delay(5);                            //延时5us
 DrvGPIO_ClrBit(E_GPA, 2);          //scl=0
 DrvSYS_Delay(5);                            //延时5us
 DrvGPIO_ClrBit(E_GPA, 0);         //sda=0
 DrvSYS_Delay(5);
 }
 
 void ack(void)          //应答信号
 {
 DrvGPIO_ClrBit(E_GPA, 0);         //sda=0
 DrvSYS_Delay(5);                            //延时5us
 DrvGPIO_SetBit(E_GPA, 2);          //scl=1
 DrvSYS_Delay(5);                             //延时5us
 DrvGPIO_ClrBit(E_GPA, 2);          //scl=0
 DrvSYS_Delay(5);                                 //延时5us
 DrvGPIO_SetBit(E_GPA, 0);          //sda=1
 DrvSYS_Delay(5);
 
 }
 
 
 void write8bit(int input)         //写一个字节数据
 {
 int i;
 DrvGPIO_ClrBit(E_GPA, 2);          //scl=0
 DrvSYS_Delay(5);                           //延时5us
 for(i=0;i<8;i++)
 {
 if((input<<i)&0x80)
 DrvGPIO_SetBit(E_GPA, 0);          //sda=1
 else
 DrvGPIO_ClrBit(E_GPA, 0);         //sda=0
 DrvSYS_Delay(5);                            //延时5us
 DrvGPIO_SetBit(E_GPA, 2);          //scl=1
 DrvSYS_Delay(5);                                   //延时5us
 DrvGPIO_ClrBit(E_GPA, 2);          //scl=0
 DrvSYS_Delay(5);
 
 }
 DrvGPIO_ClrBit(E_GPA, 2);          //scl=0
 DrvSYS_Delay(5);                            //延时5us
 DrvGPIO_SetBit(E_GPA, 0);         //sda=1
 DrvSYS_Delay(5);                            //延时5us
 }
 
 int read8bit(void)                   //读一个字节数据
 {
 int temp,rbyte=0;
 
 DrvGPIO_Open(E_GPA,0, E_IO_INPUT); //将sda置为输入
 for(temp=0;temp<8;temp++)
 {
 rbyte=rbyte<<1;
 if(DrvGPIO_GetBit(E_GPA,0))
 rbyte=rbyte|0x01;                           //延时5us
 DrvGPIO_SetBit(E_GPA, 2);          //scl=1
 DrvSYS_Delay(5);                                 //延时5us
 DrvGPIO_ClrBit(E_GPA, 2);          //scl=0
 DrvSYS_Delay(5);
 }
 DrvGPIO_Open(E_GPA,0, E_IO_OUTPUT);//将sda置为输出
 DrvGPIO_ClrBit(E_GPA, 2);          //scl=0 //调试连续读操作时发现不能将SCL拉高读完一次数据后
 DrvGPIO_SetBit(E_GPA, 0);          //sda=1
 DrvSYS_Delay(5);                           //延时5us
 return(rbyte);
 }
 
 void init(void)
 {
 DrvGPIO_SetBit(E_GPA, 0);          //sda=1
 DrvGPIO_SetBit(E_GPA, 2);          //scl=1
 }
 
 void writebyte(int add,int dat)          //将一个字节数据dat写入某个地址add
 {
 start();
 if(add>=256)                                                //2402的地址是A0,但是2404的高256位地址为A2
 write8bit(0xA2);
 else
 write8bit(0xA0);
 
 waitack();
 
 if(add>=256)
 write8bit(add-256);
 else
 write8bit(add);
 waitack();
 
 write8bit(dat);
 waitack();
 
 stop();
 }
 
 int readbyte(char add)
 {
 int byte;
 
 start();
 if(add>=256)
 write8bit(0xA2);
 else
 write8bit(0xA0);
 waitack();
 
 if(add>=256)
 write8bit(add-256);
 else
 write8bit(add);
 waitack();
 
 start();
 if(add<256)
 write8bit(0xA1);
 else
 write8bit(0xA3);
 waitack();
 
 byte=read8bit();
 noack();
 stop();
 return byte;
 }
 
 void delay_loop(void)
 {
 uint32_t j;
 for(j=0;j<60000;j++);
 for(j=0;j<60000;j++);
 for(j=0;j<60000;j++);
 for(j=0;j<60000;j++);
 }
 
 int main()
 {
 int a;
 UNLOCKREG(x);    //解锁
 DrvSYS_SetOscCtrl(E_SYS_XTL12M, 1);          //配置晶振
 DrvSYS_Delay(5000);
 LOCKREG(x);
 
 
 DrvGPIO_Open(E_GPA, 0, E_IO_OUTPUT);//将管脚配置为输出
 DrvGPIO_Open(E_GPA, 2, E_IO_OUTPUT);//
 DrvGPIO_Open(E_GPA, 4, E_IO_OUTPUT);//
 DrvGPIO_Open(E_GPB, 0, E_IO_OUTPUT);//
 writebyte(20,3);     //将3写入2402的地址20的寄存器中
 delay_loop();
 a=readbyte(20);                 //读取2402地址20处的数据
 
 while(1)
 {
 if(a==3)
 {
 DrvGPIO_ClrBit(E_GPB,0);
 delay_loop();
 DrvGPIO_SetBit(E_GPB,0);
 delay_loop();
 
 }
 }
 }
 | 
 
×本帖子中包含更多资源您需要 登录 才可以下载或查看,没有账号?注册 
  |