概述
先上I2C初始化。
头文件`
#ifndef _I2C_H_
#define _I2C_H_
#include "stm32f10x.h"
#include "rtthread.h"
#include <stdbool.h>
/**************************I2C参数定义,I2C1或I2C2********************************/
#define I2Cx I2C1
#define I2C_APBxClock_FUN RCC_APB1PeriphClockCmd
#define I2C_CLK RCC_APB1Periph_I2C1
#define I2C_GPIO_APBxClock_FUN RCC_APB2PeriphClockCmd
#define I2C_GPIO_CLK RCC_APB2Periph_GPIOB
#define I2C_SCL_PORT GPIOB
#define I2C_SCL_PIN GPIO_Pin_6
#define I2C_SDA_PORT GPIOB
#define I2C_SDA_PIN GPIO_Pin_7
/* STM32 I2C 快速模式 */
#define I2C_Speed 100000 //*
/* 这个地址只要与STM32外挂的I2C器件地址不一样即可 */
#define I2Cx_OWN_ADDRESS7 0X0A
#define MCP4725_ADDR 0x60//MCP4725默认地址
void I2C1_Init(void);
void I2C_WriteDAC(uint16_t data,bool mod);
#endif //_I2C_H_
#include "./I2C/i2c.h"
/**
* @brief I2C I/O配置
* @param 无
* @retval 无
*/
static void I2C_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* 使能与 I2C 有关的时钟 */
I2C_GPIO_APBxClock_FUN ( I2C_GPIO_CLK, ENABLE );
I2C_APBxClock_FUN ( I2C_CLK, ENABLE );
/* I2C_SCL、I2C_SDA*/
GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // 开漏输出
GPIO_Init(I2C_SCL_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = I2C_SDA_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // 开漏输出
GPIO_Init(I2C_SDA_PORT, &GPIO_InitStructure);
}
/**
* @brief I2C 工作模式配置
* @param 无
* @retval 无
*/
static void I2C_Mode_Configu(void)
{
I2C_InitTypeDef I2C_InitStructure;
/* I2C 配置 */
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
/* 高电平数据稳定,低电平数据变化 SCL 时钟线的占空比 */
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 =I2Cx_OWN_ADDRESS7;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable ;
/* I2C的寻址模式 */
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
/* 通信速率 */
I2C_InitStructure.I2C_ClockSpeed = I2C_Speed;
/* I2C 初始化 */
I2C_Init(I2Cx, &I2C_InitStructure);
/* 使能 I2C */
I2C_Cmd(I2Cx, ENABLE);
}
/**
* @brief I2C 外设(EEPROM)初始化
* @param 无
* @retval 无
*/
void I2C1_Init(void)
{
I2C_GPIO_Config();
I2C_Mode_Configu();
}
写入dac值函数
/*********************************************
* 写DAC模块寄存器 *
*参数1:写入值(0-4095,0为0V电压,4095为100% *
VDD电压) *
*参数2:true-快速模式(不写入EEPROM),false-*
标准模式(写入EEPROM)即首次上电从EEPROM中读 *
取值。 *
*返回值:无 *
*********************************************/
void I2C_WriteDAC(uint16_t data,bool mod)
{
if(data>4095)
data=4095;
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
I2C_GenerateSTART(I2C1, ENABLE);//开启I2C1
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));/*EV5,主模式*/
I2C_Send7bitAddress(I2C1, MCP4725_ADDR<<1 , I2C_Direction_Transmitter);//MCP4725器件地址 -- 默认0x60
if(mod)//判断是否是快速模式,即只写DAC寄存器不写入EEPROM
{
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, (data&0xf00)>>8);//取出高四位
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1, data&0xff);//发送数据
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}
else//标准模式
{
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, 64);//64代表写寄存器
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1, data>>4);//发送数据
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1, (data&15)<<4);//发送数据
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}
I2C_GenerateSTOP(I2C1, ENABLE);//关闭I2C1总线
}
厂家只给了arduino的例程
#include <Wire.h>//Include the Wire library to talk I2C
//This is the I2C Address of the MCP4725, by default (A0 pulled to GND).
//Please note that this breakout is for the MCP4725A0.
#define MCP4725_ADDR 0x60
//For devices with A0 pulled HIGH, use 0x61
//Sinewave Tables were generated using this calculator:
//http://www.daycounter.com/Calculators/Sine-Generator-Calculator.phtml
int lookup = 0;//varaible for navigating through the tables
int sintab2[512] =
{
2048, 2073, 2098, 2123, 2148, 2174, 2199, 2224,
2249, 2274, 2299, 2324, 2349, 2373, 2398, 2423,
2448, 2472, 2497, 2521, 2546, 2570, 2594, 2618,
2643, 2667, 2690, 2714, 2738, 2762, 2785, 2808,
2832, 2855, 2878, 2901, 2924, 2946, 2969, 2991,
3013, 3036, 3057, 3079, 3101, 3122, 3144, 3165,
3186, 3207, 3227, 3248, 3268, 3288, 3308, 3328,
3347, 3367, 3386, 3405, 3423, 3442, 3460, 3478,
3496, 3514, 3531, 3548, 3565, 3582, 3599, 3615,
3631, 3647, 3663, 3678, 3693, 3708, 3722, 3737,
3751, 3765, 3778, 3792, 3805, 3817, 3830, 3842,
3854, 3866, 3877, 3888, 3899, 3910, 3920, 3930,
3940, 3950, 3959, 3968, 3976, 3985, 3993, 4000,
4008, 4015, 4022, 4028, 4035, 4041, 4046, 4052,
4057, 4061, 4066, 4070, 4074, 4077, 4081, 4084,
4086, 4088, 4090, 4092, 4094, 4095, 4095, 4095,
4095, 4095, 4095, 4095, 4094, 4092, 4090, 4088,
4086, 4084, 4081, 4077, 4074, 4070, 4066, 4061,
4057, 4052, 4046, 4041, 4035, 4028, 4022, 4015,
4008, 4000, 3993, 3985, 3976, 3968, 3959, 3950,
3940, 3930, 3920, 3910, 3899, 3888, 3877, 3866,
3854, 3842, 3830, 3817, 3805, 3792, 3778, 3765,
3751, 3737, 3722, 3708, 3693, 3678, 3663, 3647,
3631, 3615, 3599, 3582, 3565, 3548, 3531, 3514,
3496, 3478, 3460, 3442, 3423, 3405, 3386, 3367,
3347, 3328, 3308, 3288, 3268, 3248, 3227, 3207,
3186, 3165, 3144, 3122, 3101, 3079, 3057, 3036,
3013, 2991, 2969, 2946, 2924, 2901, 2878, 2855,
2832, 2808, 2785, 2762, 2738, 2714, 2690, 2667,
2643, 2618, 2594, 2570, 2546, 2521, 2497, 2472,
2448, 2423, 2398, 2373, 2349, 2324, 2299, 2274,
2249, 2224, 2199, 2174, 2148, 2123, 2098, 2073,
2048, 2023, 1998, 1973, 1948, 1922, 1897, 1872,
1847, 1822, 1797, 1772, 1747, 1723, 1698, 1673,
1648, 1624, 1599, 1575, 1550, 1526, 1502, 1478,
1453, 1429, 1406, 1382, 1358, 1334, 1311, 1288,
1264, 1241, 1218, 1195, 1172, 1150, 1127, 1105,
1083, 1060, 1039, 1017, 995, 974, 952, 931,
910, 889, 869, 848, 828, 808, 788, 768,
749, 729, 710, 691, 673, 654, 636, 618,
600, 582, 565, 548, 531, 514, 497, 481,
465, 449, 433, 418, 403, 388, 374, 359,
345, 331, 318, 304, 291, 279, 266, 254,
242, 230, 219, 208, 197, 186, 176, 166,
156, 146, 137, 128, 120, 111, 103, 96,
88, 81, 74, 68, 61, 55, 50, 44,
39, 35, 30, 26, 22, 19, 15, 12,
10, 8, 6, 4, 2, 1, 1, 0,
0, 0, 1, 1, 2, 4, 6, 8,
10, 12, 15, 19, 22, 26, 30, 35,
39, 44, 50, 55, 61, 68, 74, 81,
88, 96, 103, 111, 120, 128, 137, 146,
156, 166, 176, 186, 197, 208, 219, 230,
242, 254, 266, 279, 291, 304, 318, 331,
345, 359, 374, 388, 403, 418, 433, 449,
465, 481, 497, 514, 531, 548, 565, 582,
600, 618, 636, 654, 673, 691, 710, 729,
749, 768, 788, 808, 828, 848, 869, 889,
910, 931, 952, 974, 995, 1017, 1039, 1060,
1083, 1105, 1127, 1150, 1172, 1195, 1218, 1241,
1264, 1288, 1311, 1334, 1358, 1382, 1406, 1429,
1453, 1478, 1502, 1526, 1550, 1575, 1599, 1624,
1648, 1673, 1698, 1723, 1747, 1772, 1797, 1822,
1847, 1872, 1897, 1922, 1948, 1973, 1998, 2023
};
void setup()
{
Wire.begin();
// Set A2 and A3 as Outputs to make them our GND and Vcc,
//which will power the MCP4725
pinMode(A2, OUTPUT);
pinMode(A3, OUTPUT);
digitalWrite(A2, LOW);//Set A2 as GND
digitalWrite(A3, HIGH);//Set A3 as Vcc
}
//---------------------------------------------------
void loop()
{
Wire.beginTransmission(MCP4725_ADDR);
Wire.write(64); // cmd to update the DAC
Wire.write(2048 >> 4); // the 8 most significant bits...
Wire.write((2048 & 15) << 4); // the 4 least significant bits...
Wire.endTransmission();
lookup = (lookup + 1) & 511;
}
我一开始照着arduino的例程写stm32发现不行,会卡死在I2C的EV6事件,怎么调试都不行
几乎所有方法都试过之后无从下手了,然后来看arduino的I2C底层配置最终找到了原因`
void TwoWire::beginTransmission(uint8_t address)
{
// indicate that we are transmitting
transmitting = 1;
// set address of targeted slave
txAddress = address << 1;
// reset tx buffer iterator vars
txBufferIndex = 0;
txBufferLength = 0;
}
原因在这txAddress = address << 1;行代码,把器件地址左移了一位,而我却是直接发送MCP4725的地址,最后在发送时左移1位就解决。然后昨天想在论坛上找个STM32硬件I2C控制MCP4725的代码参考一下自己错在哪,居然全都要钱下载,于是乎就贴上自己已经测试成功的代码给各位参考。
最后
以上就是勤恳帽子为你收集整理的MCP4725使用STM32硬件I2C(附代码)的全部内容,希望文章能够帮你解决MCP4725使用STM32硬件I2C(附代码)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复