五、测试/调试及实验结果分析 实验结果: 实验现象观察,Led灯闪烁,每几秒蜂鸣器发出短暂(1秒左右)的蜂鸣声; GPIO 外设简介: 图 12为 GPIO0~GPIO27 模块的内部功能图。由于 28335 的大部分 IO 口都有复用功能,也就是GPIO口只是它的一个普通功能,有的IO口还有PWM 功能、SCI功能和SPI功能等。这里首先关注GPIO功能; 图 12 GPIO 功能外设 这里涉及到几个要用到的寄存器: 1、功能选择寄存器 GPAMUX1/2;每组IO一般有32个IO口可以配置。GPAMUX1对应每组的低16个IO口,GPAMUX2对应高16个IO口。 图 13 GPAMUX 配置 2、方向控制寄存器GPADIR:如果对应的位为1则配置为输出,否则则配置为输入。 3、置位寄存器 GPASET:如果对应的位为1则将对应的IO口拉高(输出高电平)。 4、强制拉低管脚 GPACLEAR:如果对应的位为1则将对应的IO口拉低(输出低电平)。 5、输出状态翻转寄存器GPATOGGLE:如果GPATOGGLE的某位为1则将相应的IO口输出状态进行翻转。 6、通用输入输出数据寄存器GPBDAT:如果 GPBDAT的某位为1则将相应的IO口输出高电平状态,否则输出低电平状态。 程序解析: 实验内容(1)的程序: // ###########################################################################
//
// FILE: Example_2833xLedBlink.c
//
// TITLE: DSP2833x eZdsp LED Blink Getting Started Program.
//
// ASSUMPTIONS:
//
// 这个程序需要DSP2833x头文件。.
//
//
// 如所提供的,这个项目被配置为“引导到SARAM”。
// 操作。2833x启动模式表如下所示。
// 有关配置eZdsp启动方式的信息,
// 请参考eZdsp附带的文档,
//
// $Boot_Table:
//
// GPIO87 GPIO86 GPIO85 GPIO84
// XA15 XA14 XA13 XA12
// PU PU PU PU
// ==========================================
// 1 1 1 1 Jump to Flash
// 1 1 1 0 SCI-A boot
// 1 1 0 1 SPI-A boot
// 1 1 0 0 I2C-A boot
// 1 0 1 1 eCAN-A boot
// 1 0 1 0 McBSP-A boot
// 1 0 0 1 Jump to XINTF x16
// 1 0 0 0 Jump to XINTF x32
// 0 1 1 1 Jump to OTP
// 0 1 1 0 Parallel GPIO I/O boot
// 0 1 0 1 Parallel XINTF boot
// 0 1 0 0 Jump to SARAM <- "boot to SARAM"
// 0 0 1 1 Branch to check boot mode
// 0 0 1 0 Boot to flash, bypass ADC cal
// 0 0 0 1 Boot to SARAM, bypass ADC cal
// 0 0 0 0 Boot to SCI-A, bypass ADC cal
// Boot_Table_End$
//
// DESCRIPTION:
//
// This example configures CPU Timer0 for a 500 msec period, and toggles the GPIO32
// LED on the 2833x eZdsp once per interrupt. For testing purposes, this example
// also increments a counter each time the timer asserts an interrupt.
//
// Watch Variables:
// CpuTimer0.InterruptCount
//
// Monitor the GPIO32 LED blink on (for 500 msec) and off (for 500 msec) on the 2833x eZdsp.
//
// ###########################################################################
#include "DSP28x_Project.h" // 设备头文件和示例包括文件
Uint16 Timer_10ms_flag;
Uint16 Timer_100ms_flag;
Uint16 Buzzer_flag;
Uint16 Timer_100ms_Count;
Uint32 Timer_1000ms_Count;
Uint32 Timer_5000ms_Count;
// 为了Buzzer_On1000ms()函数的可移植性,使用了宏定义。
// 蜂鸣器的接通与断开要参考实际驱动电路硬件,本次使用蜂鸣器驱动电路是低电平接通并工作
#define Buzzer_Pin_On GpioDataRegs.GPBDAT.bit.GPIO53 = 0 //打开蜂鸣器
#define Buzzer_Pin_Off GpioDataRegs.GPBDAT.bit.GPIO53 = 1 //关闭蜂鸣器
// 宏定义
// 蜂鸣器响一秒钟触发条件
#define Buzzer_On1000ms_Trigger Buzzer_flag = 1 //蜂鸣器响一秒钟触发条件
// 函数初始化
void GPIO_Init(void);
void Buzzer_On1000ms(void);
// 在此文件中找到的函数的原型语句.
interrupt void cpu_timer0_isr(void);
//定时器 0 中断函数
void main(void)
{
// 步骤1. 初始化系统控制:
InitSysCtrl();
//变量初始化
Timer_10ms_flag = 0;
Timer_100ms_flag = 0;
Timer_100ms_Count = 0;
Timer_1000ms_Count = 0;
Timer_5000ms_Count = 0;
Buzzer_flag = 0;
// 步骤2 初始化 GPIO:
GPIO_Init();
// 步骤3。清除所有中断并初始化PIE向量表:
// 禁用CPU中断
DINT;
// 将PIE控制寄存器初始化为其默认状态。
InitPieCtrl();
// 禁用CPU中断并清除所有CPU中断标志:
IER = 0x0000;
IFR = 0x0000;
// 用指向shell Interrupt的指针初始化PIE向量表
InitPieVectTable();
EALLOW;
// 这是写入EALLOW保护寄存器所必需的
PieVectTable.TINT0 = &cpu_timer0_isr;
EDIS;
// 这需要禁用对EALLOW保护寄存器的写操作
// 步骤4。初始化设备外设.
InitCpuTimers();
// 初始化Cpu计时器
#if (CPU_FRQ_150MHZ) // 此次编译150MHz
// 配置CPU-Timer 0每10毫秒中断一次:
// 150MHz CPU频率,10毫秒周期(单位:秒)
ConfigCpuTimer(&CpuTimer0, 150, 10000);
#endif
#if (CPU_FRQ_100MHZ)
// 配置CPU-Timer 0每500毫秒中断一次:
// 100MHz CPU频率,500毫秒周期(单位:秒)
ConfigCpuTimer(&CpuTimer0, 100, 500000);
#endif
// 下面的设置也必须更新
CpuTimer0Regs.TCR.all = 0x4001;
// 使用只写指令设置TSS= 0
// 第5步.用户特定代码,启用中断:
// 配置GPIO32为GPIO输出引脚
// 使能连接CPU- timer 0的CPU INT1
IER |= M_INT1;
// 使能PIE: Group 1中断7中的TINT0
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
// 启用全局中断和更高优先级的实时调试事件:
EINT;
// 启用全局中断INTM
ERTM;
// 启用全局实时中断DBGM
// 步骤6.无限循环执行里面的程序:
while (1)
{
if (Timer_10ms_flag) //10ms进去执行一次
{
Timer_10ms_flag = 0;
if (++Timer_100ms_Count >= 10)
{
Timer_100ms_Count = 0;
Timer_100ms_flag = 1;
}
}
if (Timer_100ms_flag) //100ms进去执行一次
{
Timer_100ms_flag = 0;
Buzzer_On1000ms();
}
if (Timer_1000ms_Count >= 50) //500ms进去执行一次
{
Timer_1000ms_Count = 0;
GpioDataRegs.GPATOGGLE.bit.GPIO0 = 1;
//LED
}
if (Timer_5000ms_Count >= 500) //5000ms进去执行一次
{
Timer_5000ms_Count = 0;
//Buzzer_flag=1;
Buzzer_On1000ms_Trigger;
}
}
}
// 定时器0中断函数
interrupt void cpu_timer0_isr(void)
{
CpuTimer0.InterruptCount++;
Timer_10ms_flag = 1;
Timer_1000ms_Count++;
Timer_5000ms_Count++;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
/**
* 函数名:void GPIO_Init()
*@brief GPIO初始化
*设置GPIO上电默认状态
*/
void GPIO_Init()
{
EALLOW;
// 用于蜂鸣器驱动
GpioCtrlRegs.GPBMUX2.bit.GPIO53 = 0;
GpioCtrlRegs.GPBDIR.bit.GPIO53 = 1;
// 用于LED灯驱动
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0;
GpioCtrlRegs.GPADIR.bit.GPIO0 = 1;
EDIS;
//设置默认上电GPIO口的状态
GpioDataRegs.GPADAT.bit.GPIO0 = 1;
//LED
GpioDataRegs.GPBDAT.bit.GPIO53 = 1;
//buzzer
}
// void Buzzer_On1000ms()改进前
/**
* 函数名:void Buzzer_On1000ms()
*@brief 驱动蜂鸣器工作一秒钟
*Buzzer_flag=1时蜂鸣器才触而发工作
*此函数要放在100ms时间片扫描执行
*/
/*
void Buzzer_On1000ms()
{
static Uint16 Flag;
//Flag=1:蜂鸣器已经打开;Flag=0:蜂鸣器未打开
static Uint16 Timer_Count;
if (Flag == 1)
{
if (++Timer_Count >= 10)
{
Timer_Count = 0;
Buzzer_flag = 0;
}
else
{
return;
}
}
if (Buzzer_flag == 1)
{
Flag = 1;
GpioDataRegs.GPBDAT.bit.GPIO53 = 0;
}
else
{
if (Flag == 0)
return;
//直接退出,目的是在此函数不开启蜂鸣器驱动时把GPIO53控制权限释放出来,否则GPIO53一直被设置高电平
GpioDataRegs.GPBDAT.bit.GPIO53 = 1;
Flag = 0;
}
}*/
// void Buzzer_On1000ms()改进后
/**
* 函数名:void Buzzer_On1000ms()
*@brief 驱动蜂鸣器工作一秒钟
*Buzzer_flag=1时蜂鸣器才触而发工作
*此函数要放在100ms时间片扫描执行
*/
void Buzzer_On1000ms()
{
static Uint16 Flag;
//Flag=1:蜂鸣器已经打开;Flag=0:蜂鸣器未打开
static Uint16 Timer_Count;
if (Flag == 1)
{
if (++Timer_Count >= 10)
//必要时可以修改蜂鸣器的工作时长,但是最短时间为100ms
{
Timer_Count = 0;
Buzzer_flag = 0;
}
else
{
return;
}
}
if (Buzzer_flag == 1)
{
Flag = 1;
Buzzer_Pin_On;
}
else
{
if (Flag == 0)
return;
//直接退出,目的是在此函数不开启蜂鸣器驱动时把GPIO53控制权限释放出来,否则GPIO53一直被设置高电平
Buzzer_Pin_Off;
Flag = 0;
}
}
//=========================================================================
// No more.
//========================================================================= 实验内容(2)的程序: #include "DSP28x_Project.h" // 设备头文件和示例包括文件
Uint16 Timer_10ms_flag;
Uint16 Timer_100ms_flag;
Uint16 Buzzer_flag;
Uint16 Timer_100ms_Count;
Uint32 Timer_1000ms_Count;
Uint32 Timer_5000ms_Count;
// 为了Buzzer_On1000ms()函数的可移植性,使用了宏定义。
// 蜂鸣器的接通与断开要参考实际驱动电路硬件,本次使用蜂鸣器驱动电路是低电平接通并工作
#define Buzzer_Pin_On GpioDataRegs.GPBDAT.bit.GPIO53 = 0 //打开蜂鸣器
#define Buzzer_Pin_Off GpioDataRegs.GPBDAT.bit.GPIO53 = 1 //关闭蜂鸣器
// 蜂鸣器响一秒钟触发条件
#define Buzzer_On1000ms_Trigger Buzzer_flag = 1 //蜂鸣器响一秒钟触发条件
// 函数初始化
void GPIO_Init(void);
void Buzzer_On1000ms(void);
// Prototype statements for functions found within this file.
__interrupt void cpu_timer0_isr(void);
__interrupt void cpu_timer1_isr(void);
__interrupt void cpu_timer2_isr(void);
void main(void)
{
// 步骤1. 初始化系统控制:
InitSysCtrl();
//变量初始化
Timer_10ms_flag = 0;
Timer_100ms_flag = 0;
Timer_100ms_Count = 0;
Timer_1000ms_Count = 0;
Timer_5000ms_Count = 0;
Buzzer_flag = 0;
// 步骤2 初始化 GPIO:
GPIO_Init();
// 步骤3。清除所有中断并初始化PIE向量表:
// 禁用CPU中断
DINT;
// 将PIE控制寄存器初始化为其默认状态。
InitPieCtrl();
// 禁用CPU中断并清除所有CPU中断标志:
IER = 0x0000;
IFR = 0x0000;
// 用指向shell Interrupt的指针初始化PIE向量表
InitPieVectTable();
EALLOW;
// 这是写入EALLOW保护寄存器所必需的
PieVectTable.TINT0 = &cpu_timer0_isr;
PieVectTable.XINT13 = &cpu_timer1_isr;
PieVectTable.TINT2 = &cpu_timer2_isr;
EDIS;
// 这需要禁用对EALLOW保护寄存器的写操作
// 步骤4。初始化设备外设.
InitCpuTimers();
// 初始化Cpu计时器
#if (CPU_FRQ_150MHZ) // 此次编译150MHz
// 配置CPU-Timer 0每10毫秒中断一次:
// 150MHz CPU频率,10毫秒周期(单位:秒)
// 配置CPU-Timer 1每1000毫秒中断一次:
// 150MHz CPU频率,1000毫秒周期(单位:秒)
ConfigCpuTimer(&CpuTimer0, 150, 10000);
ConfigCpuTimer(&CpuTimer1, 150, 1000000);
ConfigCpuTimer(&CpuTimer2, 150, 1000000);
#endif
#if (CPU_FRQ_100MHZ)
// 配置CPU-Timer 0每500毫秒中断一次:
// 100MHz CPU频率,500毫秒周期(单位:秒)
ConfigCpuTimer(&CpuTimer0, 100, 10000);
ConfigCpuTimer(&CpuTimer1, 100, 1000000);
ConfigCpuTimer(&CpuTimer2, 100, 1000000);
#endif
// 下面的设置也必须更新
CpuTimer0Regs.TCR.all = 0x4001;
// 使用只写指令设置TSS= 0
// 第5步.用户特定代码,启用中断:
// 配置GPIO32为GPIO输出引脚
CpuTimer0Regs.TCR.all = 0x4000;
// 使用只写指令设置 TSS 位 = 0
CpuTimer1Regs.TCR.all = 0x4000;
// 使用只写指令设置 TSS 位 = 0
CpuTimer2Regs.TCR.all = 0x4000;
// 使用只写指令设置 TSS 位 = 0
// 使能连接CPU- timer 0的CPU INT1
IER |= M_INT1;
IER |= M_INT13;
IER |= M_INT14;
// 使能PIE: Group 1中断7中的TINT0
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
// 启用全局中断和更高优先级的实时调试事件:
EINT;
// 启用全局中断INTM
ERTM;
// 启用全局实时中断DBGM
// 步骤6.无限循环执行里面的程序:
while (1)
{
if (Timer_10ms_flag) //10ms进去执行一次
{
Timer_10ms_flag = 0;
if (++Timer_100ms_Count >= 10)
{
Timer_100ms_Count = 0;
Timer_100ms_flag = 1;
}
}
if (Timer_100ms_flag) //100ms进去执行一次
{
Timer_100ms_flag = 0;
Buzzer_On1000ms();
}
if (Timer_1000ms_Count >= 50) //500ms进去执行一次
{
Timer_1000ms_Count = 0;
GpioDataRegs.GPATOGGLE.bit.GPIO0 = 1;
//LED
}
if (Timer_5000ms_Count >= 5) //5000ms进去执行一次
{
Timer_5000ms_Count = 0;
//Buzzer_flag=1;
Buzzer_On1000ms_Trigger;
}
}
}
__interrupt void cpu_timer0_isr(void)
{
CpuTimer0.InterruptCount++;
Timer_10ms_flag = 1;
Timer_1000ms_Count++;
// 确认此中断以接收来自组1的更多中断
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
__interrupt void cpu_timer1_isr(void)
{
CpuTimer1.InterruptCount++;
Timer_5000ms_Count++;
// CPU确认中断
EDIS;
}
__interrupt void cpu_timer2_isr(void)
{
EALLOW;
CpuTimer2.InterruptCount++;
// CPU确认中断
EDIS;
}
/**
* 函数名:void GPIO_Init()
*@brief GPIO初始化
*设置GPIO上电默认状态
*/
void GPIO_Init()
{
EALLOW;
// 用于蜂鸣器驱动
GpioCtrlRegs.GPBMUX2.bit.GPIO53 = 0;
GpioCtrlRegs.GPBDIR.bit.GPIO53 = 1;
// 用于LED灯驱动
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0;
GpioCtrlRegs.GPADIR.bit.GPIO0 = 1;
EDIS;
//设置默认上电GPIO口的状态
GpioDataRegs.GPADAT.bit.GPIO0 = 1;
//LED
GpioDataRegs.GPBDAT.bit.GPIO53 = 1;
//buzzer
}
/**
* 函数名:void Buzzer_On1000ms()
*@brief 驱动蜂鸣器工作一秒钟
*Buzzer_flag=1时蜂鸣器才触而发工作
*此函数要放在100ms时间片扫描执行
*/
void Buzzer_On1000ms()
{
static Uint16 Flag;
//Flag=1:蜂鸣器已经打开;Flag=0:蜂鸣器未打开
static Uint16 Timer_Count;
if (Flag == 1)
{
if (++Timer_Count >= 10)
//必要时可以修改蜂鸣器的工作时长,但是最短时间为100ms
{
Timer_Count = 0;
Buzzer_flag = 0;
}
else
{
return;
}
}
if (Buzzer_flag == 1)
{
Flag = 1;
Buzzer_Pin_On;
}
else
{
if (Flag == 0)
return;
//直接退出,目的是在此函数不开启蜂鸣器驱动时把GPIO53控制权限释放出来,否则GPIO53一直被设置高电平
Buzzer_Pin_Off;
Flag = 0;
}
}
//=========================================================================
// No more.
//=========================================================================
|
所有评论(0)