添加一些关于midi播放的项目

This commit is contained in:
terryLP
2025-03-24 14:30:56 +08:00
parent e31eb22077
commit 498b4ef13b
699 changed files with 186162 additions and 1 deletions
@@ -0,0 +1,79 @@
/**********************************************************************
*
* 实验名称:模拟比较实验
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:选择ACMP正负输入,初始化ACMP模块,正负输入引脚输入数据开始
* 比较,比较完成产生中断,在中断服务函数中清除中断标志位
*
************************************************************************/
#include "common.h"
#include "acmp.h"
#include "pmc.h"
#include "sysinit.h"
int main (void);
void FunForCallback(void);
/********************************************************************/
int main (void)
{
ACMP_ConfigType ACMP_Config;
PMC_ConfigType PMC_Config={0};
/*系统初始化*/
sysinit();
PMC_Config.sCtrlstatus.bits.bBandgapEn = 1; //使能带隙
PMC_Config.sCtrlstatus.bits.bLvdStopEn = 0; //低压检测在停止模式下禁用
PMC_Config.sCtrlstatus.bits.bLvdRstEn = 0; //禁用低压检测复位
PMC_Init(PMC, &PMC_Config); //初始化PMC模块
PMC_DisableLVWInterrupt(PMC); //禁用低压报警中断
printf("\nRunning the ACMP_demo project.\r\n");
/*初始化ACMP模块 */
ACMP_Config.sCtrlStatus.bits.bIntEn = TRUE; /*使能中断*/
ACMP_Config.sCtrlStatus.bits.bMod= 1; /*中断在输出上升沿触发*/
ACMP_Config.sCtrlStatus.bits.bOutEn = 1; /* ACMP输出置于外部引脚 */
ACMP_Config.sPinSelect.bits.bNegPin = 0x3; /* 负输入引脚:DAC */
ACMP_Config.sPinSelect.bits.bPosPin = 0; /* 正输入引脚:外部基准0ACMP0_IN0-PTA0 */
ACMP_Config.sDacSet.bits.bEn = TRUE; /* 使能 DAC */
ACMP_Config.sDacSet.bits.bRef = DAC_REF_VDDA; /* DAC基准电压选择:Vdda */
ACMP_Config.sDacSet.bits.bVal = 0x1F; /* DAC输出电平位:Vin/2 */
ACMP_Config.sPinEnable.bits.bEn = TRUE; /* 使能外部基准0引脚输入 */
ACMP_SetCallback(ACMP0,FunForCallback); /*注册回调函数*/
ACMP_Init(ACMP0, &ACMP_Config); /*初始化ACMP模块*/
ACMP_Enable(ACMP0); /*使能ACMP */
/************************************************************
printf("\nEnter stop mode and will be woken up by ACMP Irq.\r\n");
PMC_SetMode(PMC,PmcModeStop3); //MCU进入停止模式,通过ACMP中断唤醒
printf("\nWake up now.\r\n");
*******************************************************************/
while(1);
}
/*****************************************************************************//*!
*
* @brief ACMP回调函数.
*
* @param none.
*
* @return none.
*
*****************************************************************************/
void FunForCallback(void)
{
if(ACMP_GetFlag(ACMP0))
{
ACMP_ClrFlag(ACMP0); //清除中断标志位
}
printf("\nCallback happens.\r\n");
}
@@ -0,0 +1,36 @@
/******************************************************************************
*
* @brief Define interrupt service routines referenced by the vector table.
*
* Note: Only "vectors.c" should include this header file.
*
*******************************************************************************
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H
/******************************************************************************
* Macros
******************************************************************************/
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
#undef VECTOR_032
#define VECTOR_032 ACMP0_Isr
#undef VECTOR_037
#define VECTOR_037 ACMP1_Isr
extern void ACMP0_Isr(void);
extern void ACMP1_Isr(void);
#endif /*__ISR_H */
/* End of "isr.h" */
@@ -0,0 +1,104 @@
/**********************************************************************
*
* 实验名称:模数转换试验(FIFO模式软件触发)
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:FIFO深度设定为3级,初始化ADC模块后,当FIFO采集数据满则开始
* 转换,然后通过读取转换结果寄存器读取FIFO中的转换结果。每次
* 读取一个转换结果读取3次
*
************************************************************************/
#include "common.h"
#include "ics.h"
#include "rtc.h"
#include "uart.h"
#include "adc.h"
#include "pmc.h"
#include "sysinit.h"
/**********************************************************************/
uint16_t u16ADC_ConversionBuff[16];
uint16_t u16ADC_ConversionCount = 0;
volatile uint8_t u8ADC_ConversionFlag = 0;
int main (void);
void ADC_CallBack( void );
/******************************************************************************/
int main (void)
{
uint8_t u8Ch;
ADC_ConfigType sADC_Config = {0};
/*系统初始化*/
sysinit();
printf("\nRunning the ADC_FIFO_demo project.\r\n");
UART_WaitTxComplete(TERM_PORT);
/*初始化ADC模块*/
sADC_Config.u8ClockDiv = ADC_ADIV_DIVIDE_8; /*!< ADC时钟源分频系数为8*/
sADC_Config.u8ClockSource = CLOCK_SOURCE_ADACK; /*!< ADC时钟源选择异步时钟*/
sADC_Config.u8Mode = ADC_MODE_12BIT; /*!< 12位转换*/
sADC_Config.sSetting.bIntEn = 1; /*!< 使能中断*/
sADC_Config.u8FiFoLevel = ADC_FIFO_LEVEL3; /*!< 3级FIFO */
ADC_SetCallBack(ADC_CallBack);
ADC_Init( ADC, &sADC_Config); /*!< 初始化ADC*/
while(1)
{
/*选择通道开始转换*/
u8ADC_ConversionFlag = 0;
ADC_SetChannel(ADC,ADC_CHANNEL_AD22_TEMPSENSOR);
ADC_SetChannel(ADC,ADC_CHANNEL_AD29_VREFH);
ADC_SetChannel(ADC,ADC_CHANNEL_AD30_VREFL);
/*等待转化完成 */
while( !u8ADC_ConversionFlag);
printf("ADC conversion result as below:\r\n");
for( u8Ch =0 ;u8Ch< u16ADC_ConversionCount; u8Ch ++)
{
printf("0x%x,",u16ADC_ConversionBuff[u8Ch]);
}
printf("\r\n");
printf("input any character to start a new conversion!\r\n");
// u8Ch = UART_GetChar(TERM_PORT);
u16ADC_ConversionCount = 0;
}
}
/***************************************************************************
+FUNCTION----------------------------------------------------------------
*
* @brief ADC回调函数中,在回调函数里读取转换结果
*
* @param none
*
* @return none
*
*****************************************************************************/
void ADC_CallBack( void )
{
while( !ADC_IsFIFOEmptyFlag(ADC) ) //结果FIFO中有有效的新数据
{
if( u16ADC_ConversionCount < 3 ) //读取转换结果,将结果FIFO中的数据全部读出
{
u16ADC_ConversionBuff[u16ADC_ConversionCount++] = ADC_ReadResultReg(ADC);
}
else
{
ADC_ReadResultReg(ADC); //读转换结果寄存器
}
}
u8ADC_ConversionFlag = 1;
}
/********************************************************************/
@@ -0,0 +1,29 @@
/******************************************************************************
* File: isr.h
* Purpose: Define interrupt service routines referenced by the vector table.
* Note: Only "vectors.c" should include this header file.
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H 1
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
#undef VECTOR_031
#define VECTOR_031 ADC_Isr
extern void RTC_Isr(void);
extern void ADC_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,164 @@
/********************************************************************************
*
* 实验名称:硬件触发ADC转换(FIFO模式)
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:设定FIFO深度,初始化ADC模块,ADC开始采集数据放入FIFO中,FIFO满
后等待硬件触发信号。
1:单次转换模式, 当ADC检测到第一个硬件触发信号后,开始转换FIFO
中第一个数据,检测到第二个硬件触发信号后,开始
转换FIFO中第2个数据,以此类推直到FIFO中的数据全部
转换完,然后触发ADC中断读取转换结果。当转换完成后,
如果出现新的触发脉冲,将生产新的转换集合。
例:当FIFO深度设定为3时,ADC要检测到三个硬件触发信号
才能将FIFO中的数据全部转换完成,然后产生中断。
2:连续转换模式, 当出现硬件触发信号时,会触发ADC连续采样,建议在使用
FIFO数据模式时,在中断服务函数中读取FIFO结果前禁用ADC
硬件触发使能,在读取完FIFO结果之后再打开硬件触发使能,
避免数据错乱。
***********************************************************************************/
#include "common.h"
#include "ics.h"
#include "sim.h"
#include "rtc.h"
#include "pit.h"
#include "uart.h"
#include "adc.h"
#include "etm.h"
#include "sysinit.h"
uint16_t u16ADC_ConversionBuff[16];
uint16_t u16ADC_ConversionCount = 0;
volatile uint8_t u8ADC_ConversionFlag = 0;
int main (void);
void ADC_CallBack( void );
/********************************************************************/
int main (void)
{
uint16_t u16ModuloValue;
uint32_t u32LoadValue0;
ADC_ConfigType sADC_Config = {0};
RTC_ConfigType sRTCConfig;
RTC_ConfigType *pRTC_Config=&sRTCConfig;
PIT_ConfigType sPITConfig0;
PIT_ConfigType *pPIT_Config0 =&sPITConfig0;
/*系统初始化*/
sysinit();
printf("\nRunning the ADC_HWT_demo project.\r\n");
/*********************ADC硬件触发源选择**********************************/
/**************************************************************************
*注:ETM2通道4与NMI中断输入引脚共用PB4,当选择ETM2通道4作为ADC硬件触发源时,
* 需要禁用NMI中断输入引脚
****************************************************************************/
SIM_TriggerADCByRTC(); //选择RTC溢出触发ADC转换
//SIM_TriggerADCByPIT(); //选择PIT溢出触发ADC
//SIM_TriggerADCByETM2Init(); //选择ETM2初始后延时一段时间触发ADC转换
//SIM_TriggerADCByETM2Match(); //选择ETM2匹配后延时一段时间触发ADC转换
/**********设置ETM2从匹配/初始化到触发ADC转换的延时时间*****************/
SIM_SetClockOutputDivide(0x07); //总线时钟输出分频
SIM_DelayETM2Trig2ADC(0xff); //延时计数模数值
UART_WaitTxComplete(TERM_PORT);
LED0_Init();
/* 初始化ADC模块*/
sADC_Config.u8ClockDiv = ADC_ADIV_DIVIDE_8; /*!< ADC时钟源分频系数为8 */
sADC_Config.u8ClockSource = CLOCK_SOURCE_ADACK; /*!< ADC时钟源选择异步时钟 */
sADC_Config.u8Mode = ADC_MODE_12BIT; /*!< 12位转换 */
sADC_Config.sSetting.bIntEn = 1; /*!< 使能中断*/
sADC_Config.u8FiFoLevel = ADC_FIFO_LEVEL3; /*!< 3级FIFO */
sADC_Config.sSetting.bContinuousEn=0; /*!< 单次转换模式 */
sADC_Config.sSetting.bHardwareTriggerEn=1; /*!< 使能硬件触发模式 */
ADC_SetCallBack(ADC_CallBack);
ADC_Init( ADC, &sADC_Config); //初始化ADC模块
/*RTC溢出触发ADC */
u16ModuloValue = 0x09;
pRTC_Config->u16ModuloValue = u16ModuloValue; //设定模数值
pRTC_Config->bInterruptEn=0; //禁用中断
pRTC_Config->bClockSource = RTC_CLKSRC_1KHZ; //选择1KHz时钟源
pRTC_Config->bClockPresaler = RTC_CLK_PRESCALER_100; //时钟分频系数100
RTC_Init(pRTC_Config);
/*PIT0溢出触发ADC */
/*
u32LoadValue0 = 0xFFFFFF; //设定装载值
pPIT_Config0->u32LoadValue = u32LoadValue0;
pPIT_Config0->bFreeze = FALSE; //在调试模式时仍然运行
pPIT_Config0->bModuleDis = FALSE; //使能PIT模块
pPIT_Config0->bChainMode = FALSE; //禁用链模式
pPIT_Config0->bInterruptEn = FALSE; //禁用中断
pPIT_Config0->bETMerEn = TRUE; //使能PIT通道
PIT_Init(PIT_CHANNEL0, pPIT_Config0);
*/
/*选择ETM2匹配触发*/
/*
ETM_PWMInit(ETM2, ETM_PWMMODE_EDGEALLIGNED, ETM_PWM_HIGHTRUEPULSE);
ETM_SetETMEnhanced(ETM2);
ETM2->EXTTRIG |= ETM_EXTTRIG_CH1TRIG_MASK;//使能通道1匹配触发
ETM_SetModValue(ETM2, 29999); // 设置ETM2模值
ETM_SetChannelValue(ETM2, ETM_CHANNEL_CHANNEL1, 5000); //设置ETM2通道值
ETM_ClockSet(ETM2, ETM_CLOCK_SYSTEMCLOCK, ETM_CLOCK_PS_DIV128); //设置ETM2模块时钟源及分频系数.
NVIC_DisableIRQ(ETM2_IRQn);
*/
/*选择ETM2初始触发*/
/*
ETM_PWMInit(ETM2, ETM_PWMMODE_EDGEALLIGNED, ETM_PWM_HIGHTRUEPULSE);
ETM_SetETMEnhanced(ETM2);
ETM_SetCounterInitValue(ETM2, 3000);
ETM2->EXTTRIG |= ETM_EXTTRIG_INITTRIGEN_MASK; //初始化触发使能
ETM_SetModValue(ETM2, 9999); // 设置ETM2模值
ETM_SetChannelValue(ETM2, ETM_CHANNEL_CHANNEL1, 5000); //设置ETM2通道值
ETM_ClockSet(ETM2, ETM_CLOCK_SYSTEMCLOCK, ETM_CLOCK_PS_DIV128); //设置ETM2模块时钟源及分频系数.
*/
/***********设置转换通道,等待触发信号 ***********************/
ADC_SetChannel(ADC,ADC_CHANNEL_AD22_TEMPSENSOR);
ADC_SetChannel(ADC,ADC_CHANNEL_AD29_VREFH);
ADC_SetChannel(ADC,ADC_CHANNEL_AD30_VREFL);
while(1)
{
}
}
/***************************************************************************
+FUNCTION----------------------------------------------------------------
*
* @brief ADC回调函数中,在回调函数里读取转换结果
*
* @param none
*
* @return none
*
*****************************************************************************/
void ADC_CallBack( void )
{
uint8_t u8Ch;
LED0_Toggle();
while( !ADC_IsFIFOEmptyFlag(ADC) ) ////结果FIFO中有有效的新数据
{
if( u16ADC_ConversionCount < 3 ) //读取转换结果,将结果FIFO中的数据全部读出
{
u16ADC_ConversionBuff[u16ADC_ConversionCount++] = ADC_ReadResultReg(ADC);
}
else
{
ADC_ReadResultReg(ADC);
}
}
/*打印转换结果*/
printf("ADC conversion result as below:\r\n");
for( u8Ch =0 ; u8Ch< u16ADC_ConversionCount; u8Ch ++)
{
printf("0x%x,",u16ADC_ConversionBuff[u8Ch]);
}
printf("\r\n");
u16ADC_ConversionCount = 0;;
}
/********************************************************************/
@@ -0,0 +1,31 @@
/******************************************************************************
* File: isr.h
* Purpose: Define interrupt service routines referenced by the vector table.
* Note: Only "vectors.c" should include this header file.
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H 1
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
#undef VECTOR_035
#define VECTOR_035 ETM2_Isr /*!< Vector 35 points to ETM2 interrupt service routine */
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
#undef VECTOR_031
#define VECTOR_031 ADC_Isr
#undef VECTOR_038
#define VECTOR_038 PIT_Ch0Isr /*!< Vector 38 points to PIT channel 0 interrupt service routine */
#undef VECTOR_039
#define VECTOR_039 PIT_Ch1Isr /*!< Vector 39 points to PIT channel 1 interrupt service routine */
extern void ETM2_Isr(void);
extern void RTC_Isr(void);
extern void ADC_Isr(void);
extern void PIT_Ch1Isr(void);
extern void PIT_Ch0Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,101 @@
/**********************************************************************
*
* 实验名称:模数转换实验(软件触发)
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:初始化ADC模块,选择转换输入通道开始转换。转换完成触发中断,
* 在中断服务函数中读取转换结果
************************************************************************/
#include "common.h"
#include "ics.h"
#include "rtc.h"
#include "uart.h"
#include "adc.h"
#include "sysinit.h"
/******************************************************************************/
uint16_t u16ADC_ConversionBuff[16];
uint16_t u16ADC_ConversionCount = 0;
volatile uint8_t u8ADC_ConversionFlag = 0;
int main (void);
void ADC_CallBack( void );
/******************************************************************************/
int main (void)
{
uint8_t u8Ch;
ADC_ConfigType sADC_Config = {0};
/*系统初始化*/
sysinit();
printf("\nRunning the ADC_Int_demo project.\r\n");
UART_WaitTxComplete(TERM_PORT);
/*初始化ADC模块*/
sADC_Config.u8ClockDiv = ADC_ADIV_DIVIDE_4; /*!< ADC时钟源分频系数为4*/
sADC_Config.u8ClockSource = CLOCK_SOURCE_BUS_CLOCK; /*!< ADC时钟源选择总线时钟*/
sADC_Config.u8Mode = ADC_MODE_12BIT; /*!< 12位转换*/
sADC_Config.sSetting.bIntEn = 1; /*!< 使能中断*/
ADC_SetCallBack(ADC_CallBack);
ADC_Init( ADC, &sADC_Config); /*!< 初始化ADC模块*/
while(1)
{
/* 设置转换通道,开始转换*/
u8ADC_ConversionFlag = 0;
ADC_SetChannel(ADC,ADC_CHANNEL_AD22_TEMPSENSOR);
/* 等待转换完成*/
while( !u8ADC_ConversionFlag);
/* 设置转换通道,开始转换*/
u8ADC_ConversionFlag = 0;
ADC_SetChannel(ADC,ADC_CHANNEL_AD29_VREFH);
/* 等待转换完成*/
while( !u8ADC_ConversionFlag);
/* 设置转换通道,开始转换*/
u8ADC_ConversionFlag = 0;
ADC_SetChannel(ADC,ADC_CHANNEL_AD30_VREFL);
/* 等待转换完成*/
while( !u8ADC_ConversionFlag);
printf("ADC conversion result as below:\r\n");
for( u8Ch =0 ;u8Ch< u16ADC_ConversionCount; u8Ch ++)
{
printf("0x%x,",u16ADC_ConversionBuff[u8Ch]);
}
printf("\r\n");
printf("input any character to start a new conversion!\r\n");
//u8Ch = UART_GetChar(TERM_PORT);
u16ADC_ConversionCount = 0;
}
}
/***************************************************************************
+FUNCTION----------------------------------------------------------------
*
* @brief 回调函数读取转换结果
*
* @param none
*
* @return none
*
*****************************************************************************/
void ADC_CallBack( void )
{
if( u16ADC_ConversionCount < 3 ) //读取转换结果
{
u16ADC_ConversionBuff[u16ADC_ConversionCount++] = ADC_ReadResultReg(ADC);
}
u8ADC_ConversionFlag = 1;
}
/********************************************************************/
@@ -0,0 +1,28 @@
/******************************************************************************
* File: isr.h
* Purpose: Define interrupt service routines referenced by the vector table.
* Note: Only "vectors.c" should include this header file.
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H 1
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
#undef VECTOR_031
#define VECTOR_031 ADC_Isr
extern void RTC_Isr(void);
extern void ADC_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,52 @@
/**********************************************************************
*
* 实验名称:模数转换实验(软件触发)
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:初始化ADC模块,选择转换输入通道开始转换。采用轮询的方式读取
* 转换结果
*
************************************************************************/
#include "common.h"
#include "ics.h"
#include "rtc.h"
#include "uart.h"
#include "adc.h"
#include "sysinit.h"
int main (void);
/********************************************************************/
int main (void)
{
ADC_ConfigType sADC_Config = {0};
/* 系统初始化*/
sysinit();
printf("\nRunning the ADC_Poll_demo project.\r\n");
UART_WaitTxComplete(TERM_PORT);
/*初始化ADC模块*/
sADC_Config.u8ClockDiv = ADC_ADIV_DIVIDE_8; /*!< ADC时钟源分频系数为8*/
sADC_Config.u8ClockSource = CLOCK_SOURCE_BUS_CLOCK; /*!< ADC时钟源选择总线时钟*/
sADC_Config.u8Mode = ADC_MODE_12BIT; /*!< 12位转换*/
ADC_Init( ADC, &sADC_Config); /*!< 初始化ADC模块*/
while(1)
{
/*设置转换通道开始转换,等待转换完成读取转换结果*/
printf("VREFH conversion value:0x%x\r\n",ADC_PollRead(ADC,ADC_CHANNEL_AD29_VREFH));
printf("VREFL conversion value:0x%x\r\n",ADC_PollRead(ADC,ADC_CHANNEL_AD30_VREFL));
printf("Temperature sensor conversion value:0x%x\r\n",ADC_PollRead(ADC,ADC_CHANNEL_AD22_TEMPSENSOR));
printf("input any character to start a new conversion!\r\n");
UART_GetChar(TERM_PORT);
}
}
/********************************************************************/
@@ -0,0 +1,27 @@
/******************************************************************************
* File: isr.h
* Purpose: Define interrupt service routines referenced by the vector table.
* Note: Only "vectors.c" should include this header file.
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H 1
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
extern void RTC_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,73 @@
/**********************************************************************
*
* 实验名称:内部温度传感器实验
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:ADC采集内部温度传感器对应的电压值,将其转换成数字量,然后计算出当前温度
* 值通过串口打印出来
*
************************************************************************/
#include "common.h"
#include "ics.h"
#include "rtc.h"
#include "uart.h"
#include "adc.h"
#include "sysinit.h"
#include "pmc.h"
#define VDD 3.3 //测试R4,R5中间的电压值
int main (void);
/**********************************************************************/
int main (void)
{
float Vtemp,m,temp,VBG;
int32_t advrefh,adtemp,advcore;
ADC_ConfigType sADC_Config = {0};
PMC_ConfigType PMC_Config={0};
sysinit();
PMC_Config.sCtrlstatus.bits.bBandgapEn = 1; //使能带隙
PMC_Config.sCtrlstatus.bits.bLvdStopEn = 0;
PMC_Config.sCtrlstatus.bits.bLvdRstEn = 0;
PMC_Init(PMC, &PMC_Config); //初始化PMC模块
UART_WaitTxComplete(TERM_PORT);
/*初始化ADC模块*/
sADC_Config.u8ClockDiv = ADC_ADIV_DIVIDE_8; /*!< ADC时钟源分频系数为8*/
sADC_Config.u8ClockSource = CLOCK_SOURCE_BUS_CLOCK_DIVIDE_2; /*!< ADC时钟源选择总线时钟2分频*/
sADC_Config.u8Mode = ADC_MODE_10BIT; /*!< 10位转换*/
sADC_Config.sSetting.bLongSampleEn=1; /*!<长采样模式,*/
ADC_Init( ADC, &sADC_Config); /*!<初始化ADC模块*/
while(1)
{
advrefh=ADC_PollRead(ADC,ADC_CHANNEL_AD29_VREFH); /*ADC读取Vrefh的值*/
adtemp=ADC_PollRead(ADC,ADC_CHANNEL_AD22_TEMPSENSOR); /*!< ADC读取温传感器数值*/
advcore= ADC_PollRead(ADC,ADC_CHANNEL_AD23_BANDGAP); /*!< ADC读取带隙值*/
VBG = VDD*advcore/advrefh; /*<计算带隙电压值*/
Vtemp = VBG*adtemp/advcore; /*<计算当前温度下温度传感器对应的电压值*/
printf("VBG value:%f\r\n",VBG);
printf("Temperature sensor conversion value:%f\r\n",Vtemp);
/**********************************************************************************************
注:当温度为25 度时温度传感器对应的电压值,Vtemp25=1.419V。当Vtemp>Vtemp25 时表示当前温度低
于25 度,当Vtemp<Vtemp25 时表示当前温度高于25 度
M:温度相对电压变化率,当温度大于25 度时,M=-3.65mv/℃,当温度小于25 度时M=-3.4mv/℃
**********************************************************************************************/
if(Vtemp >1.419) m=-3.4;
else m=-3.65;
temp = 25 - (1.419-Vtemp)*1000/m; /*<计算当前温度*/
printf("Temperature value:%f\r\n",temp);
UART_GetChar(TERM_PORT);
}
}
/********************************************************************/
@@ -0,0 +1,27 @@
/******************************************************************************
* File: isr.h
* Purpose: Define interrupt service routines referenced by the vector table.
* Note: Only "vectors.c" should include this header file.
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H 1
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
extern void RTC_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,304 @@
/**********************************************************************
*
* 实验名称:BOS位带操作实验
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:BOS位带操作,能够降低总线的占用率和CPU的执行时间,也可节省代码
* 空间,以降低系统能耗的效果。
*
************************************************************************/
#include "common.h"
#include "ics.h"
#include "rtc.h"
#include "uart.h"
#include "systick.h"
#include "bos.h"
#include "sysinit.h"
/************************************************************************************
*
* 使用BFI/UBFX功能需要注意的是,BFI/UBFX操作指定的外设偏移地址是addr[18:0]addr[19]
* 用作"w"指示符的最低有效位,而非地址位。GPIO寄存器的偏移地址位是addr[19:0],地址空间
* 在FF000.因此会有1bit 的地址冲突。为此在使用BFI/UBFX操作GPIO的寄存器时,使用的是内存
* 映射出来的地址空间,此时GPIO的起始地址将为F000,如果还使用原来的地址,命令将会无效。
*
**********************************************************************************/
#define GPIO_ALIAS_OFFSET 0x000F0000L
#define GPIOB_PDOR_ALIAS (((uint32_t)&GPIOB->PDOR)-GPIO_ALIAS_OFFSET) /*!<GPIO寄存器内存映射地址空间 */
/******************************************************************************/
int main (void);
void RTC_Task(void);
uint32_t BOS_LogicOPwithC(void);
uint32_t BOS_LogicOPwithBOS(void);
uint32_t BOS_BFIwithC(uint32_t *pAddr, uint8_t u8BitPos, uint8_t u8FieldWidth, uint32_t u32Data);
uint32_t BOS_BFIwithBOS(void);
/*****************************************************************************/
#ifdef __GNUC__
#define __ramfunc __attribute__((section (".data")))
#endif
/********************************************************************/
int main (void)
{
/*系统初始化*/
sysinit();
ICS_ConfigType sICSConfig;
RTC_ConfigType sRTCConfig;
RTC_ConfigType *pRTCConfig = &sRTCConfig;
UART_ConfigType sConfig;
printf("\r\nRunning the BOS_demo project.\r\n");
#if defined(__ICCARM__)
printf("Build by IAR\r\n");
#elif defined(__GNUC__)
printf("Build by GUNC\r\n");
#elif defined(__CC_ARM)
printf("Build by MDK\r\n");
#else
printf("Unrecognized compiler!\r\n");
#endif
LED0_Init();
LED2_Init();
/*配置RTC每隔一秒产生一次中断*/
pRTCConfig->u16ModuloValue = 9;
pRTCConfig->bInterruptEn = RTC_INTERRUPT_ENABLE; /* 使能中断 */
pRTCConfig->bClockSource = RTC_CLKSRC_1KHZ; /* 时钟频率1khz*/
pRTCConfig->bClockPresaler = RTC_CLK_PRESCALER_100; /* 分频系数100*/
RTC_SetCallback(RTC_Task);
RTC_Init(pRTCConfig);
printf("\nIt is in FEE mode now,");
UART_WaitTxComplete(TERM_PORT);
/*将时钟模式由 FEE 模式切换到 FEI 模式*/
sICSConfig.u32ClkFreq = 10000;
ICS_SwitchMode(FEE,FEI, &sICSConfig);
/* 由于总线时钟发生改变,从新初始化UART模块*/
sConfig.u32SysClkHz = 40000000L;
sConfig.u32Baudrate = UART_PRINT_BITRATE;
UART_Init (TERM_PORT, &sConfig);
printf("switch to FEI mode.\n");
OSC_Enable();
/* 开始测试常规C位操作和BOS位操作CPU执行时间 */
printf("Logic operation in C takes %d ticks!\r\n", BOS_LogicOPwithC());
printf("Logic operation with BOS takes %d ticks!\r\n", BOS_LogicOPwithBOS());
/*!
* 配置 PTG0 到 PTG3 引脚为输出引脚
*/
GPIOB->PDDR |= (0xF << 16); /* 配置PTG0~PTG3引脚为输出 */
GPIOB->PIDR &= ~(0xF << 16); /* 注: 为了从引脚中读到正确的数据,必须清理PIDR寄存器 */
printf("Bit field operation in C takes %d ticks!\r\n", BOS_BFIwithC((uint32_t*)&GPIOB->PDOR,16,4-1, 5<<16));
printf("Bit field operation with BOS takes %d ticks!\r\n", BOS_BFIwithBOS());
printf("Test completed!\n");
while(1)
{
}
}
/*****************************************************************************//*!
*
* @brief 采用常规C对寄存器执行异或操作.
*
* @param none
*
* @return none
*
*****************************************************************************/
#if (defined(__ICCARM__) || defined(__GNUC__))
__ramfunc uint32_t BOS_LogicOPwithC(void)
#elif defined(__CC_ARM)
uint32_t BOS_LogicOPwithC(void)
#endif
{
uint32_t u32PortVal = 0;
uint32_t u32LogicOPTicks;
/*!
* 配置PTA1 作为输出引脚
*/
GPIOA->PDDR |= 0x02;
GPIOA->PIDR &= ~0x02; /* 注:为了从引脚中读到正确的数据,端口输入禁用寄存器对应位清零 */
/*初始化SysTick定时器,计算代码执行时间*/
SysTick->CTRL &= ~(SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk);
SysTick->VAL = 0x0; /*清除当前值寄存器 */
SysTick->LOAD = 0x00FFFFFF;
SysTick->CTRL |= (SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk);
/* exe: */
/*! \
* 常规的读、修改、写顺序去切换一个GPIO输出
*/
u32PortVal = GPIOA->PDOR;
u32PortVal ^= 0x02;
GPIOA->PDOR = u32PortVal;
u32PortVal = GPIOA->PDOR;
u32PortVal ^= 0x02;
GPIOA->PDOR = u32PortVal;
u32PortVal = GPIOA->PDOR;
u32PortVal ^= 0x02;
GPIOA->PDOR = u32PortVal;
u32PortVal = GPIOA->PDOR;
u32PortVal ^= 0x02;
GPIOA->PDOR = u32PortVal;
u32PortVal = GPIOA->PDOR;
u32PortVal ^= 0x02;
GPIOA->PDOR = u32PortVal;
/* 测量代码执行的时间 */
u32LogicOPTicks = SysTick->VAL;
return (SysTick->LOAD - u32LogicOPTicks);
}
/*****************************************************************************//*!
*
* @brief 采用BOS位带操作执行异或操作 .
*
* @param none
*
* @return none
*
*****************************************************************************/
#if (defined(__ICCARM__) || defined(__GNUC__))
__ramfunc uint32_t BOS_LogicOPwithBOS(void)
#elif defined(__CC_ARM)
uint32_t BOS_LogicOPwithBOS(void)
#endif
{
uint32_t u32LogicOPTicks;
/*!
* 配置PTA1 作为输出引脚
*/
GPIOA->PDDR |= 0x02;
GPIOA->PIDR &= ~0x02; /* 注:为了从引脚中读到正确的数据,端口输入禁用寄存器对应位清零 */
/*初始化SysTick定时器,计算代码执行时间*/
SysTick->CTRL &= ~(SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk);
SysTick->VAL = 0x0; /*清除当前值寄存器 */
SysTick->LOAD = 0x00FFFFFF;
SysTick->CTRL |= (SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk);
/* exe: */
BOS_XOR(&GPIOA->PDOR) = 0x02;
BOS_XOR(&GPIOA->PDOR) = 0x02;
BOS_XOR(&GPIOA->PDOR) = 0x02;
BOS_XOR(&GPIOA->PDOR) = 0x02;
BOS_XOR(&GPIOA->PDOR) = 0x02;
/* 测量代码执行的时间 */
u32LogicOPTicks = SysTick->VAL;
return (SysTick->LOAD - u32LogicOPTicks);
}
/*****************************************************************************//*!
*
* @brief 采用常规C,对寄存器执行一段数据的插入.
*
* @param[in] pAddr 指向目标地址
* @param[in] u8BitPos 插入数据的其实位
* @param[in] u8FieldWidth 插入数据宽度-1
* @param[in] u32Data 要插入寄存器的数据
*
* @return none
*
*****************************************************************************/
#if (defined(__ICCARM__) || defined(__GNUC__))
__ramfunc uint32_t BOS_BFIwithC(uint32_t *pAddr, uint8_t u8BitPos, uint8_t u8FieldWidth, uint32_t u32Data)
#elif defined(__CC_ARM)
uint32_t BOS_BFIwithC(uint32_t *pAddr, uint8_t u8BitPos, uint8_t u8FieldWidth, uint32_t u32Data)
#endif
{
uint32_t u32RegVal;
uint32_t u32Mask;
uint32_t u32LogicOPTicks;
/*初始化SysTick定时器,计算代码执行时间*/
SysTick->CTRL &= ~(SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk);
SysTick->VAL = 0x0; /*清除当前值寄存器 */
SysTick->LOAD = 0x00FFFFFF;
SysTick->CTRL |= (SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk);
/* exe: */
u32RegVal = *pAddr;
u32Mask = ((1 << (u8FieldWidth+1)) - 1) << u8BitPos;
u32RegVal = (u32RegVal & ~u32Mask)|((u32Data) & u32Mask);
*pAddr = u32RegVal;
/* 测量代码执行的时间 */
u32LogicOPTicks = SysTick->VAL;
return (SysTick->LOAD - u32LogicOPTicks);
}
/*****************************************************************************//*!
*
* @brief 采用BOS位操作对寄存器执行一段数据的插入
*
* @param none
*
* @return none
*
*****************************************************************************/
#if (defined(__ICCARM__) || defined(__GNUC__))
__ramfunc uint32_t BOS_BFIwithBOS(void)
#elif defined(__CC_ARM)
uint32_t BOS_BFIwithBOS(void)
#endif
{
uint32_t u32LogicOPTicks;
uint32_t u32Data = (0x5 << 16);
uint32_t u32Addr = GPIOB_PDOR_ALIAS;
/* 配置 PTG0~PTG3 为输出引脚 */
GPIOB->PDDR |= (0xF << 16); /* 配置 PTG0~PTG3 为输出引脚 */
GPIOB->PDOR = 0; /*PTG0 to PTG3输出为0 */
GPIOB->PIDR &= ~(0xF << 16); /* 注:为了从引脚中读到正确的数据,端口输入禁用寄存器对应位清零 */
/*初始化SysTick定时器,计算代码执行时间*/
SysTick->CTRL &= ~(SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk);
SysTick->VAL = 0x0; /*清除当前值寄存器 */
SysTick->LOAD = 0x00FFFFFF;
SysTick->CTRL |= (SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk);
/* exe: */
BOS_BITFIELD_INSERT(u32Addr,16,4) = u32Data; /* 写 5 位数据到16~19位*/
/* 测量代码执行的时间 */
u32LogicOPTicks = SysTick->VAL;
/* check if the data field is inserted correctly (canceled)*/
/*
if(u32Data != GPIOB->PDIR)
{
printf("Error: bitfield insertion with BOS failed!\n");
}
*/
return (SysTick->LOAD - u32LogicOPTicks);
}
/*****************************************************************************//*!
*
* @brief RTC回调函数
*
* @param none
*
* @return none
*
*****************************************************************************/
void RTC_Task(void)
{
/* 切换 LED1 */
LED0_Toggle();
}
/********************************************************************/
@@ -0,0 +1,34 @@
/******************************************************************************
*
* @brief define interrupt service routines referenced by the vector table.
*
* Note: Only "vectors.c" should include this header file.
*
*******************************************************************************
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
/*!
* @brief define interrupt service routine for different vectors.
*
*/
#undef VECTOR_036
#define VECTOR_036 RTC_Isr /*!< Vector 36 points to RTC interrupt service routine */
extern void RTC_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,64 @@
/**********************************************************************
*
* 实验名称:CRC循环冗余校验
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:选择CRC校验模式,设定种子值、多项式、读写数字的转置类型等,
* 输入要校验的数据,最终生成校验码(校验和)
*
************************************************************************/
#include "common.h"
#include "crc.h"
#include "uart.h"
#include "sysinit.h"
int main (void);
/********************************************************************/
int main (void)
{
uint32_t u32Crc_ConverterResult;
uint32_t u32SeedValue;
CRC_ConfigType sCRC_ConfigType = {0};
CRC_ConfigType *pCRC_Config=&sCRC_ConfigType;
uint8_t MessageSource[] = {"123456789"} ; /*!< 要校验的数据*/
/*系统初始化*/
sysinit();
printf("\nRunning the CRC_demo project.\r\n");
/*配置CRC寄存器,使其工作在16CRC模式 */
pCRC_Config->u32PolyData = 0x1021; /*!< 16位 CRC-CCITT 多项式 */
u32SeedValue = 0xFFFF; /*!< 设定种子值(检验和初始值) */
pCRC_Config->bWidth = CRC_WIDTH_16BIT; /*!< 选择16位CRC协议 */
pCRC_Config->bTransposeReadType = CRC_READ_TRANSPOSE_NONE; /*!< 读取的CRC数据寄存器的值不转置 */
pCRC_Config->bTransposeWriteType = CRC_WRITE_TRANSPOSE_NONE; /*!< 写入到CRC数据寄存器的值不转置 */
CRC_Init(pCRC_Config); /*!< 初始化CRC模块*/
printf("CRC0->GPOLY=0x%x, CRC0->CTRL=0x%x\r\n",CRC0->GPOLY,CRC0->CTRL);
/*开始进16位模式CRC计算,生成校验和*/
u32Crc_ConverterResult = CRC_Cal16(u32SeedValue, &MessageSource[0], (sizeof(MessageSource)-1));
printf("CRC-CCITT function calculation result = 0x%x @seed = 0x%x .\r\n", u32Crc_ConverterResult, u32SeedValue );
/* 复位CRC模块*/
CRC_DeInit();
/*配置CRC寄存器,使其工作在32位模式*/
pCRC_Config->u32PolyData = 0x04C11DB7; /*!< 设置CRC32 多项式*/
u32SeedValue = 0xFFFFFFFF; /*!< 设定种子值(检验和初始值) */
pCRC_Config->bWidth = CRC_WIDTH_32BIT; /*!< 选择32位CRC协议 */
pCRC_Config->bTransposeReadType = CRC_READ_TRANSPOSE_ALL; /*!< 读取数据寄存器的值,字节中的位和字节均转置 */
pCRC_Config->bTransposeWriteType = CRC_WRITE_TRANSPOSE_BIT; /*!< 写数据时,字节中的位转置,字节不转置 */
pCRC_Config->bFinalXOR = TRUE; /*!< 反转CRC数据寄存器的读取值*/
CRC_Init(pCRC_Config); /*!< 初始化CRC模块 */
/*开始进行32位CRC计算,生成校验和*/
u32Crc_ConverterResult = CRC_Cal32(u32SeedValue, &MessageSource[0], (sizeof(MessageSource)-1));
printf("CRC32 function calculation result = 0x%x @seed = 0x%x .\r\n", u32Crc_ConverterResult, u32SeedValue );
while(1);
}
@@ -0,0 +1,23 @@
/******************************************************************************
* @brief define interrupt service routines referenced by the vector table.
*
* Note: Only "vectors.c" should include this header file.
*
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,69 @@
/**********************************************************************
*
* 实验名称:通道联合PWM输出
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:ETM2的通道0和通道1组合产生一个PWM方波,通道0管脚为PC0,通道1管脚为PC1
*
************************************************************************/
#include "common.h"
#include "rtc.h"
#include "ETM.h"
#include "uart.h"
#include "sysinit.h"
void ETM2_Task(void);
/********************************************************************/
int main (void)
{
/* 系统初始化*/
sysinit();
printf("\nRunning the ETM_demo project.\r\n");
LED0_Init();
/* 设置ETM2为组合模式 */
ETM_PWMInit(ETM2, ETM_PWMMODE_COMBINE, ETM_PWM_LOWTRUEPULSE);
/* 设ETM2的MOD值 */
ETM_SetModValue(ETM2, 3999); //频率为10KHz
/* 时钟及分频系数的配置 */
ETM_ClockSet(ETM2, ETM_CLOCK_SYSTEMCLOCK, ETM_CLOCK_PS_DIV1);
ETM_SetCallback(ETM2, ETM2_Task);//设置ETM2回调函数点
NVIC_EnableIRQ(ETM2_IRQn); //使能IRQ中断
ETM_EnableOverflowInt(ETM2); //开启溢出中断
/* 设置占空比,设置通道对占空比为50% */
ETM_SetDutyCycleCombine(ETM2, ETM_CHANNEL_CHANNEL1, 50);
while(1);
}
/*****************************************************************************//*!
*
* @brief ETM中断回调任务函数.
*
* @param none.
*
* @return none.
*
*****************************************************************************/
void ETM2_Task(void)
{
static uint32_t count;
ETM_ClrOverFlowFlag(ETM2); //清除溢出标志位
if(count == 2000)
{
count = 0;
UART_PutChar(TERM_PORT,'@');//传输字符@到串口1
}
else
{
count++;
}
}
/********************************************************************/
@@ -0,0 +1,38 @@
/******************************************************************************
*
* @brief define interrupt service routines referenced by the vector table.
*
* Note: Only "vectors.c" should include this header file.
*
*******************************************************************************
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
/*!
* @brief define interrupt service routine for different vectors.
*
*/
#undef VECTOR_035
#define VECTOR_035 ETM2_Isr /*!< Vector 35 points to ETM2 interrupt service routine */
#undef VECTOR_036
#define VECTOR_036 RTC_Isr /*!< Vector 36 points to RTC interrupt service routine */
extern void RTC_Isr(void);
extern void ETM2_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,87 @@
/**********************************************************************
*
* 实验名称:ETM双边沿捕捉
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:跳变沿脉冲捕获,由 ETM0的通道1产生脉冲信号,周期为10000,
* 脉冲宽度为5000,使用ETM2的通道0作为捕获口,将ETM2 Ch0PC0
* 与ETM0 Ch0PB2)短接。
*
************************************************************************/
#include "common.h"
#include "ics.h"
#include "ETM.h"
#include "uart.h"
#include "sysinit.h"
void ETM2_Task(void);
volatile uint16_t u16Ch0Value,u16Ch1Value;
volatile uint8_t u8IntMark;
uint16_t x,y;
/********************************************************************/
int main (void)
{
/* 初始化 */
sysinit();
/* ETM0通道0(即PB2脚)输出方波即PB2脚, 周期10000,脉冲宽度为5000 */
SIM_RemapETM0CH0Pin();
ETM_OutputCompareInit(ETM0, ETM_CHANNEL_CHANNEL0, ETM_OUTPUT_TOGGLE);//Modify
/* 装载ETM0的MOD计数值 */
ETM_SetModValue(ETM0, 5000);
/* 设置时钟*/
ETM_ClockSet(ETM0, ETM_CLOCK_SYSTEMCLOCK, ETM_CLOCK_PS_DIV1);
/* 配置ETM2的通道用来测出脉冲的宽度或周期*/
ETM_DualEdgeCaptureInit( ETM2,
ETM_CHANNELPAIR0, /* 通道对0:通道0和通道1 */
ETM_INPUTCAPTURE_DUALEDGE_ONESHOT, /* 单次模式 */
ETM_INPUTCAPTURE_DUALEDGE_RISINGEDGE, /* 通道0检测上升沿 */
ETM_INPUTCAPTURE_DUALEDGE_FALLInGEDGE /* 通道1检测下降沿 */
);
/*ETM2的时钟设置,为系统时钟,1分频*/
ETM_ClockSet(ETM2, ETM_CLOCK_SYSTEMCLOCK, ETM_CLOCK_PS_DIV1);
ETM_SetCallback(ETM2, ETM2_Task);
NVIC_EnableIRQ(ETM2_IRQn);//使能IRQ中断
ETM_EnableChannelInt(ETM2, (ETM_CHANNELPAIR0+1));//使能通道中断
while(1)
{
if(u8IntMark)
{
u16Ch0Value = ETM2->CONTROLS[0].CnV;
u16Ch1Value = ETM2->CONTROLS[1].CnV;
u8IntMark = 0;//反转标志位
x = u16Ch0Value;
y = u16Ch1Value;
printf("\n Dual edge capture end. The input wave period is %d\n",(uint16_t)(y-x));
/* 重新开启跳变沿捕捉 */
ETM2->COMBINE |= (ETM_COMBINE_DECAP0_MASK << (ETM_CHANNELPAIR0 * 4));
}
}
}
/*****************************************************************************//*!
*
* @brief ETM2中断回调任务函数
*
* @param none
*
* @return none
*
*****************************************************************************/
void ETM2_Task(void)
{
ETM_ClrChannelFlag(ETM2, ETM_CHANNELPAIR0);
ETM_ClrChannelFlag(ETM2, ETM_CHANNELPAIR0+1);
u8IntMark = 1;//置位标志位
}
/********************************************************************/
@@ -0,0 +1,34 @@
/******************************************************************************
*
* @brief define interrupt service routines referenced by the vector table.
*
* Note: Only "vectors.c" should include this header file.
*
*******************************************************************************
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
/*!
* @brief define interrupt service routine for different vectors.
*
*/
#undef VECTOR_035
#define VECTOR_035 ETM2_Isr /*!< Vector 35 points to ETM2 interrupt service routine */
extern void ETM2_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,100 @@
/**********************************************************************
*
* 实验名称:ETM边沿PWM输出--呼吸灯
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:ETM2通道1输出边沿对齐的PWM波,来控制NV32F100板上的D2闪烁
*
************************************************************************/
#include "common.h"
#include "ics.h"
#include "etm.h"
#include "uart.h"
#include "sysinit.h"
void ETM2_Task(void);
/********************************************************************/
int main (void)
{
/* 初始化 */
sysinit();
SIM_RemapETM2CH1Pin(); //选择映射ETM2CH1到PH1引脚,默认ETM2CH1对应PC1
ETM_PWMInit(ETM2, ETM_PWMMODE_EDGEALLIGNED, ETM_PWM_HIGHTRUEPULSE);
ETM_disblechannel(ETM2,0);//ETM_PWMInit函数默认打开所有通道功能,若不想其他引脚输出/用作其他功能,需要禁用。
ETM_disblechannel(ETM2,2);
ETM_disblechannel(ETM2,3);
ETM_disblechannel(ETM2,4);
ETM_disblechannel(ETM2,5);
/* 更新MOD的值 */
ETM_SetModValue(ETM2, 9999);
/* 设置时钟源,使能计数器 */
ETM_ClockSet(ETM2, ETM_CLOCK_SYSTEMCLOCK, ETM_CLOCK_PS_DIV1);
/* 使能ETM2的IRQ中断 */
NVIC_EnableIRQ(ETM2_IRQn);
/* 设置中断回调函数 */
ETM_SetCallback(ETM2, ETM2_Task);
/* 使能ETM2溢出中断 */
ETM_EnableOverflowInt(ETM2);
while(1);
}
/*****************************************************************************//*!
*
* @brief ETM2中断回调任务函数
*
* @param none.
*
* @return none.
*
*****************************************************************************/
uint16_t u16ChV_old, u16ChV_new;
void ETM2_Task(void)
{
static uint16_t u16count;
static uint8_t u8DirMark;
ETM_ClrOverFlowFlag(ETM2);//清除溢出标志位
if(100 == u16count)
{
u16count = 0;
u16ChV_old = ETM2->CONTROLS[1].CnV;
if(!u8DirMark)
{
u16ChV_new = u16ChV_old + 200;
if(u16ChV_new >= ETM2->MOD)
{
u16ChV_new = ETM2->MOD - 200;
u8DirMark = 1;
}
else
{
}
}
else
{
u16ChV_new = u16ChV_old - 200;
if(u16ChV_new < 200)
{
u16ChV_new = 200;
u8DirMark = 0;
}
else
{
}
}
/* 刷新通道值 */
ETM_SetChannelValue(ETM2, ETM_CHANNEL_CHANNEL1, u16ChV_new);
}
else
{
u16count++;
}
}
/********************************************************************/
@@ -0,0 +1,35 @@
/******************************************************************************
*
* @brief define interrupt service routines referenced by the vector table.
*
* Note: Only "vectors.c" should include this header file.
*
*******************************************************************************
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
/*!
* @brief define interrupt service routine for different vectors.
*
*/
#undef VECTOR_035
#define VECTOR_035 ETM2_Isr /*!< Vector 35 points to ETM2 interrupt service routine */
extern void ETM2_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,34 @@
/**********************************************************************
*
* 实验名称:ETM输出比较
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:ETM0的通道1产生触发波形,该通道所对应的管脚为PB3
*
************************************************************************/
#include "common.h"
#include "ics.h"
#include "etm.h"
#include "uart.h"
#include "sysinit.h"
/********************************************************************/
int main (void)
{
/* 系统初始化 */
sysinit();
SIM_RemapETM0CH1Pin();//映射通道到管脚PB3
/* ETM0为输出比较模式, 通道1产生触发波形 */
ETM_OutputCompareInit(ETM0, ETM_CHANNEL_CHANNEL1, ETM_OUTPUT_TOGGLE);
//加载对应的MOD数值
ETM_SetModValue(ETM0, 5000);
//设置CnV的值
ETM_SetChannelValue(ETM0, ETM_CHANNEL_CHANNEL1, 2000);
//时钟配置/
ETM_ClockSet(ETM0, ETM_CLOCK_SYSTEMCLOCK, ETM_CLOCK_PS_DIV1);
while(1);
}
@@ -0,0 +1,34 @@
/******************************************************************************
*
* @brief define interrupt service routines referenced by the vector table.
*
* Note: Only "vectors.c" should include this header file.
*
*******************************************************************************
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
/*!
* @brief define interrupt service routine for different vectors.
*
*/
#undef VECTOR_036
#define VECTOR_036 RTC_Isr /*!< Vector 36 points to RTC interrupt service routine */
extern void RTC_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,43 @@
/**********************************************************************
*
* 实验名称:PWM互补输出
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:选用FEI内部时钟,总线时钟40Mhz,联合ETM2的通道0(PH0)和通道1(PH1)互补输出
*
************************************************************************/
#include "common.h"
#include "ics.h"
#include "etm.h"
#include "uart.h"
#include "sysinit.h"
int main (void)
{
sysinit();//系统初始化
SIM_RemapETM2CH0Pin();//映射对应通道管脚到PH0
SIM_RemapETM2CH1Pin();//映射对应通道管脚到PH1
SIM->SCGC |= SIM_SCGC_ETM2_MASK; //使能ETM2时钟
ETM2->COMBINE &= ~ ETM_COMBINE_COMBINE0_MASK; //通道0和通道1独立
ETM2->SC |= ETM_SC_CPWMS_MASK; //选择先增后减的计数方式
ETM2->COMBINE |= ETM_COMBINE_COMP0_MASK; //通道0和通道1的输出互补
ETM2->CONTROLS[0].CnSC = ETM_CnSC_ELSA_MASK; //低真脉冲
ETM2->CONTROLS[1].CnSC = ETM_CnSC_ELSA_MASK;
ETM_SetModValue(ETM2, 3999);//设置频率10KHz
ETM_SetChannelValue(ETM2, ETM_CHANNEL_CHANNEL0, 2000);//设置占空比为50%
ETM_SetChannelValue(ETM2, ETM_CHANNEL_CHANNEL1, 2000);
ETM_ClockSet(ETM2, ETM_CLOCK_SYSTEMCLOCK, ETM_CLOCK_PS_DIV1); //ETM2时钟设置
while(1);
}
@@ -0,0 +1,34 @@
/******************************************************************************
*
* @brief define interrupt service routines referenced by the vector table.
*
* Note: Only "vectors.c" should include this header file.
*
*******************************************************************************
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
/*!
* @brief define interrupt service routine for different vectors.
*
*/
#undef VECTOR_036
#define VECTOR_036 RTC_Isr /*!< Vector 36 points to RTC interrupt service routine */
extern void RTC_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,120 @@
/**********************************************************************
*
* 实验名称:FLASH擦写
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:使用FLASH模拟EEPROM,实现字节的编程
* 实验说明:NV32F100x系列芯片不带有硬件EEPROM
* 除128K FLASH空间外,还带有5K的NVR空间:0x0040_0000-0x0040_13FF
* 操作与前128K一致,不过该区域在执行整片擦除时不会被擦除,可供用户用来作为数据存储区域
*
************************************************************************/
#include "common.h"
#include "rtc.h"
#include "flash.h"
#include "sysinit.h"
#include "eeprom.h"
int main (void);
/********************************************************************/
int main (void)
{
uint32_t i;
uint8_t u8DataBuff[512];
sysinit();
printf("\nRunning the Flash_demo project.\n");
LED0_Init();
LED2_Init();
Flash_Init();
/* 擦除第63个扇区*/
Flash_EraseSector(63*FLASH_SECTOR_SIZE);
for(i=0;i<512;i++)
{
u8DataBuff[i] = (uint8_t)i;
}
/****************对128K内的FLASH进行读写操作****************/
/*向擦除的扇区写入数据*/
Flash_Program(63*FLASH_SECTOR_SIZE,&u8DataBuff[0],512);
//
// for( i=0;i<512/16;i++ )
// {
// for(ch =0;ch<16;ch++)
// {
// printf("0x%x,",*((uint8_t *)(i*16+ch+63*FLASH_SECTOR_SIZE)));
// }
// printf("\n");
// }
//
/****************Flash模拟EEPROM操作****************/
/*
*
*模拟EEPROM的首地址:0x00401000(NVR空间)
*模拟EEPROM的大小 1K
*模拟EEPROM第一次使用前,可以先进行擦除擦做,这样可以提高写的效率
*
**********************************************************************************/
EEPROM_Erase(0x00);
EEPROM_Erase(0x200); //建议在最开始进行erase操作
//以字为单位写,空间大小为1K,调用EEPROM_Write函数
for(i=0;i<256;i++)
{
EEPROM_Write(4*i,1024-4*i);
}
//对该范围内的任意地址再写数据
EEPROM_Write(24,0xaa5555aa);
EEPROM_Write(68,0x55aaaa55);
EEPROM_Write(128,0x3fec);
EEPROM_Write(156,0xccbb);
EEPROM_Write(256,0xbbcc);
EEPROM_Write(264,0xccdd);
EEPROM_Write(300,0x3fff);
EEPROM_Write(512,0x5f5f);
EEPROM_Write(900,0x9f9f);
for(i=0;i<256;i++)
{
printf("adr:%d =0x%x \n",4*i,EEPROM_Read(4*i));
}
//批量写1-2个扇区
printf("/***************************批量测试**************************/ \n");
//地址偏移量为340,写一个扇区的数据
EERPOM_Writeup4byte(340,u8DataBuff,512);
/*for(i=0;i<256;i++)
{
printf("adr %d =0x%x \n",4*i,EEPROM_Read(4*i));
}
*/
EEPROM_Erase(0x00);
EEPROM_Erase(0x200);
//byte字节写,byte字节读取
printf("/***************************byte写测试**************************/ \n");
EEPROM_WriteByte(132,0x13);
printf("adr :132 =0x%x \n",EEPROM_Read(132));
EEPROM_WriteByte(133,0x11);
printf("adr :132 =0x%x \n",EEPROM_Read(132));
EEPROM_WriteByte(132,0x14);
printf("adr :132 =0x%x \n",EEPROM_Read(132));
EEPROM_WriteByte(132,0x12);
printf("adr :132 =0x%x \n",EEPROM_ReadByte(132));
EEPROM_WriteByte(132,0x15);
printf("adr :132 =0x%x \n",EEPROM_ReadByte(132));
while(1);
}
@@ -0,0 +1,27 @@
/******************************************************************************
* File: isr.h
* Purpose: Define interrupt service routines referenced by the vector table.
* Note: Only "vectors.c" should include this header file.
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H 1
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
extern void RTC_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,73 @@
/**********************************************************************
*
* 实验名称:GPIO位带操作
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:通BOS位操作,实现GPIO寄存器的位操作。 不仅降低了总线占有率和CPU执行时间,还节省代码空间
*
************************************************************************/
#include "common.h"
#include "systick.h"
#include "bos.h"
#include "gpio.h"
#include "delay.h"
#include "sysinit.h"
//#include "start.h"
#define LED0_OFF PTE7_OUT_HIGH //PE7输出为高电平
#define LED0_ON PTE7_OUT_LOW //PE7输出为低电平
#define LED1_OFF PTH1_OUT_HIGH
#define LED1_ON PTH1_OUT_LOW
#define LED2_OFF PTH2_OUT_HIGH
#define LED2_ON PTH2_OUT_LOW
int main (void);
int main (void)
{
uint32_t value;
sysinit();
DelayInit(); //延时初始化
BOS_BIT_SET(&GPIOB->PDDR,GPIO_PTE7); //设置PE7引脚为输出
BOS_BIT_SET(&GPIOB->PDDR,GPIO_PTH1); //设置PH1引脚为输出
BOS_BIT_SET(&GPIOB->PDDR,GPIO_PTH2); //设置PH2引脚为输出
BOS_BIT_CLEAR(&GPIOA->PDDR,GPIO_PTA1); //设置PA1引脚为输入
BOS_BIT_CLEAR(&GPIOA->PIDR,GPIO_PTA1);
BOS_BIT_SET(&PORT->PUEL,GPIO_PTA1); //端口PA1使能上拉
value = PTA1_IN; //读取PA1端口输入
printf("PA1=%X.\r\n",value);
while(1)
{
DelayMs(1000);
LED0_OFF;
DelayMs(1000);
LED1_OFF;
DelayMs(1000);
LED2_OFF;
DelayMs(1000);
LED2_ON;
DelayMs(1000);
LED1_ON;
DelayMs(1000);
LED0_ON;
DelayMs(1000);
LED0_ON;
LED1_ON;
LED2_ON;
DelayMs(1000);
LED0_ON;
LED1_ON;
LED2_ON;
}
}
/********************************************************************/
@@ -0,0 +1,42 @@
/******************************************************************************
*
* @brief define interrupt service routines referenced by the vector table.
*
* Note: Only "vectors.c" should include this header file.
*
*******************************************************************************
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
/*!
* @brief define interrupt service routine for different vectors.
*
*/
#undef VECTOR_036
#define VECTOR_036 RTC_Isr /*!< Vector 36 points to RTC interrupt service routine */
#undef VECTOR_015
#define VECTOR_015 SysTick_Isr /*!< Vector 15 points to SysTick interrupt service routine */
#undef VECTOR_040
#define VECTOR_040 KBI0_Isr
extern void KBI0_Isr(void);
extern void SysTick_Isr(void);
extern void RTC_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,81 @@
/**********************************************************************
*
* 实验名称:FGPIO端口数据输出切换实验
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验条件: KEIL的优化等级调整到3级优化
* 实验效果:PB2引脚为输出引脚,切换PB2数据输出,可测量PB2输出波形的周期
* 最大可达到内核时钟频率的1/2
*
**********************************************************************/
#include "common.h"
#include "rtc.h"
#include "gpio.h"
#include "sim.h"
#include "sysinit.h"
int main (void);
void gpio_t(void);
/********************************************************************/
int main (void)
{
/*系统初始化*/
sysinit();
printf("\nRunning the GPIO_OneCycle_demo project.\r\n");
printf("\nBy default Core Clock is 40MHz.\r\n");
printf("\nBy one cycle GPIO access, PTB2 output frequency is expected to be 20MHz.\r\n");
/* 使能总线时钟在PH2上 */
SIM_EnableClockOutput();
/* 配置PB2为输出引脚*/
GPIO_Init(GPIOA, GPIO_PTB2_MASK, GPIO_PinOutput);
/* PB2输出为 0 */
GPIO_PinClear(GPIO_PTB2);
gpio_t();
}
void gpio_t(void)
{
for(;;)
{
/* 通过FastGPIO切换PB2输出, 输出波形的频率= 内核时钟/2 */
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
FGPIO_Toggle(FGPIOA, GPIO_PTB2_MASK);
}
}
/*****************************************************************************/
@@ -0,0 +1,34 @@
/******************************************************************************
*
* @brief define interrupt service routines referenced by the vector table.
*
* Note: Only "vectors.c" should include this header file.
*
*******************************************************************************
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
/*!
* @brief define interrupt service routine for different vectors.
*
*/
#undef VECTOR_036
#define VECTOR_036 RTC_Isr /*!< Vector 36 points to RTC interrupt service routine */
extern void RTC_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,62 @@
/**********************************************************************
*
* 实验名称:GPIO端口输出配置
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:配置GPIO端口为输出引脚,板载D4灯1S闪烁一次
*
************************************************************************/
#include "common.h"
#include "rtc.h"
#include "uart.h"
#include "gpio.h"
#include "sysinit.h"
int main (void);
void RTC_Task(void);
/********************************************************************/
int main (void)
{
/*系统初始化*/
sysinit();
RTC_ConfigType sRTCConfig;
RTC_ConfigType *pRTCConfig = &sRTCConfig;
printf("\nRunning the GPIO_demo project.\n");
/* 配置RTC模块每隔1s产生一次中断 */
pRTCConfig->u16ModuloValue = 9;
pRTCConfig->bInterruptEn = RTC_INTERRUPT_ENABLE; /* 使能中断*/
pRTCConfig->bClockSource = RTC_CLKSRC_1KHZ; /* 选择1KHz时钟源 */
pRTCConfig->bClockPresaler = RTC_CLK_PRESCALER_100; /* 时钟分频系数100 */
RTC_SetCallback(RTC_Task);
RTC_Init(pRTCConfig);
/* 方法1.初始化PE7为输出引脚--通过32位引脚掩码确定要初始化的引脚 */
GPIO_Init(GPIOB, GPIO_PTE7_MASK, GPIO_PinOutput);
/* 方法2.初始化PE7为输出引脚--通过定义的GPIO引脚名确定要初始化的引脚*/
//GPIO_PinInit(GPIO_PTE7, GPIO_PinOutput);
while (1);
}
/*****************************************************************************//*!
*
* @brief RTC中断回调函数
*
*****************************************************************************/
void RTC_Task(void)
{
/* 切换PE7输出,闪亮LED1 */
/* 方法1.切换PE7端口数据输出————通过32位引脚掩码确定要切换输出的引脚 */
GPIO_Toggle(GPIOB, GPIO_PTE7_MASK);
/* 方法2.切换PE7端口数据输出----通过定义的GPIO引脚名确定要切换输出的引脚 */
// GPIO_PinToggle(GPIO_PTE7);
}
/********************************************************************/
@@ -0,0 +1,34 @@
/******************************************************************************
*
* @brief define interrupt service routines referenced by the vector table.
*
* Note: Only "vectors.c" should include this header file.
*
*******************************************************************************
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
/*!
* @brief define interrupt service routine for different vectors.
*
*/
#undef VECTOR_036
#define VECTOR_036 RTC_Isr /*!< Vector 36 points to RTC interrupt service routine */
extern void RTC_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,109 @@
/**********************************************************************
*
* 实验名称:I2C主机收发数据实验(采用中断的方式收发数据)
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:SPI发送的同时接收相同的数据,比较接收和发送的数据相同,判断
* SPI通信成功
*
************************************************************************/
#include "common.h"
#include "ics.h"
#include "rtc.h"
#include "uart.h"
#include "i2c.h"
#include "i2C_app.h"
#include "sysinit.h"
#define I2C_READ_DATA_LENGTH 64
#define I2C_SLAVE_ADDRESS1 0x50
uint8_t u8I2C_SendBuff[64];
uint8_t u8I2C_ReceiveBuff[64];
uint32_t u32I2C_ReceiveLength;
int main (void);
/********************************************************************/
int main (void)
{
uint8_t u8I2C_ErrorStatus;
I2C_ConfigType sI2C_Config = {0};
volatile uint32_t i;
sysinit();
printf("\nRunning the I2C_MasterInt_demo project.\r\n");
LED0_Init();
LED2_Init();
UART_WaitTxComplete(TERM_PORT);
/* 初始化I2C接收数据大小以及中断回调入口 */
I2C_InitGlobalVariable( );
/* 对I2C结构体的各个成员参数进行配置 */
sI2C_Config.u16Slt = 0; //设置低超时scl低电平保持时间为 0
sI2C_Config.u16F = 0x1F; //设置分频系数
sI2C_Config.sSetting.bIntEn = 1;//打开中断使能
sI2C_Config.sSetting.bI2CEn = 1;//打开I2C使能
I2C_Init(I2C0,&sI2C_Config ); //初始化I2C模块
for(i=0;i<64;i++)
{
u8I2C_SendBuff[i] = i; //给发送数据的数组里存放数据
}
while(1)
{
/*反馈接收字节的个数*/
u32I2C_ReceiveLength = I2C_MasterCheckRead(&u8I2C_ReceiveBuff[0]);
if( !I2C_IsBusy(I2C0) )
{
/* 若I2C总线不繁忙,则从从机获取数据 */
printf("start to read data from slave!\r\n");
I2C_MasterRead(I2C_SLAVE_ADDRESS1,I2C_READ_DATA_LENGTH);
}
if( u32I2C_ReceiveLength == 0 )
{
printf("don't receive any data from slave!\r\n");
}
else
{
for(i=0;i<u32I2C_ReceiveLength;i++)
{
if( (i%8) == 0 )
{
printf("\r\n");
}
printf("0x%x,",u8I2C_ReceiveBuff[i]);
}
if( u32I2C_ReceiveLength >= I2C_READ_DATA_LENGTH )
{
printf("\r\nreceived all required data!\r\n");
printf("start to send data to slave!\r\n");
u8I2C_SendBuff[0]++;
for(i=1;i<64;i++)
{
u8I2C_SendBuff[i] = i+u8I2C_SendBuff[0];
}
/* 等待I2C空闲空闲,并反馈失败的数目 */
u8I2C_ErrorStatus = I2C_MasterSend(I2C_SLAVE_ADDRESS1,&u8I2C_SendBuff[0],64);
if( u8I2C_ErrorStatus != I2C_ERROR_NULL )
{
printf("I2C transfer status:0x%x\r\n",u8I2C_ErrorStatus);
}
}
}
for(i=0;i<0xfffff;i++);
}
}
@@ -0,0 +1,380 @@
/******************************************************************************
*
* @brief I2C数据收发驱动函数
*
******************************************************************************/
#include "common.h"
#include "i2c.h"
#include "i2c_app.h"
static I2C_MasterSendType sI2C_MasterSendInfo = {0};
static I2C_MasterReceiveType sI2C_MasterReceiveInfo = {0};
static I2C_SlaveSendType sI2C_SlaveSendInfo = {0};
static I2C_SlaveReceiveType sI2C_SlaveReceiveInfo = {0};
//static uint8_t u8I2C_BusStatus = I2C_BUS_NORMAL;
/*****************************************************************************//*!
*
* @brief I2C模块回调功能函数.
*
* @param none
*
* @return none
*
*****************************************************************************/
void I2C_CallBack( void )
{
I2C_ClearStatus(I2C0,I2C_S_IICIF_MASK);//清除中断标志位
if( I2C_GetStatus(I2C0) & I2C_S_ARBL_MASK )
{
I2C_ClearStatus(I2C0,I2C_S_ARBL_MASK);
if( !(I2C_GetStatus(I2C0) & I2C_S_IAAS_MASK) )
{
// IIAAS is 0
return;
}
}
if( I2C_IsSMB_SLTF(I2C0) )
{
/* clear this flag */
I2C_ClearSLTF(I2C0);
/* Scl holding low over specified counter, add your code in here */
//u8I2C_BusStatus |= I2C_BUS_SLTF;
}
if( I2C_IsSMB_SHTF2(I2C0) )
{
/* clear this flag */
I2C_ClearSHTF2(I2C0);
/* Scl holding low over specified counter, add your code in here */
//u8I2C_BusStatus |= I2C_BUS_SHTF2;
}
if( I2C_IsMasterMode(I2C0) )
{
I2C_MasterIntProcessing();
}
else
{
I2C_SlaveIntProcessing();
}
}
/*****************************************************************************//*!
*
* @brief 初始化从机接收区长度以及设置回调函数.
*
* @param[in] none.
*
* @return none.
*
*****************************************************************************/
void I2C_InitGlobalVariable( void )
{
sI2C_SlaveReceiveInfo.u32FreeLength = I2C_SLAVE_RECEIVE_BUFFER_LENGTH;
I2C0_SetCallBack(I2C_CallBack);
}
/*****************************************************************************//*!
*
* @brief I2C主机中断服务框架.
*
* @param none.
*
* @return none.
*
*****************************************************************************/
void I2C_MasterIntProcessing( void )
{
if( I2C_IsTxMode(I2C0) )
{
if( sI2C_MasterSendInfo.u32Pointer < sI2C_MasterSendInfo.u32Length )
{
I2C_WriteDataReg(I2C0,sI2C_MasterSendInfo.u8SendBuff[sI2C_MasterSendInfo.u32Pointer++]);
}
else
{
I2C_Stop(I2C0);//I2C0->C1 &= ~I2C_C1_MST_MASK;
}
}
else
{
/* 主机从从机接收数据 */
if( sI2C_MasterReceiveInfo.u32Pointer < ( sI2C_MasterReceiveInfo.u32Length -1) )
{
I2C_SendAck(I2C0);
sI2C_MasterReceiveInfo.u8ReceiveBuff[sI2C_MasterReceiveInfo.u32Pointer++] =
I2C_ReadDataReg(I2C0);
}
else if( sI2C_MasterReceiveInfo.u32Pointer == (sI2C_MasterReceiveInfo.u32Length -1) )
{
I2C_SendNack(I2C0);
sI2C_MasterReceiveInfo.u8ReceiveBuff[sI2C_MasterReceiveInfo.u32Pointer++] =
I2C_ReadDataReg(I2C0);
}
else
{
I2C_Stop(I2C0);
I2C_ReadDataReg(I2C0);
}
}
}
/*****************************************************************************//*!
*
* @brief I2C从机中断服务框架.
*
* @param none.
*
* @return none.
*
*****************************************************************************/
void I2C_SlaveIntProcessing( void )
{
if( I2C_GetStatus(I2C0) & I2C_S_IAAS_MASK )
{
I2C_SendAck(I2C0);
if( I2C_GetStatus(I2C0)& I2C_S_SRW_MASK )
{
// 从机发送数据
I2C_TxEnable(I2C0);
sI2C_SlaveSendInfo.u32Pointer = 0;
I2C_WriteDataReg(I2C0,sI2C_SlaveSendInfo.u8SendBuff[sI2C_SlaveSendInfo.u32Pointer++]);
}
else
{
I2C_RxEnable(I2C0);
I2C_ReadDataReg(I2C0);
}
}
else
{
if( I2C0->S & I2C_S_SRW_MASK )
{
// 若需要从主机获取ACK信号
if(I2C_IsReceivedAck(I2C0))
{
//没有接收到ACK信号
I2C_RxEnable(I2C0);
I2C_ReadDataReg(I2C0);
// 选取接收
}
else
{
if( sI2C_SlaveSendInfo.u32Pointer < sI2C_SlaveSendInfo.u32Length )
{
I2C_WriteDataReg(I2C0,sI2C_SlaveSendInfo.u8SendBuff[sI2C_SlaveSendInfo.u32Pointer++]);
}
else
{
I2C_WriteDataReg( I2C0, 0xff );
}
}
}
else
{
if( sI2C_SlaveReceiveInfo.u32FreeLength != 0 )
{
sI2C_SlaveReceiveInfo.u8ReceiveBuff[sI2C_SlaveReceiveInfo.u32Tail++] = I2C_ReadDataReg(I2C0);
if( sI2C_SlaveReceiveInfo.u32Tail >= I2C_SLAVE_RECEIVE_BUFFER_LENGTH )
{
sI2C_SlaveReceiveInfo.u32Tail = 0;
}
sI2C_SlaveReceiveInfo.u32FreeLength --;
}
else
{
/* 接收器满 */
I2C_ReadDataReg(I2C0);
}
}
}
}
/*****************************************************************************//*!
*
* @brief I2C从机在中断模式下接收数据.
*
* @param[out] pRdBuff 指向接收数据的首地址.
*
* @return 接收到数据的长度.
*
*****************************************************************************/
uint32_t I2C_SlaveReceive( uint8_t *pRdBuff )
{
uint32_t i;
I2C_IntDisable(I2C0);
i = 0;
while( sI2C_SlaveReceiveInfo.u32FreeLength < I2C_SLAVE_RECEIVE_BUFFER_LENGTH )
{
if( sI2C_SlaveReceiveInfo.u32Head != sI2C_SlaveReceiveInfo.u32Tail )
{
pRdBuff[i++] = sI2C_SlaveReceiveInfo.u8ReceiveBuff[sI2C_SlaveReceiveInfo.u32Head++];
if( sI2C_SlaveReceiveInfo.u32Head >= I2C_SLAVE_RECEIVE_BUFFER_LENGTH )
{
sI2C_SlaveReceiveInfo.u32Head = 0;
}
sI2C_SlaveReceiveInfo.u32FreeLength ++;
}
}
I2C_IntEnable(I2C0);
return i;
}
/*****************************************************************************//*!
*
* @brief I2C从机在中断模式下发送数据.
*
* @param[in] pRdBuff 指向发送数据的首地址.
* @param[in] uiLength 所要发送数据的长度.
*
* @return 发送的状态
*
*****************************************************************************/
uint8_t I2C_SlaveSend( uint8_t *pWrBuff, uint32_t uiLength )
{
if( uiLength > I2C_SLAVE_SEND_BUFFER_LENGTH )
{
return FALSE;
}
I2C_IntDisable(I2C0);
sI2C_SlaveSendInfo.u32Length = uiLength;
memcpy((void *)&sI2C_SlaveSendInfo.u8SendBuff[0],(void *)pWrBuff,uiLength);
I2C_IntEnable(I2C0);
return TRUE;
}
/*****************************************************************************//*!
*
* @brief 检测I2C模块接收到了多少数据,把接收到的数据放入缓冲区.
*
* @param[out] pRdBuff 指向接收数据的首地址.
*
* @return 返回接收到数据的长度.
*
*****************************************************************************/
uint32_t I2C_MasterCheckRead( uint8_t *pRdBuff )
{
uint32_t uiPointer;
if( sI2C_MasterReceiveInfo.u32Pointer !=0 )
{
memcpy((void *) pRdBuff,
(void *)&sI2C_MasterReceiveInfo.u8ReceiveBuff[0],
sI2C_MasterReceiveInfo.u32Pointer );
uiPointer = sI2C_MasterReceiveInfo.u32Pointer;
sI2C_MasterReceiveInfo.u32Pointer = 0;
return uiPointer;
}
else
{
return 0;
}
}
/*****************************************************************************//*!
*
* @brief I2C主机在中断模式下接收数据.
*
* @param[in] u16Address I2C从机地址.
* @param[in] u32Length 从从机中读取数据的长度.
*
* @return 错误状态.
*
*****************************************************************************/
uint8_t I2C_MasterRead( uint16_t u16Address,uint32_t u32Length )
{
uint8_t u8Status;
I2C_IntDisable(I2C0);
/* 发送起始信号 */
u8Status = I2C_Start(I2C0);
if( u8Status == I2C_ERROR_NULL )
{
u8Status = I2C_WriteOneByte(I2C0,(uint8)((u16Address<<1)|0x01));
if( u8Status == I2C_ERROR_NULL )
{
sI2C_MasterReceiveInfo.u32Length = u32Length;
sI2C_MasterReceiveInfo.u32Pointer = 0;
I2C_SendAck(I2C0);
I2C_RxEnable(I2C0);
I2C_ReadDataReg(I2C0);
}
}
I2C_IntEnable(I2C0);
return u8Status;
}
/*****************************************************************************//*!
*
* @brief I2C主机在中断模式下发送数据.
* @param[in] u16Address I2C从机地址.
* @pWrBuff[in] pWrBuff 指向所要发送数据的首地址.
* @param[in] u32Length 要向从机的数据长度.
*
* @return 错误状态
*
*****************************************************************************/
uint8_t I2C_MasterSend( uint16_t Address,uint8_t *pWrBuff, uint32_t u32Length )
{
uint8_t u8Status;
if( I2C_IsBusy(I2C0) )
{
return I2C_ERROR_BUS_BUSY;
}
I2C_IntDisable(I2C0);
/* 发送起始信号 */
u8Status = I2C_Start(I2C0);
I2C_TxEnable(I2C0);
if( u8Status == I2C_ERROR_NULL )
{
u8Status = I2C_WriteOneByte(I2C0,(uint8)((Address<<1)&0xfe));
if( u8Status == I2C_ERROR_NULL )
{
memcpy((void *)&sI2C_MasterSendInfo.u8SendBuff[0],
(void *)pWrBuff,u32Length);
}
}
sI2C_MasterSendInfo.u32Pointer = 0;
sI2C_MasterSendInfo.u32Length = u32Length;
I2C_IntEnable(I2C0);
I2C_WriteDataReg(I2C0, sI2C_MasterSendInfo.u8SendBuff[sI2C_MasterSendInfo.u32Pointer++] );
return u8Status;
}
@@ -0,0 +1,71 @@
/******************************************************************************
*
* @brief I2C数据收发驱动函数接口.
*
*******************************************************************************/
#ifndef _I2C_APP_H__
#define _I2C_APP_H__
#define I2C_MASTER_SEND_BUFFER_LENGTH 64
#define I2C_MASTER_RECEIVE_BUFFER_LENGTH 64
#define I2C_SLAVE_SEND_BUFFER_LENGTH 64
#define I2C_SLAVE_RECEIVE_BUFFER_LENGTH 65
/*!
* @brief 定义I2C主机发送数据类型.
*
*/
typedef struct
{
uint32_t u32Pointer;
uint32_t u32Length;
uint8_t u8SendBuff[I2C_MASTER_SEND_BUFFER_LENGTH];
}I2C_MasterSendType;
/*!
* @brief 定义I2C主机接收数据类型.
*
*/
typedef struct
{
uint32_t u32Pointer;
uint32_t u32Length;
uint8_t u8ReceiveBuff[I2C_MASTER_RECEIVE_BUFFER_LENGTH];
}I2C_MasterReceiveType;
/*!
* @brief 定义I2C从机接收数据类型.
*
*/
typedef struct
{
uint32_t u32Head;
uint32_t u32Tail;
uint32_t u32FreeLength;
uint8_t u8ReceiveBuff[I2C_SLAVE_RECEIVE_BUFFER_LENGTH];
}I2C_SlaveReceiveType;
/*!
* @brief 定义I2C从机发送数据类型.
*
*/
typedef struct
{
uint32_t u32Pointer;
uint32_t u32Length;
uint8_t u8SendBuff[I2C_SLAVE_SEND_BUFFER_LENGTH];
}I2C_SlaveSendType;
/******************************************************************************
******************************************************************************/
void I2C_CallBack( void );
void I2C_InitGlobalVariable( void );
void I2C_MasterIntProcessing( void );
void I2C_SlaveIntProcessing( void );
uint32_t I2C_SlaveReceive( uint8_t *pRdBuff );
uint8_t I2C_SlaveSend( uint8_t *pWrBuff, uint32_t uiLength );
uint32_t I2C_MasterCheckRead( uint8_t *pRdBuff );
uint8_t I2C_MasterRead( uint16_t u16Address,uint32_t u32Length );
uint8_t I2C_MasterSend( uint16_t Address,uint8_t *pWrBuff, uint32_t u32Length );
#endif //
@@ -0,0 +1,29 @@
/******************************************************************************
* File: isr.h
* Purpose: Define interrupt service routines referenced by the vector table.
* Note: Only "vectors.c" should include this header file.
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H 1
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
#undef VECTOR_024
#define VECTOR_024 I2C0_Isr
extern void RTC_Isr(void);
extern void I2C0_Isr( void );
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,78 @@
/**********************************************************************
*
* 实验名称:I2C主机收发数据(采用查询的方式收发数据)
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:提供I2C主机查询法收发数据的框架
*
************************************************************************/
#include "common.h"
#include "ics.h"
#include "rtc.h"
#include "uart.h"
#include "i2c.h"
#include "sysinit.h"
#define I2C_SLAVE_ADDRESS1 0x50
uint8_t u8I2C_SendBuff[64];
uint8_t u8I2C_ReceiveBuff[64];
int main (void);
void RTC_Task(void);
/********************************************************************/
int main (void)
{
I2C_ConfigType sI2C_Config = {0};
volatile uint32_t i,j;
sysinit();
for(i=0;i<0xfff;i++);
printf("\nRunning the I2C_MasterPoll_demo project.\r\n");
LED0_Init();
LED2_Init();
UART_WaitTxComplete(TERM_PORT);
/* 初始化I2C模块为查询模式 */
sI2C_Config.u16F = 0x1F;//设置分频系数
sI2C_Config.sSetting.bIntEn = 0;//禁用中断
sI2C_Config.sSetting.bI2CEn = 1;//使能I2C
I2C_Init(I2C0,&sI2C_Config );//设置分频系数
for(i=0;i<64;i++)
{
u8I2C_SendBuff[i] = i;//给发送数据的数组里存放数据
}
while(1)
{
//等待数据收发,查询法
I2C_MasterSendWait(I2C0,I2C_SLAVE_ADDRESS1,&u8I2C_SendBuff[0],64);
I2C_MasterReadWait(I2C0,I2C_SLAVE_ADDRESS1,&u8I2C_ReceiveBuff[0],64);
printf("Read data from I2C slave:\r\n");
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
printf("0x%x,", u8I2C_ReceiveBuff[i*8+j]);
}
printf("\r\n");
}
u8I2C_SendBuff[0]++;
for(i=1;i<64;i++)
{
u8I2C_SendBuff[i] = i+u8I2C_SendBuff[0];
}
for(i=0;i<0xfffff;i++);
}
}
@@ -0,0 +1,27 @@
/******************************************************************************
* File: isr.h
* Purpose: Define interrupt service routines referenced by the vector table.
* Note: Only "vectors.c" should include this header file.
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H 1
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
extern void RTC_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,90 @@
/**********************************************************************
*
* 实验名称:I2C从机通讯
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:本例为I2C通讯中从机的设定
*
************************************************************************/
#include "common.h"
#include "ics.h"
#include "rtc.h"
#include "uart.h"
#include "i2c.h"
#include "i2C_app.h"
#include "sysinit.h"
#define I2C_SLAVE_ADDRESS 0x50<<1
uint8_t u8I2C_SendBuff[64];
uint8_t u8I2C_ReceiveBuff[64];
int main (void);
/********************************************************************/
int main (void)
{
uint8_t u8I2C_ReceiveLength;
uint32_t i;
I2C_ConfigType sI2C_Config = {0};
sysinit();
printf("\nRunning the I2C_Slave_demo project.\r\n");
LED0_Init();
LED2_Init();
UART_WaitTxComplete(TERM_PORT);//等待串口发送完成
/* 初始化I2C接收数据大小以及中断回调入口 */
I2C_InitGlobalVariable( );
sI2C_Config.u16Slt = 0;//设置低超时scl低电平保持时间为 0
sI2C_Config.u16F = 0x1F;//设置分频系数
sI2C_Config.u16OwnA1 = I2C_SLAVE_ADDRESS;//设置I2C从机地址
sI2C_Config.sSetting.bIntEn = 1;//打开中断使能
sI2C_Config.sSetting.bI2CEn = 1;//打开I2C使能
I2C_Init(I2C0,&sI2C_Config);//初始化I2C
for(i=0;i<64;i++)
{
u8I2C_SendBuff[i] = i;//给发送数据的数组里存放数据
}
u8I2C_SendBuff[0] = 0xa0;
I2C_SlaveSend(u8I2C_SendBuff,64);
while(1)
{
u8I2C_ReceiveLength = I2C_SlaveReceive(&u8I2C_ReceiveBuff[0]);
if( u8I2C_ReceiveLength < 64 )
{
/* 发送旧数据给主机 */
I2C_SlaveSend(&u8I2C_SendBuff[0],64);
}
else
{
/* 发送从主机接收到的新数据 */
I2C_SlaveSend(&u8I2C_ReceiveBuff[0],64);
}
if( u8I2C_ReceiveLength )
{
printf("I2C received data:\r\n");
for(i=0;i<u8I2C_ReceiveLength;i++)
{
if( (i%8) == 0 )
{
printf("\r\n");
}
printf("0x%x,", u8I2C_ReceiveBuff[i]);
}
printf("\r\n");
}
for(i=0;i<0xfffff;i++);
}
}
@@ -0,0 +1,381 @@
/******************************************************************************
*
* @brief I2C数据收发驱动函数
*
******************************************************************************/
#include "common.h"
#include "i2c.h"
#include "i2c_app.h"
static I2C_MasterSendType sI2C_MasterSendInfo = {0};
static I2C_MasterReceiveType sI2C_MasterReceiveInfo = {0};
static I2C_SlaveSendType sI2C_SlaveSendInfo = {0};
static I2C_SlaveReceiveType sI2C_SlaveReceiveInfo = {0};
//static uint8_t u8I2C_BusStatus = I2C_BUS_NORMAL;
/*****************************************************************************//*!
*
* @brief I2C模块回调功能函数.
*
* @param none
*
* @return none
*
*****************************************************************************/
void I2C_CallBack( void )
{
I2C_ClearStatus(I2C0,I2C_S_IICIF_MASK);//清除中断标志位
if( I2C_GetStatus(I2C0) & I2C_S_ARBL_MASK )
{
I2C_ClearStatus(I2C0,I2C_S_ARBL_MASK);
if( !(I2C_GetStatus(I2C0) & I2C_S_IAAS_MASK) )
{
// IIAAS is 0
return;
}
}
if( I2C_IsSMB_SLTF(I2C0) )
{
/* clear this flag */
I2C_ClearSLTF(I2C0);
/* Scl holding low over specified counter, add your code in here */
//u8I2C_BusStatus |= I2C_BUS_SLTF;
}
if( I2C_IsSMB_SHTF2(I2C0) )
{
/* clear this flag */
I2C_ClearSHTF2(I2C0);
/* Scl holding low over specified counter, add your code in here */
//u8I2C_BusStatus |= I2C_BUS_SHTF2;
}
if( I2C_IsMasterMode(I2C0) )
{
I2C_MasterIntProcessing();
}
else
{
I2C_SlaveIntProcessing();
}
}
/*****************************************************************************//*!
*
* @brief 初始化从机接收区长度以及设置回调函数.
*
* @param[in] none.
*
* @return none.
*
*****************************************************************************/
void I2C_InitGlobalVariable( void )
{
sI2C_SlaveReceiveInfo.u32FreeLength = I2C_SLAVE_RECEIVE_BUFFER_LENGTH;
I2C0_SetCallBack(I2C_CallBack);
}
/*****************************************************************************//*!
*
* @brief I2C主机中断服务框架.
*
* @param none.
*
* @return none.
*
*****************************************************************************/
void I2C_MasterIntProcessing( void )
{
if( I2C_IsTxMode(I2C0) )
{
if( sI2C_MasterSendInfo.u32Pointer < sI2C_MasterSendInfo.u32Length )
{
I2C_WriteDataReg(I2C0,sI2C_MasterSendInfo.u8SendBuff[sI2C_MasterSendInfo.u32Pointer++]);
}
else
{
I2C_Stop(I2C0);//I2C0->C1 &= ~I2C_C1_MST_MASK;
}
}
else
{
/* 主机从从机接收数据 */
if( sI2C_MasterReceiveInfo.u32Pointer < ( sI2C_MasterReceiveInfo.u32Length -1) )
{
I2C_SendAck(I2C0);
sI2C_MasterReceiveInfo.u8ReceiveBuff[sI2C_MasterReceiveInfo.u32Pointer++] =
I2C_ReadDataReg(I2C0);
}
else if( sI2C_MasterReceiveInfo.u32Pointer == (sI2C_MasterReceiveInfo.u32Length -1) )
{
I2C_SendNack(I2C0);
sI2C_MasterReceiveInfo.u8ReceiveBuff[sI2C_MasterReceiveInfo.u32Pointer++] =
I2C_ReadDataReg(I2C0);
}
else
{
I2C_Stop(I2C0);
I2C_ReadDataReg(I2C0);
}
}
}
/*****************************************************************************//*!
*
* @brief I2C从机中断服务框架.
*
* @param none.
*
* @return none.
*
*****************************************************************************/
void I2C_SlaveIntProcessing( void )
{
if( I2C_GetStatus(I2C0) & I2C_S_IAAS_MASK )
{
I2C_SendAck(I2C0);
if( I2C_GetStatus(I2C0)& I2C_S_SRW_MASK )
{
// 从机发送数据
I2C_TxEnable(I2C0);
sI2C_SlaveSendInfo.u32Pointer = 0;
I2C_WriteDataReg(I2C0,sI2C_SlaveSendInfo.u8SendBuff[sI2C_SlaveSendInfo.u32Pointer++]);
}
else
{
I2C_RxEnable(I2C0);
I2C_ReadDataReg(I2C0);
}
}
else
{
if( I2C0->S & I2C_S_SRW_MASK )
{
// 若需要从主机获取ACK信号
if(I2C_IsReceivedAck(I2C0))
{
//没有接收到ACK信号
I2C_RxEnable(I2C0);
I2C_ReadDataReg(I2C0);
// 选取接收
}
else
{
if( sI2C_SlaveSendInfo.u32Pointer < sI2C_SlaveSendInfo.u32Length )
{
I2C_WriteDataReg(I2C0,sI2C_SlaveSendInfo.u8SendBuff[sI2C_SlaveSendInfo.u32Pointer++]);
}
else
{
I2C_WriteDataReg( I2C0, 0xff );
}
}
}
else
{
if( sI2C_SlaveReceiveInfo.u32FreeLength != 0 )
{
sI2C_SlaveReceiveInfo.u8ReceiveBuff[sI2C_SlaveReceiveInfo.u32Tail++] = I2C_ReadDataReg(I2C0);
if( sI2C_SlaveReceiveInfo.u32Tail >= I2C_SLAVE_RECEIVE_BUFFER_LENGTH )
{
sI2C_SlaveReceiveInfo.u32Tail = 0;
}
sI2C_SlaveReceiveInfo.u32FreeLength --;
}
else
{
/* 接收器满 */
I2C_ReadDataReg(I2C0);
}
}
}
}
/*****************************************************************************//*!
*
* @brief I2C从机在中断模式下接收数据.
*
* @param[out] pRdBuff 指向接收数据的首地址.
*
* @return 接收到数据的长度.
*
*****************************************************************************/
uint32_t I2C_SlaveReceive( uint8_t *pRdBuff )
{
uint32_t i;
I2C_IntDisable(I2C0);
i = 0;
while( sI2C_SlaveReceiveInfo.u32FreeLength < I2C_SLAVE_RECEIVE_BUFFER_LENGTH )
{
if( sI2C_SlaveReceiveInfo.u32Head != sI2C_SlaveReceiveInfo.u32Tail )
{
pRdBuff[i++] = sI2C_SlaveReceiveInfo.u8ReceiveBuff[sI2C_SlaveReceiveInfo.u32Head++];
if( sI2C_SlaveReceiveInfo.u32Head >= I2C_SLAVE_RECEIVE_BUFFER_LENGTH )
{
sI2C_SlaveReceiveInfo.u32Head = 0;
}
sI2C_SlaveReceiveInfo.u32FreeLength ++;
}
}
I2C_IntEnable(I2C0);
return i;
}
/*****************************************************************************//*!
*
* @brief I2C从机在中断模式下发送数据.
*
* @param[in] pRdBuff 指向发送数据的首地址.
* @param[in] uiLength 所要发送数据的长度.
*
* @return 发送的状态
*
*****************************************************************************/
uint8_t I2C_SlaveSend( uint8_t *pWrBuff, uint32_t uiLength )
{
if( uiLength > I2C_SLAVE_SEND_BUFFER_LENGTH )
{
return FALSE;
}
I2C_IntDisable(I2C0);
sI2C_SlaveSendInfo.u32Length = uiLength;
memcpy((void *)&sI2C_SlaveSendInfo.u8SendBuff[0],(void *)pWrBuff,uiLength);
I2C_IntEnable(I2C0);
return TRUE;
}
/*****************************************************************************//*!
*
* @brief 检测I2C模块接收到了多少数据,把接收到的数据放入缓冲区.
*
* @param[out] pRdBuff 指向接收数据的首地址.
*
* @return 返回接收到数据的长度.
*
*****************************************************************************/
uint32_t I2C_MasterCheckRead( uint8_t *pRdBuff )
{
uint32_t uiPointer;
if( sI2C_MasterReceiveInfo.u32Pointer !=0 )
{
memcpy((void *) pRdBuff,
(void *)&sI2C_MasterReceiveInfo.u8ReceiveBuff[0],
sI2C_MasterReceiveInfo.u32Pointer );
uiPointer = sI2C_MasterReceiveInfo.u32Pointer;
sI2C_MasterReceiveInfo.u32Pointer = 0;
return uiPointer;
}
else
{
return 0;
}
}
/*****************************************************************************//*!
*
* @brief I2C主机在中断模式下接收数据.
*
* @param[in] u16Address I2C从机地址.
* @param[in] u32Length 从从机中读取数据的长度.
*
* @return 错误状态.
*
*****************************************************************************/
uint8_t I2C_MasterRead( uint16_t u16Address,uint32_t u32Length )
{
uint8_t u8Status;
I2C_IntDisable(I2C0);
/* 发送起始信号 */
u8Status = I2C_Start(I2C0);
if( u8Status == I2C_ERROR_NULL )
{
u8Status = I2C_WriteOneByte(I2C0,(uint8)((u16Address<<1)|0x01));
if( u8Status == I2C_ERROR_NULL )
{
sI2C_MasterReceiveInfo.u32Length = u32Length;
sI2C_MasterReceiveInfo.u32Pointer = 0;
I2C_SendAck(I2C0);
I2C_RxEnable(I2C0);
I2C_ReadDataReg(I2C0);
}
}
I2C_IntEnable(I2C0);
return u8Status;
}
/*****************************************************************************//*!
*
* @brief I2C主机在中断模式下发送数据.
* @param[in] u16Address I2C从机地址.
* @pWrBuff[in] pWrBuff 指向所要发送数据的首地址.
* @param[in] u32Length 要向从机的数据长度.
*
* @return 错误状态
*
*****************************************************************************/
uint8_t I2C_MasterSend( uint16_t Address,uint8_t *pWrBuff, uint32_t u32Length )
{
uint8_t u8Status;
if( I2C_IsBusy(I2C0) )
{
return I2C_ERROR_BUS_BUSY;
}
I2C_IntDisable(I2C0);
/* 发送起始信号 */
u8Status = I2C_Start(I2C0);
I2C_TxEnable(I2C0);
if( u8Status == I2C_ERROR_NULL )
{
u8Status = I2C_WriteOneByte(I2C0,(uint8)((Address<<1)&0xfe));
if( u8Status == I2C_ERROR_NULL )
{
memcpy((void *)&sI2C_MasterSendInfo.u8SendBuff[0],
(void *)pWrBuff,u32Length);
}
}
sI2C_MasterSendInfo.u32Pointer = 0;
sI2C_MasterSendInfo.u32Length = u32Length;
I2C_IntEnable(I2C0);
I2C_WriteDataReg(I2C0, sI2C_MasterSendInfo.u8SendBuff[sI2C_MasterSendInfo.u32Pointer++] );
return u8Status;
}
@@ -0,0 +1,72 @@
/******************************************************************************
*
* @brief I2C数据收发驱动函数接口.
*
*******************************************************************************/
#ifndef _I2C_APP_H__
#define _I2C_APP_H__
#define I2C_MASTER_SEND_BUFFER_LENGTH 64
#define I2C_MASTER_RECEIVE_BUFFER_LENGTH 64
#define I2C_SLAVE_SEND_BUFFER_LENGTH 64
#define I2C_SLAVE_RECEIVE_BUFFER_LENGTH 65
/*!
* @brief 定义I2C主机发送数据类型.
*
*/
typedef struct
{
uint32_t u32Pointer;
uint32_t u32Length;
uint8_t u8SendBuff[I2C_MASTER_SEND_BUFFER_LENGTH];
}I2C_MasterSendType;
/*!
* @brief 定义I2C主机接收数据类型.
*
*/
typedef struct
{
uint32_t u32Pointer;
uint32_t u32Length;
uint8_t u8ReceiveBuff[I2C_MASTER_RECEIVE_BUFFER_LENGTH];
}I2C_MasterReceiveType;
/*!
* @brief 定义I2C从机接收数据类型.
*
*/
typedef struct
{
uint32_t u32Head;
uint32_t u32Tail;
uint32_t u32FreeLength;
uint8_t u8ReceiveBuff[I2C_SLAVE_RECEIVE_BUFFER_LENGTH];
}I2C_SlaveReceiveType;
/*!
* @brief 定义I2C从机发送数据类型.
*
*/
typedef struct
{
uint32_t u32Pointer;
uint32_t u32Length;
uint8_t u8SendBuff[I2C_SLAVE_SEND_BUFFER_LENGTH];
}I2C_SlaveSendType;
/******************************************************************************
******************************************************************************/
void I2C_CallBack( void );
void I2C_InitGlobalVariable( void );
void I2C_MasterIntProcessing( void );
void I2C_SlaveIntProcessing( void );
uint32_t I2C_SlaveReceive( uint8_t *pRdBuff );
uint8_t I2C_SlaveSend( uint8_t *pWrBuff, uint32_t uiLength );
uint32_t I2C_MasterCheckRead( uint8_t *pRdBuff );
uint8_t I2C_MasterRead( uint16_t u16Address,uint32_t u32Length );
uint8_t I2C_MasterSend( uint16_t Address,uint8_t *pWrBuff, uint32_t u32Length );
#endif //
@@ -0,0 +1,31 @@
/******************************************************************************
* File: isr.h
* Purpose: Define interrupt service routines referenced by the vector table.
* Note: Only "vectors.c" should include this header file.
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H 1
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
#undef VECTOR_024
#define VECTOR_024 I2C0_Isr
extern void RTC_Isr(void);
extern void I2C0_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,92 @@
/**********************************************************************
*
* 实验名称:KBI键盘中断实验
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:初始化KBI模块,选择中断输入引脚,和检测模式,按下按键触发KBI
* 中断切换LED状态
*
************************************************************************/
#include "common.h"
#include "ics.h"
#include "rtc.h"
#include "uart.h"
#include "kbi.h"
#include "sysinit.h"
int main (void);
void KBI0_Task(void);
void KBI1_Task(void);
/********************************************************************/
int main (void)
{
uint8_t i;
KBI_ConfigType sKBIConfig;
/*系统初始化*/
sysinit();
printf("\nRunning the KBI_demo project.\r\n");
LED1_Init();
LED2_Init();
PORT->IOFLT = 0xa4be0000; //KBI0、KBI1输入滤波,KBI0和KBI小于32MS的毛刺都会被滤除 //Modify
UART_WaitTxComplete(TERM_PORT);
/* 禁用KBI中断输入引脚*/
for (i = 0; i < KBI_MAX_PINS_PER_PORT; i++)
{
sKBIConfig.sPin[i].bEn = 0;
}
sKBIConfig.sBits.bMode = 0; /*!< 选择 边沿检测 */
sKBIConfig.sPin[0].bEdge = KBI_FALLING_EDGE_LOW_LEVEL; /*!< 选择 下降沿或低电平检测 */
sKBIConfig.sBits.bIntEn = 1; //使能KBI中断
sKBIConfig.sPin[0].bEn = 1; //使能KBI中断输入引脚
KBI_Init(KBI0, &sKBIConfig); //初始化KBI0
KBI_Init(KBI1, &sKBIConfig); //初始化KBI1
KBI_SetCallback(KBI0, &KBI0_Task); //设置回调函数
KBI_SetCallback(KBI1, &KBI1_Task);
while(1);
}
/*****************************************************************************//*!
*
* @brief KBI0回调函数
*
* @param none.
*
* @return none
*
*****************************************************************************/
void KBI0_Task(void)
{
LED1_Toggle();
printf("KBI0 routinue.\r\n");
}
/*****************************************************************************//*!
*
* @brief KBI1回调函数.
*
* @param none.
*
* @return none.
*
*****************************************************************************/
void KBI1_Task(void)
{
LED2_Toggle();
printf("KBI1 routinue.\r\n");
}
/********************************************************************/
@@ -0,0 +1,36 @@
/******************************************************************************
*
* @brief define interrupt service routines referenced by the vector table.
*
* Note: Only "vectors.c" should include this header file.
*
*******************************************************************************
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H 1
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
#undef VECTOR_040
#define VECTOR_040 KBI0_Isr
#undef VECTOR_041
#define VECTOR_041 KBI1_Isr
extern void RTC_Isr(void);
extern void KBI0_Isr(void);
extern void KBI1_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,84 @@
/**********************************************************************
*
* 实验名称:PIT定时中断
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验说明:PIT例程设置定时器1链接至定时器0产生每秒1次的中断.
* 以总线时钟在本例程中为40MHZ,所以说,时钟周期为25ns ,产生一秒的中断需要40,000,000个时钟周期,中断任务函数中LED灯翻转.
*
* 设定PIT0触发1,000,000个周期, PIT1定时器1触发40次,总周期为40,000,000个时钟周期
*
************************************************************************/
#include "common.h"
#include "uart.h"
#include "pit.h"
#include "sysinit.h"
int main (void);
void PIT_Task(void);
/*****************************************************************************
*****************************************************************************/
int main (void)
{
uint8_t u8Ch;
uint32_t u32LoadValue0, u32LoadValue1;
PIT_ConfigType sPITConfig0, sPITConfig1;
PIT_ConfigType *pPIT_Config1 =&sPITConfig1;
PIT_ConfigType *pPIT_Config0 =&sPITConfig0;
/* 系统初始化 */
sysinit();
printf("\nRunning the PIT_demo project.\r\n");
LED0_Init();
/* PIT时钟源为总线时钟 */
/* 通道0装载值为 = (1000000-1),通道1装载值为 = (40-1) */
u32LoadValue0 = 0xF423F; /* 通道0装载值 */
u32LoadValue1 = 0x13; /* 通道1装载值 */
/* 配置通道1为链接模式,开启中断并且使能 */
pPIT_Config1->u32LoadValue = u32LoadValue1;
pPIT_Config1->bFreeze = FALSE; //定时器在调试模式下继续运行
pPIT_Config1->bModuleDis = FALSE; //使能定时器模块
pPIT_Config1->bInterruptEn = TRUE; //开启对应通道的IRQ中断
pPIT_Config1->bChainMode = TRUE; //定时器链接到PIT0
pPIT_Config1->bETMerEn = TRUE; //定时器使能
/* 配置通道0, 仅仅使能 */
pPIT_Config0->u32LoadValue = u32LoadValue0;
pPIT_Config0->bFreeze = FALSE; //定时器在调试模式下继续运行
pPIT_Config0->bModuleDis = FALSE; //使能定时器模块
pPIT_Config0->bInterruptEn = FALSE;
pPIT_Config0->bChainMode = FALSE;
pPIT_Config0->bETMerEn = TRUE; //定时器使能
PIT_Init(PIT_CHANNEL0, pPIT_Config0); //初始化PIT模块通道0
PIT_Init(PIT_CHANNEL1, pPIT_Config1); //初始化PIT模块通道1
PIT_SetCallback(PIT_CHANNEL1, PIT_Task); //设置通道1中断回调函数
while(1)
{
}
}
/*****************************************************************************//*!
*
* @PIT中断任务函数
*
* @无输入
*
* @无返回
*
*****************************************************************************/
void PIT_Task(void)
{
LED0_Toggle(); /*!< 闪烁 */
}
/********************************************************************/
@@ -0,0 +1,37 @@
/******************************************************************************
* @brief define interrupt service routines referenced by the vector table.
*
* Note: Only "vectors.c" should include this header file.
*
*******************************************************************************
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
/*!
* @brief define interrupt service routine for different vectors.
*
*/
#undef VECTOR_038
#define VECTOR_038 PIT_Ch0Isr /*!< Vector 38 points to PIT channel 0 interrupt service routine */
#undef VECTOR_039
#define VECTOR_039 PIT_Ch1Isr /*!< Vector 39 points to PIT channel 1 interrupt service routine */
extern void PIT_Ch1Isr(void);
extern void PIT_Ch0Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,74 @@
/**********************************************************************
*
* 实验名称:停止模式:RTC中断唤醒MCU
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:MCU进入STOP3模式后,经过10延时,RTC产生中断将MCU从STOP3模式下
* 唤醒
*
************************************************************************/
#include "common.h"
#include "rtc.h"
#include "pmc.h"
#include "uart.h"
#include "sysinit.h"
#include "sim.h"
int main (void);
void RTC_Task(void);
/********************************************************************/
int main (void)
{
uint8_t u8Ch;
PMC_ConfigType PMC_Config={0};
RTC_ConfigType RTC_Config={0};
/*系统初始化*/
sysinit();
printf("\nRunning the PMC_demo project.\r\n");
LED0_Init();
LED0_Off();
PMC_Config.sCtrlstatus.bits.bBandgapEn = 0;
PMC_Config.sCtrlstatus.bits.bLvdStopEn = 0; //低压检测在停止模式下禁用
PMC_Config.sCtrlstatus.bits.bLvdRstEn = 0; //禁用低压检测复位
PMC_Init(PMC, &PMC_Config); //初始化PMC模块
PMC_DisableLVWInterrupt(PMC); //禁用低压报警中断
u8Ch = PMC_GetLVWFlag(PMC);
RTC_Config.u16ModuloValue = 0x09; //设置RTC模值
RTC_Config.bClockSource = RTC_CLKSRC_1KHZ; //选择1KHZ时钟源
RTC_Config.bClockPresaler = RTC_CLK_PRESCALER_1000; //设置时钟分频系数
RTC_SetCallback(RTC_Task); //设置回调函数
RTC_Config.bInterruptEn = 1; //使能RTC中断
RTC_Init(&RTC_Config); //初始化RTC模块
/*在执行STOP指令前完成RTC初始化*/
/*MCU进入停止模式,经过10延时,由RTC中断唤醒*/
printf("\nEnter stop mode and will be woken up in about 10s by RTC Irq.\r\n");
PMC_SetMode(PMC,PmcModeStop3);
while(!(ICS->S & ICS_S_LOCK_MASK));//从停止模式唤醒后,需要等待FLL稳定
printf("\nWake up now.\r\n");
while(1);
}
/*****************************************************************************//*!
*
* @brief RTC回调函数
*
* @param none.
*
* @return none.
*
*****************************************************************************/
void RTC_Task(void)
{
LED0_Toggle();
}
/********************************************************************/
@@ -0,0 +1,27 @@
/******************************************************************************
* File: isr.h
* Purpose: Define interrupt service routines referenced by the vector table.
* Note: Only "vectors.c" should include this header file.
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H 1
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
extern void RTC_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,81 @@
/**********************************************************************
*
* 实验名称:RTC定时中断
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:RTC时钟源选择LPOCLK-1KHZ,板载LED每隔1S轮显一次
*
************************************************************************/
#include "common.h"
#include "rtc.h"
#include "uart.h"
#include "sysinit.h"
int main (void);
void RTC_Task(void);
uint8_t i=0;
/********************************************************************/
int main (void)
{
uint8_t u8Ch;
uint16_t u16ModuloValue;
RTC_ConfigType sRTCConfig;
RTC_ConfigType *pRTC_Config=&sRTCConfig;
/* 系统初始化 */
sysinit();
printf("\nRunning the RTC_demo project.\r\n");
LED0_Init();
LED1_Init();
LED2_Init();
/* 配置RTC的中断频率为1HZ */
u16ModuloValue = 0x09;//模值为10
pRTC_Config->u16ModuloValue = u16ModuloValue;//装载值到模数寄存器中
pRTC_Config->bInterruptEn = RTC_INTERRUPT_ENABLE; //使能中断
pRTC_Config->bClockSource = RTC_CLKSRC_1KHZ; //选取时钟源为1KHZ
pRTC_Config->bClockPresaler = RTC_CLK_PRESCALER_100; //分频数为100
RTC_SetCallback(RTC_Task);
RTC_Init(pRTC_Config);
while(1)
{
}
}
/*****************************************************************************//*!
*
* @RTC中断任务函数,闪烁LED,三个LED轮显
*
* @无返回
*
*****************************************************************************/
void RTC_Task(void)
{
i=i+1;
if(i%3==2)
{
LED0_On();
LED1_Off();
LED2_Off();
}
else if(i%3==1)
{
LED0_Off();
LED1_On();
LED2_Off();
}
else
{
LED0_Off();
LED1_Off();
LED2_On();
}
}
/********************************************************************/
@@ -0,0 +1,33 @@
/******************************************************************************
* @brief define interrupt service routines referenced by the vector table.
*
* Note: Only "vectors.c" should include this header file.
*
*******************************************************************************
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
/*!
* @brief define interrupt service routine for different vectors.
*
*/
#undef VECTOR_036
#define VECTOR_036 RTC_Isr /*!< Vector 36 points to RTC interrupt service routine */
extern void RTC_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,105 @@
/**********************************************************************
*
* 实验名称:SPI主机收发数据实验(采用中断的方式收发数据)
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:SPI发送的同时接收相同的数据,比较接收和发送的数据相同,判断
* SPI通信成功
*
************************************************************************/
#include "common.h"
#include "ics.h"
#include "rtc.h"
#include "uart.h"
#include "spi.h"
#include "systick.h"
#include "spi_app.h"
#include "sysinit.h"
/******************************************************************************
* 定义收发数据大小和SPI波特率
******************************************************************************/
#define SPI0_TX_DATA_SIZE 128
#define SPI_BIT_RATE 1000000 /* ~1Mbps */
static SPI_WidthType gu8SPI0_RxBuff[SPI0_TX_DATA_SIZE];
static SPI_WidthType gu8SPI0_TxBuff[SPI0_TX_DATA_SIZE];
static uint32_t gu32ErrorCount = 0;
static uint8_t gu8Pattern = 0;
static uint32_t gu32Loop = 0;
int main (void);
/********************************************************************/
int main (void)
{
static uint32_t i;
SPI_ConfigType sSPIConfig = {0};
PORT->HDRVE = 0x30;
sysinit();
printf("\nRunning the SPI_MasterInt_demo project.\r\n");
LED0_Init();
LED2_Init();
UART_WaitTxComplete(TERM_PORT);
SPI_InitGlobalVariable(); /*SPI模块接收发和发送数据初始化配置*/
SIM->PINSEL |= SIM_PINSEL_SPI0PS_MASK;
/* 初始化SPI0位主机模式*/
sSPIConfig.u32BitRate = SPI_BIT_RATE; /*设置波特率*/
sSPIConfig.u32BusClkHz = BUS_CLK_HZ;
sSPIConfig.sSettings.bModuleEn = 1; /*!<使能SPI模块*/
sSPIConfig.sSettings.bMasterMode = 1; /*设置SPI主机模*/
sSPIConfig.sSettings.bClkPhase1 = 0; /*设置时钟相位*/
sSPIConfig.sSettings.bMasterAutoDriveSS = 1; /*!< 从机选择输出使能 */
SPI_Init(SPI0, &sSPIConfig);
gu8Pattern = 0x55;
/*初始化要发送的数据*/
for(i = 0; i < SPI0_TX_DATA_SIZE; i++)
{
gu8SPI0_TxBuff[i] = i+ gu8Pattern;
}
NVIC_EnableIRQ(SPI0_IRQn);
while(1)
{
/*开始发送和接收数据*/
SPI_Transfer(SPI0,gu8SPI0_RxBuff, gu8SPI0_TxBuff, SPI0_TX_DATA_SIZE);
/*等待数据全部接收*/
while(!(SPI_GetTransferStatus(SPI0) & SPI_STATUS_RX_OVER) );
SPI_ResetTransferStatus(SPI0);
/*核对接收的数据是否正确*/
for(i = 0; i < SPI0_TX_DATA_SIZE; i++)
{
if(gu8SPI0_RxBuff[i] != gu8SPI0_TxBuff[i])
{
gu32ErrorCount++;
RED_Init(); /*亮灯 */
break;
}
}
printf("Error counter is %d\r\n",gu32ErrorCount);
gu32Loop ++;
printf("SPI communication counter %d\r\n",gu32Loop);
for(i=0;i<0xffff;i++);
}
}
@@ -0,0 +1,44 @@
/******************************************************************************
*
* @brief define interrupt service routines referenced by the vector table.
*
* Note: Only "vectors.c" should include this header file.
*
*******************************************************************************
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
/*!
* @brief define interrupt service routine for different vectors.
*
*/
#undef VECTOR_036
#define VECTOR_036 RTC_Isr /*!< Vector 36 points to RTC interrupt service routine */
#undef VECTOR_026
#define VECTOR_026 SPI0_Isr /*!< Vector 36 points to RTC interrupt service routine */
#undef VECTOR_027
#define VECTOR_027 SPI1_Isr /*!< Vector 36 points to RTC interrupt service routine */
extern void RTC_Isr(void);
void SPI0_Isr(void);
void SPI1_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,212 @@
/******************************************************************************
*
* @brief SPI数据收发驱动函数
*
******************************************************************************/
#include "common.h"
#include "spi.h"
#include "spi_app.h"
/******************************************************************************/
static SPI_WidthType *pSPI_RxBuf[MAX_SPI_NO] = {NULL}; /* 接收数组指针 */
static SPI_WidthType *pSPI_TxBuf[MAX_SPI_NO] = {NULL}; /* 发送数组指针 */
static uint16_t u16SPI_RxBuffWrPointer[MAX_SPI_NO] = {0}; /* 接收数组元素变量 */
static uint16_t u16SPI_TxBuffRdPointer[MAX_SPI_NO] = {0}; /* 发送数组元素变量 */
static uint32_t gu32SPI_BuffSize[MAX_SPI_NO] = {0}; /* 数组大小*/
static uint8_t u8SPI_Status[MAX_SPI_NO];
/******************************************************************************/
void SPI0_MasterCallback(void);
void SPI1_MasterCallback(void);
/*****************************************************************************//*!
*
* @brief SPI模块接收发和发送数据初始化配置
*
* @param[in] pSPI 指向SPI模块.
* @param[in] pConfig 指向配置结构体参数.
*
* @return none.
*
*****************************************************************************/
void SPI_InitGlobalVariable( void )
{
pSPI_RxBuf[0] = NULL;
pSPI_TxBuf[0] = NULL;
u16SPI_RxBuffWrPointer[0] = 0;
u16SPI_TxBuffRdPointer[0] = 0;
u8SPI_Status[0] = SPI_STATUS_IDLE; //SPI空闲状态
SPI_SetCallback(SPI0,SPI0_MasterCallback); //注册SPI0回调函数,通过SPI0中断服务函数调用
pSPI_RxBuf[1] = NULL;
pSPI_TxBuf[1] = NULL;
u16SPI_RxBuffWrPointer[1] = 0;
u16SPI_TxBuffRdPointer[1] = 0;
u8SPI_Status[1] = SPI_STATUS_IDLE;
SPI_SetCallback(SPI1,SPI1_MasterCallback); //注册SPI1回调函数,通过SPI1中断服务函数调用
}
/*****************************************************************************//*!
*
* @brief SPI收发数据设置,该函数的作用传递接收数组和发送数组的指针和数据大小。
*
* @param[in] pSPI 指向SPI模块
* @param[in] pWrBuff -- 发送数组指针.
* @param[in] uiLength --接收和发送数据大小
* @param[out] pRdBuff --接收数组指针.
*
* @return if <0, means error, 0: success.
*
*****************************************************************************/
ResultType SPI_Transfer(SPI_Type *pSPI, SPI_WidthType* pRdBuff, SPI_WidthType * pWrBuff,uint32 u32Length)
{
uint8_t iSPI = ((uint32_t)pSPI-(uint32_t)SPI0)>>12;
ResultType err = SPI_ERR_SUCCESS;
if(!u32Length)
{
return (err);
}
/*传递接收数和发送数组的指针和数组大小*/
gu32SPI_BuffSize[iSPI] = u32Length; //记录要发送和接收数据大小
pSPI_RxBuf[iSPI] = pRdBuff; //传递接收数组的指针
pSPI_TxBuf[iSPI] = pWrBuff; //传递接收数组的指针
u16SPI_RxBuffWrPointer[iSPI] = 0;
u16SPI_TxBuffRdPointer[iSPI] = 0;
u8SPI_Status[iSPI] = SPI_STATUS_BUSY;
SPI_TxIntEnable(pSPI); /* 使能发送中断*/
SPI_IntEnable(pSPI);
return (err);
}
/*****************************************************************************//*!
*
* @brief SPI0 回调函数通过SPI0中断服务函数调用
*
* @param[in] none.
*
* @return none.
*
*****************************************************************************/
void SPI0_MasterCallback(void)
{
/*判断接收缓冲区是否满,满则读取接收的数据*/
if(SPI_IsSPRF(SPI0))
{
if( u16SPI_RxBuffWrPointer[0] < gu32SPI_BuffSize[0] ) /*判读接收数组是否满(数据是否全部接收)*/
{
pSPI_RxBuf[0][u16SPI_RxBuffWrPointer[0]++] = SPI_ReadDataReg(SPI0); /*读接收到的数据到接收数组中*/
}
if (u16SPI_RxBuffWrPointer[0] >= gu32SPI_BuffSize[0]) /*数据全部接收完*/
{
SPI_ReadDataReg(SPI0);
u8SPI_Status[0] |= SPI_STATUS_RX_OVER;
}
}
/*判断发送缓数据缓冲区是否为空,为空则将发送数组的数据写到发送缓冲区*/
if(SPI_IsSPTEF(SPI0))
{
if(u16SPI_TxBuffRdPointer[0] < gu32SPI_BuffSize[0]) /*判断数据是否全部发送完全,没有发送完继续写数据*/
{
SPI_WriteDataReg(SPI0,pSPI_TxBuf[0][u16SPI_TxBuffRdPointer[0]++]); /*写数据到发送缓冲区*/
}
else
{
SPI_TxIntDisable(SPI0);
u8SPI_Status[0] |= SPI_STATUS_TX_OVER;
}
}
}
/*****************************************************************************//*!
*
* @brief SPI1 回调函数通过中断服务函数调用
*
* @param[in] none.
*
* @return if <0, means error, 0: success.
*
*****************************************************************************/
void SPI1_MasterCallback(void)
{
/*判断接收缓冲区是否满,满则读取接收的数据*/
if(SPI_IsSPRF(SPI1))
{
if( u16SPI_RxBuffWrPointer[1] < gu32SPI_BuffSize[1] ) /*判读接收数组是否满(数据是否全部接收)*/
{
pSPI_RxBuf[1][u16SPI_RxBuffWrPointer[1]++] = SPI_ReadDataReg(SPI1); /*读接收到的数据到接收数组中*/
}
if( u16SPI_RxBuffWrPointer[1] >= gu32SPI_BuffSize[1] ) /*数据全部接收完*/
{
SPI_ReadDataReg(SPI1);
u8SPI_Status[1] |= SPI_STATUS_RX_OVER;
}
}
/*判断发送缓数据缓冲区是否为空,为空则将发送数组的数据写到发送缓冲区*/
if(SPI_IsSPTEF(SPI1))
{
if(u16SPI_TxBuffRdPointer[1] < gu32SPI_BuffSize[1]) /*判断数据是否全部发送完全,没有发送完继续写数据*/
{
SPI_WriteDataReg(SPI1,pSPI_TxBuf[1][u16SPI_TxBuffRdPointer[1]++]);
}
else
{
SPI_TxIntDisable(SPI1);
u8SPI_Status[1] |= SPI_STATUS_TX_OVER;
}
}
}
/*****************************************************************************//*!
*
* @brief 获取发送/接收状态
*
* @param[in] pSPI 指向SPI模块.
*
* @return 发送状态.
*
*****************************************************************************/
uint8_t SPI_GetTransferStatus( SPI_Type *pSPI )
{
if( pSPI == SPI0 )
{
return u8SPI_Status[0];
}
else
{
return u8SPI_Status[1];
}
}
/*****************************************************************************//*!
*
* @brief 复位发送/接收状态
*
* @param[in] pSPI 指向SPI模块.
*
* @return none.
*
*****************************************************************************/
void SPI_ResetTransferStatus( SPI_Type *pSPI )
{
if( pSPI == SPI0 )
{
u8SPI_Status[0] = SPI_STATUS_IDLE;
}
else
{
u8SPI_Status[1] = SPI_STATUS_IDLE;
}
}
@@ -0,0 +1,48 @@
#ifndef SPI_APP_H_
#define SPI_APP_H_
#include "spi.h"
/******************************************************************************
* 定义 PTE3 用作 SPI0 CS
*
*******************************************************************************/
#define CS0_PIN_MASK ( 1 << 3)
#define CS0_PIN_INPUT() (GPIOB_PDDR &= ~CS0_PIN_MASK)
#define CS0_PIN_Init() {GPIOB_PDDR |= CS0_PIN_MASK; GPIOB_PSOR = CS0_PIN_MASK;}
#define CS0_HIGH() (GPIOB_PSOR = CS0_PIN_MASK)
#define CS0_LOW() (GPIOB_PCOR = CS0_PIN_MASK)
/******************************************************************************
* 定义SPI模块数
******************************************************************************/
#define MAX_SPI_NO 2
/******************************************************************************
* 定义SPI驱动数组大小
*
*******************************************************************************/
#define SPI0_TX_BUF_MAX 16
#define SPI0_RX_BUF_MAX 16
#define SPI1_TX_BUF_MAX 16
#define SPI1_RX_BUF_MAX 16
/******************************************************************************
* 定义SPI接收和发送状态
*
*******************************************************************************/
#define SPI_STATUS_IDLE 0x00
#define SPI_STATUS_RX_OVER 0x01
#define SPI_STATUS_TX_OVER 0x02
#define SPI_STATUS_BUSY 0x80
/******************************************************************************/
ResultType SPI_Transfer(SPI_Type *pSPI, SPI_WidthType* pRdBuff, SPI_WidthType *pWrBuff,uint32 uiLength);
void SPI_InitGlobalVariable( void );
uint8_t SPI_GetTransferStatus( SPI_Type *pSPI );
void SPI_ResetTransferStatus( SPI_Type *pSPI );
#endif
@@ -0,0 +1,91 @@
/**********************************************************************
*
* 实验名称:SPI主机收发数据实验(采用轮训的方式收发数据)
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:SPI发送的同时接收相同的数据,比较接收和发送的数据相同,判断
* SPI通信成功
*
************************************************************************/
#include "common.h"
#include "ics.h"
#include "rtc.h"
#include "uart.h"
#include "spi.h"
#include "sysinit.h"
/******************************************************************************
* 定义收发数据大小和SPI波特率
******************************************************************************/
#define SPI0_TX_DATA_SIZE 128
#define SPI_BIT_RATE 1000000 /* ~1Mbps */
static SPI_WidthType gu8SPI0_RxBuff[SPI0_TX_DATA_SIZE];
static SPI_WidthType gu8SPI0_TxBuff[SPI0_TX_DATA_SIZE];
static uint32_t gu32ErrorCount = 0;
static uint8_t gu8Pattern = 0;
static uint32_t gu32Loop = 0;
int main (void);
/********************************************************************/
int main (void)
{
uint32_t i;
SPI_ConfigType sSPIConfig = {0};
sysinit();
printf("\nRunning the SPI_MasterPoll_demo project.\r\n");
LED0_Init();
LED2_Init();
UART_WaitTxComplete(TERM_PORT);
SIM->PINSEL |= SIM_PINSEL_SPI0PS_MASK;
/* 初始化SPI0位主机模式*/
sSPIConfig.u32BitRate = SPI_BIT_RATE; /*设置波特率*/
sSPIConfig.u32BusClkHz = BUS_CLK_HZ;
sSPIConfig.sSettings.bModuleEn = 1; /*!<使能SPI模块*/
sSPIConfig.sSettings.bMasterMode = 1; /*设置SPI主机模*/
sSPIConfig.sSettings.bClkPhase1 = 1; /*设置时钟相位*/
sSPIConfig.sSettings.bMasterAutoDriveSS = 1; /*!< 从机选择输出使能 */
SPI_Init(SPI0, &sSPIConfig);
gu8Pattern = 0x55;
/*初始化要发送的数据*/
for(i = 0; i < SPI0_TX_DATA_SIZE; i++)
{
gu8SPI0_TxBuff[i] = i+ gu8Pattern;
}
while(1)
{
SPI_TransferWait(SPI0,gu8SPI0_RxBuff,gu8SPI0_TxBuff,SPI0_TX_DATA_SIZE);
/*核对接收到的数据*/
for(i = 0; i < SPI0_TX_DATA_SIZE; i++)
{
if(gu8SPI0_RxBuff[i] != gu8SPI0_TxBuff[i])
{
gu32ErrorCount++;
RED_Init(); /* 亮灯 */
break;
}
}
printf("Error counter is %d\r\n",gu32ErrorCount);
gu32Loop ++;
printf("SPI communication counter %d\r\n",gu32Loop);
for(i=0;i<0xffff;i++);
}
}
@@ -0,0 +1,33 @@
/******************************************************************************
* @brief define interrupt service routines referenced by the vector table.
*
* Note: Only "vectors.c" should include this header file.
*
*******************************************************************************
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
/*!
* @brief define interrupt service routine for different vectors.
*
*/
#undef VECTOR_036
#define VECTOR_036 RTC_Isr /*!< Vector 36 points to RTC interrupt service routine */
extern void RTC_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,103 @@
/**********************************************************************
*
* 实验名称:SPI从机收发实验
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:SPI发送的同时接收相同的数据,比较接收和发送的数据相同,判断
* SPI通信成功
*
************************************************************************/
#include "common.h"
#include "ics.h"
#include "rtc.h"
#include "uart.h"
#include "spi.h"
#include "spi_app.h"
#include "sysinit.h"
/******************************************************************************
* 定义收发数据大小和SPI波特率
******************************************************************************/
#define SPI0_TX_DATA_SIZE 128
#define SPI_BIT_RATE 1000000 /* ~1Mbps */
static SPI_WidthType gu8SPI0_RxBuff[SPI0_TX_DATA_SIZE];
static SPI_WidthType gu8SPI0_TxBuff[SPI0_TX_DATA_SIZE];
static uint32_t gu32ErrorCount = 0;
static uint8_t gu8Pattern = 0;
static uint32_t gu32Loop = 0;
int main (void);
void RTC_Task(void);
/****************************************************************************/
int main (void)
{
uint32_t i;
SPI_ConfigType sSPIConfig = {0};
sysinit();
printf("\nRunning the SPI_Slave_demo project.\r\n");
LED0_Init();
LED2_Init();
UART_WaitTxComplete(TERM_PORT);
SPI_InitGlobalVariable(); /*SPI模块接收发和发送数据初始化配置*/
SIM->PINSEL |= SIM_PINSEL_SPI0PS_MASK;
/* initialize SPI0 as master */
sSPIConfig.u32BitRate = SPI_BIT_RATE;
sSPIConfig.u32BusClkHz = BUS_CLK_HZ;
sSPIConfig.sSettings.bModuleEn = 1; /*!<使能SPI模块*/
sSPIConfig.sSettings.bMasterMode = 0; /*设置SPI从机模*/
sSPIConfig.sSettings.bClkPhase1 = 0; /*设置时钟相位*/
sSPIConfig.sSettings.bMasterAutoDriveSS = 1; /*!< 从机选择输出使能 */
SPI_Init(SPI0, &sSPIConfig);
gu8Pattern = 0x55;
/*初始化要发送的数据*/
for(i = 0; i < SPI0_TX_DATA_SIZE; i++)
{
gu8SPI0_TxBuff[i] = i+ gu8Pattern;
}
NVIC_EnableIRQ(SPI0_IRQn);
while(1)
{
/*开始发送和接收数据*/
SPI_Transfer(SPI0,gu8SPI0_RxBuff, gu8SPI0_TxBuff, SPI0_TX_DATA_SIZE);
/*等待数据发送完成*/
while(!(SPI_GetTransferStatus(SPI0) & SPI_STATUS_TX_OVER) );
SPI_ResetTransferStatus(SPI0);
/*核对接收到的数据*/
for(i = 0; i < SPI0_TX_DATA_SIZE; i++)
{
if(gu8SPI0_RxBuff[i] != gu8SPI0_TxBuff[i])
{
gu32ErrorCount++;
RED_Init(); /*亮灯*/
break;
}
}
printf("Error counter is %d\r\n",gu32ErrorCount);
gu32Loop ++;
printf("SPI communication counter %d\r\n",gu32Loop);
for(i=0;i<0xfff;i++);
}
}
@@ -0,0 +1,43 @@
/******************************************************************************
*
* @brief define interrupt service routines referenced by the vector table.
*
* Note: Only "vectors.c" should include this header file.
*
*******************************************************************************
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
/*!
* @brief define interrupt service routine for different vectors.
*
*/
#undef VECTOR_036
#define VECTOR_036 RTC_Isr /*!< Vector 36 points to RTC interrupt service routine */
#undef VECTOR_026
#define VECTOR_026 SPI0_Isr /*!< Vector 36 points to RTC interrupt service routine */
#undef VECTOR_027
#define VECTOR_027 SPI1_Isr /*!< Vector 36 points to RTC interrupt service routine */
extern void RTC_Isr(void);
void SPI0_Isr(void);
void SPI1_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,212 @@
/******************************************************************************
*
* @brief SPI数据收发驱动函数
*
******************************************************************************/
#include "common.h"
#include "spi.h"
#include "spi_app.h"
/******************************************************************************/
static SPI_WidthType *pSPI_RxBuf[MAX_SPI_NO] = {NULL}; /* 接收数组指针 */
static SPI_WidthType *pSPI_TxBuf[MAX_SPI_NO] = {NULL}; /* 发送数组指针 */
static uint16_t u16SPI_RxBuffWrPointer[MAX_SPI_NO] = {0}; /* 接收数组元素变量 */
static uint16_t u16SPI_TxBuffRdPointer[MAX_SPI_NO] = {0}; /* 发送数组元素变量 */
static uint32_t gu32SPI_BuffSize[MAX_SPI_NO] = {0}; /* 数组大小*/
static uint8_t u8SPI_Status[MAX_SPI_NO];
/******************************************************************************/
void SPI0_MasterCallback(void);
void SPI1_MasterCallback(void);
/*****************************************************************************//*!
*
* @brief SPI模块接收发和发送数据初始化配置
*
* @param[in] pSPI 指向SPI模块.
* @param[in] pConfig 指向配置结构体参数.
*
* @return none.
*
*****************************************************************************/
void SPI_InitGlobalVariable( void )
{
pSPI_RxBuf[0] = NULL;
pSPI_TxBuf[0] = NULL;
u16SPI_RxBuffWrPointer[0] = 0;
u16SPI_TxBuffRdPointer[0] = 0;
u8SPI_Status[0] = SPI_STATUS_IDLE; //SPI空闲状态
SPI_SetCallback(SPI0,SPI0_MasterCallback); //注册SPI0回调函数,通过SPI0中断服务函数调用
pSPI_RxBuf[1] = NULL;
pSPI_TxBuf[1] = NULL;
u16SPI_RxBuffWrPointer[1] = 0;
u16SPI_TxBuffRdPointer[1] = 0;
u8SPI_Status[1] = SPI_STATUS_IDLE;
SPI_SetCallback(SPI1,SPI1_MasterCallback); //注册SPI1回调函数,通过SPI1中断服务函数调用
}
/*****************************************************************************//*!
*
* @brief SPI收发数据设置,该函数的作用传递接收数组和发送数组的指针和数据大小。
*
* @param[in] pSPI 指向SPI模块
* @param[in] pWrBuff -- 发送数组指针.
* @param[in] uiLength --接收和发送数据大小
* @param[out] pRdBuff --接收数组指针.
*
* @return if <0, means error, 0: success.
*
*****************************************************************************/
ResultType SPI_Transfer(SPI_Type *pSPI, SPI_WidthType* pRdBuff, SPI_WidthType * pWrBuff,uint32 u32Length)
{
uint8_t iSPI = ((uint32_t)pSPI-(uint32_t)SPI0)>>12;
ResultType err = SPI_ERR_SUCCESS;
if(!u32Length)
{
return (err);
}
/*传递接收数和发送数组的指针和数组大小*/
gu32SPI_BuffSize[iSPI] = u32Length; //记录要发送和接收数据大小
pSPI_RxBuf[iSPI] = pRdBuff; //传递接收数组的指针
pSPI_TxBuf[iSPI] = pWrBuff; //传递接收数组的指针
u16SPI_RxBuffWrPointer[iSPI] = 0;
u16SPI_TxBuffRdPointer[iSPI] = 0;
u8SPI_Status[iSPI] = SPI_STATUS_BUSY;
SPI_TxIntEnable(pSPI); /* 使能发送中断*/
SPI_IntEnable(pSPI);
return (err);
}
/*****************************************************************************//*!
*
* @brief SPI0 回调函数通过SPI0中断服务函数调用
*
* @param[in] none.
*
* @return none.
*
*****************************************************************************/
void SPI0_MasterCallback(void)
{
/*判断接收缓冲区是否满,满则读取接收的数据*/
if(SPI_IsSPRF(SPI0))
{
if( u16SPI_RxBuffWrPointer[0] < gu32SPI_BuffSize[0] ) /*判读接收数组是否满(数据是否全部接收)*/
{
pSPI_RxBuf[0][u16SPI_RxBuffWrPointer[0]++] = SPI_ReadDataReg(SPI0); /*读接收到的数据到接收数组中*/
}
if (u16SPI_RxBuffWrPointer[0] >= gu32SPI_BuffSize[0]) /*数据全部接收完*/
{
SPI_ReadDataReg(SPI0);
u8SPI_Status[0] |= SPI_STATUS_RX_OVER;
}
}
/*判断发送缓数据缓冲区是否为空,为空则将发送数组的数据写到发送缓冲区*/
if(SPI_IsSPTEF(SPI0))
{
if(u16SPI_TxBuffRdPointer[0] < gu32SPI_BuffSize[0]) /*判断数据是否全部发送完全,没有发送完继续写数据*/
{
SPI_WriteDataReg(SPI0,pSPI_TxBuf[0][u16SPI_TxBuffRdPointer[0]++]); /*写数据到发送缓冲区*/
}
else
{
SPI_TxIntDisable(SPI0);
u8SPI_Status[0] |= SPI_STATUS_TX_OVER;
}
}
}
/*****************************************************************************//*!
*
* @brief SPI1 回调函数通过中断服务函数调用
*
* @param[in] none.
*
* @return if <0, means error, 0: success.
*
*****************************************************************************/
void SPI1_MasterCallback(void)
{
/*判断接收缓冲区是否满,满则读取接收的数据*/
if(SPI_IsSPRF(SPI1))
{
if( u16SPI_RxBuffWrPointer[1] < gu32SPI_BuffSize[1] ) /*判读接收数组是否满(数据是否全部接收)*/
{
pSPI_RxBuf[1][u16SPI_RxBuffWrPointer[1]++] = SPI_ReadDataReg(SPI1); /*读接收到的数据到接收数组中*/
}
if( u16SPI_RxBuffWrPointer[1] >= gu32SPI_BuffSize[1] ) /*数据全部接收完*/
{
SPI_ReadDataReg(SPI1);
u8SPI_Status[1] |= SPI_STATUS_RX_OVER;
}
}
/*判断发送缓数据缓冲区是否为空,为空则将发送数组的数据写到发送缓冲区*/
if(SPI_IsSPTEF(SPI1))
{
if(u16SPI_TxBuffRdPointer[1] < gu32SPI_BuffSize[1]) /*判断数据是否全部发送完全,没有发送完继续写数据*/
{
SPI_WriteDataReg(SPI1,pSPI_TxBuf[1][u16SPI_TxBuffRdPointer[1]++]);
}
else
{
SPI_TxIntDisable(SPI1);
u8SPI_Status[1] |= SPI_STATUS_TX_OVER;
}
}
}
/*****************************************************************************//*!
*
* @brief 获取发送/接收状态
*
* @param[in] pSPI 指向SPI模块.
*
* @return 发送状态.
*
*****************************************************************************/
uint8_t SPI_GetTransferStatus( SPI_Type *pSPI )
{
if( pSPI == SPI0 )
{
return u8SPI_Status[0];
}
else
{
return u8SPI_Status[1];
}
}
/*****************************************************************************//*!
*
* @brief 复位发送/接收状态
*
* @param[in] pSPI 指向SPI模块.
*
* @return none.
*
*****************************************************************************/
void SPI_ResetTransferStatus( SPI_Type *pSPI )
{
if( pSPI == SPI0 )
{
u8SPI_Status[0] = SPI_STATUS_IDLE;
}
else
{
u8SPI_Status[1] = SPI_STATUS_IDLE;
}
}
@@ -0,0 +1,47 @@
#ifndef SPI_APP_H_
#define SPI_APP_H_
#include "spi.h"
/******************************************************************************
* 定义 PTE3 用作 SPI0 CS
*
*******************************************************************************/
#define CS0_PIN_MASK ( 1 << 3)
#define CS0_PIN_INPUT() (GPIOB_PDDR &= ~CS0_PIN_MASK)
#define CS0_PIN_Init() {GPIOB_PDDR |= CS0_PIN_MASK; GPIOB_PSOR = CS0_PIN_MASK;}
#define CS0_HIGH() (GPIOB_PSOR = CS0_PIN_MASK)
#define CS0_LOW() (GPIOB_PCOR = CS0_PIN_MASK)
/******************************************************************************
* 定义SPI模块数
******************************************************************************/
#define MAX_SPI_NO 2
/******************************************************************************
* 定义SPI驱动数组大小
*
*******************************************************************************/
#define SPI0_TX_BUF_MAX 16
#define SPI0_RX_BUF_MAX 16
#define SPI1_TX_BUF_MAX 16
#define SPI1_RX_BUF_MAX 16
/******************************************************************************
* 定义SPI接收和发送状态
*
*******************************************************************************/
#define SPI_STATUS_IDLE 0x00
#define SPI_STATUS_RX_OVER 0x01
#define SPI_STATUS_TX_OVER 0x02
#define SPI_STATUS_BUSY 0x80
/******************************************************************************/
ResultType SPI_Transfer(SPI_Type *pSPI, SPI_WidthType* pRdBuff, SPI_WidthType *pWrBuff,uint32 uiLength);
void SPI_InitGlobalVariable( void );
uint8_t SPI_GetTransferStatus( SPI_Type *pSPI );
void SPI_ResetTransferStatus( SPI_Type *pSPI );
#endif
@@ -0,0 +1,63 @@
/**********************************************************************
*
* 实验名称:滴答定时器Systick中断例程
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:提供SYSTICK定时器的中断框架 ,完成LED闪烁
* 工程中完成100mS的定时中断,SYSTICK时钟为内核时钟,在Tick_Init函数中
* 对SysTick->LOAD赋值,其中(BUS_CLK_HZ)/10-1为100MS(BUS_CLK_HZ/1000)-1为1MS
* 以此类推。
* 注:对LOAD寄存器的赋值不得超过24位,该寄存器为低24位有效,最大值为16777215
*
************************************************************************/
#include "common.h"
#include "rtc.h"
#include "pmc.h"
#include "uart.h"
#include "sysinit.h"
#include "sim.h"
#include "core_cm0plus.h"
#include "systick.h"
int main (void);
void Tick_Init(void);
void SysTick_CallBack(void);
int main (void)
{
sysinit();
printf("\nRunning the Systick_demo project.\n");
LED2_Init();
Tick_Init();
while(1);
}
/****************************************************************************//*!
*
* @brief SYSTICK定时中断初始化
*
*****************************************************************************/
void Tick_Init(void)
{
SysTick_SetCallBack(SysTick_CallBack);
SysTick->CTRL =0;
SysTick->LOAD = (BUS_CLK_HZ)/10-1; //配置定时中断时间为100MS
SysTick->VAL = 0;
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk| SysTick_CTRL_CLKSOURCE_Msk; //开中断开定时器
}
/****************************************************************************//*!
*
* @brief Systick中断服务子函数
*
*****************************************************************************/
void SysTick_CallBack(void)
{
LED2_Toggle();
}
/********************************************************************/
@@ -0,0 +1,34 @@
/******************************************************************************
*
* @brief define interrupt service routines referenced by the vector table.
*
* Note: Only "vectors.c" should include this header file.
*
*******************************************************************************
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
/*!
* @brief define interrupt service routine for different vectors.
*
*/
#undef VECTOR_015
#define VECTOR_015 SysTick_Isr /*!< Vector 15 points to SysTick interrupt service routine */
extern void SysTick_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,83 @@
/**********************************************************************
*
* 实验名称:串口中断收发数据(采用中断的方式收发数据)
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:提供串口中断收发数据的框架
*
************************************************************************/
#include "common.h"
#include "rtc.h"
#include "uart.h"
#include "UART_app.h"
#include "sysinit.h"
#define SEND_BUF_LEN 50
uint8_t send_buf[SEND_BUF_LEN]; //发送缓冲区
volatile uint8_t u8IsSendDone; //定义发送完成标志位
/******************************************************************************
******************************************************************************/
void printf_int(int8* str)
{
uint32 len = 0;
u8IsSendDone = 0;
while(*str)
{
send_buf[len++] = *str;
str++;
if (len >= (SEND_BUF_LEN-1))
{
send_buf[SEND_BUF_LEN-1] = 0;
break;
}
}
UART_SendInt(UART1, send_buf, len);//UART1口串口发送初始化
}
/*
串口数据发送完成函数*/
void UART_SendDone(void)//发送完成时,将标志位置位
{
u8IsSendDone = 1;
}
int main (void)
{
UART_ConfigType sConfig;
/*执行系统初始化*/
sysinit();
u8IsSendDone = 1;
sConfig.u32SysClkHz = BUS_CLK_HZ;//配置系统时钟和波特率
sConfig.u32Baudrate = UART_PRINT_BITRATE;
UART_Init(UART1,&sConfig); //初始化串口1
UART_SetTxDoneCallback(UART1, UART_SendDone);//串口中断回调函数
UART_SetCallback(UART_HandleInt);
LED0_Init();//初始化LED灯
printf("\nRunning the UART_Interrupt_demo project.\r\n");
/* 打开串口1中断 */
NVIC_EnableIRQ(UART1_IRQn);
printf_int("\nPrint characters using interrupt mode.\r\n");
while (!u8IsSendDone); /* 等待发送完成 */
printf_int("\nrepeat Print characters using interrupt mode.\r\n");
while (!u8IsSendDone); /* 等待发送完成 */
while (1);
}
@@ -0,0 +1,157 @@
/******************************************************************************
*
* @brief UART数据收发驱动函数
*
******************************************************************************/
#include "UART_app.h"
static uint8_t *pUART_TxBuff[MAX_UART_NO] = {NULL}; /* 发送数组指针 */
static uint8_t *pUART_RxBuff[MAX_UART_NO] = {NULL}; /* 接收数组指针 */
static uint16_t gu16UART_TxBuffPos[MAX_UART_NO] = {0}; /* 发送数组元素变量 */
static uint16_t gu16UART_RxBuffPos[MAX_UART_NO] = {0}; /* 接收数组元素变量 */
static uint32_t gu32UART_BuffSize[MAX_UART_NO] = {0}; /* 数组大小*/
UART_TxDoneCallbackType UART_TxDoneCallback[MAX_UART_NO] = {NULL};
UART_RxDoneCallbackType UART_RxDoneCallback[MAX_UART_NO] = {NULL};
/*****************************************************************************//*!
*
* @brief 在中断模式下发送一串字符串.
*
* @param[in] pUART UART的基址
* @param[in] pSendBuff 指向所要发送的字符串头地址
* @param[in] u32Length 字符的数量
*
* @return none
*
*****************************************************************************/
void UART_SendInt(UART_Type *pUART, uint8_t *pSendBuff, uint32_t u32Length)
{
uint8_t u8Port = ((uint32_t)pUART-(uint32_t)UART0)>>12;
/* 存放所要发送数据的指针以及大小 */
pUART_TxBuff[u8Port] = pSendBuff;
gu32UART_BuffSize[u8Port] = u32Length;
gu16UART_TxBuffPos[u8Port] = 0;
UART_EnableTxBuffEmptyInt(pUART); /* 使能发送中断 */
}
/*****************************************************************************//*!
*
* @brief 在中断模式下接收一串字符串.
*
* @param[in] pUART UART的基址
* @param[in] pReceiveBuff 指向所要接收的字符串头地址
* @param[in] u32Length 字符的数量
*
* @return none
*
*****************************************************************************/
void UART_ReceiveInt(UART_Type *pUART, uint8_t *pReceiveBuff, uint32_t u32Length)
{
uint8_t u8Port = ((uint32_t)pUART-(uint32_t)UART0)>>12;
/* 存放所要接收数据的指针以及大小 */
pUART_RxBuff[u8Port] = pReceiveBuff;
gu32UART_BuffSize[u8Port] = u32Length;
gu16UART_RxBuffPos[u8Port] = 0;
UART_EnableRxBuffFullInt(pUART); /* 使能接收中断 */
}
/*****************************************************************************//*!
*
* @brief UART中断处理.
*
* @param[in] pUART UART的基址
*
* @return none
*
*****************************************************************************/
void UART_HandleInt(UART_Type *pUART)
{
uint8_t u8Port;
uint8_t *pRdBuff;
uint8_t *pWrBuff;
volatile uint8_t read_temp = 0;
u8Port = ((uint32_t)pUART-(uint32_t)UART0)>>12;
/* 检查接收是否过载 */
if(UART_CheckFlag(pUART,UART_FlagOR))
{
read_temp = UART_ReadDataReg(pUART);
}
/* 检测接收器是否满 */
else if(UART_IsRxBuffFull(pUART))
{
/* 接收数据的缓冲区 */
pRdBuff = pUART_RxBuff[u8Port]; /* 获取接收缓冲区 */
read_temp = UART_ReadDataReg(pUART);
pRdBuff[gu16UART_RxBuffPos[u8Port]++]= read_temp; /* 存放接收到的数据 */
//pRdBuff[gu16UART_RxBuffPos[u8Port]++] = UART_ReadDataReg(pUART);
if(gu16UART_RxBuffPos[u8Port] == gu32UART_BuffSize[u8Port])
{
/* 若接收区已满,则停止接收 */
UART_DisableRxBuffFullInt(pUART);
if (UART_RxDoneCallback[u8Port])
{
/* 返回接收完成 */
UART_RxDoneCallback[u8Port]();
}
}
}
/* 检测发送器 */
else if(UART_IsTxBuffEmpty(pUART))
{
if(gu16UART_TxBuffPos[u8Port] != gu32UART_BuffSize[u8Port])
{
pWrBuff = pUART_TxBuff[u8Port];
UART_WriteDataReg(pUART, pWrBuff[gu16UART_TxBuffPos[u8Port]++]);
}
else
{
UART_DisableTxBuffEmptyInt(pUART);
if (UART_TxDoneCallback[u8Port])
{
/* 返回发送完成 */
UART_TxDoneCallback[u8Port]();
}
}
}
else
{
}
}
/*****************************************************************************//*!
*
* @brief UART中断发送回调接口.
*
* @param[in] pUART UART的基址
* @param[in] pfnCallback 回调函数的地址
*
* @return none
*
*****************************************************************************/
void UART_SetTxDoneCallback(UART_Type *pUART, UART_TxDoneCallbackType pfnCallback)
{
uint8_t u8Port = ((uint32_t)pUART-(uint32_t)UART0)>>12;
UART_TxDoneCallback[u8Port] = pfnCallback;
}
/*****************************************************************************//*!
*
* @brief UART中断接收回调接口.
*
* @param[in] pUART UART的基址
* @param[in] pfnCallback 回调函数的地址
*
* @return none
*
*****************************************************************************/
void UART_SetRxDoneCallback(UART_Type *pUART, UART_RxDoneCallbackType pfnCallback)
{
uint8_t u8Port = ((uint32_t)pUART-(uint32_t)UART0)>>12;
UART_RxDoneCallback[u8Port] = pfnCallback;
}
@@ -0,0 +1,29 @@
/******************************************************************************
*
* @brief @brief UARTÊý¾ÝÊÕ·¢Çý¶¯º¯Êý½Ó¿Ú.
*
*******************************************************************************/
#ifndef _UART_APP_H_
#define _UART_APP_H_
/******************************************************************************
******************************************************************************/
#include "common.h"
#include "uart.h"
typedef void (*UART_TxDoneCallbackType)(void);
typedef void (*UART_RxDoneCallbackType)(void);
/******************************************************************************
******************************************************************************/
void UART_SendInt(UART_Type *pUART, uint8_t *pSendBuff, uint32_t u32Length);
void UART_ReceiveInt(UART_Type *pUART, uint8_t *pReceiveBuff, uint32_t u32Length);
void UART_HandleInt(UART_Type *pUART);
void UART_SetTxDoneCallback(UART_Type *pUART, UART_TxDoneCallbackType pfnCallback);
void UART_SetRxDoneCallback(UART_Type *pUART, UART_RxDoneCallbackType pfnCallback);
#endif /* #ifndef _UART_APP_H_ */
@@ -0,0 +1,39 @@
/******************************************************************************
* File: isr.h
* Purpose: Define interrupt service routines referenced by the vector table.
* Note: Only "vectors.c" should include this header file.
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
#undef VECTOR_028
#undef VECTOR_029
#undef VECTOR_030
#define VECTOR_028 UART0_Isr
#define VECTOR_029 UART1_Isr
#define VECTOR_030 UART2_Isr
extern void RTC_Isr(void);
extern void UART0_Isr(void);
extern void UART1_Isr(void);
extern void UART2_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,58 @@
/**********************************************************************
*
* 实验名称:UART环回模式
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:本例程为回环测试,UART1口为正常模式完成收发,UART0口为循环模式
* 输入"loopback"在串口助手的窗口中回显
*
************************************************************************/
#include "common.h"
#include "rtc.h"
#include "uart.h"
#include "uart_app.h"
#include "sysinit.h"
#define SEND_BUF_LEN 1
#define RECEIVE_BUF_LEN 1
uint8_t send_buf[SEND_BUF_LEN] = {'L'};
uint8_t receive_buf[RECEIVE_BUF_LEN] = {0};
/******************************************************************************/
int main (void)
{
UART_ConfigType sConfig;
/*执行系统初始化*/
sysinit();
sConfig.u32SysClkHz = BUS_CLK_HZ;//选择系统时钟
sConfig.u32Baudrate = 115200;//配置波特率为115200
LED0_Init();//初始化 LED
printf("\nRunning the UART_Loopback_demo project.\r\n");
printf("\nEnter any character to echo...\r\n");
UART_WaitTxComplete(UART1);//等待串口1发送完成
UART_Init(UART0,&sConfig);//初始化串口 0
UART_EnableLoopback(UART0);//开启串口0环回,设定UART0为循环模式
UART_SetCallback(UART_HandleInt);
/* 禁用串口 1 收发中断 */
UART_DisableInterrupt(TERM_PORT, UART_RxBuffFullInt);
UART_DisableInterrupt(TERM_PORT, UART_TxBuffEmptyInt);
/* 使能串口 1 接收溢出中断 */
UART_EnableInterrupt(UART1, UART_RxOverrunInt);
NVIC_EnableIRQ(UART1_IRQn);//打开串口1中断
while (1)
{
send_buf[0] = UART_GetChar(TERM_PORT); //获取串口1上的字符,存放到发送缓冲区
UART_SendWait(UART0, send_buf, 20); //发送缓冲区字符到UART0口
UART_ReceiveWait(UART0, receive_buf, 20);//把UART0的内容放入接收缓冲区中
UART_PutChar(TERM_PORT, receive_buf[0]);//接收缓冲区的数据放入 UART1 口的数据寄存器
}
}
@@ -0,0 +1,157 @@
/******************************************************************************
*
* @brief UART数据收发驱动函数
*
******************************************************************************/
#include "UART_app.h"
static uint8_t *pUART_TxBuff[MAX_UART_NO] = {NULL}; /* 发送数组指针 */
static uint8_t *pUART_RxBuff[MAX_UART_NO] = {NULL}; /* 接收数组指针 */
static uint16_t gu16UART_TxBuffPos[MAX_UART_NO] = {0}; /* 发送数组元素变量 */
static uint16_t gu16UART_RxBuffPos[MAX_UART_NO] = {0}; /* 接收数组元素变量 */
static uint32_t gu32UART_BuffSize[MAX_UART_NO] = {0}; /* 数组大小*/
UART_TxDoneCallbackType UART_TxDoneCallback[MAX_UART_NO] = {NULL};
UART_RxDoneCallbackType UART_RxDoneCallback[MAX_UART_NO] = {NULL};
/*****************************************************************************//*!
*
* @brief 在中断模式下发送一串字符串.
*
* @param[in] pUART UART的基址
* @param[in] pSendBuff 指向所要发送的字符串头地址
* @param[in] u32Length 字符的数量
*
* @return none
*
*****************************************************************************/
void UART_SendInt(UART_Type *pUART, uint8_t *pSendBuff, uint32_t u32Length)
{
uint8_t u8Port = ((uint32_t)pUART-(uint32_t)UART0)>>12;
/* 存放所要发送数据的指针以及大小 */
pUART_TxBuff[u8Port] = pSendBuff;
gu32UART_BuffSize[u8Port] = u32Length;
gu16UART_TxBuffPos[u8Port] = 0;
UART_EnableTxBuffEmptyInt(pUART); /* 使能发送中断 */
}
/*****************************************************************************//*!
*
* @brief 在中断模式下接收一串字符串.
*
* @param[in] pUART UART的基址
* @param[in] pReceiveBuff 指向所要接收的字符串头地址
* @param[in] u32Length 字符的数量
*
* @return none
*
*****************************************************************************/
void UART_ReceiveInt(UART_Type *pUART, uint8_t *pReceiveBuff, uint32_t u32Length)
{
uint8_t u8Port = ((uint32_t)pUART-(uint32_t)UART0)>>12;
/* 存放所要接收数据的指针以及大小 */
pUART_RxBuff[u8Port] = pReceiveBuff;
gu32UART_BuffSize[u8Port] = u32Length;
gu16UART_RxBuffPos[u8Port] = 0;
UART_EnableRxBuffFullInt(pUART); /* 使能接收中断 */
}
/*****************************************************************************//*!
*
* @brief UART中断处理.
*
* @param[in] pUART UART的基址
*
* @return none
*
*****************************************************************************/
void UART_HandleInt(UART_Type *pUART)
{
uint8_t u8Port;
uint8_t *pRdBuff;
uint8_t *pWrBuff;
volatile uint8_t read_temp = 0;
u8Port = ((uint32_t)pUART-(uint32_t)UART0)>>12;
/* 检查接收是否过载 */
if(UART_CheckFlag(pUART,UART_FlagOR))
{
read_temp = UART_ReadDataReg(pUART);
}
/* 检测接收器是否满 */
else if(UART_IsRxBuffFull(pUART))
{
/* 接收数据的缓冲区 */
pRdBuff = pUART_RxBuff[u8Port]; /* 获取接收缓冲区 */
read_temp = UART_ReadDataReg(pUART);
pRdBuff[gu16UART_RxBuffPos[u8Port]++]= read_temp; /* 存放接收到的数据 */
//pRdBuff[gu16UART_RxBuffPos[u8Port]++] = UART_ReadDataReg(pUART);
if(gu16UART_RxBuffPos[u8Port] == gu32UART_BuffSize[u8Port])
{
/* 若接收区已满,则停止接收 */
UART_DisableRxBuffFullInt(pUART);
if (UART_RxDoneCallback[u8Port])
{
/* 返回接收完成 */
UART_RxDoneCallback[u8Port]();
}
}
}
/* 检测发送器 */
else if(UART_IsTxBuffEmpty(pUART))
{
if(gu16UART_TxBuffPos[u8Port] != gu32UART_BuffSize[u8Port])
{
pWrBuff = pUART_TxBuff[u8Port];
UART_WriteDataReg(pUART, pWrBuff[gu16UART_TxBuffPos[u8Port]++]);
}
else
{
UART_DisableTxBuffEmptyInt(pUART);
if (UART_TxDoneCallback[u8Port])
{
/* 返回发送完成 */
UART_TxDoneCallback[u8Port]();
}
}
}
else
{
}
}
/*****************************************************************************//*!
*
* @brief UART中断发送回调接口.
*
* @param[in] pUART UART的基址
* @param[in] pfnCallback 回调函数的地址
*
* @return none
*
*****************************************************************************/
void UART_SetTxDoneCallback(UART_Type *pUART, UART_TxDoneCallbackType pfnCallback)
{
uint8_t u8Port = ((uint32_t)pUART-(uint32_t)UART0)>>12;
UART_TxDoneCallback[u8Port] = pfnCallback;
}
/*****************************************************************************//*!
*
* @brief UART中断接收回调接口.
*
* @param[in] pUART UART的基址
* @param[in] pfnCallback 回调函数的地址
*
* @return none
*
*****************************************************************************/
void UART_SetRxDoneCallback(UART_Type *pUART, UART_RxDoneCallbackType pfnCallback)
{
uint8_t u8Port = ((uint32_t)pUART-(uint32_t)UART0)>>12;
UART_RxDoneCallback[u8Port] = pfnCallback;
}
@@ -0,0 +1,30 @@
/******************************************************************************
* @brief provide commond UART utilities.
*
*******************************************************************************/
#ifndef _UART_APP_H_
#define _UART_APP_H_
/******************************************************************************
* Includes
******************************************************************************/
#include "common.h"
#include "uart.h"
/* callback types */
typedef void (*UART_TxDoneCallbackType)(void);
typedef void (*UART_RxDoneCallbackType)(void);
/******************************************************************************
* Global functions declaration
******************************************************************************/
void UART_SendInt(UART_Type *pUART, uint8_t *pSendBuff, uint32_t u32Length);
void UART_ReceiveInt(UART_Type *pUART, uint8_t *pReceiveBuff, uint32_t u32Length);
void UART_HandleInt(UART_Type *pUART);
void UART_SetTxDoneCallback(UART_Type *pUART, UART_TxDoneCallbackType pfnCallback);
void UART_SetRxDoneCallback(UART_Type *pUART, UART_RxDoneCallbackType pfnCallback);
#endif /* #ifndef _UART_APP_H_ */
@@ -0,0 +1,43 @@
/******************************************************************************
*
* @brief define interrupt service routines referenced by the vector table.
*
* Note: Only "vectors.c" should include this header file.
*
*******************************************************************************
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
/*!
* @brief define interrupt service routine for different vectors.
*
*/
#undef VECTOR_028
#undef VECTOR_029
#undef VECTOR_030
#define VECTOR_028 UART0_Isr
#define VECTOR_029 UART1_Isr
#define VECTOR_030 UART2_Isr
extern void RTC_Isr(void);
extern void UART0_Isr(void);
extern void UART1_Isr(void);
extern void UART2_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,40 @@
/**********************************************************************
*
* 实验名称:UART查询法样例
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:使用查询法发送字符串
*
************************************************************************/
#include "common.h"
#include "rtc.h"
#include "uart.h"
#include "sysinit.h"
#define SEND_BUF_LEN 50
uint8_t send_buf[SEND_BUF_LEN] = "\nUART send char by polling\n\r";
/******************************************************************************/
int main (void)
{
UART_ConfigType sConfig;
/* 执行系统初始化 */
sysinit();
sConfig.u32SysClkHz = BUS_CLK_HZ;//选择时钟源为总线时钟
sConfig.u32Baudrate = UART_PRINT_BITRATE;//设置波特率
UART_Init(UART1,&sConfig);//初始化串口 1
LED0_Init();
printf("\nRunning the UART_Poll_demo project.\r\n");//打印运行工程名
UART_SendWait(UART1, send_buf, 50);//发送缓冲区的数据放入 UART1 口的数据寄存器中
while (1);
}
@@ -0,0 +1,34 @@
/******************************************************************************
*
* @brief define interrupt service routines referenced by the vector table.
*
* Note: Only "vectors.c" should include this header file.
*
*******************************************************************************
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
/*!
* @brief define interrupt service routine for different vectors.
*
*/
#undef VECTOR_036
#define VECTOR_036 RTC_Isr /*!< Vector 36 points to RTC interrupt service routine */
extern void RTC_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,91 @@
/**********************************************************************
*
* 实验名称:看门狗--喂狗/刷新例程
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:提供看门狗框架,看门狗的使能需要在NV32_config.h宏定义ENABLE_WDOG
*
************************************************************************/
#include "common.h"
#include "ics.h"
#include "rtc.h"
#include "uart.h"
#include "wdog.h"
#include "sim.h"
#include "sysinit.h"
int main (void);
void DelayUS(uint32_t u32ETMeUS);
/********************************************************************/
int main (void)
{
WDOG_ConfigType sWDOGConfig = {0}; /*! < 声明看门狗配置结构体 */
/* 执行系统初始化 */
sysinit();
sWDOGConfig.sBits.bWaitEnable = TRUE;
sWDOGConfig.sBits.bStopEnable = TRUE;
sWDOGConfig.sBits.bDbgEnable = TRUE;
sWDOGConfig.sBits.bUpdateEnable = FALSE;
sWDOGConfig.sBits.bDisable = FALSE; /* 使能看门狗*/
sWDOGConfig.sBits.bClkSrc = WDOG_CLK_INTERNAL_1KHZ;
sWDOGConfig.u16ETMeOut = 1000; /*< 1s */
sWDOGConfig.u16WinETMe = 0;
WDOG_Init(&sWDOGConfig);
printf("\nRunning the wdog_feed_demo project.\r\n");
if(WDOG_IsReset()) /*!< 检查有无看门狗复位 */
{
LED0_Init(); /*!< 初始化LED0 */
while(1)
{
LED0_Toggle(); /*!< 看门狗复位发生LED0闪烁 */
WDOG_Feed();
DelayUS(50000); /*!< 延迟50MS */
}
}
LED2_Init(); /*!< 初始化LED2 */
while(1)
{
LED2_Toggle(); /*!< 没有看门狗复位发生,则LED2闪烁 */
DelayUS(50000); /*!< 延迟50MS */
}
}
/**************************************************************************//*!
*
* @brief 使用RTC作微秒级延迟.
*
* @param[in] u32ETMeUS 所要延迟的数量级.
*
* @return none
*
*****************************************************************************/
void DelayUS(uint32_t u32ETMeUS)
{
RTC_ConfigType sRTCConfig, *pRTC_Config;
pRTC_Config = &sRTCConfig;
/* configure RTC to 1us period */
pRTC_Config->u16ModuloValue = u32ETMeUS/4-1;
pRTC_Config->bInterruptEn = FALSE; /*!< 禁用中断 */
pRTC_Config->bClockSource = RTC_CLKSRC_BUS; /*!< 选择总线时钟为时钟源 */
pRTC_Config->bClockPresaler = RTC_CLK_PRESCALER_100; /*!< 分频系数为100 */
RTC_Init(&sRTCConfig);
while(!RTC_GetFlags())
;
RTC_ClrFlags();
RTC_DeInit();
}
/*****************************************************************************/
@@ -0,0 +1,34 @@
/******************************************************************************
*
* @brief define interrupt service routines referenced by the vector table.
*
* Note: Only "vectors.c" should include this header file.
*
*******************************************************************************
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
/*!
* @brief define interrupt service routine for different vectors.
*
*/
#undef VECTOR_036
#define VECTOR_036 RTC_Isr /*!< Vector 36 points to RTC interrupt service routine */
extern void RTC_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,34 @@
/******************************************************************************
*
* @brief define interrupt service routines referenced by the vector table.
*
* Note: Only "vectors.c" should include this header file.
*
*******************************************************************************
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
/*!
* @brief define interrupt service routine for different vectors.
*
*/
#undef VECTOR_036
#define VECTOR_036 RTC_Isr /*!< Vector 36 points to RTC interrupt service routine */
extern void RTC_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
@@ -0,0 +1,83 @@
/**********************************************************************
*
* 实验名称:MCU时钟模式切换实验
* 实验平台:NV32开发板
* 板载芯片:NV32F100FL64E
* 实验效果:MCU的时钟模式由当前的FEE模式切换到FEI模式
*
************************************************************************/
#include "common.h"
#include "ics.h"
#include "rtc.h"
#include "uart.h"
#include "sysinit.h"
int main (void);
void RTC_Task(void);
/********************************************************************/
int main (void)
{
uint8_t u8Ch;
ICS_ConfigType sICSConfig;
RTC_ConfigType sRTCConfig;
RTC_ConfigType *pRTCConfig = &sRTCConfig;
UART_ConfigType sConfig;
/*系统初始化*/
sysinit();
printf("\nRunning the platinum project.\r\n");
LED0_Init();
LED2_Init();
/*初始化RTC模块,每隔1s产生一次中断*/
pRTCConfig->u16ModuloValue = 9;
pRTCConfig->bInterruptEn = RTC_INTERRUPT_ENABLE; /*使能中断 */
pRTCConfig->bClockSource = RTC_CLKSRC_1KHZ; /*时钟源1KHz*/
pRTCConfig->bClockPresaler = RTC_CLK_PRESCALER_100; /*时钟分频系数100*/
RTC_SetCallback(RTC_Task);
RTC_Init(pRTCConfig);
printf("\nIt is in FEE mode now.\r\n");
UART_WaitTxComplete(TERM_PORT);
/*将时钟模式由FEI模式切换到FEE模式*/
sICSConfig.oscConfig.bGain = 1; /* 使能高增益 */
sICSConfig.oscConfig.bRange = 1; /* 使能高范围 */
sICSConfig.oscConfig.bEnable = 1; /* 使能 OSC */
sICSConfig.oscConfig.bIsCryst = 1; /* OSC的输出选择选择振动器时钟源 */
sICSConfig.oscConfig.bWaitInit = 1; /* 等待振荡器初始化化完成 */
sICSConfig.u32ClkFreq = 10000; /* 板载为10M晶振*/
ICS_SwitchMode(FEI,FEE, &sICSConfig);
ICS_SetBusDivider(1); //总线时钟不得高于40M主频,所以10M晶振256分频再1280倍频后为50M,需要经过BDIV二分频为25M
/* 由于时钟模式转变,总线时钟发生变化从新初始化UART模块*/
sConfig.u32SysClkHz = 25000000L;
sConfig.u32Baudrate = UART_PRINT_BITRATE;
UART_Init (TERM_PORT, &sConfig);
printf("switch to FEE mode.\r\n");
while(1);
}
/*****************************************************************************//*!
*
* @brief RTC模块回调函数
*
* @param none
*
* @return none
*
*****************************************************************************/
void RTC_Task(void)
{
/*切换LED0状态 */
LED0_Toggle();
}
/********************************************************************/