yanzaihong 发表于 2011-8-1 10:36:09

請教馬老師在CVAVR環境中的I2C通信問題

本是新手正在學習AVR,最近在做個多機通信實驗,硬件用兩片M48,想用M48本身自帶的I2C做通信實驗,

板子是自己用洞洞板搭建,編譯環境是CVAVR,在網上潛水多日,無解~~想請教馬老師及各位高手以下問題,請賜教。

1,在CVAVR環境和函數中給出“讀”和“寫”。請問可直接用在I2C通信,可以嗎?還煩請詳細解說下,謝謝!

2,最好有實驗的程序代碼,加講解,這樣理解起來快些,


                                                          先謝謝了!

machao 发表于 2011-8-1 13:00:23

用I2C做多机(主)之间的通信比较复杂,用CVAVR中的I2C函数实现比较麻烦,建议使用I2C中断方式。

如果只是使用2片M48,并且规定了其中一片肯定为主,另一片为副,用CVAVR中的I2C函数实现还是方便的。

具体的参考代码请下载我编写教程配备光盘资料中的AVR311和AVR315。

另外,你说是新手,不知道“新”的成色为几分。太“新”的话还是应该先从简单的学起。没有一定的基础和积累,上面给出的2个例子你可能也看不明白的。

yanzaihong 发表于 2011-8-1 13:10:14

先谢谢马老师的回复!现在主要就是实现两机的通信,一主,一副,学习的例子也做过不少,加上在网上也潜水许久,这几日在I2C通信

上纠结了,想请问马老师多多指引才是!

还想咨询下马老师,你的新书在那些书店均有出售。(找了好久才看到有第一版的:《 AVR单片机嵌入式系统原理与应用实践 》)

machao 发表于 2011-8-1 13:43:22

新书刚出印刷厂,这个星期开始陆续发到各个书店(当然,这些书店要定)

machao 发表于 2011-8-1 13:49:07

回复【2楼】yanzaihong
先谢谢马老师的回复!现在主要就是实现两机的通信,一主,一副,学习的例子也做过不少,加上在网上也潜水许久,这几日在i2c通信
上纠结了,想请问马老师多多指引才是!
还想咨询下马老师,你的新书在那些书店均有出售。(找了好久才看到有第一版的:《 avr单片机嵌入式系统原理与应用实践 》)
-----------------------------------------------------------------------

两机通信?!从专业角度看就是模糊的说法。

是两个都是I2C总线上的主机,还是肯定一个只能是主,另一个肯定是副。这个是不同的,实现的难度大不同。

前者需要考虑总线仲裁的!后者不需要,容易多了。

yanzaihong 发表于 2011-8-1 14:03:05

多謝馬老師的講解,請問下可發個CVAVR環境中使用M48的通信程序,我在對應相關的資料學習下!謝謝!

panxiaoyi 发表于 2011-8-2 13:53:50

我有个简单的例子,不知道是否可以帮上忙

/*****************************************************
CodeWizardAVR V1.25.9 Professional
Chip type         : ATmega48
Clock frequency   : 8.000000 MHz
Memory model      : Small
External SRAM size: 0
Data Stack size   : 128
*****************************************************/
// TWCR   寄存器说明
// Bit 7 – TWINT: TWI 中断标志
// Bit 6 – TWEA: 使能TWI 应答
// Bit 5 – TWSTA: TWI START 状态位
// Bit 4 – TWSTO: TWI STOP 状态位
// Bit 3 – TWWC: TWI 写冲突标志
// Bit 2 – TWEN: TWI 使能
// Bit 1 – Res: 保留
// Bit 0 – TWIE: TWI 中断使能

#include <mega48.h>
#include <delay.h>
#include <nokia3310.h>

#define twi_start            TWCR=0b10100101;               //主机发出start信号
#define twi_data_run         TWCR=0b10000101;               //清除中断.启动.停止的标记/启动主机数据收或发
#define twi_data_run_ack   TWCR=0b11000101;               //清除中断.启动.停止的标记/启动主机数据收或发/应答使能
#define twi_stop             TWCR=0b11010101;               //主机停止/释放总线/TWI就绪
#define twi_status         TWSR                           //TWI运行状态
#define twi_datas            TWDR

unsigned char inbox, outbox, news;               //收件箱/发件箱/新信息
unsigned char twi_mode;                                     //主机发送器=10/主机接收器=20/从机发送器=30/从机接收器=40
unsigned char n=0, x=0;                                     //需要传输的字节的个数 x
unsigned char address_device, address_paga;               //器件地址/器件内部的页地址

interrupt void twi_isr(void)
{
lcd_puthex(twi_status);                                 //监视TWI运行状态
   
switch(twi_status)
{
    case 0x08:                                              //start信号已发送
    {
      twi_datas=address_device+0;                           //器件地址+发送模式(SLA+W)
      twi_data_run;                                       //传输数据
      break;                                                
    }
   
    case 0x10:                                              //重复start信号已发送
    {
      twi_datas=address_device+1;                           //器件地址+接收模式(SLA+R)
      twi_data_run;                                       //传输数据
      break;
    }
         
    case 0x18:                                              //SLA+W已发送,接收到ACK
    {
      n=0;                                                //计数复位
      twi_datas=address_paga;                               //页地址
      twi_data_run;                                       //传输数据
      break;
    }
   
    case 0x28:                                              //数据已发送,接收到ACK
    {
      if(twi_mode==20) {twi_start; break;}                  //再次发送start信号
      if(n>=x) {twi_stop; break;}                           //数据发送完毕就发送stop信号
      twi_datas=outbox;                                  //继续加载数据
      twi_data_run;
      n++;
      break;
    }
      
    case 0x40:                                              //SLA+R已发送,接收到ACK
    {
      n=0;                                                //计数复位
      if(x>1)twi_data_run_ack; else twi_data_run;         //如果主机只接收一个数据就不需要返回ack信号
      break;
    }
      
    case 0x50:                                              //接收到数据 ACK 已返回(主机返回应答ACK)
    {
      news=twi_datas;                                    //保存接收到的数据
      if(n+2<x) twi_data_run_ack; else twi_data_run;      //接收到倒数第二个数据时就取消接收应答并继续接收
      n++;
      break;
    }
   
    case 0x58:                                              //接收到数据 NO ACK 已返回
    {
      news=twi_datas;
      twi_stop;
      break;
    }
   
    default:
    {      
      twi_stop;
      break;
    }
}
}

//*******************************************************************************************************************
   
void main(void)
{
delay_ms(10);
lcd_init();
lcd_cls();
TWBR=32;                                                //8MHz/(16+2*32)=100KHz   
#asm("sei")                                             //打开全局中断
while (1)
{
    //写数组到AT24C02的指定页
    lcd_gotoxy(0,0);
    twi_mode=10; x=4;                                       //主机:发送模式/需要发送的字节个数(不含地址和页2个字节)
    address_device=160; address_paga=0;                     //器件地址和页地址
    outbox=1; outbox=2; outbox=3; outbox=4;   //更新发件箱的数据
    twi_start;                                              //主机发送start信号
    delay_ms(10);
    lcd_puthex(twi_status);
   
    //连续读AT24C02指定页地址的数组
    lcd_gotoxy(0,2);
    twi_mode=20; x=5;                                       //主机:接收模式/需要接收的字节个数(不含地址和页2个字节)
    address_device=160; address_paga=0;                     //器件地址和页地址
    twi_start;
    delay_ms(10);
    lcd_puthex(twi_status);
   
    //将新信息复制到收件箱并显示
    lcd_gotoxy(0,5);
    for(n=0;n<x;n++) {inbox=news; lcd_puthex(inbox);}
    lcd_putchar(' '); lcd_puthex(TWCR);
   
    while(1);      
};
}

点击此处下载 ourdev_663552UERRDK.rar(文件大小:47K) (原文件名:M48读写AT24C02 001.rar)

panxiaoyi 发表于 2011-8-2 14:02:33

程序运行结果如下图

http://cache.amobbs.com/bbs_upload782111/files_43/ourdev_663554XVA3M8.JPG
(原文件名:捕获2.JPG)

machao 发表于 2011-8-2 14:25:09

楼上只是典型的单主I2C应用,且从机芯片本身协议已经规定的。太普通了。

LZ是说两片M48通过I2C通信,如果:

1。规定一个M48为主,另一个为从的话,需要自己制订相应的I2C命令协议,需要编写2个不同的软件,分别运行在2片M48上。
2。如果两个M48都可能为主(主动发起一次通信过程),那么也需要自己制订相应的I2C命令协议,而且还要考虑I2C总线仲裁的处理,更复杂些。
所以,不要以为会操作什么24CXX,就认为真正掌握了I2C了,还差的远呢。

=================
LZ:

我在1楼已经给出了参考的资料,在我编写的教程光盘中有,也可以到ATMEL公司站上下载,里面有AVR作为主机和从机的例子和代码,尽管不是CVAVR环境下的,但总是用C写的代码,可以参考。

没有人送现成的代码东西给你,能给你这样具体思路和提示已经是少见的情况了,省下的需要自己努力。

yanzaihong 发表于 2011-8-2 20:05:52

回复【6楼】panxiaoyi 啊艺
-----------------------------------------------------------------------

先謝謝你的回復!以前在你那買過一套小的M48-M16的小實驗板,也是從那時候愛上了AVR ,這幾天正在努力的看相關資料,及編寫程序實驗,希望早點能調試OK,


可一用在你以前做的帶24C02的M48板子上嗎!

yanzaihong 发表于 2011-8-2 20:11:06

回复【8楼】machao
-----------------------------------------------------------------------

前幾天買了本馬老師的《AVR单片机嵌入式系统原理与应用实践》第一版的書,明天到,要潛心修煉, 期望早日調試通過!

yanzaihong 发表于 2011-8-5 15:07:28

今天書到了,大概看了下書,是2010年7月第四次印刷的,辛苦了馬老師。剛好這幾天有多余的時間好好的拜讀!
页: [1]
查看完整版本: 請教馬老師在CVAVR環境中的I2C通信問題