打印

pic16f946的I2C编程

[复制链接]
4082|11
手机看帖
扫描二维码
随时随地手机跟帖
沙发
machunshui| | 2009-11-30 16:53 | 只看该作者
1. 看手册,看寄存器,看时序
2.到MICRCOHIP网站,下载相关例子代码
3.自己写单元程序,测试

4.程序中出现的错误自己不能解决,才到论坛有针对性地提问。

使用特权

评论回复
板凳
liht1634|  楼主 | 2009-12-1 07:59 | 只看该作者
本帖最后由 liht1634 于 2009-12-1 08:09 编辑

PIC16F946的SSP 模块有5 个寄存器用于I2C 操作:
• SSP 控制寄存器(SSPCON)
• SSP 状态寄存器(SSPSTAT)
• 串行接收/ 发送缓冲器(SSPBUF)
• SSP 移位寄存器(SSPSR)——不可直接访问
• SSP 地址寄存器(SSPADD)
控制寄存器可以控制启动、停止等操作,状态寄存器指示状态。
SSPSTAT状态寄存器,初始化时我直接CLRF SSPSTAT
bit 7 SMP:SPI 数据输入采样相位位
I2 C™ 模式:此位必须保持清零

bit 6 CKE:SPI 时钟边沿选择位
SPI 模式, CKP = 0:
I2 C 模式:此位必须保持清零

bit 5 D/A:数据/ 地址位(仅I2C 模式)
1 = 表示上次接收或发送的字节是数据
0 = 表示上次接收或发送的字节是地址

bit 4 P:停止位(仅I2C 模式)
当禁止SSP 模块或上次检测到启动位时,该位被清零。
SSPEN 被清零。
1 = 表示上次检测到了停止位(此位在复位时为0)
0 = 表示上次没有检测到停止位

bit 3 S:启动位(仅I2C 模式)
当禁止SSP 模块或上次检测到停止位时,该位被清零。
SSPEN 被清零。
1 = 表示上次检测到了启动位(此位在复位时为0)
0 = 表示上次没有检测到启动位

bit 2 R/W:读/ 写信息位(仅I2C 模式)
该位用来保存在上次地址匹配后的R/W 位信息。此位仅在地址匹配与遇到下一个启动位、停
止位或ACK 位之间有效。
1 = 读
0 = 写

bit 1 UA:更新地址位(仅10 位I2C 模式)
1 = 表示用户需要更新SSPADD 寄存器中的地址
0 = 不需要更新地址

bit 0 BF:缓冲器满状态位
接收(SPI 和I2 C 模式):
1 = 接收完成, SSPBUF 满
0 = 接收未完成, SSPBUF 空
发送(仅I2 C 模式):
1 = 正在发送, SSPBUF 满
0 = 发送完成, SSPBUF 空

SSPCON控制寄存器,初始化时我直接送入B'00110110 '。
bit 7 WCOL:写冲突检测位
1 = 正在发送前一个字时,又有数据写入SSPBUF 寄存器(必须用软件清零)
0 = 无冲突

bit 6 SSPOV:接收溢出指示位
在I2 C™ 模式下:
1 = SSPBUF 中仍保存前一数据时,又接收到一个新的字节。SSPOV 在发送模式下是“无关位”。
两种模式下都必须用软件将SSPOV 清零。
0 = 无溢出

bit 5 SSPEN:同步串行端口使能位
在I2 C 模式下:
1 = 使能串行端口并将SDA 和SCL 引脚配置为串行端口引脚
0 = 禁止串行端口并将这些引脚配置为I/O 端口引脚
在两种模式下,当使能时,这些引脚必须被正确配置为输入或输出。

bit 4 CKP:时钟极性选择位
在I2 C 模式下:
SCK 释放控制
1 = 使能时钟,释放时钟线
0 = 保持时钟为低电平(时钟低电平时间延长)。(用于确保数据建立时间。)

bit 3-0 SSPM<3:0>:同步串行端口模式选择位
0110 = I2C 从动模式, 7 位地址
0111 = I2C 从动模式, 10 位地址
1011 = I2C 固件控制主控模式(从动空闲模式)
1110 = I2C 从动模式, 7 位地址,并允许启动位和停止位中断
1111 = I2C 从动模式, 10 位地址,并允许启动位和停止位中断
它没有像PIC16F877的SSPCON中SEN(启动信号使能位),可在SDA和SCL引脚上建立启动信号时序。怎么样让它启动呢?望赐教,不胜感激!

使用特权

评论回复
地板
machunshui| | 2009-12-1 08:47 | 只看该作者
PIC16F917的串行外设模块是SSP,
并非MSSP,
实现I2C主模式比较麻烦,
手册对I2C主模式的介绍基本没有。

启动和停止是通过软件控制IO口线模拟产生。
具体可以参考microchip网站上的**:
Use of the SSP Module in the I2C Multi-Master Environment

这篇**有比较详细的汇编代码实现

使用特权

评论回复
5
machunshui| | 2009-12-1 08:48 | 只看该作者
6
liht1634|  楼主 | 2009-12-1 08:55 | 只看该作者
machunshui:是PIC16F946,谢!

使用特权

评论回复
7
machunshui| | 2009-12-1 09:01 | 只看该作者
PIC16F946也是SSP,
非MSSP
一样的道理

使用特权

评论回复
8
liht1634|  楼主 | 2009-12-1 13:19 | 只看该作者
对machunshui:谢谢指教,SSP和MSSP有什么样的区别?

使用特权

评论回复
9
machunshui| | 2009-12-1 13:51 | 只看该作者
从应用角度讲

MSSP 主同步串行口,实现I2C主模式比较方便,启动,停止都是寄存器实现,
可以说比SSP更自动化一点

SSP 同步串行口,实现I2C主模式比较麻烦

使用特权

评论回复
10
liht1634|  楼主 | 2009-12-1 13:52 | 只看该作者
本帖最后由 liht1634 于 2009-12-1 14:07 编辑

LIST        P=16F946         ; list directive to define processor
                #INCLUDE    <P16F946.INC>    ; processor specific variable definitions
;*******************************************
                ORG       00H
                NOP
                GOTO     INIT_IIC
                ORG       04H
                GOTO     INT_SERV
;*******************************************
INIT_IIC
                BANKSEL PORTC
                BCF     PORTC,6               ;Set SDA SCL low when not tri-stated
                BCF     PORTC,7
                MOVLW   B'00000100'
                MOVWF   FLAG_SW4

                BANKSEL SSPADD              
                MOVLW   B'10100000'           ;Slave address
                MOVWF   SSPADD
                CLRF    SSPSTAT
                BANKSEL SSPCON
                MOVLW   B'00111011'           ;Setup SSP module for I2C 7 bit 固件控制主控模式
                MOVWF   SSPCON                              
                BANKSEL PIE1                  ;Enable interrupts               
                BSF     PIE1,SSPIE
                BSF     TRISC,SDA
                BSF     TRISC,SCL
                BSF     INTCON,PEIE           ;Enable all peripheral interrupts
                BSF     INTCON,GIE            ;Enable global interrupts
                BANKSEL PIR1
                BCF     PIR1,SSPIF            ;Clear SSP interrupt flag

                CALL    IIC_WRITE
                GOTO   $
;*******************************************
IIC_WRITE
                CALL    IIC_START
                CALL    IIC_WAIT

                BANKSEL SSPADD
                MOVF    SSPADD,0              ;从器地址+写控制位 1010 000 0
                BANKSEL SSPBUF
                MOVWF   SSPBUF               
                CALL    IIC_WAIT

                BANKSEL SSPBUF
                MOVLW   01H                   ;待写入的从器件地址01H
                MOVWF   SSPBUF                              
                CALL    IIC_WAIT

                MOVF    FLAG_SW4,0            ;待写入的的数据
                MOVWF   SSPBUF
                CALL    IIC_WAIT
                CALL    IIC_STOP
                CALL    IIC_WAIT                                                                                         
                RETURN
;==============发开始命令===================
IIC_START                                     ;SCL is high while SDA goes from high to low transition
                BANKSEL TRISC
                BSF     TRISC,SDA
                BSF     TRISC,SCL         
                NOP
                NOP
                NOP
                BCF     TRISC,SDA
                NOP
                NOP
                NOP
                BCF     TRISC,SCL
                RETURN
;==============发停止命令===================
IIC_STOP                                      ;SDA goes from low to high during SCL high state
                BANKSEL TRISC
                BCF     TRISC,SDA
                BSF     TRISC,SCL
                NOP
                NOP
                NOP
                BSF     TRISC,SDA
                NOP
                NOP
                NOP
                BCF     TRISC,SCL
                RETURN
;==============等待发送结束=================
IIC_WAIT
                BANKSEL PIR1
                BTFSS   PIR1,SSPIF
                GOTO    $-1
                BCF     PIR1,SSPIF
                RETURN
;*******************************************
INT_SERV                                           ;中断服务
                RETFIE
;*******************************************
                END

希望程序将FLAG_SW4单元的内容写入到I2C的01H单元中,现在程序执行到第二个CALL    IIC_WAIT就出不来了,该怎么改?望赐教!!!

使用特权

评论回复
11
liht1634|  楼主 | 2009-12-2 15:48 | 只看该作者
没有一个人知道?

使用特权

评论回复
12
liht1634|  楼主 | 2009-12-3 09:46 | 只看该作者
己经用模拟I2C完成了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

178

主题

365

帖子

1

粉丝