第十章 I2C接口实验
注:在AT91SAM7Sxx系列中,I2C称作TWI。
一.实验目的
能够正确读写I2C接口芯片存储器(24C02),即写入24C02的数据与读出来的数据相同。
二.实验程序和参数设置
1> 连接器选项设置和启动代码与上一个实验相同
2> I2C驱动程序
ATMEL官方网站上有这方便的参考程序。主要由I2C接口的初始化、I2C的读和写三部分组成。
#i nclude "board.h"
#i nclude "twi.h"
void InitTwi(void)
{ AT91F_TWI_CfgPIO();      //配置TWI的TWD和TWCK管脚 AT91F_PIO_CfgOpendrain(AT91C_BASE_PIOA,(unsigned int)AT91C_PA3_TWD);  
AT91F_TWI_CfgPMC ();      //使能TWI外围时钟
AT91F_TWI_Configure (AT91C_BASE_TWI);  //将TWI设置成主模式
AT91F_SetTwiClock(AT91C_BASE_TWI);   //计算、设置时钟发生寄存器
}
//*----------------------------------------------------------------------------
//* \fn    AT91F_SetTwiClock
//*计算、设置TWI时钟发生寄存器
//*----------------------------------------------------------------------------
void AT91F_SetTwiClock(const AT91PS_TWI pTwi)
{ int sclock;
sclock = (10*MCK /AT91C_TWI_CLOCK);
sclock = (MCK /AT91C_TWI_CLOCK);
if (sclock % 10 >= 5)
  sclock = (sclock /10) - 5;
else
sclock = (sclock /10)- 6;
sclock = (sclock + (4 - sclock %4)) >> 2; // div 4
    pTwi->TWI_CWGR = 0x00010000 | sclock | (sclock
}
//*----------------------------------------------------------------------------
//* \fn    AT91F_TWI_Write
//* \brief Send n bytes to a slave device
//*----------------------------------------------------------------------------
int AT91F_TWI_Write(const AT91PS_TWI pTwi ,int address, char *data2send, int size)
{ unsigned int status;
pTwi->TWI_MMR=(AT91C_EEPROM_I2C_ADDRESS| AT91C_TWI_IADRSZ_1_BYTE ) & ~AT91C_TWI_MREAD;  
pTwi->TWI_IADR = address; // Set TWI Internal Address Register
status = pTwi->TWI_SR;
pTwi->TWI_THR = *(data2send++);
pTwi->TWI_CR = AT91C_TWI_START;
while (size-- >1){  // Wait THR Holding register to be empty
  while (!(pTwi->TWI_SR & AT91C_TWI_TXRDY));
  pTwi->TWI_THR = *(data2send++);// Send first byte
}
pTwi->TWI_CR = AT91C_TWI_STOP;   
status = pTwi->TWI_SR;
while (!(pTwi->TWI_SR & AT91C_TWI_TXCOMP)); // Wait transfer is finished   
return AT91C_EEPROM_WRITE_OK;
}
//*----------------------------------------------------------------------------
//* \fn    AT91F_TWI_Read
//* \brief Read n bytes from a slave device
//*----------------------------------------------------------------------------
int AT91F_TWI_Read(const AT91PS_TWI pTwi , int address, char *data2rec, int size)
{ unsigned int status;  
pTwi->TWI_MMR=(AT91C_EEPROM_I2C_ADDRESS|AT91C_TWI_IADRSZ_1_BYTE) | AT91C_TWI_MREAD; // Set the TWI Master Mode Register
pTwi->TWI_IADR = address; // Set TWI Internal Address Register
pTwi->TWI_CR = AT91C_TWI_START; // Start transfer
status = pTwi->TWI_SR;
while (size-- >1){ // Wait RHR Holding register is full
  while (!(pTwi->TWI_SR & AT91C_TWI_RXRDY));  
  *(data2rec++) = pTwi->TWI_RHR; // Read byte
}
pTwi->TWI_CR = AT91C_TWI_STOP;
status = pTwi->TWI_SR;
    while (!(pTwi->TWI_SR & AT91C_TWI_TXCOMP)); // Wait transfer is finished
*data2rec = pTwi->TWI_RHR; // Read last byte
return AT91C_EEPROM_READ_OK;
}
3> 主函数
在主函数中,首先调用了TWI的初始化函数,然后进入了超级大循环。在每次写和读时,都对它们的数据缓冲区进行初始化,以查看读、写的正确性。
#i nclude "board.h"
#i nclude "twi.h"
int main ( void )
{ int loop,index=0;
char Wri_data[16], Red_data[16];  //定义写和读缓冲区
InitTwi();      //TWI初始化
while (1)
{ for (loop = 0; loop 初始化写和读缓冲区的内容
   data1[loop] = loop + index;
   data2[loop] = 0;
  }
  index += 1;
  AT91F_TWI_Write(AT91C_BASE_TWI, 0x0, Wri_data, EEP_RW_CHK_CNT);//写
  AT91F_TWI_Read(AT91C_BASE_TWI, 0x0, Red_data, EEP_RW_CHK_CNT);//读
}//用单步调试,可比较Wri_data[16]Red_data[16]的内容来判断读写是否正确。
}
三.出现的问题与解决方法
            1> 无论写入任何数据,读出来都是同样的数,表明数据没有写入(在调试时对其写操作,器件没有产生应答)。

原因是24C02的写保护管脚没有接地,内部的数据被写保护了。注意:有些厂家的EEROM的该管脚处于悬空时为不保护状态,而有些厂家的EEROM会处于保护状态,因此在用之前一定要仔细阅读厂家的数据手册,或不要将该脚悬空。
2> 对24WC02写的数据和读的数据不一样。
原因是I2C的时钟太快。在本实验程序中,可以减少twi.h中的AT91C_TWI_CLOCK常量的数值。或者直接在程序中修改TWI时钟波形发生寄存器TWI_CWGR。
3> 当写入16字节数据,再读出16字节数据时,最后一个字节总为0。
原因是TWI Master Mode Register的IADRSZ(器件内部地址长度)设成了两个字节(Two-byte),要将改成一个字节(One-byte)。

转载于:https://blog.51cto.com/sunnydragon/203198

ARM入门笔记(9)相关推荐

  1. 网上下的--ARM入门笔记

    简单的介绍 打今天起菜鸟的ARM笔记算是开张了,也算给我的这些笔记找个存的地方. 为什么要发布出来?也许是大家感兴趣的,其实这些笔记之所以叫笔记而不是文章,是因为它们完全是本人个人学习经验的总结,而这 ...

  2. ARM入门笔记(7)

    串口DMA控制实验 一.背景 DMA是Direct Memory Access的缩写,即"存储器直接访问".它是指一种高速的数据传输操作,允许在外部设备和存储器之间直接读写数据,即 ...

  3. 嵌入式OS入门笔记-以RTX为案例:二.快速移植到RTX

    嵌入式OS入门笔记-以RTX为案例:二.快速移植到RTX 本篇笔记将简单介绍RTX,包括基本架构,如何在Keil中配置.需要安装ARM-MDK和一块硬件板,笔记以STM32F4Discovery为例子 ...

  4. 嵌入式OS入门笔记-以RTX为案例:一.简介

    嵌入式OS入门笔记-以RTX为案例:一.简介 最近在做OS相关的项目,一方面涉及到大量(通用)操作系统的概念和理解,另一方面要深入到一个小实时操作系统的源代码中,并在此操作系统上开发应用.虽然说内容上 ...

  5. RISC-V入门笔记(新手必看!)

    目录 什么是RISC-V RISC-V 发展 RISC-V指令集 RISC-V特权架构 RISC-V通用寄存器 RISC-V CSR寄存器 M模式CSR寄存器 S模式CSR寄存器 总结 笔者学习RIS ...

  6. 【S32K】S32K144入门笔记(1) 从零开始进行开发环境搭建

    0.目录 文章目录 0.目录 1. 起因 2. 开发环境 2.1 软件开发环境选择 2.2 S32DS 2.2.1 下载&安装 2.2.2 Demo工程 2.3 硬件开发板选择 2.3.1 硬 ...

  7. 【S32K】S32K144入门笔记(2) Can(can_pal组件)

    0. 引言 真没想到距离写第一篇S32K144入门笔记(1) 从零开始进行开发环境搭建已经过去了半年. 当时是项目紧逼,20天之前要把这个片子的大部分外设跑起来,做好BOOT+APP架构,在十一之前出 ...

  8. Android Studio 基础入门笔记

    Android Studio 基础入门笔记 Android Studio 基础入门笔记 为什么选择使用 Android Studio 而不是EclipseADT 安卓配置JDK AS如何更新 常规的 ...

  9. vue router 入门笔记

    vue router 入门笔记 tips: components优先级大于component,即当一个route对象里同时配置了component和components时component视为无效 即 ...

最新文章

  1. poj2356(抽屉原理)
  2. 小波去噪MATLAB代码
  3. from mysql_MySQL的FROM
  4. shell编程之case语句及函数
  5. (转)UITableViewCell复用问题
  6. 过气旗舰不如?刘作虎确认一加新机:比一加7 Pro更超值
  7. openwrt uci
  8. vue.js环境部署
  9. ABAP字符串的加密与解密
  10. 靠播放业务吃不饱?音乐流媒体纷纷“加电商”卖周边
  11. JQuery+div+css实现无限级联树
  12. 简单的了解下前端路由 hash 与 history 差异
  13. Electron 打包时下载 xxx-electron-v1.6.8-arch-x64.zip 文件出错
  14. html微博登录代码,微博第三方登陆js实现
  15. VMWARE虚拟机启动失败,模块“Disk”启动失败
  16. PDFbox-PDF解析(坐标定位,分页读取)
  17. 未知USB设备(设备描述符请求失败)终于解决。网上查到的所有方法我都试过了,全部失败。我的成功方法就是调整“电源选项”
  18. 苹果照片未删却不见了_手机删除的照片如何恢复?不得不说这方法好!
  19. vue引入组件路径报错“Already included file name ”
  20. 无线传感器网络路由协议

热门文章

  1. Win10 UWP开发系列:解决Win10不同版本的Style差异导致的兼容性问题
  2. Linux学习建议 学习测试环境标准化配置
  3. 设置cookie存活时间_Django之cookie、session、token
  4. 嵌入式linux如何下载程序,Linux平台的下载程序-嵌入式系统-与非网
  5. 探索ElasticSearch(一)
  6. js == 和 ===
  7. texlive2015+texstudio
  8. [na]vrrp两用(网关冗余+服务器热备)
  9. hdu 1116 欧拉回路 并查集 一组字符串能否首尾相连成一个字符串
  10. url加密解密的一个cs类