找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1039|回复: 0
打印 上一主题 下一主题
收起左侧

stm32f4标准库开发—模拟iic

[复制链接]
跳转到指定楼层
楼主
stm32f4标准库开发——模拟iic主要概念:
IIC总线:I2C总线是一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。
IIC总线定义:时钟线:sck数据线:sda
软件模拟:通过软件控制普通GPIO 引脚高低点评切换,来模拟总线时序,从而达到与总线协议一样的效果。
缺点:与使用硬件IIC 相比,会占用更多的 CPU 时间。

实验目的:
本实现通过软件模拟IIC 时序,编写 IIC 发送接收函数。

硬件电路:
本实验的蜂鸣器为有源蜂鸣器
PB8-->  IIC_SCL
PB9-->  IIC_SDA

主要库函数调用:
#define sda_in() {GPIOB->MODER&=~(3<<(9*2));GPIOB->MODER|=0<<9*2;} #define sda_out() {GPIOB->MODER&=~(3<<(9*2));GPIOB->MODER|=1<<9*2;} #define iic_sda_out(x) PBout(9)=x #define iic_scl_out(x) PBout(8)=x #define iix_read_sda() PBin(9) 代码: //iic.c #include "iic.h" #include "base.h" #include "delay.h" //*********************************************************************** //移

植修改部分

#define sda_in() {GPIOB->MODER&=~(3<<(9*2));GPIOB->MODER|=0<<9*2;} #define sda_out() {GPIOB->MODER&=~(3<<(9*2));GPIOB->MODER|=1<<9*2;} #define iic_sda_out(x) PBout(9)=x #define iic_scl_out(x) PBout(8)=x #define iix_read_sda() PBin(9) static void iic_gpio_init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOB, &GPIO_InitStructure); } static void iic_gpio_deinit(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOB, &GPIO_InitStructure); }

//*********************************************************************** void iic_init(void) { iic_gpio_init(); iic_scl_out(1); iic_sda_out(1); } void iic_deinit(void) { iic_gpio_deinit(); iic_scl_out(1); iic_sda_out(1); } void iic_start(void) { sda_out(); iic_sda_out(1); iic_scl_out(1); delay_us(4); iic_sda_out(0); delay_us(4); iic_scl_out(0); } void iic_stop(void) { sda_out(); iic_scl_out(0); iic_sda_out(0); delay_us(4); iic_scl_out(1); iic_sda_out(1); delay_us(4); } uint8_t iic_wait_ack(void) { uint8_t ucerrtime = 0; sda_in(); iic_sda_out(1); delay_us(1); iic_scl_out(1); delay_us(1); while(iix_read_sda()) { ucerrtime++; if(ucerrtime > 250) { iic_stop(); return 1; } } iic_scl_out(0); return 0; } void iic_ack(void) { iic_scl_out(0); sda_out(); iic_sda_out(0); delay_us(2); iic_scl_out(1); delay_us(2); iic_scl_out(0); } void iic_nack(void) { iic_scl_out(0); sda_out(); iic_sda_out(1); delay_us(2); iic_scl_out(1); delay_us(2); iic_scl_out(0); } void iic_send_byte(uint8_t txd) { uint8_t t; sda_out(); iic_scl_out(0); for(t = 0; t < 8; t++) { iic_sda_out((txd & 0x80) >> 7); txd <<= 1; delay_us(2); iic_scl_out(1); delay_us(2); iic_scl_out(0); delay_us(2); } } uint8_t iic_read_byte(unsigned char ack) { unsigned char i, receive = 0; sda_in(); for(i = 0; i < 8; i++ ) { iic_scl_out(0); delay_us(2); iic_scl_out(1); receive <<= 1; if(iix_read_sda()) receive++; delay_us(1); } if (!ack) iic_nack(); else iic_ack(); return receive; }

//iic.h #ifndef _IIC_H #define _IIC_H #include "stdint.h" void iic_init(void); void iic_deinit(void); void iic_start(void); void iic_stop(void); void iic_send_byte(uint8_t txd); uint8_t iic_read_byte(unsigned char ack); uint8_t iic_wait_ack(void); void iic_ack(void); void iic_nack(void); void iic_write_one_byte(uint8_t daddr, uint8_t addr, uint8_t data); uint8_t iic_read_one_byte(uint8_t daddr, uint8_t addr); #endif

编译运行:result
如下,编译无报错,无警告。

总结:
理论上gpio操作加上精确的延时,能模拟出任何总线的时序
iic.c将移植部分单独摘取出来,方便未来的移植开发


关注公号InsertingAll,获取嵌入式学习资源,学习更多嵌入式知识


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表