模拟 I2C 本文展示了STM32 I2C Software Transfer 模拟 I2C 内容涉及 : I2C 字节数据模拟输出独写 缓存读写 USART串口的识别 IO口输入输出 按键的外部中断处理 32位数据通讯,字符串通讯,单字符通讯
完整代码 : : GITthub 代码源码下载 24C02 数据包: :EEPROM 芯片文件下载
前言
STM32 的I2C简介 如果我们直接控制 STM32的两个 GPIO 引脚,分别用作 SCL及 SDA,按照上述信号的 时序要求,直接像控制 LED 灯那样控制引脚的输出(若是接收数据时则读取 SDA 电平),就 可以实现 I2C 通讯。同样,假如我们按照 USART 的要求去控制引脚,也能实现 USART 通 讯。所以只要遵守协议,就是标准的通讯,不管您如何实现它,不管是 ST 生产的控制器还 是 ATMEL 生产的存储器, 都能按通讯标准交互。 由于直接控制 GPIO 引脚电平产生通讯时序时,需要由 CPU 控制每个时刻的引脚状态, 所以称之为“软件模拟协议”方式。 相对地,还有“硬件协议”方式,STM32 的 I2C 片上外设专门负责实现 I2C 通讯协议, 只要配置好该外设,它就会自动根据协议要求产生通讯信号,收发数据并缓存起来,CPU 只要检测该外设的状态和访问数据寄存器,就能完成数据收发。这种由硬件外设处理 I2C 协议的方式减轻了 CPU 的工作,且使软件设计更加简单。 i2c通信协议,从物理层上来看这是一种非常简洁明了的通信协议。本身一共就两条总线,一条SCL(时钟总线),一条SDA(数据总线)。通信原理是通过对SCL和SDA线高低电平时序的控制,来 产生I2C总线协议所需要的信号进行数据的传递。在总线空闲状态时,这两根线一般被上面所接的上拉电阻拉高,保持着高电平( 原文链接:ttps://blog.csdn.net/qq_42660303/article/details/81154995)
一、 编程要点
I2C: 1) 配置通讯使用的目标引脚为开漏模式 2) 使能 I2C 外设的时钟 3) 配置 I2C 外设的模式、地址、速率等参数并使能 I2C 外设 4) 编写基本 I2C 按字节收发的函数 5) 编写读写 EEPROM 存储内容的函数 6) 编写测试程序,对读写数据进行校验
二、使用步骤
1.理解原理图
通讯引脚 I2C 的所有硬件架构都是根据图中左侧 SCL 线和 SDA 线展开的(其中的 SMBA 线用于 SMBUS的警告信号,I2C通讯没有使用)。STM32芯片有多个 I2C外设,它们的 I2C 通讯信 号引出到不同的 GPIO 引脚上,使用时必须配置到这些指定的引脚,见
I2C协议规定,总线上数据的传输必须以一个起始信号作为开始条件,以一个结束信号作为传输的停止条件。起始和结束信号总是由主设备产生。总线在空闲状态 时,SCL和SDA都保持着高电平,当SCL为高电平而SDA由高到低的跳变,表示产生一个起始条件;当SCL为高而SDA由低到高的跳变,表示产生一个 停止条件。在起始条件产生后,总线处于忙状态,由本次数据传输的主从设备独占,其他I2C器件无法访问总线;而在停止条件产生后,本次数据传输的主从设备 将释放总线,总线再次处于空闲状态。如图所示:原文链接:https://blog.csdn.net/qq_42660303/article/details/81154995
在了解起始条件和停止条件后,我们再来看看在这个过程中数据的传输是如何进行的。前面我们已经提到过,数据传输以字节为单位。主设备在SCL线上产生每个 时钟脉冲的过程中将在SDA线上传输一个数据位,当一个字节按数据位从高位到低位的顺序传输完后,紧接着从设备将拉低SDA线,回传给主设备一个应答位, 此时才认为一个字节真正的被传输完成。当然,并不是所有的字节传输都必须有一个应答位,比如:当从设备不能再接收主设备发送的数据时,从设备将回传一个否 定应答位。数据传输的过程如图所示:原文链接:https://blog.csdn.net/qq_42660303/article/details/81154995
(注意)Keil 配置状态
我的博客这里有项目配置 设计; 点击链接 (https://blog.csdn.net/u012651389/article/details/119189949) 在这里插入图片描述
2.建立主程序 main.c
在这里插入图片描述
代码如下 :
#include "stm32f10x.h"
#include "PROJ_book.h"
void fn_LED_Flash_Init(void);
void fn_usart_show_Init(void);
void fn_DMA_show_Init(void);
void fn_I2C_EE_Init(void);
void fn_I2C_EE_Soft_Init(void);
uint8_t writeData[_I2C_PageSize]={4,5,6,7,8,9,10,11};
uint8_t writeData2[_I2C_PageSize]={24,25,26,27,28,29,30,31};
uint8_t ReadData[_I2C_PageSize]={0};
int main(void)
{
uint8_t i=0;
fn_RCC_Init();
fn_Led_Init();
fn_Key_Init();
fn_USART_Init();
fn_LED_Flash_Init();
fn_usart_show_Init();
fn_EXTI_GPIO_Config();
fn_DMA_show_Init();
fn_I2C_EE_Init();
fn_I2C_EE_Soft_Init();
while(1);
}
void fn_LED_Flash_Init(void){
uint16_t count_Init = 2;
printf("\n ---> LED开始运行 \n");
while(count_Init-->0){
fn_LED_ALL_OFF();
__R_OUT__;
fn_Systick_Delay(500,_Systick_ms);
fn_LED_ALL_OFF();
__G_OUT__;
fn_Systick_Delay(500,_Systick_ms);
fn_LED_ALL_OFF();
__B_OUT__;
fn_Systick_Delay(500,_Systick_ms);
fn_LED_ALL_OFF();
__R_OUT__;
}
}
void fn_usart_show_Init(void){
fn_Usart_Send_Byte(_DEBUG_USARTx,'\r');
printf("-->串口通信指测试完毕 \n");
fn_Usart_SendString(_DEBUG_USARTx," : wangqi \n");
}
void fn_DMA_show_Init(void){
printf("\n ---> DMA开始运行 \n");
_DMA_ROM_TO_RAM(Map_BUFFER_SIZE ,aSRC_Cont_Buffer , aDST_Buffer);
_DMA_RAM_TO_USART(Map_BUFFER_SIZE ,USART_Source_ADDR , aDST_Buffer);
printf("---> DMA运行完毕 \n");
}
void fn_I2C_EE_Init(void){
printf("\n-->I2C_函数写入开始 \n");
_I2C_EE_Init();
I2C_Write_fun(writeData ,EEP_Firstpage ,_I2C_PageSize);
I2C_Read_fun(ReadData ,EEP_Firstpage ,_I2C_PageSize);
printf("--->I2C_函数写入完毕\n\r");
}
void fn_I2C_EE_Soft_Init(void){
printf("\n-->I2C_软件函数写入开始 \n");
I2C_Soft_Init();
I2C_Soft_Write_fun(writeData2 ,EEP_Firstpage ,_I2C_PageSize);
I2C_Soft_Read_fun(ReadData ,EEP_Firstpage ,_I2C_PageSize);
printf("\n--->I2C_软件函数写入完毕\n\r");
}
void delay(int x){
int y = 0xFFFFF;
while((x--)>0){
while((y--)>0){
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
}
}
}
3.建立I2C模拟传输的 头文件 I2C_soft_book.h
代码如下 :
#ifndef __I2C_SOFT_BOOK_H_
#define __I2C_SOFT_BOOK_H_
#include "stm32f10x.h"
#define _Soft_I2C_GPIO_APBxClock_FUN RCC_APB2PeriphClockCmd
#define _Soft_I2C_GPIO_CLK RCC_APB2Periph_GPIOB
#define _Soft_I2C_SCL_PORT GPIOB
#define _Soft_I2C_SCL_PIN GPIO_Pin_6
#define _Soft_I2C_SDA_PORT GPIOB
#define _Soft_I2C_SDA_PIN GPIO_Pin_7
#define _I2C_SCL_1() _Soft_I2C_SCL_PORT->BSRR = _Soft_I2C_SCL_PIN
#define _I2C_SCL_0() _Soft_I2C_SCL_PORT->BRR = _Soft_I2C_SCL_PIN
#define _I2C_SDA_1() _Soft_I2C_SCL_PORT->BSRR = _Soft_I2C_SDA_PIN
#define _I2C_SDA_0() _Soft_I2C_SCL_PORT->BRR = _Soft_I2C_SDA_PIN
#define _I2C_SDA_READ() ((_Soft_I2C_SCL_PORT->IDR & _Soft_I2C_SDA_PIN)!=0)
#define I2C_WR 0
#define I2C_RD 1
#define Soft_EEPROM_ADDRESS 0xA0
#define _I2C_Soft_PageSize 8
#define _I2C_Soft_SIZE 256
#define EEP_Soft_Firstpage 0x90
void I2C_Soft_Init(void);
void EE_Soft_Trase(void);
uint8_t I2C_Soft_Write_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite);
uint8_t I2C_Soft_Read_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite);
#endif
4.建立I2C模拟传输的 头文件 I2C_soft_book.c
代码如下 :
#include "I2C_soft_book.h"
#include "Systick_book.h"
static I2C_GPIO_Soft_Config(void){
GPIO_InitTypeDef GPIO_InitStructure;
_Soft_I2C_GPIO_APBxClock_FUN(_Soft_I2C_GPIO_CLK , ENABLE);
GPIO_InitStructure.GPIO_Pin = _Soft_I2C_SCL_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(_Soft_I2C_SCL_PORT,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = _Soft_I2C_SDA_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(_Soft_I2C_SDA_PORT,&GPIO_InitStructure);
}
static void I2C_Start(void){
_I2C_SCL_1();
_I2C_SDA_1();
fn_Systick_Delay(50,_Systick_us);
_I2C_SDA_0();
fn_Systick_Delay(50,_Systick_us);
_I2C_SCL_0();
fn_Systick_Delay(50,_Systick_us);
}
static void I2C_Stop(void){
_I2C_SDA_0();
_I2C_SCL_1();
fn_Systick_Delay(50,_Systick_us);
_I2C_SDA_1();
}
static void I2C_SendByte(uint8_t _ucByte){
uint8_t i;
for( i=0; i<8;i++ ){
if(_ucByte & 0x80){
_I2C_SDA_1();
}else{
_I2C_SDA_0();
}
fn_Systick_Delay(50,_Systick_us);
_I2C_SCL_1();
fn_Systick_Delay(50,_Systick_us);
_I2C_SCL_0();
_ucByte <<=1;
fn_Systick_Delay(50,_Systick_us);
}
_I2C_SDA_1();
}
static uint8_t I2C_ReadByte(void){
uint8_t i;
uint8_t value;
value = 0;
for(i=0 ;i<8 ;i++ ){
value <<=1;
_I2C_SCL_1();
fn_Systick_Delay(50,_Systick_us);
if(_I2C_SDA_READ()){
value++;
}
_I2C_SCL_0();
fn_Systick_Delay(50,_Systick_us);
}
return value;
}
static uint8_t I2C_WaitAck(void){
uint8_t re;
_I2C_SDA_1();
fn_Systick_Delay(50,_Systick_us);
_I2C_SCL_1();
fn_Systick_Delay(50,_Systick_us);
if(_I2C_SDA_READ()){
re = 1;
}else{
re = 0;
}
_I2C_SCL_0();
fn_Systick_Delay(50,_Systick_us);
return re;
}
static void I2C_ACK(void){
_I2C_SDA_0();
fn_Systick_Delay(50,_Systick_us);
_I2C_SCL_1();
fn_Systick_Delay(50,_Systick_us);
_I2C_SCL_0();
fn_Systick_Delay(50,_Systick_us);
_I2C_SDA_1();
}
static void I2C_NACK(void){
_I2C_SDA_1();
fn_Systick_Delay(50,_Systick_us);
_I2C_SCL_1();
fn_Systick_Delay(50,_Systick_us);
_I2C_SCL_0();
fn_Systick_Delay(50,_Systick_us);
}
static uint8_t I2C_CheckDevice(uint8_t _Address){
uint8_t ucAck;
I2C_GPIO_Soft_Config();
I2C_Start();
I2C_SendByte(_Address | I2C_WR);
ucAck = I2C_WaitAck();
I2C_Stop();
return ucAck;
}
static uint8_t EE_Soft_Check_State(void){
if(I2C_CheckDevice(Soft_EEPROM_ADDRESS)==0){return 1;}
else{I2C_Stop(); return 0;}
}
static uint8_t I2C_Soft_BufferRead(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead){
uint16_t i ;
I2C_Start();
I2C_SendByte(Soft_EEPROM_ADDRESS | I2C_WR);
if(I2C_WaitAck()!=0){printf("EEPROM 错误 1 !\r\n"); goto CMD_Fail;}
I2C_SendByte((uint8_t)ReadAddr);
if(I2C_WaitAck()!=0){printf("EEPROM 错误 2 !\r\n");goto CMD_Fail;}
I2C_Start();
I2C_SendByte(Soft_EEPROM_ADDRESS| I2C_RD);
if(I2C_WaitAck()!=0){printf("EEPROM 错误3 !\r\n"); goto CMD_Fail;}
for(i=0 ;i<NumByteToRead ;i++ ){
pBuffer[i] = I2C_ReadByte();
if(i!=NumByteToRead-1){
I2C_ACK();
}else{
I2C_NACK();
}
}
I2C_Stop();
return 1;
CMD_Fail:
I2C_Stop();
return 0;
}
static uint8_t EE_Soft_WriteBytes(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead){
uint16_t i , m;
uint16_t usAddr;
usAddr = ReadAddr;
for(i=0 ;i<NumByteToRead;i++ ){
if((i==0)||(usAddr)&(_I2C_Soft_PageSize-1)==0){
I2C_Stop();
m = 100;
for (m = 0; m < 100; m++){
I2C_Start();
I2C_SendByte(Soft_EEPROM_ADDRESS| I2C_WR);
if(I2C_WaitAck()==0){break;}
}
if(m==100){printf("EEPROM 错误 4 !\r\n"); goto CMD_FAIL_bytes ; }
I2C_SendByte((uint8_t)usAddr);
if(I2C_WaitAck()!=0){printf("EEPROM 错误 5 !\r\n"); goto CMD_FAIL_bytes;}
}
I2C_SendByte(pBuffer[i]);
if(I2C_WaitAck()!=0){printf("EEPROM 错误 7 !\r\n"); goto CMD_FAIL_bytes;}
usAddr++;
}
I2C_Stop();
return 1;
CMD_FAIL_bytes:
I2C_Stop();
return 0;
}
void EE_Soft_Trase(void){
uint16_t i ;
uint8_t buf[_I2C_Soft_SIZE]={0};
for(i=0 ;i<_I2C_Soft_SIZE ;i++ ){
buf[i] = 0xFF;
}
if(EE_Soft_WriteBytes(buf,0,_I2C_Soft_SIZE)==0){
printf("擦除EEPROM出错!\r\n");
return;
}else{
printf("擦除EEPROM出错!\r\n");
}
}
void I2C_Soft_Init(void){
if(EE_Soft_Check_State()==0){
printf("没有检测到串行EEPROM!\r\n");
}
}
uint8_t I2C_Soft_Write_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite){
uint16_t i;
if(EE_Soft_Check_State()==0){
printf("没有检测到串行EEPROM!\r\n");
return 1;
}
if(EE_Soft_WriteBytes(pBuffer,WriteAddr ,NumByteToWrite)==0){
printf("写EEPROM错误!\r\n");
return 1;
}else{
printf("写EEPROM成功!\r\n");
}
fn_Systick_Delay(150,_Systick_us);
printf("EEPROM写入数据检查检查\r\n");
for(i=0 ;i<NumByteToWrite ;i++ ){
printf(" %d ",pBuffer[i]);
if((i & 15)==15){
printf("\r\n");
}
}
return 0;
}
uint8_t I2C_Soft_Read_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite){
uint16_t i;
if(I2C_Soft_BufferRead(pBuffer,WriteAddr,NumByteToWrite)==0){
printf("读EEPROM错误!\r\n");
return 1;
}else{
printf("\n读EEPROM成功!\r\n");
}
printf("EEPROM读取数据数据检查 \r\n");
for(i=0 ;i<NumByteToWrite ;i++ ){
printf(" %d ",pBuffer[i]);
if((i & 15)==15){
printf("\r\n");
}
}
return 1;
}
5.建立I2C硬件传输的 头文件 I2C_book.h
代码如下 :
#ifndef __I2C_BOOK_H_
#define __I2C_BOOK_H_
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "USART_book.h"
#define _EEPROM_I2Cx I2C1
#define _EEPROM_I2C_APBxClock_FUN RCC_APB1PeriphClockCmd
#define _EEPROM_I2C_CLK RCC_APB1Periph_I2C1
#define _EEPROM_I2C_GPIO_APBxClock_FUN RCC_APB2PeriphClockCmd
#define _EEPROM_I2C_GPIO_CLK RCC_APB2Periph_GPIOB
#define _EEPROM_I2C_SCL_PORT GPIOB
#define _EEPROM_I2C_SCL_PIN GPIO_Pin_6
#define _EEPROM_I2C_SDA_PORT GPIOB
#define _EEPROM_I2C_SDA_PIN GPIO_Pin_7
#define _I2C_Speed 400000
#define _I2Cx_OWN_ADDRESS7 0x5f
#define _I2C_PageSize 8
#define EEP_Firstpage 0x90
#define EEP_SIZE 0xFF
#define EEPROM_ADDRESS 0xA0
void _I2C_EE_Init(void);
void I2C_Write_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite);
void I2C_Read_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite);
#endif
6.建立I2C硬件传输的 头文件 I2C_book.c
代码如下 :
#include "I2C_book.h"
#include "Systick_book.h"
static void I2C_GPIO_Config(void){
GPIO_InitTypeDef GPIO_InitStructure;
_EEPROM_I2C_APBxClock_FUN(_EEPROM_I2C_CLK,ENABLE);
_EEPROM_I2C_GPIO_APBxClock_FUN(_EEPROM_I2C_GPIO_CLK,ENABLE);
GPIO_InitStructure.GPIO_Pin = _EEPROM_I2C_SCL_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(_EEPROM_I2C_SCL_PORT,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = _EEPROM_I2C_SDA_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(_EEPROM_I2C_SDA_PORT,&GPIO_InitStructure);
}
static void I2C_Mode_Config(void){
I2C_InitTypeDef I2C_InitStructure;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = _I2Cx_OWN_ADDRESS7;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = _I2C_Speed;
I2C_Init(_EEPROM_I2Cx,&I2C_InitStructure);
I2C_Cmd(_EEPROM_I2Cx,ENABLE);
}
static uint32_t I2C_TIMEOUT_UserCallback(uint8_t errorCode){
fn_Usart_SendString(_DEBUG_USARTx,"I2C 等待超时!errorCode =");
printf("%d\n",errorCode);
return 0;
}
#define I2CT_FLAG_TIMEOUT ((uint32_t)0x6000)
#define I2CT_LONG_TIMEOUT ((uint32_t)(10*I2CT_FLAG_TIMEOUT))
static uint16_t I2CTimeout;
static uint32_t I2C_EE_ByteWrite(u8* pBuffer, uint8_t WriteAddr ){
I2CTimeout = I2CT_LONG_TIMEOUT;
while(I2C_GetFlagStatus(_EEPROM_I2Cx , ENABLE)){
if((I2CTimeout--) == 0){return I2C_TIMEOUT_UserCallback(4);}
}
I2C_GenerateSTART(_EEPROM_I2Cx , ENABLE);
I2CTimeout = I2CT_LONG_TIMEOUT;
while(!I2C_CheckEvent(_EEPROM_I2Cx,I2C_EVENT_MASTER_MODE_SELECT)){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(5);}
}
I2C_Send7bitAddress(_EEPROM_I2Cx,EEPROM_ADDRESS,I2C_Direction_Transmitter);
I2CTimeout = I2CT_LONG_TIMEOUT;
while(I2C_CheckEvent(_EEPROM_I2Cx,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) == ERROR){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(6);}
}
I2C_SendData(_EEPROM_I2Cx,WriteAddr);
I2CTimeout = I2CT_LONG_TIMEOUT;
while(!I2C_CheckEvent(_EEPROM_I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(2);}
}
I2C_SendData(_EEPROM_I2Cx,*pBuffer);
I2CTimeout = I2CT_LONG_TIMEOUT;
while(!I2C_CheckEvent(_EEPROM_I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(3);}
}
I2C_SendData(_EEPROM_I2Cx,ENABLE);
return 1;
}
static void I2C_EE_WaitEepromStandbyState(void){
vu16 SR1_Tmp = 0;
do{
I2C_GenerateSTART(_EEPROM_I2Cx,ENABLE);
SR1_Tmp = I2C_ReadRegister(_EEPROM_I2Cx, I2C_Register_SR1);
I2C_Send7bitAddress(_EEPROM_I2Cx,EEPROM_ADDRESS,I2C_Direction_Transmitter);
}while(!(I2C_ReadRegister(_EEPROM_I2Cx, I2C_Register_SR1) & 0x0002));
I2C_ClearFlag(_EEPROM_I2Cx, I2C_FLAG_AF);
I2C_GenerateSTOP(_EEPROM_I2Cx , ENABLE);
}
static uint8_t I2C_EE_PageWrite(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite){
I2CTimeout = I2CT_LONG_TIMEOUT;
while(I2C_GetFlagStatus(_EEPROM_I2Cx , ENABLE)){
if((I2CTimeout--) == 0){return I2C_TIMEOUT_UserCallback(4);}
}
I2C_GenerateSTART(_EEPROM_I2Cx , ENABLE);
I2CTimeout = I2CT_LONG_TIMEOUT;
while(!I2C_CheckEvent(_EEPROM_I2Cx,I2C_EVENT_MASTER_MODE_SELECT)){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(5);}
}
I2C_Send7bitAddress(_EEPROM_I2Cx,EEPROM_ADDRESS,I2C_Direction_Transmitter);
I2CTimeout = I2CT_LONG_TIMEOUT;
while(I2C_CheckEvent(_EEPROM_I2Cx,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) == ERROR){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(6);}
}
I2C_SendData(_EEPROM_I2Cx,WriteAddr);
I2CTimeout = I2CT_LONG_TIMEOUT;
while(!I2C_CheckEvent(_EEPROM_I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTING)){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(7);}
}
while(NumByteToWrite--){
I2C_SendData(_EEPROM_I2Cx,*pBuffer++);
I2CTimeout = I2CT_FLAG_TIMEOUT;
while(!I2C_CheckEvent(_EEPROM_I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(8);}
}
}
I2C_GenerateSTOP(_EEPROM_I2Cx,ENABLE);
return 1;
}
#define I2C_PageSize 8
static void I2C_EE_BufferWrite(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite){
u8 NumOfPage = 0, NumOfSingle = 0 , Addr = 0 , count = 0,temp = 0;
Addr = WriteAddr % I2C_PageSize;
count = I2C_PageSize - Addr;
NumOfPage = NumByteToWrite / I2C_PageSize;
NumOfSingle = NumByteToWrite % I2C_PageSize;
if(Addr == 0){
if(NumOfPage==0){
I2C_EE_PageWrite(pBuffer , WriteAddr, NumOfSingle);
I2C_EE_WaitEepromStandbyState();
}
else{
while(NumOfPage--){
I2C_EE_PageWrite(pBuffer , WriteAddr, I2C_PageSize);
I2C_EE_WaitEepromStandbyState();
WriteAddr += I2C_PageSize ;
pBuffer += I2C_PageSize ;
}
if(NumOfSingle != 0){
I2C_EE_PageWrite(pBuffer , WriteAddr, NumOfSingle);
I2C_EE_WaitEepromStandbyState();
}
}
}
else{
if(NumOfPage == 0){
if(NumOfSingle > count){
temp = NumOfSingle - count;
I2C_EE_PageWrite(pBuffer , WriteAddr, count);
I2C_EE_WaitEepromStandbyState();
WriteAddr += count ;
pBuffer += count ;
I2C_EE_PageWrite(pBuffer , WriteAddr, temp);
I2C_EE_WaitEepromStandbyState();
}else{
I2C_EE_PageWrite(pBuffer , WriteAddr, NumByteToWrite);
I2C_EE_WaitEepromStandbyState();
}
}
else{
NumByteToWrite -= count;
NumOfPage = NumByteToWrite / I2C_PageSize ;
NumOfSingle = NumByteToWrite % I2C_PageSize;
if(count!=0){
I2C_EE_PageWrite(pBuffer , WriteAddr, count);
I2C_EE_WaitEepromStandbyState();
WriteAddr += count ;
pBuffer += count ;
}
while(NumOfPage--){
I2C_EE_PageWrite(pBuffer , WriteAddr, I2C_PageSize);
I2C_EE_WaitEepromStandbyState();
WriteAddr += I2C_PageSize ;
pBuffer += I2C_PageSize ;
}
if(NumOfSingle !=0){
I2C_EE_PageWrite(pBuffer , WriteAddr, NumOfSingle);
I2C_EE_WaitEepromStandbyState();
}
}
}
}
static uint8_t I2C_EE_BufferRead(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead){
I2CTimeout = I2CT_LONG_TIMEOUT ;
while(I2C_GetFlagStatus(_EEPROM_I2Cx , I2C_FLAG_BUSY)){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(9);}
}
I2C_GenerateSTART(_EEPROM_I2Cx , ENABLE);
I2CTimeout = I2CT_FLAG_TIMEOUT;
while(! I2C_CheckEvent(_EEPROM_I2Cx , I2C_EVENT_MASTER_MODE_SELECT)){
if((I2CTimeout--)==0){ return I2C_TIMEOUT_UserCallback(10);}
}
I2C_Send7bitAddress(_EEPROM_I2Cx , EEPROM_ADDRESS , I2C_Direction_Transmitter);
I2CTimeout = I2CT_FLAG_TIMEOUT;
while(! I2C_CheckEvent(_EEPROM_I2Cx , I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){
if((I2CTimeout--)==0){ return I2C_TIMEOUT_UserCallback(11);}
}
I2C_Cmd(_EEPROM_I2Cx ,ENABLE );
I2C_SendData(_EEPROM_I2Cx, ReadAddr);
I2CTimeout = I2CT_FLAG_TIMEOUT ;
while(! I2C_CheckEvent(_EEPROM_I2Cx , I2C_EVENT_MASTER_BYTE_TRANSMITTED)){
if((I2CTimeout--)==0){ return I2C_TIMEOUT_UserCallback(12);}
}
I2C_GenerateSTART(_EEPROM_I2Cx , ENABLE);
I2CTimeout = I2CT_FLAG_TIMEOUT;
while(! I2C_CheckEvent(_EEPROM_I2Cx , I2C_EVENT_MASTER_MODE_SELECT)){
if((I2CTimeout--)==0){ return I2C_TIMEOUT_UserCallback(13);}
}
I2C_Send7bitAddress(_EEPROM_I2Cx , EEPROM_ADDRESS , I2C_Direction_Receiver);
I2CTimeout = I2CT_FLAG_TIMEOUT;
while(! I2C_CheckEvent(_EEPROM_I2Cx , I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)){
if((I2CTimeout--)==0){ return I2C_TIMEOUT_UserCallback(14);}
}
while(NumByteToRead){
if(NumByteToRead == 1){
I2C_AcknowledgeConfig(_EEPROM_I2Cx , DISABLE);
}
I2CTimeout = I2CT_LONG_TIMEOUT;
while(I2C_CheckEvent(_EEPROM_I2Cx , I2C_EVENT_MASTER_BYTE_RECEIVED)==0){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(3);}
}
*pBuffer = I2C_ReceiveData(_EEPROM_I2Cx);
pBuffer++;
NumByteToRead--;
}
I2C_GenerateSTOP(_EEPROM_I2Cx , ENABLE);
I2C_AcknowledgeConfig(_EEPROM_I2Cx , ENABLE);
return 1;
}
void _I2C_EE_Init(void){
I2C_GPIO_Config();
I2C_Mode_Config();
}
void I2C_Write_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite){
u16 i;
printf("I2C_写入数据 \n");
I2C_EE_WaitEepromStandbyState();
I2C_EE_PageWrite(pBuffer,WriteAddr, NumByteToWrite);
for(i=0 ;i<NumByteToWrite ;i++ ){
printf("%d ", *pBuffer++);
if(i%16 == 15)
printf("\n\r");
}
printf("\nI2C_写入数据完成 \n");
I2C_EE_WaitEepromStandbyState();
for(i=0 ;i<NumByteToWrite ;i++ ){
printf("%d ", pBuffer[i]);
if(i%16 == 15)
printf("\n\r");
}
}
void I2C_Read_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite){
u16 i;
printf("I2C_数据检测 \n");
I2C_EE_BufferRead(pBuffer,WriteAddr,NumByteToWrite);
printf("\nI2C_数据读取完毕 \n");
for(i=0 ;i<NumByteToWrite ;i++ ){
printf("%d ", pBuffer[i]);
if(i%16 == 15)
printf("\n\r");
}
printf("\n--->I2C_数据检测完成\n");
}
7.建立USART传输的 头文件 USART_book.h
代码如下 :
#ifndef __USART_BOOK_H_
#define __USART_BOOK_H_
#include "stm32f10x.h"
#include <stdio.h>
#include "stm32f10x_usart.h"
#include "stm32f10x_rcc.h"
#define _DEBUG_USARTx USART1
#define _DEBUG_USART_CLK RCC_APB2Periph_USART1
#define _DEBUG_USART_APBxClkCmd RCC_APB2PeriphClockCmd
#define _DEBUG_USART_BAUDRATE 115200
#define _DEBUG_USART_GPIO_CLK RCC_APB2Periph_GPIOA
#define _DEBUG_USART_GPIO_APBxCLKCmd RCC_APB2PeriphClockCmd
#define _DEBUG_USART_TX_GPIO_PORT GPIOA
#define _DEBUG_USART_TX_GPIO_PIN GPIO_Pin_9
#define _DEBUG_USART_TX_GPIO_MODE GPIO_Mode_AF_PP
#define _DEBUG_USART_RX_GPIO_PORT GPIOA
#define _DEBUG_USART_RX_GPIO_PIN GPIO_Pin_10
#define _DEBUG_USART_RX_GPIO_MODE GPIO_Mode_IN_FLOATING
#define _DEBUG_NVIC_USART_IRQ USART1_IRQn
#define _DRBUG_USART_IRQHandler USART1_IRQHandler
void fn_USART_IO_Config(void);
void fn_USART_Config(void);
void fn_USART_Init(void);
void fn_Usart_Send_Byte(USART_TypeDef * pUSARTx , uint8_t ch );
void fn_Usart_SendString(USART_TypeDef *pUSARTx , char * str);
void Usart_SendHalf_32_Word( USART_TypeDef * pUSARTx, uint32_t ch);
int fputc (int ch , FILE *f);
int fgetc(FILE *f);
void _DRBUG_USART_IRQHandler(void);
#endif
8.建立USART传输的C文件 USART_book.c
代码如下 :
#include "USART_book.h"
static void NVIC_Configuration(void){
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = _DEBUG_NVIC_USART_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void fn_USART_IO_Config(void){
GPIO_InitTypeDef GPIO_InitStructure;
_DEBUG_USART_GPIO_APBxCLKCmd(_DEBUG_USART_GPIO_CLK , ENABLE);
GPIO_InitStructure.GPIO_Pin = _DEBUG_USART_TX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = _DEBUG_USART_TX_GPIO_MODE;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(_DEBUG_USART_TX_GPIO_PORT,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = _DEBUG_USART_RX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = _DEBUG_USART_RX_GPIO_MODE;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(_DEBUG_USART_RX_GPIO_PORT,&GPIO_InitStructure);
}
void fn_USART_Config(void){
USART_InitTypeDef USART_InitStructure;
_DEBUG_USART_APBxClkCmd(_DEBUG_USART_CLK , ENABLE);
USART_InitStructure.USART_BaudRate = _DEBUG_USART_BAUDRATE;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx ;
USART_Init(_DEBUG_USARTx , &USART_InitStructure);
NVIC_Configuration();
USART_ITConfig(_DEBUG_USARTx , USART_IT_RXNE , ENABLE);
USART_Cmd(_DEBUG_USARTx , ENABLE);
}
void fn_Usart_Send_Byte(USART_TypeDef * pUSARTx , uint8_t ch ){
USART_SendData(pUSARTx , ch);
while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TXE)==RESET);
}
void fn_Usart_SendString(USART_TypeDef *pUSARTx , char * str){
unsigned int k = 0;
do{
fn_Usart_Send_Byte(pUSARTx,*(str + k++));
}while(*(str + k)!='\0');
while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC));
}
void Usart_SendHalf_32_Word( USART_TypeDef * pUSARTx, uint32_t ch){
uint32_t temp_Half32;
uint8_t temp_Half=0,i_Half=4;
temp_Half32 =ch;
while(i_Half-->0){
temp_Half=(temp_Half32 & 0xFF000000)>>24;
temp_Half32<<=8;
fn_Usart_Send_Byte(pUSARTx,temp_Half);
}
while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC));
}
void fn_USART_Init(void){
fn_USART_IO_Config();
fn_USART_Config();
}
int fputc (int ch , FILE *f){
USART_SendData(_DEBUG_USARTx , (uint8_t)ch);
while(USART_GetFlagStatus(_DEBUG_USARTx,USART_FLAG_TXE)==RESET);
return (ch);
}
int fgetc(FILE *f){
while(USART_GetITStatus(_DEBUG_USARTx,USART_IT_RXNE)==RESET);
return (int)USART_ReceiveData(_DEBUG_USARTx);
}
void _DRBUG_USART_IRQHandler(void){
uint8_t ucTemp = 0;
if(USART_GetITStatus(_DEBUG_USARTx,USART_IT_RXNE)!=RESET){
ucTemp = USART_ReceiveData(_DEBUG_USARTx);
USART_SendData(_DEBUG_USARTx ,ucTemp );
}
}
9.建立DMA传输的 头文件 DMA_book.h
代码如下 :
#ifndef __DMA_BOOK_H_
#define __DMA_BOOK_H_
#include "stm32f10x.h"
#define DMA_CLOCK RCC_AHBPeriph_DMA1
#define Map_DMA_CHANNEL DMA1_Channel6
#define Map_BUFFER_SIZE 20
#define DMA_FLAG_TC DMA1_FLAG_TC6
extern const uint32_t aSRC_Cont_Buffer[Map_BUFFER_SIZE] ;
extern uint32_t aDST_Buffer[Map_BUFFER_SIZE];
#define USART_DMA_CHANNEL DMA1_Channel4
#define USART_Source_ADDR (USART1_BASE+0x04)
extern uint32_t USART_BUFFER_SIZE ;
extern uint32_t* USART_DMA_Buffer ;
void _DMA_Config(DMA_Channel_TypeDef* _DMAy_Channelx , uint32_t _BUFFER_SIZE , uint32_t _DMA_OutSource_ADDR, uint32_t _DMA_InSource_ADDR , uint32_t _DMA_DIR);
void _USART_DMA_Config(DMA_Channel_TypeDef* _DMAy_Channelx , uint32_t _BUFFER_SIZE , uint32_t _DMA_OutSource_ADDR, uint32_t _DMA_InSource_ADDR , uint32_t _DMA_DIR);
uint8_t _Buffercmp(const uint32_t *pBuffer, uint32_t * pBuffer1 , uint16_t BufferLength);
void _Buffer_Show(uint32_t * pBuffer , uint16_t BufferLength);
void _DMA_ROM_TO_RAM(uint32_t _BUFFER_SIZE , uint32_t _DMA_Source_ADDR, uint32_t _DMA_AIM_ADDR );
void _DMA_RAM_TO_USART(uint32_t _BUFFER_SIZE , uint32_t _DMA_Source_ADDR, uint32_t _DMA_AIM_ADDR );
#define _Map_DMA_Config_ _DMA_Config(Map_DMA_CHANNEL ,Map_BUFFER_SIZE ,aSRC_Cont_Buffer , aDST_Buffer , DMA_DIR_PeripheralSRC)
#define _USART_DMA_Config_ _USART_DMA_Config(USART_DMA_CHANNEL ,USART_BUFFER_SIZE ,USART_Source_ADDR , USART_DMA_Buffer , DMA_DIR_PeripheralDST)
#define _DMA_InnerChange_ _Buffercmp(aSRC_Cont_Buffer , aDST_Buffer, Map_BUFFER_SIZE)
#define _RMA_InnerShow_ _Buffer_Show(aDST_Buffer, Map_BUFFER_SIZE)
#endif
10.建立DMA传输的C文件 DMA_book.c
代码如下 :
#include "DMA_book.h"
#include "USART_book.h"
#include "Systick_book.h"
const uint32_t aSRC_Cont_Buffer [Map_BUFFER_SIZE]={
'W','E','L','L',
'C','O','M','E',
' ','S','T','M',
'3','2',' ','S',
'T','U','D','Y',
};
uint32_t aDST_Buffer[Map_BUFFER_SIZE] ;
uint32_t* USART_DMA_Buffer ;
uint32_t USART_BUFFER_SIZE ;
void _DMA_Config(DMA_Channel_TypeDef* _DMAy_Channelx , uint32_t _BUFFER_SIZE , uint32_t _DMA_Source_ADDR, uint32_t _DMA_AIM_ADDR , uint32_t _DMA_DIR){
DMA_InitTypeDef DMA_InitStructure ;
RCC_AHBPeriphClockCmd(DMA_CLOCK,ENABLE);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)_DMA_Source_ADDR ;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)_DMA_AIM_ADDR;
DMA_InitStructure.DMA_DIR = _DMA_DIR ;
DMA_InitStructure.DMA_BufferSize = _BUFFER_SIZE;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;
DMA_Init(_DMAy_Channelx , &DMA_InitStructure);
DMA_Cmd(_DMAy_Channelx , ENABLE);
}
void _USART_DMA_Config(DMA_Channel_TypeDef* _DMAy_Channelx , uint32_t _BUFFER_SIZE , uint32_t _DMA_Source_ADDR, uint32_t _DMA_AIM_ADDR , uint32_t _DMA_DIR){
DMA_InitTypeDef DMA_InitStructure ;
RCC_AHBPeriphClockCmd(DMA_CLOCK,ENABLE);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)_DMA_Source_ADDR ;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)_DMA_AIM_ADDR;
DMA_InitStructure.DMA_DIR = _DMA_DIR ;
DMA_InitStructure.DMA_BufferSize = _BUFFER_SIZE;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(_DMAy_Channelx , &DMA_InitStructure);
DMA_Cmd(_DMAy_Channelx , ENABLE);
}
uint8_t _Buffercmp(const uint32_t *pBuffer, uint32_t * pBuffer1 , uint16_t BufferLength){
while(BufferLength--){
if(*pBuffer != *pBuffer1){
return 0;
}
pBuffer++;
pBuffer1++;
}
return 1;
}
void _Buffer_Show(uint32_t * pBuffer , uint16_t BufferLength){
while(BufferLength--){
Usart_SendHalf_32_Word(_DEBUG_USARTx,*pBuffer++);
}
}
void _DMA_ROM_TO_RAM(uint32_t _BUFFER_SIZE , uint32_t _DMA_Source_ADDR, uint32_t _DMA_AIM_ADDR ){
printf("开始 ROM内存到RAM内存的DMA操作 \n");
_DMA_Config(Map_DMA_CHANNEL ,_BUFFER_SIZE ,_DMA_Source_ADDR , _DMA_AIM_ADDR , DMA_DIR_PeripheralSRC);
while(DMA_GetFlagStatus(DMA_FLAG_TC) == RESET);
if(_DMA_InnerChange_== 0 ){
printf("ROM内存到DMA操作异常 \n");
}else{
printf("ROM内存到DMA操作正常 \n");
}
_RMA_InnerShow_;
}
void _DMA_RAM_TO_USART(uint32_t _BUFFER_SIZE , uint32_t _DMA_Source_ADDR, uint32_t _DMA_AIM_ADDR ){
printf("\n开始 ROM到USART的传送初始化\n");
USART_BUFFER_SIZE = _BUFFER_SIZE;
USART_DMA_Buffer = _DMA_AIM_ADDR;
_USART_DMA_Config(USART_DMA_CHANNEL ,USART_BUFFER_SIZE ,_DMA_Source_ADDR , USART_DMA_Buffer , DMA_DIR_PeripheralDST);
USART_DMACmd(_DEBUG_USARTx , USART_DMAReq_Tx , ENABLE);
fn_Systick_Delay(250,_Systick_ms);
while(USART_GetFlagStatus(_DEBUG_USARTx,USART_FLAG_TXE)==RESET);
printf("\rROM内存到USART外设的DMA操作完毕\n");
}
11.建立EXIT的 头文件 Exit_book.h
代码如下 :
#ifndef __EXIT_BOOK_H_
#define __EXIT_BOOK_H_
#include "stm32f10x.h"
#define _KEY_EXTI_IN_GPIO_Port GPIOA
#define _KEY_EXTI_IN_GPIO_Pin GPIO_Pin_0
#define _EXTI_IN_GPIO_PortSource GPIO_PortSourceGPIOA
#define _EXTI_IN_GPIO_PinSource GPIO_PinSource0
#define _EXTI_IN_EXTI_Line EXTI_Line0
#define _EXTI_IN_EXTI_Trigger EXTI_Trigger_Rising
#define _EXTI_IN_GPIO_Clock RCC_APB2Periph_AFIO
#define _EXTI_IN_EXTI_Mode EXTI_Mode_Interrupt
#define _EXTI_IN_EXTI_LineCmd ENABLE
#define _NVIC_IN_EXTI_IRQChannel EXTI0_IRQn
#define _NVIC_IN_EXTI_IRQChannelCmd ENABLE
#define _KEY2_EXTI_IN_GPIO_Port GPIOC
#define _KEY2_EXTI_IN_GPIO_Pin GPIO_Pin_13
#define _EXTI_IN2_GPIO_PortSource GPIO_PortSourceGPIOC
#define _EXTI_IN2_GPIO_PinSource GPIO_PinSource13
#define _EXTI_IN2_EXTI_Line EXTI_Line13
#define _EXTI_IN2_EXTI_Trigger EXTI_Trigger_Falling
#define _EXTI_IN2_GPIO_Clock RCC_APB2Periph_AFIO
#define _EXTI_IN2_EXTI_Mode EXTI_Mode_Interrupt
#define _EXTI_IN2_EXTI_LineCmd ENABLE
#define _NVIC_IN2_EXTI_IRQChannel EXTI15_10_IRQn
#define _NVIC_IN2_EXTI_IRQChannelCmd ENABLE
void fn_EXTI_GPIO_Config(void);
void fn_NVIC_Config(void);
void EXTI0_IRQHandler(void);
#endif
12.建立EXIT的C文件 Exit_book.c
代码如下 :
#include "Exit_book.h"
#include "Led_book.h"
void fn_EXTI_GPIO_Config(void){
EXTI_InitTypeDef EXIT_InitStruck;
RCC_APB2PeriphClockCmd(_EXTI_IN_GPIO_Clock , ENABLE);
GPIO_EXTILineConfig(_EXTI_IN_GPIO_PortSource | _EXTI_IN2_GPIO_PortSource , _EXTI_IN_GPIO_PinSource | _EXTI_IN2_GPIO_PinSource);
EXIT_InitStruck.EXTI_Line = _EXTI_IN_EXTI_Line ;
EXIT_InitStruck.EXTI_Mode = _EXTI_IN_EXTI_Mode;
EXIT_InitStruck.EXTI_Trigger = _EXTI_IN_EXTI_Trigger ;
EXIT_InitStruck.EXTI_LineCmd = _EXTI_IN_EXTI_LineCmd;
EXTI_Init(&EXIT_InitStruck);
EXIT_InitStruck.EXTI_Line = _EXTI_IN2_EXTI_Line;
EXIT_InitStruck.EXTI_Mode = _EXTI_IN2_EXTI_Mode;
EXIT_InitStruck.EXTI_Trigger = _EXTI_IN2_EXTI_Trigger;
EXIT_InitStruck.EXTI_LineCmd = _EXTI_IN_EXTI_LineCmd;
EXTI_Init(&EXIT_InitStruck);
fn_NVIC_Config();
}
void fn_NVIC_Config(void){
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStruct.NVIC_IRQChannel = _NVIC_IN_EXTI_IRQChannel;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelCmd = _NVIC_IN_EXTI_IRQChannelCmd;
NVIC_Init(&NVIC_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = _NVIC_IN2_EXTI_IRQChannel;
NVIC_Init(&NVIC_InitStruct);
}
void EXTI0_IRQHandler(void){
if(EXTI_GetITStatus(_EXTI_IN_EXTI_Line)!= RESET){
if(GPIO_ReadInputDataBit(_KEY_EXTI_IN_GPIO_Port, _KEY_EXTI_IN_GPIO_Pin)==1){
__LED_Change__;
}
}
EXTI_ClearITPendingBit(_EXTI_IN_EXTI_Line);
}
void EXTI15_10_IRQHandler(void){
if(EXTI_GetITStatus(_EXTI_IN2_EXTI_Line)!= RESET){
if(GPIO_ReadInputDataBit(_KEY2_EXTI_IN_GPIO_Port, _KEY2_EXTI_IN_GPIO_Pin)==0){
__LED_Change__;
}
}
EXTI_ClearITPendingBit(_EXTI_IN2_EXTI_Line);
}
13.建立Key传输的 头文件 Key_book.h
代码如下 :
#ifndef __KEY_BOOK_H_
#define __KEY_BOOK_H_
#include "stm32f10x.h"
#include "Led_book.h"
#define KEY_IN_GPIO_Port GPIOA
#define KEY_IN_GPIO_Clock RCC_APB2Periph_GPIOA
#define KEY_IN_GPIO_Pin GPIO_Pin_0
#define KEY_IN_GPIO_Pin_Bit 0
#define Key_IN_GPIO_Modle GPIO_Mode_IN_FLOATING
#define KEY2_IN_GPIO_Port GPIOC
#define KEY2_IN_GPIO_Clock RCC_APB2Periph_GPIOC
#define KEY2_IN_GPIO_Pin GPIO_Pin_13
#define KEY2_IN_GPIO_Pin_Bit 13
#define Key2_IN_GPIO_Modle GPIO_Mode_IN_FLOATING
typedef union {
struct{
unsigned char BIT0:1;unsigned char BIT1:1;unsigned char BIT2:1;unsigned char BIT3:1;
unsigned char BIT4:1;unsigned char BIT5:1;unsigned char BIT6:1;unsigned char BIT7:1;
}DATA_BIT;
uint8_t DATA_BYTE;
}Per_key_type;
extern volatile Per_key_type key_flag;
#define bkey_10ms key_flag.DATA_BIT.BIT0
#define bkey_judge key_flag.DATA_BIT.BIT1
#define bkey_judge_long key_flag.DATA_BIT.BIT2
#define bkey_Effect key_flag.DATA_BIT.BIT3
#define bkey_LongEffect key_flag.DATA_BIT.BIT4
#define bkey_Effect_Lose key_flag.DATA_BIT.BIT5
#define bkey_Effect_LLose key_flag.DATA_BIT.BIT6
void fn_Key_GPIO_Config( GPIO_TypeDef* _GPIO_x , uint32_t _GPIO_Clock , uint16_t _GPIO_Pin_x , GPIOMode_TypeDef _GPIOMode_TypeDef );
void fn_Key_Init(void);
void fn_key_judge(void);
void fn_key_Effect(void);
void fn_key_Check(void);
#endif
14.建立Key的C文件 Key_book.c
代码如下 :
#include "Key_book.h"
volatile Per_key_type key_flag;
void fn_Key_GPIO_Config( GPIO_TypeDef* _GPIO_x , uint32_t _GPIO_Clock , uint16_t _GPIO_Pin_x , GPIOMode_TypeDef _GPIOMode_TypeDef ){
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = _GPIOMode_TypeDef;
GPIO_InitStruct.GPIO_Pin = _GPIO_Pin_x;
RCC_APB2PeriphClockCmd(_GPIO_Clock,ENABLE);
GPIO_Init(_GPIO_x , &GPIO_InitStruct);
}
void fn_Key_Init(void){
fn_Key_GPIO_Config(KEY_IN_GPIO_Port,KEY_IN_GPIO_Clock,KEY_IN_GPIO_Pin,Key_IN_GPIO_Modle);
fn_Key_GPIO_Config(KEY2_IN_GPIO_Port,KEY2_IN_GPIO_Clock,KEY2_IN_GPIO_Pin,Key2_IN_GPIO_Modle);
}
#define _LONG_key 30
static uint16_t count_key ;
void fn_key_judge(void){
if(!bkey_10ms){return;}
bkey_10ms = 0;
if(GPIO_ReadInputDataBit(KEY_IN_GPIO_Port,KEY_IN_GPIO_Pin)){
if(count_key++<3){return;}
if(!bkey_judge){
bkey_judge = 1;
bkey_Effect = 1;
}else{
if(count_key>_LONG_key){
bkey_judge_long = 1;
bkey_LongEffect = 1;
}
}
}
else{
count_key = 0;
if(bkey_judge){
bkey_judge = 0;
if(bkey_judge_long){
bkey_judge_long = 0;
bkey_Effect_LLose = 1;
}else{
bkey_judge_long = 0;
bkey_Effect_Lose = 1;
}
}else{
bkey_judge = 0;
}
}
}
void fn_key_Effect(void){
if(bkey_Effect){
bkey_Effect = 0;
fn_LED_Corporate(LED_OUT_GPIO_Port,LED_OUT_GPIO_Pin,LED_Corporate_Toggle);
}
}
void fn_key_Check(void){
fn_key_judge();
fn_key_Effect();
}
15.建立LED 的头文件 Led_book.h
代码如下 :
#ifndef __LED_BOOK_H_
#define __LED_BOOK_H_
#include "stm32f10x.h"
#define LED_OUT_GPIO_Port GPIOB
#define LED_OUT_GPIO_Clock RCC_APB2Periph_GPIOB
#define LED_OUT_GPIO_Pin GPIO_Pin_5
#define LED_OUT_GPIO_Pin_Bit 5
#define LED_OUT_GPIO_Modle GPIO_Mode_Out_PP
#define LED_R_OUT_GPIO_Pin GPIO_Pin_5
#define LED_G_OUT_GPIO_Pin GPIO_Pin_0
#define LED_B_OUT_GPIO_Pin GPIO_Pin_1
typedef enum {
LED_Corporate_On = 1,
LED_Corporate_OFF = 2,
LED_Corporate_Toggle = 3,
} LED_Corporate_state_t;
void fn_LED_GPIO_Config(GPIO_TypeDef* _GPIO_x , uint32_t _GPIO_Clock ,\
uint16_t _GPIO_Pin_x , GPIOMode_TypeDef _GPIOMode_TypeDef);
void fn_Led_Init(void);
void fn_LED_Corporate(GPIO_TypeDef* _GPIO_x , uint16_t _GPIO_Pin_x , \
LED_Corporate_state_t _LED_Corporate_state_t );
void fn_LED_ALL_OFF(void);
#define __LED_Change__ fn_LED_Corporate(LED_OUT_GPIO_Port,LED_OUT_GPIO_Pin,LED_Corporate_Toggle)
#define __R_OUT__ GPIO_ResetBits(LED_OUT_GPIO_Port,LED_R_OUT_GPIO_Pin)
#define __G_OUT__ GPIO_ResetBits(LED_OUT_GPIO_Port,LED_G_OUT_GPIO_Pin)
#define __B_OUT__ GPIO_ResetBits(LED_OUT_GPIO_Port,LED_B_OUT_GPIO_Pin)
#endif
16.建立LED 的 文件 Led_book.c
代码如下 :
#include "Led_book.h"
#define LED_GPIO_Speed GPIO_Speed_10MHz
void fn_LED_GPIO_Config(GPIO_TypeDef* _GPIO_x , uint32_t _GPIO_Clock ,uint16_t _GPIO_Pin_x , GPIOMode_TypeDef _GPIOMode_TypeDef){
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = _GPIOMode_TypeDef;
GPIO_InitStruct.GPIO_Pin = _GPIO_Pin_x;
GPIO_InitStruct.GPIO_Speed = LED_GPIO_Speed;
RCC_APB2PeriphClockCmd(_GPIO_Clock ,ENABLE);
GPIO_Init(_GPIO_x , &GPIO_InitStruct) ;
GPIO_SetBits(_GPIO_x,_GPIO_Pin_x);
}
void fn_Led_Init(void){
fn_LED_GPIO_Config (LED_OUT_GPIO_Port,LED_OUT_GPIO_Clock,LED_OUT_GPIO_Pin,LED_OUT_GPIO_Modle);
fn_LED_GPIO_Config (LED_OUT_GPIO_Port,LED_OUT_GPIO_Clock,LED_R_OUT_GPIO_Pin,LED_OUT_GPIO_Modle);
fn_LED_GPIO_Config (LED_OUT_GPIO_Port,LED_OUT_GPIO_Clock,LED_G_OUT_GPIO_Pin,LED_OUT_GPIO_Modle);
fn_LED_GPIO_Config (LED_OUT_GPIO_Port,LED_OUT_GPIO_Clock,LED_B_OUT_GPIO_Pin,LED_OUT_GPIO_Modle);
fn_LED_ALL_OFF();
}
void fn_LED_Corporate(GPIO_TypeDef* _GPIO_x , uint16_t _GPIO_Pin_x , LED_Corporate_state_t _LED_Corporate_state_t ){
switch(_LED_Corporate_state_t){
case LED_Corporate_On :
GPIO_SetBits(_GPIO_x,_GPIO_Pin_x);
break;
case LED_Corporate_OFF:
GPIO_ResetBits(_GPIO_x,_GPIO_Pin_x);
break;
case LED_Corporate_Toggle:
GPIO_ReadOutputDataBit(_GPIO_x,_GPIO_Pin_x)?GPIO_ResetBits(_GPIO_x,_GPIO_Pin_x):GPIO_SetBits(_GPIO_x,_GPIO_Pin_x);
break;
}
}
void fn_LED_ALL_OFF(void){
GPIO_SetBits(LED_OUT_GPIO_Port,LED_R_OUT_GPIO_Pin);
GPIO_SetBits(LED_OUT_GPIO_Port,LED_G_OUT_GPIO_Pin);
GPIO_SetBits(LED_OUT_GPIO_Port,LED_B_OUT_GPIO_Pin);
}
17.建立 Systick传输的 头文件 Systick_book.h
代码如下 :
#ifndef __SYSTIC_BOOK_H_
#define __SYSTIC_BOOK_H_
#include "stm32f10x.h"
#include "Key_book.h"
typedef enum {
_Systick_us = 1,
_Systick_ms = 2,
_Systick_s = 3,
} Systick_time_state_t;
void fn_Systick_Delay(uint32_t _Delay_time , Systick_time_state_t _Systick_time_state_t);
void fn_Systick_Delay_Handler_set(uint32_t _Delay_ms , Systick_time_state_t _Systick_time_state_t);
void fn_SysTick_delay_decrement(void);
void SysTick_Handler(void);
#define __Systick_Delay_Handler_set__ fn_Systick_Delay_Handler_set(10,_Systick_ms)
#endif
18.建立 Systick的C文件 Systick_book.c
代码如下 :
#include "Systick_book.h"
void fn_Systick_Delay(uint32_t _Delay_time , Systick_time_state_t _Systick_time_state_t){
uint32_t i;
if(_Systick_time_state_t == _Systick_us){SysTick_Config(SystemCoreClock/1000000);}
if(_Systick_time_state_t == _Systick_ms){
SysTick_Config(SystemCoreClock/1000);
}
else{SysTick_Config(SystemCoreClock);}
for( i=0;i<_Delay_time ; i++){
while(!((SysTick->CTRL)&(1<<16)));
}
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}
static uint32_t _SysTick_delay = 0 ;
void fn_Systick_Delay_Handler_set(uint32_t _Delay_ms , Systick_time_state_t _Systick_time_state_t){
if(_Systick_time_state_t == _Systick_us){SysTick_Config(SystemCoreClock/1000000);}
if(_Systick_time_state_t == _Systick_ms){
SysTick_Config(SystemCoreClock/1000);
}
else{SysTick_Config(SystemCoreClock);}
_SysTick_delay = _Delay_ms ;
}
static uint32_t SysTick_delay = 0 ;
void fn_SysTick_delay_decrement(void){
if(SysTick_delay++ > _SysTick_delay){
SysTick_delay = 0;
bkey_10ms = 1;
}
}
void SysTick_Handler(void){
fn_SysTick_delay_decrement();
}
19.建立 头文件函数 头文件 PROJ_book.h
代码如下 :
#ifndef __PROJ_BOOK_H__
#define __PROJ_BOOK_H__
#include "stm32f10x.h"
#include "Led_book.h"
#include "Key_book.h"
#include "RCC_book.h"
#include "Systick_book.h"
#include "Exit_book.h"
#include "USART_book.h"
#include "DMA_book.h"
#include "I2C_book.h"
#include "I2C_soft_book.h"
#endif
|