历史上的今天
今天是:2025年07月26日(星期六)
2021年07月26日 | MC9S12XEP100 IIC模块 驱动程序
2021-07-26 来源:eefocus
前言
相关理论
相关理论请自行参考数据手册。
此为我对数据手册IIC模块部分的翻译:https://blog.csdn.net/lin_strong/article/details/80259571
驱动模块简介
整个模块是中断驱动的,ISR的运行逻辑基本就是照着数据手册中给出的框图。

这里稍微有一点要注意的,就是在主机接收器的寻址周期(即图左边中间那个Master Rx)结束时不是要切换Rx mode并虚读么,这个时候应该要判断下下一个读的字节是不是最后一个,并据此来设置TXAK,而不应该像图上那样直接就触发下一个接收了,当然,驱动程序中已经写了这个逻辑了。
另外当前模块并不支持10bit 地址,主要就是暂时用不到,懒得写。
模块提供了模块初始化,主机发送/主机接收,函数注册的接口。
中断与主机接口之间采用信号量的方式进行通讯,主机接口先进行会导致中断的操作,然后阻塞地pend信号量;IIC的中断会驱动着完成后续的工作,然后post信号量并通知结果;然后主机接口就会成功pend到信号量,并得知操作结果。
模块内部提供了默认的信号量实现,当在RTOS中运行时,可以通过函数注册接口把操作系统提供的信号量函数给模块使用,这样就可以最大化内核的使用,减少无意义的任务切换开销。后面提供了对uCOS-II进行适配的函数。
从机功能则是完全由中断驱动的,当使用从机功能时,要求用户按照声明的函数提供具体实现,当发生从机接收/从机发送时,对应的函数会被调用,以传递给用户刚刚收到的数据,或从用户处获取下一个要发送的数据。
头文件的配置中提供了一些宏以实现按照需求对代码进行精简,以及对模块进行配置。主要要记得根据自己的CPU频率修改IIC_INIT_IBFD的值。
由于模块是中断驱动的,一定要记得把中断向量指向中断服务例程IIC_ISR,并启用中断,使用uCOS-II的时候则要把中断向量指向.s文件中的IIC_uC_ISR。
代码
驱动模块
头文件:
/*
*******************************************************************************************
*
* IIC INTERFACE
* IIC接口
*
* File : IIC.h
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/03/26
* version: V1.4
* History: 2018/05/07 V1.0 the prototype
* 2018/05/15 V1.1 add the slave part of IIC.
* add the functions register, so user can change the behaviour
* of the module.
* V1.2 a tip on the ISR
* 2018/05/20 V1.3 figure out the method to make ISR in this module and in IIC_uCos
* compatible.
* 2019/03/26 V1.4 some modification to the malloc configuration.
* NOTE(s): 1. don't support 10-bit address for now.
* 2. this module is ISR-drived, so you must point the IIC_ISR to the corresponding
* address and enable interrupt.
* 3. note that the funcitons in this module is not thread-safe.
*********************************************************************************************
*/
#ifndef IIC_H
#define IIC_H
/*
********************************************************************************************
* INCLUDES
********************************************************************************************
*/
#include "common.h"
/*
******************************************************************************************
* CONSTANT
******************************************************************************************
*/
// IIC address length
#define IIC_ADDRLEN_7BIT 0
#define IIC_ADDRLEN_10BIT 1
/*
*******************************************************************************************
* CONFIGURE 主配置
*******************************************************************************************
*/
// to exclude code for IIC slave mode.
// #define IIC_SLAVEMODE_DISABLE
// to exclude code for IIC master Rx mode.
// #define IIC_MASTER_RX_DISABLE
// to exclude code for IIC master Tx mode.
// #define IIC_MASTER_TX_DISABLE
// to enable debug message through standard printf
// #define _DEBUG
//************ 初始化配置 ***************//
// 根据手册设置分频寄存器
#ifndef IIC_INIT_IBFD
#define IIC_INIT_IBFD 0x94 // 总线时钟32MHz,设置SCL主频为100KHz
#endif
// IIC模块使用的地址长度
#ifndef IIC_INIT_ADDRLEN
#define IIC_INIT_ADDRLEN IIC_ADDRLEN_7BIT // 当前只支持7位地址,不支持10位的
#endif
// IIC模块使用的从机地址(定义在低7bits),如果启用了从机代码
#ifndef IIC_INIT_SLAVEADDR
#define IIC_INIT_SLAVEADDR 0x37
#endif
// 在等待模式下内部时钟是否停止
#ifndef IIC_INIT_STOPINWAIT
#define IIC_INIT_STOPINWAIT TRUE
#endif
/*
****************************************************************************************
* ERROR CODES
****************************************************************************************
*/
#define IIC_ERR_NULL 0
#define IIC_ERR_AUG 1 // 参数错误
#define IIC_ERR_NOACK 2 // 未收到答复
#define IIC_ERR_IBAL 3 // 仲裁丢失
#define IIC_ERR_IBB 4 // 总线忙
#define IIC_ERR_TIMEOUT 5 // 等待超时
#define IIC_ERR_UNKNOWN 6 // 未知错误
/*
******************************************************************************************
* TYPE DEFINE
******************************************************************************************
*/
// Description: IIC内部阻塞等待时使用的函数,比如可以在其中添加线程Dly函数来实现阻塞等待时放弃CPU时间
// Arguments : wCnt 当前等待次数计数
// return : TRUE 继续等待
// FALSE 停止等待,返回错误
typedef unsigned char (* IIC_FUNC_WAITFUNC)(unsigned long wCnt);
// IIC内部信号量相关函数,当使用操作系统时可以替换为操作系统的信号量
// Description: 等待信号量
// Arguments :
// return : TRUE 成功pend到信号量
// FALSE 等待超时或其他错误
typedef unsigned char (* IIC_FUNC_SEM_PEND)(void);
// Description: 发送信号量
// Arguments :
// return :
typedef void (* IIC_FUNC_SEM_POST)(void);
// Description: 重置信号量
// Arguments :
// return :
typedef void (* IIC_FUNC_SEM_RESET)(void);
/*
************************************************************************************
* FUNCTION PROTOTYPES 函数原型
************************************************************************************
*/
unsigned char IIC_Init(void);
#define IIC_ReceiveChar(calAddr,pChar) IIC_Recv(calAddr,pChar,1)
unsigned char IIC_Recv(unsigned char calAddr,unsigned char *rBuf,unsigned short len);
#define IIC_SendChar(calAddr,pChar) IIC_Send(calAddr,pChar,1)
unsigned char IIC_Send(unsigned char calAddr,unsigned char *sBuf,unsigned short len);
void IIC_FuncReg_Wait(IIC_FUNC_WAITFUNC f);
void IIC_FuncReg_Sem(IIC_FUNC_SEM_RESET r,IIC_FUNC_SEM_POST pt,IIC_FUNC_SEM_PEND pd);
// 启用从机时要求用户实现的函数
// 注意,这些函数是在ISR中被调用的
// Description: when is in slave Tx mode, to get the next byte to send from user.
// Argument : No the number of current byte of this conversation. begin from 0;
// return : the byte to send.
extern unsigned char IIC_Send_AsSlave(unsigned short No);
// Description: when is in slave Rx mode, to pass the next byte received to user.
// Argument : No the number of current byte of this conversation. begin from 0;
// c the data recevied.
// return :
extern void IIC_Recv_AsSlave(unsigned short No,unsigned char c);
// ISR 中断服务例程
#pragma push
#pragma CODE_SEG __NEAR_SEG NON_BANKED
interrupt void near IIC_ISR(void);
#pragma pop
/*
************************************************************************************
* ERROR CHECK 错误检查
************************************************************************************
*/
#ifdef IIC_SLAVEMODE_DISABLE
#ifdef IIC_MASTER_RX_DISABLE
#ifdef IIC_MASTER_TX_DISABLE
#error "can't exclude all slave and master code."
#endif
#endif
#endif
#endif // of IIC_H
源文件:
/*
*******************************************************************************************
*
* MC9S12XEP100 IMPLEMENTATION OF IIC INTERFACES
* IIC接口的MC9S12XEP100实现
*
* File : IIC.c
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/03/26
* version: V1.4
* History: 2018/05/07 V1.0 the prototype
* 2018/05/15 V1.1 add the slave part of IIC.
* add the functions register, so user can change the behaviour
* of the module.
* V1.2 a tip on the ISR
* 2018/05/20 V1.3 figure out the method to make ISR in this module and in IIC_uCos
* compatible.
* 2019/03/26 V1.4 some modification to the malloc configuration.
* some modification to the code to eliminate compiler warning.
史海拾趣
|
范围包括但不限于Ethernet, IP, MPLS, TCP/UDP协议,交换机/路由器/防火墙等。 如果我不懂的会尽量帮忙找到答案。 大家共同提高:)… 查看全部问答> |
|
当时上大学时跟老师做实验,我们把低频和高频信号加在线圈上,用他们产生的磁场作用到兔子和老鼠的头部,大概是2个星期后,把兔子和老鼠的脑子做切片时,发现脑细胞有明显的变化,有些已经萎缩,有些就是畸形,总是肯定是有影响的,建议远离。… 查看全部问答> |
|
1.WindRiver有Wind SNMPManager开发包吗? 2.是用net-snmp移植到vxworks6.1还是用snmp++了? 我现在需要在vxworks6.1实现管理端程序,不知道这个怎么着手?希望大家指导,谢谢。… 查看全部问答> |
|
一个单选按钮控件,我用它来做选择的功能,想实现当用户点击后可以通过点击其他按钮将单选按钮圈圈里的黑点取消掉,怎么实现? 对MFC的控件不是太熟悉,望大家多帮忙咯,谢谢嗯!… 查看全部问答> |
|
有哪位大侠知道 static CMOS有何特性啊?告知一声,谢谢! The DM350 is designed in full static CMOS, so when you stop a module clock, it retains the module\'s state.… 查看全部问答> |
|
急求一个用8051控制TC35i GSM模块发短信的C语言程序 急求一个用8051控制TC35i GSM模块发短信的C语言程序 程序越简单越好。只要求发短信。急!!谢谢 邮箱84085155@qq.com… 查看全部问答> |




