入门第五步——I2C通信
由于I2C通信是单片机和I2C模块通信,如果不借用逻辑分析仪之类的工具的话,很难观测到数据的传输(考虑到初入行,没有能力购买逻辑分析仪),正好前面我们已经学习了UART通信,本次教程将通过UART串口来打印写入和读出的数据。由于我采用的是低功耗模块,所以为了芯片的最大化利用,我将采用低功耗模式来编程,UART和I2C将通过中断的方式来读写数据。另外本次采用的I2C模块是MB85RC04非易失铁电寄存器。
首先我们看一下这个寄存器的技术手册,查一下他的器件地址和通信流程。
从这张图可以看出,该寄存器的器件地址为1010XXX(),即AX(),这个括号代表写或者读。大部分器件是0写1读,这个具体得看器件手册,我这个是0写1读。另外考虑到实际的工作需求,我们采用页写和页读,这个具体的也需要查看器件手册是怎么规定的。看下图
这个是写多个数据,在实际项目中写一个数据的还是很少见的。
这个是顺序读,简单概括也就是读多个数据,且按照给定的读的地址依次往后读取给定的长度。
话说回来再讲一下通信原理:I2C 总线使用连接设备的"SCL"(串行时钟总线)和"SDA"(串行数据总线)来传送信息。主机在 SCL线上输出串行时钟信号,数据在 SDA 线上进行传输,每传输一个字节(最高位 MSB 开始传输),后面跟随一个应答位。一个 SCL 时钟脉冲传输一个数据位。通常标准 I2C 传输协议包含四个部分:起始(S)或重复起始信号(Sr),从机地址及读写位,传输数据,停止信号§。
其实I2C的通信原理并不复杂,就是上面这个流程,主机发一次消息,从机回一次消息,不回复表示没有从机响应,就结束通信或者重新发起。
讲到这里,我们还需要了解一下华大单片机的I2C状态码。看下图
今天我们用到的是主发送和主接收。
下面开始写代码。
新建一个App_I2c.c和.h
/**
******************************************************************************
** \brief I2C初始化函数
**
** \return 无返回值
**
** 采用硬件I2C1,传输时钟为PCLK,速率为标准速率100KHZ
**
******************************************************************************/
#include "App_I2c_Init.h"
///< I2C 模块配置
void App_I2c_Init(void)
{
stc_i2c_cfg_t stcI2cCfg;
DDL_ZERO_STRUCT(stcI2cCfg); ///< 初始化结构体变量的值为0
Sysctrl_SetPeripheralGate(SysctrlPeripheralI2c1,TRUE); ///< 开启I2C1时钟门控
stcI2cCfg.u32Pclk = Sysctrl_GetPClkFreq(); ///< 获取PCLK时钟
stcI2cCfg.u32Baud = 100000; ///< 100KHz
stcI2cCfg.enMode = I2cMasterMode; ///< 主机模式
stcI2cCfg.u8SlaveAddr = 0x55; ///< 从地址,主模式无效
stcI2cCfg.bGc = FALSE; ///< 广播地址应答使能关闭
I2C_Init(M0P_I2C1,&stcI2cCfg); ///< 模块初始化
EnableNvic(I2C1_IRQn, IrqLevel3, TRUE); ///< 系统中断使能
}
.h就是包含一下头文件和外部声明,这需要在初始化头文件里面调用初始化。
中断函数里面需要添加I2C中断,考虑到我们既写又读,再加上作为初学者,我们分开写函数更好,方便自己理解。
写一个I2C_PageWrite()函数和I2C_PageRead()函数,写到这我们是不是需要一个变量来说明我们是写操作还是读操作,那我们在这规定一下我们整个程序的一个流程。看下图
研究这个图,我们可以发现一个问题,写的过程中我们怎么知道数据是否写成功了?改进一下,我们写完就读,然后和写进去的数据进行比较,如果一样就返回0x01,不一样就返回0x00,在读过程我们也判断一下。
这个流程就比较完美了,写完了先验证是否真的写入。下面将流程变为现实。
过程慢慢描述进度会变慢,我这里就不多赘述,看完整代码。
这里有重新写个.c和.h(Data_treating.c和Data_treating.h)
Data_treating.c
#include "Data_treating.h"
#define I2C_SLAVEWT 0xA0 //I2C设备地址+写
#define I2C_SLAVERD 0xA1 //I2C设备地址+读
#define Return_startByte 0xFF //反馈数据首地址
//#define u32Len Rxbuff.len-2 //I2C存储数据字节长度
#define Command_bit Rxbuff.u8[1] //I2C读或写数据命令位
volatile uint8_t I2cState = 0; //获取I2C状态
volatile uint8_t u8Addr = 0x00; //FRAM地址字节
volatile uint8_t I2CState; //FRAM地址字节
volatile uint8_t u32Len;
FRAME_RW_t FRAME_RW;
void CheckWrite() //检查需要写的数据和已经写入的数据是否一致
{
for (uint8_t i=0;i<Rxbuff.len-3;i++)
{
if(Rxbuff.u8[i+2]!= Rxbuff.I2[i+2])
{
TxBuff.buff[2]=0x00; //TxBuff.buff[1]为标志位,0未成功写入,1成功写入
return;
}
TxBuff.buff[2]=0x01;
}
}
void I2C_PageWrite(uint8_t *pu8Data) ///I2C按页写入(写入数据为pu8Data传入数组)
{
I2cState = I2C_GetState(M0P_I2C1);
u32Len =Rxbuff.len-2; //I2c存储数据的长度为串口接收数据长度-2(0xFF和命令)
switch(I2cState)
{
case 0x08: ///< 已发送起始条件
{
I2C_ClearFunc(M0P_I2C1, I2cStart_En);
I2C_WriteByte(M0P_I2C1, I2C_SLAVEWT); ///< 从设备地址发送
break;
}
case 0x18: ///< 已发送SLA+W,并接收到ACK
{
I2C_WriteByte(M0P_I2C1, u8Addr); ///< 从设备内存地址发送
break;
}
case 0x28: ///< 上一次发送数据后接收到ACK
{
if(Rxbuff.idc > u32Len)
{
I2C_SetFunc(M0P_I2C1, I2cStop_En); //将发送停止条件
Rxbuff.idc = 2;
PeriperalStatus.bitField.i2c=0;
break;
}
else
{
I2C_WriteByte(M0P_I2C1, Rxbuff.u8[Rxbuff.idc++]); ///< 发送数据
break;
}
}
default:
I2C_SetFunc(M0P_I2C1, I2cStop_En); ///< 其他错误状态,结束起始条件
break;
}
I2C_ClearIrq(M0P_I2C1); //清除中断状态标志位
}
void I2C_PageRead(uint8_t *pu8Data) ///I2C按页读出(读出数据到pu8Data数组)
{
I2cState = I2C_GetState(M0P_I2C1);
u32Len= Rxbuff.len-2; //I2c读取数据的长度为串口接收数据长度-2(0xFF和命令)
switch(I2cState)
{
case 0x08: ///< 已发送起始条件,将发送SLA+W
{
I2C_ClearFunc(M0P_I2C1,I2cStart_En);
I2C_WriteByte(M0P_I2C1,I2C_SLAVEWT);
break;
}
case 0x18: ///< 已发送SLA+W,并接收到ACK
{
I2C_WriteByte(M0P_I2C1,u8Addr); ///< 发送从机内存地址
break;
}
case 0x28: ///< 已发送数据,接收到ACK
{
I2C_SetFunc(M0P_I2C1,I2cStart_En); ///< 发送重复起始条件
break;
}
case 0x10: ///< 已发送重复起始条件
{
I2C_ClearFunc(M0P_I2C1,I2cStart_En);
I2C_WriteByte(M0P_I2C1,I2C_SLAVERD);///< 发送SLA+R,开始从从机读取数据
break;
}
case 0x40: ///< 已发送SLA+R,并接收到ACK
{
if(1 < (u32Len))
{
I2C_SetFunc(M0P_I2C1, I2cAck_En); //读取数据超过1个字节才发送ACK
}
break;
}
case 0x50: ///< 已接收数据字节,并已返回ACK信号
{
pu8Data[Rxbuff.idc++] = I2C_ReadByte(M0P_I2C1);
if(Rxbuff.idc==u32Len)
{
I2C_ClearFunc(M0P_I2C1,I2cAck_En); ///< 已接收到倒数第二个字节,关闭ACK应答功能
}
break;
}
case 0x58: ///< 已接收到最后一个数据,NACK已返回
{
pu8Data[Rxbuff.idc++] = I2C_ReadByte(M0P_I2C1);
I2C_SetFunc(M0P_I2C1,I2cStop_En); ///< 发送停止条件
Rxbuff.idc = 2;
Rxbuff.idt = 0;
Rxbuff.u8[1]=Rxbuff01;
PeriperalStatus.bitField.i2c=0;
break;
}
default:
I2C_SetFunc(M0P_I2C1, I2cStop_En); ///< 其他错误状态,结束起始条件
break;
}
I2C_ClearIrq(M0P_I2C1); //清除中断状态标志位
}
void SendData_ToPc(void)
{
switch(Command_bit)
{
case FRAME_Write: // 写操作
{
FRAME_RW=FRAME_Write;
CheckWrite(); // 写成功,进行数据校验
TxBuff.buff[0]=Return_startByte; //反馈数组首字节
TxBuff.buff[1]=FRAME_RW;
TxBuff.buff[3]=XoRCheck(TxBuff.buff, 3);
LPUart_SendDataIt(M0P_LPUART1, TxBuff.buff[TxBuff.idx]); // 发送第一个字节
break;
}
case FRAME_Read:
{
FRAME_RW=FRAME_Read; // 读操作
Rxbuff.idc = 0;
Rxbuff.I2[0]=Return_startByte; //反馈数组首字节
Rxbuff.I2[1]=FRAME_RW;
Rxbuff.I2[Rxbuff.len-1]=XoRCheck(Rxbuff.I2, Rxbuff.len-1); // IIC读数据,BCC校验存储位
LPUart_SendDataIt(M0P_LPUART1, Rxbuff.I2[Rxbuff.idc]);
break;
}
}
}
void LpUart_Send(void)
{
switch(Command_bit)
{
case FRAME_Write: // 写操作
{
if(TxBuff.idx<3) // 回传PC数据有3个,如果TxBuff.idx小于3继续发送
{
LPUart_SendDataIt(M0P_LPUART1, TxBuff.buff[++TxBuff.idx]);
break;
}
TxBuff.idx = 0;
break;
}
case FRAME_Read:
{
if( Rxbuff.idc < Rxbuff.len-1)
{
LPUart_SendDataIt(M0P_LPUART1, Rxbuff.I2[++Rxbuff.idc]);
break;
}
Rxbuff.idc = 0;
break;
}
}
}
Data_treating.h
#ifndef __DATA_TREATING_H__
#define __DATA_TREATING_H__
#include "Sys_Init.h"
// 定义FRAME_RW_t枚举类型,用于表示IIC读写操作
typedef enum{
FRAME_Read = 1, // 读操作
FRAME_Write = 0 // 写操作
}__attribute__((packed)) FRAME_RW_t;
void I2C_PageWrite(uint8_t *pu8Data); // TODO: 实现I2C页写功能
void I2C_PageRead(uint8_t *pu8Data); // TODO: 实现I2C页读功能
void SendData_ToPc(void); // TODO: 实现将数据发送到PC端的功能
void LpUart_Send(void); // 发送数据到LPUART接口
#endif
main.c
#include "main.h"
TxBuf TxBuff;
SystemStatus_t SystemStatus;
PeripheralStatus_t PeriperalStatus;
int32_t main()
{
delay1ms(2000);
Sys_Init();
while(1)
{
switch(SystemStatus)
{
case RxCompleteState: //串口写数据到单片机,写完成标志状态1
{
if(Rxbuff.u8[Rxbuff.len-1] == XoRCheck(Rxbuff.u8, Rxbuff.len-1))
{
PeriperalStatus.bitField.i2c=1;
I2C_SetFunc(M0P_I2C1, I2cStart_En); //启动I2C传输
SystemStatus=I2CWriteCompleteState;
}
break;
}
case I2CWriteCompleteState: //单片机写数据到FRAM,写完成标志状态2
{
if(PeriperalStatus.bitField.i2c==0)
{
Rxbuff.u8[1]=FRAME_Read;
I2C_SetFunc(M0P_I2C1, I2cStart_En); //启动I2C传输
PeriperalStatus.bitField.i2c=1;
SystemStatus = I2CReadCompleteState;
}
break;
}
case I2CReadCompleteState: //单片机读FRAM数据,读完成标志状态3
{
if(PeriperalStatus.bitField.i2c==0)
{
SendData_ToPc();
SystemStatus = DummyState;
}
break;
}
default:
break;
}
EnterSleepMode();
}
}
main.h
#ifndef __MAIN_H__
#define __MAIN_H__
#include "Sys_Init.h"
/********************************************************************************
** \brief 串口待发送类型定义
******************************************************************************/
typedef struct
{
uint8_t buff[32]; //串口发送数据缓存
uint8_t I2cbuff[32]; //串口发送数据缓存
uint8_t XoRbuff[32]; //
uint8_t idx; //串口发送数据索引
}TxBuf;
/********************************************************************************
** brief Timer0与IIC外设状态共用体
******************************************************************************/
typedef union{
uint32_t u32;
struct{
uint32_t timer0: 1;
uint32_t i2c: 1;
}bitField;
}PeripheralStatus_t;
/**
******************************************************************************
** \brief 系统执行过程状态枚举
*****************************************************************************/
typedef enum SystemStatus
{
DummyState = 0u,
RxCompleteState = 1u,
I2CWriteCompleteState = 2u,
I2CReadCompleteState = 3u,
}SystemStatus_t;
extern TxBuf TxBuff;
extern SystemStatus_t SystemStatus;
extern PeripheralStatus_t PeriperalStatus;
#endif
Sys_Init.c
/**
******************************************************************************
** \brief 系统初始化函数
**
** \return 无返回值
**
** 时钟初始化,设定为外部低速时钟32768Hz
** GPIO初始化
** 串口Serial初始化
** Timer0初始化 4M
** I2C1初始化
******************************************************************************/
#include "Sys_Init.h"
/**
******************************************************************************
** \brief 时钟初始化函数
**
** \return 无返回值
**
** 时钟初始化,设定为外部低速时钟32768Hz
**
******************************************************************************/
void App_SysClkInit(void) //时钟初始化,设定为外部低速时钟32768Hz
{
stc_sysctrl_clk_cfg_t stcClkCfg;
//时钟初始化
stcClkCfg.enClkSrc = SysctrlClkRCH;
stcClkCfg.enHClkDiv = SysctrlHclkDiv1;
stcClkCfg.enPClkDiv = SysctrlPclkDiv1;
Sysctrl_ClkInit(&stcClkCfg);
//使能时钟
Sysctrl_SetRCLTrim(SysctrlRclFreq38400);
Sysctrl_ClkSourceEnable(SysctrlClkRCL, TRUE);
}
/**
******************************************************************************
** \brief 异或检验函数
**
** \param 需要校验的数组
** \param 检验的数据长度
**
** \return 有返回值(Check),返回校验结果
**
******************************************************************************/
uint8_t XoRCheck(uint8_t *array,uint8_t length) //数据异或校验
{
uint8_t i=0 ;
uint8_t Check = 0;
for(i=0; i<length; i++)
{
Check ^= array[i];
}
return Check;
}
/********************************************************************************
** \brief 系统cpu工作模式切换
******************************************************************************/
void EnterSleepMode(void)
{
if(PeriperalStatus.u32) //如果外设都关闭状态1
{
Lpm_GotoSleep(FALSE); // 执行普通睡眠模式
return;
}
Lpm_GotoDeepSleep(FALSE);// 否则,执行深度睡眠模式
}
/**
******************************************************************************
** \brief 初始化函数
**
** \return 无返回值
**
** 各个函数初始化
**
******************************************************************************/
void Sys_Init(void)
{
App_SysClkInit(); //时钟初始化
App_Gpio_Init(); //GPIO初始化
App_Serial_Init(); //Serial初始化
App_Timer0_Init(); //Timer0初始化 4M
App_I2c_Init(); //I2C1初始化
}
Sys_Init.h
#ifndef __SYS_INIT_H__
#define __SYS_INIT_H__
#include "App_Gpio_Init.h"
#include "App_Serial_Init.h"
#include "App_Timer0_Init.h"
#include "App_interrupts.h"
#include "App_I2c_Init.h"
#include "ddl.h"
void Sys_Init(void);
uint8_t XoRCheck(uint8_t *array,uint8_t length);
void EnterSleepMode(void);
#endif
App_Gpio_Init.c
/**
******************************************************************************
** \brief GPIO初始化函数
**
** \return 无返回值
** 晶振引脚初始化
** I2C引脚初始化,配置复用功能
** LPUART1引脚初始化,配置复用功能
******************************************************************************/
#include "App_Gpio_Init.h"
volatile uint8_t Flag;
void App_Gpio_Init()
{
const MCU_IO_TypeDef McuIoInitTbl[] =
{
{.port = GpioPortE, .pin = GpioPin2, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PE02
{.port = GpioPortE, .pin = GpioPin3, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PE03
{.port = GpioPortE, .pin = GpioPin4, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PE04
{.port = GpioPortE, .pin = GpioPin5, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PE05
{.port = GpioPortC, .pin = GpioPin13, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC13
{.port = GpioPortC, .pin = GpioPin14, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirIn, .io_cfg.enDrv = GpioDrvH,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC14
{.port = GpioPortC, .pin = GpioPin15, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirIn, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC15
{.port = GpioPortF, .pin = GpioPin0, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PF00
{.port = GpioPortF, .pin = GpioPin1, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirIn, .io_cfg.enDrv = GpioDrvH,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PF01->Key
{.port = GpioPortC, .pin = GpioPin0, .io_cfg.bOutputVal = TRUE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC00->LED1
{.port = GpioPortC, .pin = GpioPin1, .io_cfg.bOutputVal = TRUE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC01->LED2
{.port = GpioPortC, .pin = GpioPin2, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC02
{.port = GpioPortC, .pin = GpioPin3, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirIn, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC03
{.port = GpioPortA, .pin = GpioPin0, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA00
{.port = GpioPortA, .pin = GpioPin1, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA01
{.port = GpioPortA, .pin = GpioPin2, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA02->UART1_TXD
{.port = GpioPortA, .pin = GpioPin3, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA03->UART1_RXD
{.port = GpioPortF, .pin = GpioPin4, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PF04
{.port = GpioPortF, .pin = GpioPin5, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PF05
{.port = GpioPortA, .pin = GpioPin4, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA04
{.port = GpioPortA, .pin = GpioPin5, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA05
{.port = GpioPortA, .pin = GpioPin6, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA06
{.port = GpioPortA, .pin = GpioPin7, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA07
{.port = GpioPortC, .pin = GpioPin4, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC04
{.port = GpioPortC, .pin = GpioPin5, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC05
{.port = GpioPortB, .pin = GpioPin0, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PB00
{.port = GpioPortB, .pin = GpioPin1, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PB01
{.port = GpioPortB, .pin = GpioPin2, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PB02
{.port = GpioPortE, .pin = GpioPin11, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PE11
{.port = GpioPortE, .pin = GpioPin12, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PE12
{.port = GpioPortE, .pin = GpioPin13, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PE13
{.port = GpioPortE, .pin = GpioPin14, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PE14
{.port = GpioPortB, .pin = GpioPin10, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PB10
{.port = GpioPortB, .pin = GpioPin11, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PB11
{.port = GpioPortB, .pin = GpioPin12, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PB12
{.port = GpioPortB, .pin = GpioPin13, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PB13
{.port = GpioPortB, .pin = GpioPin14, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PB14
{.port = GpioPortB, .pin = GpioPin15, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PB15
{.port = GpioPortD, .pin = GpioPin8, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PD08
{.port = GpioPortD, .pin = GpioPin9, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PD09
{.port = GpioPortD, .pin = GpioPin10, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PD10
{.port = GpioPortD, .pin = GpioPin11, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PD11
{.port = GpioPortC, .pin = GpioPin6, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC06
{.port = GpioPortC, .pin = GpioPin7, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC07
{.port = GpioPortC, .pin = GpioPin8, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC08
{.port = GpioPortC, .pin = GpioPin9, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC09
{.port = GpioPortA, .pin = GpioPin8, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA08
{.port = GpioPortA, .pin = GpioPin9, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA09
{.port = GpioPortA, .pin = GpioPin10, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA10
{.port = GpioPortA, .pin = GpioPin11, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA11
{.port = GpioPortA, .pin = GpioPin12, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA12
//{.port = GpioPortA, .pin = GpioPin13, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
//.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA13->SWDIO
{.port = GpioPortF, .pin = GpioPin6, .io_cfg.bOutputVal = TRUE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuEnable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdEnable, .io_cfg.enCtrlMode = GpioAHB}, //PF06->SCL
{.port = GpioPortF, .pin = GpioPin7, .io_cfg.bOutputVal = TRUE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuEnable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdEnable, .io_cfg.enCtrlMode = GpioAHB}, //PF07->SCL
//{.port = GpioPortA, .pin = GpioPin14, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
//.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA14->SWCLK
{.port = GpioPortA, .pin = GpioPin15, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA15->WP
{.port = GpioPortC, .pin = GpioPin10, .io_cfg.bOutputVal = TRUE , .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuEnable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC10
{.port = GpioPortC, .pin = GpioPin11, .io_cfg.bOutputVal = TRUE, .io_cfg.enDir = GpioDirIn, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuEnable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC11
{.port = GpioPortC, .pin = GpioPin12, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC12
{.port = GpioPortD, .pin = GpioPin0, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PD00->SPI1_CS
{.port = GpioPortD, .pin = GpioPin1, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PD01->SPI1_SCK
{.port = GpioPortD, .pin = GpioPin2, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PD02
{.port = GpioPortD, .pin = GpioPin3, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PD03->SPI1_MISO
{.port = GpioPortD, .pin = GpioPin4, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PD04->SPI1_MOSI
{.port = GpioPortB, .pin = GpioPin3, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB }, //PB03
{.port = GpioPortB, .pin = GpioPin4, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB }, //PB04
{.port = GpioPortB, .pin = GpioPin5, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB }, //PB05
{.port = GpioPortB, .pin = GpioPin6, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB }, //PB06
{.port = GpioPortB, .pin = GpioPin7, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB }, //PB07
{.port = GpioPortB, .pin = GpioPin8, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB }, //PB08->UART0_TXD
{.port = GpioPortB, .pin = GpioPin9, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirIn, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB } //PB09->UART0_RXD
};
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
for(uint16_t i = 0; i<ARRAY_SZ(McuIoInitTbl); i++)
{
Gpio_Init(McuIoInitTbl[i].port, McuIoInitTbl[i].pin, (stc_gpio_cfg_t *)&McuIoInitTbl[i].io_cfg);
}
Gpio_SetAfMode(GpioPortC,GpioPin10,GpioAf1); //配置PC10为LPUART1_TX
Gpio_SetAfMode(GpioPortC,GpioPin11,GpioAf1); //配置PC11为LPUART1_RX
Gpio_SetAfMode(GpioPortF, GpioPin6,GpioAf1); ///< 配置PF06为SCL
Gpio_SetAfMode(GpioPortF, GpioPin7,GpioAf1); ///< 配置PF07为SDA
}
App_Gpio_Init.h
#ifndef __APP_GPIO_INIT_H__
#define __APP_GPIO_INIT_H__
#include "gpio.h"
#include "ddl.h"
#include "sysctrl.h"
/********************************************************************************
** \brief GPIO外设初始化结构体
******************************************************************************/
typedef struct{
en_gpio_port_t port; // GPIO端口号
en_gpio_pin_t pin; // GPIO引脚号
stc_gpio_cfg_t io_cfg; // GPIO配置信息
}MCU_IO_TypeDef;
void App_Gpio_Init(void);
#endif
App_Serial_Init.c
/**
******************************************************************************
** \brief Serial串口初始化函数
**
** \return 无返回值
**
** 采用LpUart1,内部低速时钟,38400,波特率为9600,异步全双工工作模式
**
******************************************************************************/
#include "App_Serial_Init.h"
void App_Serial_Init(void)
{
stc_lpuart_cfg_t stcCfg;
DDL_ZERO_STRUCT(stcCfg);
///<外设模块时钟使能
Sysctrl_SetPeripheralGate(SysctrlPeripheralLpUart1,TRUE);
///
stcCfg.enStopBit = LPUart1bit; ///<1停止位
stcCfg.enMmdorCk = LPUartOdd; ///<奇校验
stcCfg.stcBaud.enSclkSel = LPUartMskRcl; ///<传输时钟源
stcCfg.stcBaud.u32Sclk = 38400; ///
stcCfg.stcBaud.enSclkDiv = LPUartMsk4Or8Div; ///<采样分频
stcCfg.stcBaud.u32Baud = 9600; ///<波特率
stcCfg.enRunMode = LPUartMskMode3; ///<工作模式
LPUart_Init(M0P_LPUART1, &stcCfg);
///
LPUart_ClrStatus(M0P_LPUART1,LPUartRC); ///<清接收中断请求
LPUart_ClrStatus(M0P_LPUART1,LPUartTC); ///<清发送中断请求
LPUart_EnableIrq(M0P_LPUART1,LPUartRxIrq); ///<使能接收中断
LPUart_EnableIrq(M0P_LPUART1,LPUartTxIrq); ///<使能发送中断
EnableNvic(LPUART1_IRQn,IrqLevel3,TRUE); ///<系统中断使能
}
App_Serial_Init.h
#ifndef __APP_SERIAL_INIT_H__
#define __APP_SERIAL_INIT_H__
#include "lpuart.h"
#include "gpio.h"
#include "sysctrl.h"
extern void App_Serial_Init(void);
#endif
App_interrupts.c
/**
******************************************************************************
** \brief 中断函数的集合(低功耗串口,I2C中断,定时器Timer0中断)
**
** \return 无返回值
**
******************************************************************************/
#include "App_interrupts.h"
RxBuf Rxbuff; //定义结构体类型变量
volatile uint8_t State = 0; //获取状态机变量(电脑接收数据完成状态1,I2C写完成状态2,I2C读完成状态3)
volatile uint8_t Comm_flg = 0; //判断读写标志
volatile uint8_t u8SendLen = 0; //发送数组长度
volatile uint8_t u8ReadLen =10; //读取数组长度
volatile uint8_t Rxbuff01; //读取数组长度
volatile uint8_t Command_bit;
//static boolean_t Flag=0; //翻转电平控制变量
/**
******************************************************************************
** \brief LPUART1 中断服务函数
**
** \return 无返回值
**
******************************************************************************/
///
void LpUart1_IRQHandler(void)
{
if(LPUart_GetStatus(M0P_LPUART1, LPUartTC)) ///发送数据
{
LPUart_ClrStatus(M0P_LPUART1, LPUartTC); ///<清发送中断请求
LpUart_Send();
}
if(LPUart_GetStatus(M0P_LPUART1, LPUartRC)) ///接收数据
{
LPUart_ClrStatus(M0P_LPUART1, LPUartRC); ///<清接收中断请求
Rxbuff.u8[Rxbuff.idx] = LPUart_ReceiveData(M0P_LPUART1);///读取数据
Rxbuff.idx = (Rxbuff.idx > sizeof(Rxbuff.u8)? Rxbuff.idx:(Rxbuff.idx+1));
Bt_M0_Cnt16Set(TIM0,60736); //重载值,1s/4M=1*10^6 / 4*1*10^6 =0.25us 1.2ms/0.25us = 4800 65536-4800=60736
Bt_M0_Run(TIM0);
PeriperalStatus.bitField.timer0 = 1;
}
}
/**
******************************************************************************
** \brief Tim0中断服务函数
**
** \return 无返回值
**
******************************************************************************/
//Tim0中断服务函数
void Tim0_IRQHandler(void)
{
Bt_ClearIntFlag(TIM0,BtUevIrq); //中断清除
Bt_M0_Stop(TIM0); //停止timer0
Rxbuff01= Rxbuff.u8[1];
Rxbuff.len= Rxbuff.idx; //串口数组长度
Rxbuff.idx=0; //串口接受数据索引清0
Rxbuff.idt=0; //串口发送数据索引清0
Rxbuff.idc=2; //I2C读取数据索初始化为2(前两位为起始位和读成功校验位)
PeriperalStatus.bitField.timer0=0;
SystemStatus= RxCompleteState; //状态标志位,接收完成
}
/**
******************************************************************************
** \brief I2c1中断服务函数
**
** \return 无返回值
**
**
******************************************************************************/
///< I2c1中断函数
void I2c1_IRQHandler(void)
{
Command_bit=Rxbuff.u8[1];
switch(Command_bit)
{
case FRAME_Write: //I2C写
{
I2C_PageWrite(Rxbuff.u8);
break;
}
case FRAME_Read: //I2C读
{
I2C_PageRead(Rxbuff.I2);
break;
}
}
}
App_interrupts.h
#ifndef __APP_INTERRUPTS_H__
#define __APP_INTERRUPTS_H__
#include "Sys_Init.h"
#include "main.h"
#include "Data_treating.h"
/********************************************************************************
** \brief 串口接收数据类型定义
******************************************************************************/
typedef struct
{
uint8_t u8[32]; //串口接收数据缓存
uint8_t I2[32]; //I2C接收数据缓存
uint8_t idx; //串口接收数据索引
uint8_t idt; //串口发送数据索引
uint8_t idc; //I2C数据索引
uint8_t len; //串口接收数据长度缓存
}RxBuf;
extern volatile uint8_t State;
extern RxBuf Rxbuff;
extern volatile uint8_t Rxbuff01;
extern volatile uint8_t Command_bit;
#endif
App_Timer0_Init.c
/**
******************************************************************************
** \brief Timer0定时器初始化函数
**
** \return 无返回值
**
** 采用Timer0,定时器模式,采用内部4M时钟,初值设置为60736,计时1.2ms溢出,触发中断
**
******************************************************************************/
#include "App_Timer0_Init.h"
void App_Timer0_Init()
{
stc_bt_mode0_cfg_t stcBtConfig;
DDL_ZERO_STRUCT(stcBtConfig);
Sysctrl_SetPeripheralGate(SysctrlPeripheralBaseTim, TRUE);
stcBtConfig.enWorkMode = BtWorkMode0;
stcBtConfig.bEnGate = FALSE;
stcBtConfig.enPRS = BtPCLKDiv1;
stcBtConfig.bEnTog = FALSE;
stcBtConfig.enCT = BtTimer;
stcBtConfig.enCntMode = Bt16bitArrMode;
Bt_Mode0_Init(TIM0, &stcBtConfig);
Bt_M0_ARRSet(TIM0,60736); //重载值,1s/4M=1*10^6 / 4*1*10^6 =0.25us 1.2ms/0.25us = 4800 65536-4800=60736
Bt_ClearIntFlag(TIM0,BtUevIrq); //中断清除
Bt_Mode0_EnableIrq(TIM0); //中断使能
EnableNvic(TIM0_IRQn,IrqLevel3,TRUE); //NVIC使能
}
App_Timer0_Init.h
#ifndef __APP_TIMER0_INIT_H__
#define __APP_TIMER0_INIT_H__
#include "bt.h"
#include "ddl.h"
#include "lpm.h"
#include "clk.h"
#include "gpio.h"
extern void App_Timer0_Init(void);
#endif