yao2013lin 发表于 2013-7-7 16:26:38

请教一个avr twi程序的问题

今天上午我用iccv7 for avr写了一个twi总线读写at24c02,记忆开关机的次数,我改了有一个小时都没有把错误改好。
//开机次数的记忆
#include <iom16v.h>
#include <macros.h>
#define ucharunsigned char
#define uintunsigned int
//命令定义
//MT 为主机发送mr 为主机接收
#define START         0X08
#define RE_START      0X10
#define MT_SLA_ACK    0X18
#define MT_SLA_NOACK0X20
#define MT_DATA_ACK   0X28
#define MT_DATA_NOACK 0X30
#define MR_SLA_ACK    0X40
#define MR_SLA_NOACK0X48
#define MR_DATA_ACK   0X50
#define MR_DATA_NOACK 0X58
//前四位与器件地址有关
#define   RD_DEVICE_ADDR 0XA1
#define   WD_DEVICE_ADDR 0XA0

//常用twi操作(主模式写和读)
#define start()(TWCR=(1<<TWINT)|1<<TWSTA)|(1<<TWEN))
#define stop()   (TWCR=(1<<TWINT)|1<<TWEN)|(1<<TWSTO))
#define wait()   {while(!(TWCR&(1<<TWINT)));}
#definetest_ack()(TWSR&0XF8)
#defineset_ack()   (TWSR|=(1<<TWEA))
#defineset_noack() (TWCR=(1<<TWENA))
#definetwi()    (TWCR=(1<<TWINT)|(1<<TWEN))
#definewrite8bit(x) {TWDR=X; TWCR=(1<<TWINT)|(1<<TWEN);}


uchartable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar table2[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
uchar disp={0,0,0,0,0,0,0,0};
void delay(intt)//延时函数
{
int k,j;
for(k=0;k<t;k++)
for(j=0;j<10;j++);
}

void init (void )
{
DDRB=0XFF;   // 端口初始化
PORTB=0X00;

DDRA=0XFF;
PORTA=0;

}

void display(uchar *p)
{
      char i;
      for(i=0;i<8;i++)
      {
      PORTA=table[*p];//段选
      p++;
      PORTB=table2;//位选
      delay(10);
      }
}
   
void twi_init(void)
{
TWBR=0X20;//大于10
TWCR=0X04;//开启twi总线
TWSR=0;//1分频
}


uchariic_write(uchar wadata,uchar addr)
{
start();//开始信号
wait();//等待
if(teset_ack()!=START)//检验twi状态寄存器
return 1;

write8bit(WD_DEVICE_ADDR);//发送器件地址
wait();                   //等待
if(teset_ack()!=MT_SLA_ACK )//检验TWI 状态寄存器,屏蔽预分频位,
//如果状态字不是MT_SLA_ACK 转出错处理
return 1;

write8bit(addr);//写地址
wait();//等待
if(teset_ack()!=MR_DATA_ACK)//检验TWI 状态寄存器,屏蔽预分频器,如
//果状态字不是MT_DATA_ACK 转出错处处理
return 1;

write8bit(wadata);//写数据
wait();//等待
if(teset_ack()!=MR_DATA_ACK)//检验TWI 状态寄存器,屏蔽预分频器,如
//果状态字不是MT_DATA_ACK 转出错处处理
return 1;

stop();//停止信号
return 0;
}
uchar iic_read(uchar addr)
{
uchar temp;
start();//开始信号
wait();//等待
if(teset_ack()!=START)//检验twi状态寄存器
return 1;

write8bit(WD_DEVICE_ADDR);//发送器件地址
wait();                   //等待
if(teset_ack()!=MT_SLA_ACK )//检验TWI 状态寄存器,屏蔽预分频位,
//如果状态字不是MT_SLA_ACK 转出错处理
return 1;

write8bit(addr);//写地址
wait();//等待
if(teset_ack()!=MR_DATA_ACK)//检验TWI 状态寄存器,屏蔽预分频器,如
//果状态字不是MT_DATA_ACK 转出错处处理
return 1;

start();//开始信号
wait();//等待
if(teset_ack()!=RE_START)//检验twi状态寄存器
return 1;

write8bit( RD_DEVICE_ADDR );//发送器件地址
wait();                   //等待
if(teset_ack()!=MR_SLA_ACK )//检验TWI 状态寄存器,屏蔽预分频位,
//如果状态字不是MT_SLA_ACK 转出错处理
return 1;

twi();//重新启动
wait();//等待
if(teset_ack()!=MR_DATA_NOACK )//检验TWI 状态寄存器,屏蔽预分频位,
//如果状态字不是MT_SLA_ACK 转出错处理
return 1;

temp=TWDR;
stop()//停止信号
return temp;
}

void main(void )
{
uchar i;
init();
twi_init();
i=iic_read(0x20);
i++;
disp=i/100;
disp=i%100/10;
disp=i%100%10;
while (iic_write(i,0x20));
while(1)
{
display(disp);
}


}



yao2013lin 发表于 2013-7-7 16:30:36

这个是编译报错的截图

richu 发表于 2013-7-7 16:59:58

1、以下代码少了左括号
#define start()(TWCR=(1<<TWINT)|1<<TWSTA)|(1<<TWEN))
#define stop()   (TWCR=(1<<TWINT)|1<<TWEN)|(1<<TWSTO))
2、#definewrite8bit(x) {TWDR=X; TWCR=(1<<TWINT)|(1<<TWEN);} // x注意大小写
3、宏定义处是#definetest_ack()(TWSR&0XF8)    但函数中写的是teset_ack()

phoebuss 发表于 2013-7-7 17:05:00

额,1个小时都检查不出来...给你改好了,请认真学习一下宏定义还有注意键盘打字的粘连还有分号也别漏...PS:既然用了ACC怎么还用类似于1<<TWINT的表达...//开机次数的记忆
#include <iom16v.h>
#include <macros.h>
#define ucharunsigned char
#define uintunsigned int
//命令定义
//MT 为主机发送mr 为主机接收
#define START         0X08
#define RE_START      0X10
#define MT_SLA_ACK    0X18
#define MT_SLA_NOACK0X20
#define MT_DATA_ACK   0X28
#define MT_DATA_NOACK 0X30
#define MR_SLA_ACK    0X40
#define MR_SLA_NOACK0X48
#define MR_DATA_ACK   0X50
#define MR_DATA_NOACK 0X58
//前四位与器件地址有关
#define   RD_DEVICE_ADDR 0XA1
#define   WD_DEVICE_ADDR 0XA0

//常用twi操作(主模式写和读)
#define start()(TWCR = BIT(TWINT)|BIT(TWSTA)|BIT(TWEN))
#define stop()   (TWCR = BIT(TWINT)|BIT(TWSTO)|BIT(TWEN))
#define wait()   {while(!(TWCR & BIT(TWINT)));}
#defineteset_ack()(TWSR & 0xf8)
#defineset_ack()   (TWSR|=BIT(TWEA))
#defineset_noack() (TWCR=BIT(TWEN))
#definetwi()    (TWCR = BIT(TWINT)|BIT(TWEA)|BIT(TWEN))
#definewrite8bit(x) {TWDR = (x);TWCR = BIT(TWINT)|BIT(TWEN);}


uchartable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar table2[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
uchar disp={0,0,0,0,0,0,0,0};
void delay(intt)//延时函数
{
int k,j;
for(k=0;k<t;k++)
for(j=0;j<10;j++);
}

void init (void )
{
DDRB=0XFF;   // 端口初始化
PORTB=0X00;

DDRA=0XFF;
PORTA=0;

}

void display(uchar *p)
{
      char i;
      for(i=0;i<8;i++)
      {
      PORTA=table[*p];//段选
      p++;
      PORTB=table2;//位选
      delay(10);
      }
}
   
void twi_init(void)
{
TWBR=0X20;//大于10
TWCR=0X04;//开启twi总线
TWSR=0;//1分频
}


uchariic_write(uchar wadata,uchar addr)
{
start();//开始信号
wait();//等待
if(teset_ack()!=START)//检验twi状态寄存器
return 1;

write8bit(WD_DEVICE_ADDR);//发送器件地址
wait();                   //等待
if(teset_ack()!=MT_SLA_ACK )//检验TWI 状态寄存器,屏蔽预分频位,
//如果状态字不是MT_SLA_ACK 转出错处理
return 1;

write8bit(addr);//写地址
wait();//等待
if(teset_ack()!=MR_DATA_ACK)//检验TWI 状态寄存器,屏蔽预分频器,如
//果状态字不是MT_DATA_ACK 转出错处处理
return 1;

write8bit(wadata);//写数据
wait();//等待
if(teset_ack()!=MR_DATA_ACK)//检验TWI 状态寄存器,屏蔽预分频器,如
//果状态字不是MT_DATA_ACK 转出错处处理
return 1;

stop();//停止信号
return 0;
}
uchar iic_read(uchar addr)
{
uchar temp;
start();//开始信号
wait();//等待
if(teset_ack()!=START)//检验twi状态寄存器
return 1;

write8bit(WD_DEVICE_ADDR);//发送器件地址
wait();                   //等待
if(teset_ack()!=MT_SLA_ACK )//检验TWI 状态寄存器,屏蔽预分频位,
//如果状态字不是MT_SLA_ACK 转出错处理
return 1;

write8bit(addr);//写地址
wait();//等待
if(teset_ack()!=MR_DATA_ACK)//检验TWI 状态寄存器,屏蔽预分频器,如
//果状态字不是MT_DATA_ACK 转出错处处理
return 1;

start();//开始信号
wait();//等待
if(teset_ack()!=RE_START)//检验twi状态寄存器
return 1;

write8bit( RD_DEVICE_ADDR );//发送器件地址
wait();                   //等待
if(teset_ack()!=MR_SLA_ACK )//检验TWI 状态寄存器,屏蔽预分频位,
//如果状态字不是MT_SLA_ACK 转出错处理
return 1;

twi();//重新启动
wait();//等待
if(teset_ack()!=MR_DATA_NOACK )//检验TWI 状态寄存器,屏蔽预分频位,
//如果状态字不是MT_SLA_ACK 转出错处理
return 1;

temp=TWDR;
stop();//停止信号
return temp;
}

void main(void )
{
uchar i;
init();
twi_init();
i=iic_read(0x20);
i++;
disp=i/100;
disp=i%100/10;
disp=i%100%10;
while (iic_write(i,0x20));
while(1)
{
display(disp);
}


}

phoebuss 发表于 2013-7-7 17:06:25

richu 发表于 2013-7-7 16:59 static/image/common/back.gif
1、以下代码少了左括号
#define start()(TWCR=(1

还有一个stop()的调用少了分号...

ashaohlt 发表于 2013-7-7 17:55:41

这样没耐心很不好,语法错误都是可以自己处理的。

richu 发表于 2013-7-7 22:16:54

phoebuss 发表于 2013-7-7 17:06 static/image/common/back.gif
还有一个stop()的调用少了分号...

是的,贴出来的代码少了分号,附件中的代码是有这个分号的。

yao2013lin 发表于 2013-7-8 07:52:42

谢谢各位的帮组,我的程序改好了,我还有个疑问,如下图红色框中所示,有的程序编译是2%full,有的是%3full,还有的%6full那个值代表了什么?怎么减小那个值

yao2013lin 发表于 2013-7-8 07:53:57

richu 发表于 2013-7-7 16:59 static/image/common/back.gif
1、以下代码少了左括号
#define start()(TWCR=(1

按照你的意见,程序修改好了。{:handshake:}

yao2013lin 发表于 2013-7-8 07:55:59

phoebuss 发表于 2013-7-7 17:06 static/image/common/back.gif
还有一个stop()的调用少了分号...

检查的很仔细,我改向你好好学习,我觉得你应该写过很多代码。

yao2013lin 发表于 2013-7-8 07:57:08

ashaohlt 发表于 2013-7-7 17:55 static/image/common/back.gif
这样没耐心很不好,语法错误都是可以自己处理的。

嗯,看来写代码得认真点

phoebuss 发表于 2013-7-8 10:55:04

yao2013lin 发表于 2013-7-8 07:55 static/image/common/back.gif
检查的很仔细,我改向你好好学习,我觉得你应该写过很多代码。

我也是随便玩玩写的代码,只是错多了就会注意了...

hyghyg1234 发表于 2013-7-8 12:46:56

phoebuss 发表于 2013-7-7 17:05 static/image/common/back.gif
额,1个小时都检查不出来...给你改好了,请认真学习一下宏定义还有注意键盘打字的粘连还有分号也别漏...PS: ...

代码怎么可以贴出这种效果,记录行数

phoebuss 发表于 2013-7-8 17:49:50

hyghyg1234 发表于 2013-7-8 12:46 static/image/common/back.gif
代码怎么可以贴出这种效果,记录行数

点开高级回复里面有个双尖号图标就是了...
页: [1]
查看完整版本: 请教一个avr twi程序的问题