公司最近打算采用ST的
单片机,其他单片机工程师比较忙,好吧,我只是个打杂的,于是被抓壮丁来处理,目标是使用I2C总线和一外设
通信,想想也没啥难度。 于是,我参考网上的教程,配置了Keil的开发环境,参照了Keil给的I2C例子,写了个I2C通信代码,可是无法通信,非常着急,希望xdjm路过给打个赏,给找找虫子,非常感谢!
简单的说是这样的,使用I2C2和外设相连,(I2C2连端口复用都没得)
/* Includes ------------------------------------------------------------------*/#include "
STM32f10x_lib.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define I2C2_SLAVE_ADDRESS7 0x00 //I2C2的地址,7位寻址
#define ADV7611_SLAVE_ADDRESS7 0x98 //ADV7611的地址,7位寻址
#define BufferSize 2 //u16
#define ClockSpeed 400000 //2MHz
u8 I2C2_Buffer_Tx[BufferSize]={0,0};
u8 I2C2_Buffer_Rx[BufferSize]={0,0};
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
I2C_InitTypeDef I2C_InitStructure;
EX
ti_InitTypeDef EXTI_InitStructure;
ErrorStatus HSEStartUpStatus;
//自定义的配置功能函数
/* Private functions ---------------------------------------------------------*/
void RCC_Configuration(void); //时钟,使用某功能前必须先激活该模块的时钟
void GPIO_Configuration(void); //GPIO配置信息,使用哪种端口,输入,输出,和初始值
void NVIC_Configuration(void); //中断配置信息
void ADV7611_Write(u8* pBuffer, u16 WriteAddrOffset, u16 NumByteToWrite); //写ADV7611一段数据,字节对齐
void ADV7611_Read(u8* pBuffer, u16 ReadAddrOffset, u16 NumByteToRead); //读ADV7611一段数据,字节对齐
void delay_ms(u16 time);//非精确的延时函数
int main(void)//主过程函数
{
/* System clocks configuration ---------------------------------------------*/
RCC_Configuration();
/* NVIC configuration ------------------------------------------------------*/
NVIC_Configuration();
/* GPIO configuration ------------------------------------------------------*/
GPIO_Configuration();
//reset ADV7611 chips frist
GPIO_ResetBits(GPIOA,GPIO_Pin_9);
delay_ms(5);
GPIO_SetBits(GPIOA,GPIO_Pin_9);
delay_ms(5);
/* I2C configuration ------------------------------------------------------*/
I2C_Configuration();
I2C2_Buffer_Tx[0]=0x00; I2C2_Buffer_Tx[1]=0x00;
ADV7611_Write(I2C2_Buffer_Tx, 0x400, 2);
while (1)
{
}
}
void RCC_Configuration(void)
{
/* RCC system reset(for debug purpose) */
RCC_DeInit();
/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);
/* Wait till HSE is ready */
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus == SUCCESS)
{
/* Enable Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/* Flash 2 wait state */
FLASH_SetLatency(FLASH_Latency_2);
/* HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1);
/* PCLK1 = HCLK/2 */
RCC_PCLK1Config(RCC_HCLK_Div2);
/* PLLCLK = 8MHz * 9 = 72 MHz */
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
/* Enable PLL */
RCC_PLLCmd(ENABLE);
/* Wait till PLL is ready */
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
/* Select PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* Wait till PLL is used as system clock source */
while(RCC_GetSYSCLKSource() != 0x08)
{
}
}
/* Enable peripheral clocks --------------------------------------------------*/
/* GPIOB Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
/* GPIOA Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* AFIO clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
/* I2C1 and I2C2 Periph clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 | RCC_APB1Periph_I2C2, ENABLE);
}
/*******************************************************************************
* Function Name : GPIO_Configuration
* Description : Configures the different GPIO ports.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void GPIO_Configuration(void) //配置GPIO的管脚功能
{
GPIO_InitTypeDef GPIO_InitStructure; //初始化的结构
/* Configure I2C1 pins: SCL and SDA ----------------------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Configure I2C2 pins: SCL and SDA ----------------------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
#ifdef VECT_TAB_RAM
/* Set the Vector Table base location at 0x20000000 */
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else /* VECT_TAB_FLASH */
/* Set the Vector Table base location at 0x08000000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif
}
void I2C_Configuration(void) //配置GPIO的管脚功能
{
//配置I2C1的初始化参数
/* I2C1 configuration ------------------------------------------------------*/
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;//激活ACK
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//7bit的地址模式
I2C_InitStructure.I2C_ClockSpeed = ClockSpeed;//设置I2C的时钟频率
/* Enable I2C1 and I2C2 ----------------------------------------------------*/
I2C_Cmd(I2C1, ENABLE);
I2C_Init(I2C1, &I2C_InitStructure); //初始化I2C1
/* I2C2 configuration ------------------------------------------------------*/
I2C_InitStructure.I2C_OwnAddress1 = I2C2_SLAVE_ADDRESS7;//设置I2C2的地址信息,其他的配置信息和I2C1相同
I2C_Cmd(I2C2, ENABLE);
I2C_Init(I2C2, &I2C_InitStructure);//初始化I2C2
}
void ADV7611_Write(u8* pBuffer, u16 WriteAddrOffset, u16 NumByteToWrite)
{
u8 Offset_MSB = 0; u8 Offset_LSB = 0;
/*wait I2C idle statues */
while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));
/* Send I2C2 START condition */
I2C_GenerateSTART(I2C2, ENABLE); //I2C2产生开始信号(S),进入主发送模式
/* Test on I2C2 EV5 and clear it */
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)); //产生开始信息后,需要检测是否有EV5事件通知
/* Send MDIN380 slave Address for write */
I2C_Send7bitAddress(I2C2, ADV7611_SLAVE_ADDRESS7 , I2C_Direction_Transmitter);//发送从设备的地址,和传输方向(R?W?)
/* Test on EV6 and clear it */
while(! I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
//I2C_Cmd(I2C2, ENABLE);
/*with 16bit BUS Mode,then MSB(A10...A8),LSB(A7...A0)*/
Offset_MSB = (u8) ((WriteAddrOffset>>8)&0x0F);
Offset_LSB = (u8) (WriteAddrOffset&0x00FF);
/* Send the ADV7611's internal address (MSB) to write to */
I2C_SendData(I2C2, Offset_MSB);
/* Test on EV8 and clear it */
while(! I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
/* Send the ADV7611's internal address (LSB) to write to */
I2C_SendData(I2C2, Offset_LSB);
/* Test on EV8 and clear it */
while(! I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
/* While there is data to be written */
while(NumByteToWrite--)
{
/* Send the current byte */
I2C_SendData(I2C2, *pBuffer);
/* Point to the next byte to be written */
pBuffer++;
/* Test on EV8 and clear it */
while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}
/* Send STOP condition */
I2C_GenerateSTOP(I2C2, ENABLE);
}
void delay_ms(u16 time)
{
u16 i=0;
while(time--)
{
i=12000;
while(i--);
}
}
一周热门 更多>