本程序是操作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;
}
编译后,测试结果如下:
用户377235 2015-9-1 15:20
谢谢分享,将下面几个ack改为主机应答后,读数据正常 dat_h=iic_read(); ack(); dat_l=iic_read(); ack(); x=iic_read(); ack();