SPI ADUM1411驱动
void SPI_AD7689_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable SPI1 and GPIO clocks */
/*!< SPI_FLASH_SPI_CS_GPIO, SPI_FLASH_SPI_MOSI_GPIO,
SPI_FLASH_SPI_MISO_GPIO, SPI_FLASH_SPI_DETECT_GPIO
and SPI_FLASH_SPI_SCK_GPIO Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//这句必须加,我的理解是使能总线2上IO口的复用功能,不加的话,引脚上不出信号。
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);//关闭重映射
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|
RCC_APB2Periph_SPI1 ,
ENABLE);
/*!< Configure SPI_FLASH_SPI pins: SCK */
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_5 |GPIO_Pin_6|GPIO_Pin_7 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*!< Configure SPI_FLASH_SPI pins: SCK */
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_4 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* SPI1 configuration */
// W25X16: data input on the DIO pin is sampled on the rising edge of the CLK.
// Data on the DO and DIO pins are clocked out on the falling edge of CLK.
SPI_Cmd(SPI1, DISABLE); //必须加,必须加
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//设置为双线双向全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置为主SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;//SPI发送接收16位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;//时钟悬空低
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //数据捕获于第一个时钟沿
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS由外部管脚管理 CS为低 ,,,,,,STM32只能用soft,
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64; //波特率预分频值为8
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
// SPI_SSOutputCmd(SPI1, ENABLE); //使能或者失能指定的SPI SS输出
/* Enable SPI1 */
SPI_Cmd(SPI1, ENABLE);
}
说下自己的理解关于IO口
typedef enum
{ GPIO_Mode_AIN = 0x0, //模拟输入,使能内部AD功能的时候,引脚定义为这个
GPIO_Mode_IN_FLOATING = 0x04, //浮空输入,作为输入引脚,如果要检查引脚高低则配置为这个类型,配置为其他类型不能正确读回引脚高低状态
GPIO_Mode_IPD = 0x28, //下拉输入,
GPIO_Mode_IPU = 0x48, //上拉输入
GPIO_Mode_Out_OD = 0x14, //开漏输出
GPIO_Mode_Out_PP = 0x10, //推挽输出,作为普通IO口,输出功能
GPIO_Mode_AF_OD = 0x1C, //开漏复用功能
GPIO_Mode_AF_PP = 0x18 //推挽复用功能,不管复用功能的引脚是输入还是输出都定义为这个类型
}GPIOMode_TypeDef;
I2C DS3232驱动:
/* Send STOP condition */
I2C_GenerateSTOP(I2C1, ENABLE);
}
void I2C_DS3232_ByteRead(u8 addr ,u8* pBuffer,u16 no)
{
u8 ReadData,ReadGe,ReadShi;
u16 i;
if(no==0)
return;
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
/*允许1字节1应答模式*/
// I2C_AcknowledgeConfig(I2C1, ENABLE);
/* 发送起始位 */
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));/*EV5,主模式*/
/*发送器件地址(写)*/
I2C_Send7bitAddress(I2C1, DS3232_ADDRESS, I2C_Direction_Transmitter);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
/*发送地址*/
I2C_SendData(I2C1, addr);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));/*数据已发送*/
/*起始位*/
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
/*器件读*/
I2C_Send7bitAddress(I2C1, DS3232_ADDRESS, I2C_Direction_Receiver);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
I2C_AcknowledgeConfig(I2C1, ENABLE); //必要的时候才打开。防止总线死锁
for(i=no;i>1;i--)
{
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)); /* EV7 */
ReadData = I2C_ReceiveData(I2C1);
ReadShi=(ReadData>>4)*10;
ReadGe=ReadData&0x0f;
*pBuffer=ReadShi+ReadGe;
pBuffer++;
}
I2C_AcknowledgeConfig(I2C1, DISABLE); //最后一位后要关闭应答的
I2C_GenerateSTOP(I2C1, ENABLE); //发送停止位
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)); /* EV7 */
ReadData = I2C_ReceiveData(I2C1);
ReadShi=(ReadData>>4)*10;
ReadGe=ReadData&0x0f;
*pBuffer=ReadShi+ReadGe;
// pBuffer++;
//再次允许应答模式
//I2C_AcknowledgeConfig(I2C1, ENABLE);
}
|