搜索
bottom↓
回复: 11

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

[复制链接]

出0入0汤圆

发表于 2011-8-1 10:36:09 | 显示全部楼层 |阅读模式
本是新手正在學習AVR,最近在做個多機通信實驗,硬件用兩片M48,想用M48本身自帶的I2C做通信實驗,

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

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

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


                                                          先謝謝了!

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2011-8-1 13:00:23 | 显示全部楼层
用I2C做多机(主)之间的通信比较复杂,用CVAVR中的I2C函数实现比较麻烦,建议使用I2C中断方式。

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

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

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

出0入0汤圆

 楼主| 发表于 2011-8-1 13:10:14 | 显示全部楼层
先谢谢马老师的回复!现在主要就是实现两机的通信,一主,一副,学习的例子也做过不少,加上在网上也潜水许久,这几日在I2C通信

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

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

出0入0汤圆

发表于 2011-8-1 13:43:22 | 显示全部楼层
新书刚出印刷厂,这个星期开始陆续发到各个书店(当然,这些书店要定)

出0入0汤圆

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

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

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

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

出0入0汤圆

 楼主| 发表于 2011-8-1 14:03:05 | 显示全部楼层
多謝馬老師的講解,請問下可發個CVAVR環境中使用M48的通信程序,我在對應相關的資料學習下!  謝謝!

出0入0汤圆

发表于 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[8], outbox[8], news[8];                 //收件箱/发件箱/新信息
unsigned char twi_mode;                                     //主机发送器=10/主机接收器=20/从机发送器=30/从机接收器=40
unsigned char n=0, x=0;                                     //需要传输的字节的个数 x
unsigned char address_device, address_paga;                 //器件地址/器件内部的页地址

interrupt [TWI] 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[n];                                  //继续加载数据
      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[n]=twi_datas;                                    //保存接收到的数据
      if(n+2<x) twi_data_run_ack; else twi_data_run;        //接收到倒数第二个数据时就取消接收应答并继续接收
      n++;
      break;
    }
   
    case 0x58:                                              //接收到数据 NO ACK 已返回
    {
      news[n]=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[0]=1; outbox[1]=2; outbox[2]=3; outbox[3]=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[n]=news[n]; lcd_puthex(inbox[n]);}
    lcd_putchar(' '); lcd_puthex(TWCR);
   
    while(1);        
  };
}

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

出0入0汤圆

发表于 2011-8-2 14:02:33 | 显示全部楼层
程序运行结果如下图


(原文件名:捕获2.JPG)

出0入0汤圆

发表于 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写的代码,可以参考。

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

出0入0汤圆

 楼主| 发表于 2011-8-2 20:05:52 | 显示全部楼层
回复【6楼】panxiaoyi 啊艺
-----------------------------------------------------------------------

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


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

出0入0汤圆

 楼主| 发表于 2011-8-2 20:11:06 | 显示全部楼层
回复【8楼】machao
-----------------------------------------------------------------------

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

出0入0汤圆

 楼主| 发表于 2011-8-5 15:07:28 | 显示全部楼层
今天書到了,大概看了下書,是2010年7月第四次印刷的,辛苦了馬老師。剛好這幾天有多余的時間好好的拜讀!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 18:03

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表