GPIO模拟IIC通信测量环境光

2024-05-24 05:12

本文主要是介绍GPIO模拟IIC通信测量环境光,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

iic.h

iic.c

ap3216c.h

ap3216.c

main.c

实验效果


iic.h

#ifndef __IIC_H__
#define __IIC_H__#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"
//SDA 数据线为PF15
//SCL 时钟线为PF14//配置PF15为输出模式
#define SET_SDA_OUT do{GPIOF->MODER &=(~(0x3<<30));\GPIOF->MODER |=(0x1<<30);}while(0)//配置PF15为输入模式
#define SET_SDA_IN  do{GPIOF->MODER &=(~(0x3<<30));}while(0)//读取PF15输入寄存器的值
#define I2C_SDA_READ GPIOF->IDR & (0x1<<15)//PF14输出高电平、低电平
#define I2C_SCL_H  do{GPIOF->BSRR |= (0x1<<14);}while(0)
#define I2C_SCL_L  do{GPIOF->BRR |= (0x1<<14);}while(0)//PF15输入高电平、低电平
#define I2C_SDA_H do{GPIOF->BSRR |= (0x1<<15);}while(0)
#define I2C_SDA_L do{GPIOF->BRR |= (0x1<<15);}while(0)void delay_us(void);
//模拟I2C
void i2c_init(void);
void i2c_start(void);
void i2c_stop(void);
void i2c_write_byte(unsigned char  dat);
unsigned char i2c_read_byte(unsigned char ack);
unsigned char i2c_wait_ack(void);       
void i2c_ack(void);
void i2c_nack(void);#endif

iic.c

#include "iic.h"//微妙级的延时
void delay_us(void){unsigned int i=2000;while(i--);
}
//模拟I2C//I2C初始化
void i2c_init(void){//GPIOF时钟使能RCC->MP_AHB4ENSETR |= (0x1<<5);//配置PF14、PF15为输出模式GPIOF->MODER &= (~(0xF<<28));GPIOF->MODER |= (0x5<<28);//配置PF14、PF15为推挽输出GPIOF->OTYPER &= (~(0x3<<14));//配置PF14、PF15输出速度为超高速GPIOF->OSPEEDR |= (0xF<<28);//配置PF14、PF15无上拉下拉GPIOF->PUPDR &= (~(0xF<<28));//将SCL和SDA输出高电平I2C_SCL_H;I2C_SDA_H;}//发送起始信号
void i2c_start(void){//设置SDA为输出模式SET_SDA_OUT;//拉高数据线和时钟线I2C_SCL_H;I2C_SDA_H;delay_us();  //延时//拉低数据线I2C_SDA_L;delay_us();  //延时//拉低时钟线I2C_SCL_L;}//发送停止信号
void i2c_stop(void){//设置SDA为输出模式SET_SDA_OUT;//拉低时钟线I2C_SCL_L;delay_us();delay_us();//修改数据线为低电平I2C_SDA_L;delay_us();//拉高时钟线I2C_SCL_H;delay_us();//拉高数据线I2C_SDA_H;}//发送数据
void i2c_write_byte(unsigned char  dat){unsigned int i;//PF14配置为输出模式SET_SDA_OUT;for(i=0;i<8;i++){//拉低时钟线I2C_SCL_L;delay_us();//修改数据线的值if(dat&(0x1<<7)){I2C_SDA_H;}else{I2C_SDA_L;}delay_us();//拉高时钟线I2C_SCL_H;delay_us();   //拉高是时钟线后延时 delay_us();   //延时等待从机读取dat<<=1;}
}//读取数据
unsigned char i2c_read_byte(unsigned char ack){//配置为输入模式SET_SDA_IN;unsigned char data;for(unsigned int i=0;i<8;i++){//从机需要向寄存器写入数据//所有需要拉低时钟线I2C_SCL_L;delay_us();   //延时delay_us();   //等待从机写入数据//拉高时钟线读取数据I2C_SCL_H;delay_us();    //延时data<<=1;if(I2C_SDA_READ){data|=0x1; }else data|=0x0;}if(!ack){i2c_nack();}else{i2c_ack();}//返回读取的数值return data;
}//等带从机ack
unsigned char i2c_wait_ack(void){//拉低时钟线,修改SDA电平I2C_SCL_L;delay_us();I2C_SDA_H; //释放给从机delay_us();//SDA配置为输入模式SET_SDA_IN;delay_us();delay_us();//拉高时钟线读取从机ackI2C_SCL_H;delay_us();if(I2C_SDA_READ){return 1;}I2C_SCL_L;return 0;
}    //ack应答
void i2c_ack(void){//配置为输出模式SET_SDA_OUT;//拉低时钟线I2C_SCL_L;delay_us();//拉低数据线I2C_SDA_L;delay_us();//拉高时钟线I2C_SCL_H;delay_us();delay_us();//拉低时钟线?I2C_SCL_L;
}//非ack应答
void i2c_nack(void){//配置为输出模式SET_SDA_OUT;//拉低时钟线I2C_SCL_L;delay_us();//拉高数据线I2C_SDA_H;delay_us();//拉高时钟线I2C_SCL_H;delay_us();delay_us();//拉低时钟线?I2C_SCL_L;}

ap3216c.h

#ifndef __AP3216C_H__
#define __AP3216C_H__//ap3216c初始化
void ap3216c_init();
void ap3216c_init1();
//读取ap3216c环境光
unsigned char ap3216c_read_alsl();
unsigned char ap3216c_read_alsh();#endif

ap3216.c

#include "ap3216c.h"
#include "iic.h"
//ap3216c初始化
void ap3216c_init(){//发送起始信号i2c_start();//发送七位从机地址+1位写标志  0x1E | 0x0 = 0x3ci2c_write_byte(0x3c);//等待从机应答i2c_wait_ack();//发送8位寄存器地址0x00i2c_write_byte(0x00);//等待从机应答i2c_wait_ack();//写入数据0x3A,si7006初始值i2c_write_byte(0x1);//等待应答i2c_wait_ack();//发送停止信号 i2c_stop();
}//读取ap3216c环境光
unsigned char ap3216c_read_alsl(){//发送起始信号i2c_start();//发送七位从机地址+1位写标志  0x1E | 0x0 = 0x3Ci2c_write_byte(0x3C);//等待从机应答i2c_wait_ack();//发送8位寄存器地址0xE3i2c_write_byte(0x0C);//等待从机应答i2c_wait_ack();//发送重复开始信号i2c_start();//发送从机地址和读写标志  0x40 | 0x1 = 0x81i2c_write_byte(0x3D);//等待从机应答i2c_wait_ack();//读取环境光char als_l;als_l=i2c_read_byte(1);//发送应答//发送停止信号i2c_stop();return als_l;}
//读取ap3216c环境光
unsigned char ap3216c_read_alsh(){//发送起始信号i2c_start();//发送七位从机地址+1位写标志  0x1E | 0x0 = 0x3Ci2c_write_byte(0x3C);//等待从机应答i2c_wait_ack();//发送8位寄存器地址0xE3i2c_write_byte(0x0D);//等待从机应答i2c_wait_ack();//发送重复开始信号i2c_start();//发送从机地址和读写标志  0x40 | 0x1 = 0x81i2c_write_byte(0x3D);//等待从机应答i2c_wait_ack();//读取环境光char als_h;als_h=i2c_read_byte(1);//发送应答//发送停止信号i2c_stop();return als_h;}

main.c

#include "gpio.h"
#include "led.h"
#include "uart4.h"
#include "keyip.h"
#include "iic.h"
#include "si7006.h"
#include "ap3216c.h"
extern void printf(const char *fmt, ...);
int main()
{led1_init();i2c_init();ap3216c_init();unsigned short als;unsigned char als_l;unsigned char als_h;while (1){als_l=ap3216c_read_alsl(1);als_h=ap3216c_read_alsh(1);als=((unsigned short)als_h<<8) | als_l;printf("als=%d\n",als);if(als<100){led1_ctl(1);}else{led1_ctl(0);}delay(1000);}return 0;
}

实验效果

 

这篇关于GPIO模拟IIC通信测量环境光的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/997465

相关文章

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

usaco 1.2 Transformations(模拟)

我的做法就是一个一个情况枚举出来 注意计算公式: ( 变换后的矩阵记为C) 顺时针旋转90°:C[i] [j]=A[n-j-1] [i] (旋转180°和270° 可以多转几个九十度来推) 对称:C[i] [n-j-1]=A[i] [j] 代码有点长 。。。 /*ID: who jayLANG: C++TASK: transform*/#include<

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

hdu4431麻将模拟

给13张牌。问增加哪些牌可以胡牌。 胡牌有以下几种情况: 1、一个对子 + 4组 3个相同的牌或者顺子。 2、7个不同的对子。 3、13幺 贪心的思想: 对于某张牌>=3个,先减去3个相同,再组合顺子。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOExcepti

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

vue2 组件通信

props + emits props:用于接收父组件传递给子组件的数据。可以定义期望从父组件接收的数据结构和类型。‘子组件不可更改该数据’emits:用于定义组件可以向父组件发出的事件。这允许父组件监听子组件的事件并作出响应。(比如数据更新) props检查属性 属性名类型描述默认值typeFunction指定 prop 应该是什么类型,如 String, Number, Boolean,

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数

【算法专场】模拟(下)

目录 前言 38. 外观数列 算法分析 算法思路 算法代码 1419. 数青蛙 算法分析 算法思路 算法代码  2671. 频率跟踪器 算法分析 算法思路 算法代码 前言 在前面我们已经讲解了什么是模拟算法,这篇主要是讲解在leetcode上遇到的一些模拟题目~ 38. 外观数列 算法分析 这道题其实就是要将连续且相同的字符替换成字符重复的次数+

linux中使用rust语言在不同进程之间通信

第一种:使用mmap映射相同文件 fn main() {let pid = std::process::id();println!(