原创 NIOS核操作IIC通讯协议

2011-8-6 13:10 2506 3 4 分类: FPGA/CPLD

本程序是操作ADS1110芯片的。

在nios核加SDA和SCL两个IO口,SDA为双向的,SCL为输出的。

在IDE中输入如下代码:

iic.h中的代码:

 

#ifndef IIC_H_
#define IIC_H_


#define OUT    1
#define IN     0
#define AddWr 0x90   //写数据地址,需要参考ADS1110芯片文档
#define AddRd 0x91
#define mode  0x8c
#define time  30

typedef struct{
    void(*write_byte)(void);
    unsigned int(*read_byte)(void);
}IIC;

extern IIC iic;
#endif /*IIC_H_*/

 

iic.c中的代码:

 

#include<stdio.h>
#include<sys/unistd.h>

#include"system.h"
#include"altera_avalon_pio_regs.h"
#include"alt_types.h"
#include"../inc/iic.h"

static alt_u16 read_byte(void);
static void write_byte(void);

IIC iic={
    .write_byte = write_byte,
    .read_byte  = read_byte
};

/*
 *===================FUNCTION======================
 *    NAME: start
 * Description: IIC启动
 * ================================================
*/
static void start(void)
{
    IOWR_ALTERA_AVALON_PIO_DIRECTION(SDA_BASE,OUT);
    IOWR_ALTERA_AVALON_PIO_DATA(SDA_BASE,1);
    IOWR_ALTERA_AVALON_PIO_DATA(SCL_BASE,1);
    usleep(time);
    IOWR_ALTERA_AVALON_PIO_DATA(SDA_BASE,0);
    usleep(time);
    IOWR_ALTERA_AVALON_PIO_DATA(SCL_BASE,0);
    usleep(time);   
}

/*
 * ============FUNCTION==================================
 *        NAME: uart_send_byte
 * Description: IIC停止
*/
static void stop(void)
{
    IOWR_ALTERA_AVALON_PIO_DIRECTION(SDA_BASE,OUT);
    IOWR_ALTERA_AVALON_PIO_DATA(SDA_BASE,0);
    usleep(time);
    IOWR_ALTERA_AVALON_PIO_DATA(SCL_BASE,1);
    usleep(time);
    IOWR_ALTERA_AVALON_PIO_DATA(SDA_BASE,1);
    usleep(time);  
    IOWR_ALTERA_AVALON_PIO_DATA(SCL_BASE,0);
    usleep(time);
}
/*
 * ===FUNCTION=====================================
 *     Name: ack
 * Description: IIC应答
*/
static void ack(void)
{
    alt_u8 tmp,i=0;
   
    IOWR_ALTERA_AVALON_PIO_DATA(SCL_BASE,0);
    IOWR_ALTERA_AVALON_PIO_DIRECTION(SDA_BASE,IN);
    usleep(time);
    IOWR_ALTERA_AVALON_PIO_DATA(SCL_BASE,1);
    usleep(time);
    tmp=IORD_ALTERA_AVALON_PIO_DATA(SDA_BASE);
    while((tmp==1)&&(i<250))
    {
    i++;
    tmp=IORD_ALTERA_AVALON_PIO_DATA(SDA_BASE);
    usleep(time);
    }
    IOWR_ALTERA_AVALON_PIO_DATA(SCL_BASE,0);   
}
/*
 * ===FUNCTION===========================================
 *      Name:  iic_write
 * Description: IIC写一个字节
 * ======================================================
*/
void iic_write(alt_u8 dat)
{
    alt_u8 i,tmp;
   
    IOWR_ALTERA_AVALON_PIO_DIRECTION(SDA_BASE,OUT);
   
    for(i=0;i<8;i++){
        IOWR_ALTERA_AVALON_PIO_DATA(SCL_BASE,0);
        usleep(time);
        tmp = (dat&0x80)?1:0;
        dat<<=1;
        IOWR_ALTERA_AVALON_PIO_DATA(SDA_BASE,tmp);
        usleep(time);
        IOWR_ALTERA_AVALON_PIO_DATA(SCL_BASE,1);
        usleep(time);
    }
    IOWR_ALTERA_AVALON_PIO_DATA(SCL_BASE,0);   
}
/*
 * ===FUNCTION=======================================
 *     Name: read
 * Description: IIC读一个字节
 * ==================================================
*/
static alt_u8 iic_read(void)
{
    alt_u8 i,dat=0;
    IOWR_ALTERA_AVALON_PIO_DIRECTION(SDA_BASE,OUT);
    IOWR_ALTERA_AVALON_PIO_DATA(SDA_BASE,1);
    usleep(time);
    IOWR_ALTERA_AVALON_PIO_DIRECTION(SDA_BASE,IN);
    for(i=0;i<8;i++){
        IOWR_ALTERA_AVALON_PIO_DATA(SCL_BASE,0);
        usleep(time);
        IOWR_ALTERA_AVALON_PIO_DATA(SCL_BASE,1);
        usleep(time);
        dat<<=1;
        dat|=IORD_ALTERA_AVALON_PIO_DATA(SDA_BASE);
        usleep(time);
    }
   
    usleep(30);
   
    return dat;
}

/*
 * ===FUNCTION==========================================
 *     Name: write_byte
 * Description:write a byte to the EEPROM
 * =====================================================
*/
static void write_byte()
{
   start();
   iic_write(AddWr);
   ack();
   iic_write(mode);
   ack();
   stop();
}
/*
 * === FUNCTION=================================
 *       Name: read_byte
 * Description: read a byte from the EEPROM
 * =============================================
*/
static alt_u16 read_byte()
{
    alt_u8 dat_h,dat_l,x;
    alt_u16 dat;
    start();
    iic_write(AddRd);
    ack();   
    dat_h=iic_read();
    ack();
    dat_l=iic_read();
    ack();    
    x=iic_read();
    ack();
    stop();
    dat=(dat_h<<8)|dat_l;
    return dat;
   
}

 

main.c中的代码:

 

#include<unistd.h>
#include"../inc/iic.h"
#include<stdio.h>
#include"alt_types.h"

#define VREF  3293   //基准电压,由四位半的表测得

int main()
{
  alt_u16 temp;
  alt_u8 x,y,z,n;
  printf("\nADS1110\n");
  while(1)
  {
    iic.write_byte();
    usleep(100);
    temp=iic.read_byte();
    temp=VREF*temp/32767;
    x=temp/1000;
    y=temp%1000/100;
    z=temp%1000%100/10;
    n=temp%1000%100%10;
    usleep(50000);
    usleep(50000);
    usleep(50000);
    usleep(50000); 
    usleep(50000);
    usleep(50000);
    usleep(50000);
    usleep(50000);      
    printf("\nThe voltage is %d.%d%d%dV\n",x,y,z,n);
  } 
     return 0;  
}

 

编译后,测试结果如下:

20110806131038001.gif

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户377235 2015-9-1 15:20

谢谢分享,将下面几个ack改为主机应答后,读数据正常 dat_h=iic_read(); ack(); dat_l=iic_read(); ack(); x=iic_read(); ack();

相关推荐阅读
用户343965 2011-06-15 15:42
JTAG下载程序能运行,但是ASP下载,却运行不了
最近,做作品时,想把程序下载到Flash里面去,但是下了好几遍都不行。程序能下载,但是下载完成后,运行起来并不是那么回事。从网上找了一下,发现原来是是自己软件的原因。我用的是Quartus 9.1的,...
用户343965 2011-05-08 16:54
VGA动态显示数字
//VGA displayed//mode 800*600 72Hz//date 2011-05-04 ammodule vga_dis(               //input pins    ...
用户343965 2011-04-18 23:02
一个男人关心的东西 决定了他的层次
  无意中看到了这篇文章,觉得写得很好,就转过来了。无论是男的还是女的,都应该具备吧!                                                一、拥有自信和风...
用户343965 2011-04-15 19:54
努力做到这几点
在成功的时候要学会谦虚在失败的时候要学会坚毅在快乐的时候要学会节制在痛苦的时候要学会忍耐在愤怒的时候要学会冷静在害怕的时候要学会勇敢在焦虑的时候要学会乐观在迷惑的时候要学会分析在犹豫的时候要学会果断在...
用户343965 2011-04-15 16:53
傻孩子,你对我再好,我也不会爱上你
你可能觉得难过,不是,你应该觉得难过。 因为无论你对我怎么好,我都不领情。 我不是看不到,我只是装作看不到。 我根本不想看到。 你觉得自己很喜欢我, 甚至觉得再没有一个人可以像你那么喜欢我。你用尽全力...
EE直播间
更多
我要评论
1
3
关闭 站长推荐上一条 /3 下一条