ARM学习随笔(14) I2C转UART之SC16IS740

来源:互联网 发布:家庭网络光纤 编辑:程序博客网 时间:2024/05/20 15:40

Num1:首先要来了解I2C接口。

aduc7023I2C接口不同于51单片机的模拟出来的I2C。只要对ADuc7023相应的I2C寄存器进行操作即可。它类似于UART,具有2字节的FIFO。在未写入从地址之前,传输并未开始。

OUT和IN是从机自动进行操作的。


主机发送:

在发送字节前,必须首先将数据载入发送FIFO,即I2C0MTX中。I2C0ADR寄存器中必须指定从机的地址。对于数据写入,地址寄存器中的写操作(W)位必须置0。写入I2C0ADR寄存器会自动产生一个起始条件,并启动传输。(注意是自动产生起始条件的,而且只有写入I2C0ADR之后才能启动)
每个发送字节的第一个时钟脉冲上会产生一个I2C中断。I2C0MSTA的位2和位1置1,表示主机刚刚发送一个字节,并且FIFO下溢。因此,用户可以向FIFO添加一个字节。
如果启动传输时FIFO中只有一个字节,则第一个I2C中断发生在所发送地址的第一个时钟脉冲上。如果FIFO中有两个字节,则中断发生在所发送的第一个字节的第一个时钟脉冲上。(即启动传输时FIFO中得有字节,一个或两个都可以,在写入I2C0ADR寄存器之前写I2C0MTX。传输开始时,第一个字节将触发中断)


主机接收:

通过I2C0CNT寄存器配置要读取的字节数。其值表示要从从机读取的字节数加1。当读取够I2C0CNT配置的字节数时主机不再接收更多数据,通知从机停止传输字节,不再产生中断  重要!!!!!!
为了开始接收数据,I2C0ADR寄存器中的读操作(R)位应置1。这将启动传输,并利用I2C0ADR寄存器所设置的地址和R/W位产生起始条件。接收到每个字节后(第9个时钟脉冲ACK或NACK之后),会产生一个中断。I2C0MSTA的位3置1,表示刚刚接收到一个字节。只有读取I2C0MRX才能使此位清零。
当主机不需要接收更多数据时(即满足I2C0CNT配置的字节数,I2C0CNT是内置的计数器,自动对读取的字节数计数,达到时停止接收字节),它针对最后接收到的字节自动产生NACK。这相当于通知从机停止传输字节,以便主机能够产生停止条件。
如果没有及时读取所接收到的数据,并且FIFO已满,则主机将针对所接收到的额外数据提供一个NACK。


发送和接收触发中断的条件(首先要使能IRQEN对应的I2Cx位,比如第10位置1使能I2C1中断):

接收:启动传输后等待从机发送数据,当数据进入接收FIFO后,即产生中断

发送:启动传输后,当主机完成一个字节传输时,产生中断


产生中断以后,开始对于中断的处理:

aduc7023 读取IRQSTA判断是否是I2C1主机产生的中断,如果是,则再读取I2CxMSTA判断是接收请求中断还是发送请求中断。

若是接收请求中断,则判断有没有够接收字节数(可以少于I20CNT,但不能多于I2C0CNT),如果还需要接收,则继续读取I2C1MRX;当达到I2C0CNT时不再接收字节,不再产生中断。

若是发送请求中断,则判断发送的字节数有没有达到要求的字节数,是否要继续发送(多发送一位空的//错误,不需要多发送一位,如果是字符串,用sizeof(),自己会发送末尾的'\0'的 \\事后再实验发现这个结论也是错的,想不明白。。  )

 

(一)I2C操作

①初始化:

1.选择管脚功能为I2C功能(此I2C对应的管脚要看原理图中所连的管脚,比如scl1,sda1)

2.设置I2C时钟频率(PLLCON控制时钟系统的工作模式,POWCON0控制内核时钟频率和掉电模式,这是系统初始化要用到的,而POWCON1则控制I2C和SPI的时钟频率。为了防止意外编程,写PLLCON和POWCONx寄存器时需要遵循特定的时序。),即设置POWCON1。

所以一般配置为POWKEY3=0X76;POWCON1=0X124;(将2,5,8位置1,SPI,I2C时钟为41.78MHZ)POWKEY4=0XB1;

 

3.设置串行时钟频率:I2CxDIV

一般选择100KHZ,即设置为I2CxDIV=0XCFCF;

 

4.使能中断IRQEN(由于使用到了中断,当中断使能时,接收或发送都会触发中断,具体每一位代表什么可参考相应datasheet)

 

②主机发送操作

(具体参考AN895应用笔记,这个是ADuc702x系列,略有不同,但过程大同小异)

1.Flush TX FIFO

2.向TX FIFO中写入一字节(或两字节,根据前文发送FIFO操作中所要求的,反正传输开始时第一个字节发送出OUT就会产生中断)

3.写I2CxADR0从机地址(读写位设为写   启动传输,等待第一个字节发送出去产生中断)

4.等待要求字节数的数据传送完毕(进入IRQ服务程序,判断是否还有数据需要发送,若有继续发送到TX FIFO中

 

③主机接收操作

 

根据上图要求,读取数据前就需要设置I2CxMCNT0(内置计数器,达到以后不再读取数据)

1.设置I2CxMCNT0

2.写I2CxDAR0(读写位设置为读 传输开始等待,等待IN传给RX FIFO中,有数据传入则产生中断 ;  读数据指的是读SC16IS740芯片寄存器中的数据,如读RHR寄存器中的数据)

3.等待要求的字节数的数据读出完毕(读的字节数可以少于I2CxMCNT0,此时因为没有及时读取所接收到的数据,若FIFO已满,则主机将针对所接收到的额外数据提供一个NACK,以停止传输,若FIFO不满,则继续传输。注意FIFO只有2字节)

 

 

Num2:uart操作(可以就把SC16IS740当作aduc7023的一部分,uart的寄存器在SC16IS740里,需要用I2C通信来读取或写相应uart寄存器地址处的值)

uart初始化:

①设置波特率。打开除数锁存端,配置DLL,DLH,配置完成后关闭除数锁存端

②选择数据格式。

③设置触发深度FIFO,并复位TX FIFO,RX FIFO,使能FIFO(当UART接收到大量字符且这些数据不足够以触发接收中断(因为它们没有到达接收触发点)时,UART将在接收到最后一个字符后4字符时间内产生超时中断。超时中断也能触发uart的IRQ,它是SC16IS740上的IRQ。超时计数器将在接收到的每个停止位的中间或每次读接收FIFO时复位。)

④使能中断IEREN

所以uart内部寄存器要左移三位再写入

写寄存器操作(往相应寄存器地址处写字节即可设置,寄存器地址按上图规定左移三位):

①Flush TX FIFO

②写一字节到TX FIFO  I2C1MTX=reg;

③写从地址 I2C1ADR0=从地址(读写位为写),启动传输,然后会传输reg.

④判断数据是否传完(对于普通寄存器设置来说,接下来只要再传输一字节即可,对于THR则可能传输多个字节,按照上图来)

 

读寄存器操作(按照上图,操作时序为从地址(写)->reg->从地址(读)->数据,读出的数据要另外定义一个变量用于存放)

①I2C写操作,写reg(就是写一个寄存器地址)

②I2C读操作,读出数据存放。

 

接收器、发送器:

①接收保存寄存器(RHR)
接收器部分由一个接收保存寄存器(RHR)和接收移位寄存器(RSR)组成。RHR实际上是一个64字节FIFO。RSR接收RX端的串行数据。然后将数据转化为并行数据并转移到RHR。线控制寄存器控制接收器部分。如果FIFO被禁能,则FIFO的单元0用来存储字符。


②发送保存寄存器(THR)
发送器部分由一个发送保存寄存器(THR)和发送移位寄存器(TSR)组成。THR实际上是一个64字节FIFO。THR接收数据并将其移入TSR。然后在TSR中将其转化为串行数据并在TX端移出。如果FIFO被禁能,则FIFO仍用来存储字节。如果发生溢出则字符丢失。(THR接收数据就是在THR地址处写多个字节)

 

UartsendBytes操作:

I2C写操作,往THR地址中写n个字节(都存放到了该64字节FIFO中),等待终端读光FIFO

 

UartreadBytes操作(由于未使用中断服务程序来读取,所以与触发深度无关):

I2C读操作,读取LSR状态,通过LSR[0]判断RX FIFO中是否有数据,若有,则循环I2C读取RXLVL判断有多少字符,并通过I2C读取RHR寄存器字符,直到RXLVL没有字符数

 

 

 

 

 






1 0
原创粉丝点击