由于准备写一个基于Linux操作系统的IIC总线驱动,所以先把裸机上的程序调试通过后才去开发基于Linux操作系统的,但是有一个小问题,程序都完全按IIC总线时序来书定了,还是有些错误。主要是不能正常定位,即不能选择性读与选择性起始地址后以页的方式进行读取。在这两种方式下,写入到rIICDS地址不能发送出去,一直保存于rIICDS中,所以在对rIICDS进行读时,读到的还是写入到rIICDS中的值。
同时,看了开发板提供的例子,有一点问题,不知道是我理解错了还是什么原因。
一个重大的错误在于rGPECON的设置上。因为IIC的SDA,SCL分别为GPE15与GPE14,而例程在进行GPIO口的初始化时为 rGPECON |= 0xA00000; 这不是把GPE14,GPE15设置为IIC端口,同时,GPE14,GPE15端口没有上端口上拉电阻,而例子中把rGEPUP初始化为 rGPEUP |= 0xC000; 在2440中rGPEUP的有效位只为14位,这样初始有用吗?
下面是我的写的代码,由于本人没有用仿真器,所以不知道错在什么地方,有懂的读者,请帮忙一下。
复制代码- /************************************************
- *说明:本程序是S3C2440 IIC总线的一个简单的驱动程序
- * 由于本程序比较简单,所以,在此不再进行说明,
- * 有不懂的读者请自行阅读相关文档。
- *
- * AT24C08 的地址格式为: 1 0 1 0 A2 P1 P0 W/R
- * A2为设备地址位、P1,P0为片内页寻址 LSB=0 写
- * LSB=1 读
- *
- *CPU :S3C2440
- *编译环境 :ADS1.2
- *开发板 :MINI2440
- *作者 :soon
- *部门 : 长沙理工大学
- * 计算机与通信工程学院
- * 计算机07级04班
- *最后修改时间 :开发中
- ************************************************/
- #ifndef _MY_IIC_C_
- #define _MY_IIC_C_
- #include "../include/2440addr.h"
- #include "../include/2440lib.h"
- #include "../include/def.h"
- #include "../include/My_IIC.h"
- static int seave_gpecon;
- /*用于保存GPECON的当前值,为恢复GPECON做准备*/
- U8 write_buffer[16];
- /*写缓冲区*/
- U8 read_buffer[16];
- /*读缓冲区*/
- /*初始化GPIO*/
- void
- _init_gpio(void)
- {
- seave_gpecon = rGPECON;
- rGPECON = 0xA0000000;
- }
- /*恢复GPIO口*/
- void
- _resume_gpio(void)
- {
- rGPECON = seave_gpecon;
- }
- /*初始化IIC总线*/
- void
- _init_iic(void)
- {
- /*
- *IIC应答使能有效、IICCLK = FPCLK/16、
- *中断使能、 清除挂取条件、 TXCLK = IICCLK/16
- */
- rIICCON = (1 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
- rIICSTAT = 0x10;
- rIICADD = 0x10;
- }
- /*写一个字节到指定地址*/
- void
- _byte_write(U8 device_address, U8 word_address, U8 data)
- {
- rIICCON = (1 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
- rIICSTAT = (rIICSTAT & 0x0) | (0x1 << 7) | (0x1 << 6);
- rIICDS = device_address;
- rIICSTAT |= (0x1 << 5) | (0x1 << 4);
- while((rIICSTAT & 0x01) == 1);
-
- rIICDS = word_address;
- rIICCON &= ~(0x1 << 4);
- while((rIICSTAT & 0x01) == 1);
-
- rIICDS = data;
- rIICCON &= ~(0x1 << 4);
- while((rIICSTAT & 0x01) == 1);
- rIICSTAT &= ~(0x1 << 5);
- rIICCON = (1 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
- }
- /*以页的方式写入*/
- void _page_write(U8 device_address, U8 word_start_address,U8 *buffer_start_address)
- {
- unsigned int i;
-
- rIICCON = (1 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
- rIICSTAT = (rIICSTAT & 0x0) | (0x1 << 7) | (0x1 << 6);
- rIICDS = device_address;
- rIICSTAT |= (0x1 << 5) | (0x1 << 4);
- while((rIICSTAT & 0x01) == 1);
-
- rIICDS = word_start_address;
- rIICCON &= ~(0x1 << 4);
- while((rIICSTAT & 0x01) == 1);
-
- for(i = 0; i < 15; i ++){
- rIICDS = *(buffer_start_address + i);
- rIICCON &= ~(0x1 << 4);
- while((rIICSTAT & 0x01) == 1);
- }
-
- rIICDS = *(buffer_start_address + i);
- rIICCON &= ~(0x1 << 4);
- while((rIICSTAT & 0x01) == 1);
-
- rIICSTAT &= ~(0x1 << 5);
-
- rIICCON = (1 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
- }
- /*读当前地址单元内容*/
- U8
- _current_address_read(U8 device_address)
- {
- U8 data;
- rIICCON = (1 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
-
- rIICSTAT = (rIICSTAT &0x0) | (0x1 << 7) | (0 << 6);
- rIICDS = device_address;
- rIICSTAT |= (0x1 << 5) | (0x1 << 4);
- while((rIICSTAT & 0x01) == 1);
- rIICCON = (0 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
- data = rIICDS;
-
- rIICSTAT &= ~(0x1 << 5);
- rIICCON = (1 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
-
- return data;
- }
- /*读指定单元地址内容*/
- U8
- _random_address_read(U8 device_address, U8 word_address)
- {
- U8 data;
-
- rIICCON = (1 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
- rIICSTAT = (rIICSTAT & 0x0) | (0x1 << 7) | (0x1 << 6);
- rIICDS = device_address & 0xFE;
- rIICSTAT |= (0x1 << 5) | (0x1 << 4);
- while((rIICSTAT & 0x01) == 1);
-
- rIICDS = word_address;
- rIICCON &= ~(0x1 << 4);
- while((rIICSTAT & 0x01) == 1);
-
-
- rIICSTAT = (rIICSTAT & 0x0) | (0x1 << 7) | (0 << 6);
- rIICDS = device_address;
- rIICSTAT |= (0x1 << 5) | (0x1 << 4);
- rIICCON &= ~(0x1 << 4);
- while((rIICSTAT & 0x01) == 1);
- rIICCON = (0 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
- data = rIICDS;
-
- rIICSTAT &= ~(0x1 << 5);
- rIICCON = (1 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
-
- return data;
- }
- /*以页读方式读*/
- void
- _sequential_address_read(U8 device_address,U8 word_address,U8 *buffer_start_address)
- {
- unsigned i;
-
-
- rIICCON = (1 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
- rIICSTAT = (rIICSTAT & 0x0) | (0x1 << 7) | (0x1 << 6);
- rIICDS = device_address & 0xFE;
- rIICSTAT |= (0x1 << 5) | (0x1 << 4);
- while((rIICSTAT & 0x01) == 1);
- rIICDS = word_address;
- rIICCON &= ~(0x1 << 4);
- while((rIICSTAT & 0x01) == 1);
-
- rIICSTAT = (rIICSTAT & 0x0) | (0x1 << 7) | (0 << 6);
- rIICDS = device_address;
- rIICSTAT |= (0x1 << 5) | (0x1 << 4);
- rIICCON &= ~(0x1 << 4);
- while((rIICSTAT & 0x01) == 1);
-
- for(i = 0; i < 15; i ++){
- *(buffer_start_address + i) = rIICDS;
- rIICCON &= ~(0x1 << 4);
- while((rIICSTAT & 0x01) == 1);
- }
- rIICCON = (0 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
- *(buffer_start_address + i) = rIICDS;
- rIICSTAT &= ~(0x1 << 5);
- rIICCON = (1 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
- }
- /*用于延时一小段时间*/
- void
- _delay_time(unsigned int delay_time)
- {
- while(delay_time --);
- }
- /*测试程序*/
- void
- _test_iic(void)
- {
- char i;
-
- /*实始化读 写缓冲区*/
- for( i = 0; i < 16; i ++){
- *(write_buffer + i) = i * 2;
- *(read_buffer + i )= 0;
- }
-
- /*下面为测试按页写测试*/
-
- _page_write(DEVICE_ADDRESS_WRITE,0,write_buffer);
- _delay_time(5);
-
-
-
-
- for(i = 0; i < 16; i ++){
- _byte_write(DEVICE_ADDRESS_WRITE, i,i * 3);
- _delay_time(5000);
-
- Uart_Printf("%d %d\n",i + 1 ,_current_address_read(DEVICE_ADDRESS_READ));
- _delay_time(10);
-
- }
-
- /*下面为测试随机地址读*/
- for(i = 0; i < 16; i ++){
- Uart_Printf("%d\n",_random_address_read(DEVICE_ADDRESS_READ,i));
- _delay_time(5);
-
- Uart_Printf("%d\n",_current_address_read(DEVICE_ADDRESS_READ));
- _delay_time(5);
-
- }
-
-
- /*下面为测试按页读*/
- _sequential_address_read(DEVICE_ADDRESS_READ,3,read_buffer);
- _delay_time(5);
-
-
- for(i = 0; i < 16; i ++)
- Uart_Printf("%d %d\n",i + 1,*(read_buffer + i));
-
-
-
- Uart_Printf("\n");
- }
- #endif
- /************************************************
- ||
- ||
- ||
- || END My_IIC.c
- ||
- ||
- ||
- ************************************************/
|