一、点亮第一个LED实验
1.F28335 GPIO介绍
1.1 GPIO概念
GPIO(general purpose intput output)是通用输入输出端口的简称,可以通过软件来控制其输入和输出。(开发板上使用的 DSP 型号是 TMS320F28335,此芯片共有 176 引脚)
(1)电源引脚
(2)晶振引脚
(3)复位引脚
(4)下载引脚
(5)BOOT引脚
(6)GPIO 引脚
1.2 GPIO结构框图
GPIO输出设置:
void LED_Init(void)
{
EALLOW;//关闭写保护
SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; // 开启GPIO时钟
//LED1端口配置
GpioCtrlRegs.GPCMUX1.bit.GPIO68=0;//设置为通用GPIO功能 0-通用输出 1-外设1输出 2-外设2输出 3-外设3输出
GpioCtrlRegs.GPCDIR.bit.GPIO68=1;//设置GPIO方向为输出 1-输出 0-输入
GpioCtrlRegs.GPCPUD.bit.GPIO68=0;//使能GPIO上拉电阻 0-使能上拉 1-禁止上拉
GpioDataRegs.GPCSET.bit.GPIO68=1;//设置GPIO输出高电平
//GpioDataRegs.GPCCLEAR.bit.GPIO68 = 1; //设置GPIO输出为低电平
EDIS;//开启写保护
}
GPIO输入设置:
DSP GPIO作为输入时,硬件自带滤波功能,通过设置指定寄存器达到3次或6次采样滤波
1.3 GPIO相关寄存器
2.硬件设计
二、蜂鸣器实验
蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、 打印机、 复印机、 报警器、 电子玩具、 汽车电子设备、 电话机、 定时器等电子产品中作发声器件。蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。 压电式蜂鸣器主要由多谐振荡器、 压电蜂鸣片、 阻抗匹配器及共鸣箱、 外壳等组成。 多谐振荡器由晶体管或集成电路构成, 当接通电源后( 1.5~15V 直流工作电压),多谐振荡器起振,输出 1.5~5kHZ 的音频信号, 阻抗匹配器推动压电蜂鸣片发声。(无源蜂鸣器,因为没有振荡器,体积大,底部看不见电路板)
电磁式蜂鸣器由振荡器、 电磁线圈、 磁铁、 振动膜片及外壳等组成。接通电源后,振荡器产生的音频信号电流通过电磁线圈, 使电磁线圈产生磁场, 振动膜片在电磁线圈和磁铁的相互作用下,周期性地振动发声。(有源蜂鸣器,体积小,底部看得见电路板)
蜂鸣器驱动时需要外加驱动芯片,GPIO口驱动电流不能达到蜂鸣器工作电流,图中为无源蜂鸣器,需要输出脉冲才能工作
#define BEEP_ON (GpioDataRegs.GPASET.bit.GPIO6=1)
#define BEEP_OFF (GpioDataRegs.GPACLEAR.bit.GPIO6=1)
#define BEEP_TOGGLE (GpioDataRegs.GPATOGGLE.bit.GPIO6=1) //不能加分号
void BEEP1_Init(void)
{
EALLOW;
SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;// 开启GPIO时钟
//BEEP端口配置
GpioCtrlRegs.GPAMUX1.bit.GPIO6=0;
GpioCtrlRegs.GPADIR.bit.GPIO6=1;
GpioCtrlRegs.GPAPUD.bit.GPIO6=0;
GpioDataRegs.GPACLEAR.bit.GPIO6=1;
EDIS;
}
void main()
{
int i = 0;
InitSysCtrl();//系统时钟初始化,默认已开启F28335所有外设时钟
LED1_Init();
BEEP1_Init();
while(1)
{
i++;
BEEP_TOGGLE; //GPIO翻转
if(i%1000==0)
{
LED1_TOGGLE;
}
DELAY_US(100); //延时可以使GPIO端口输出脉冲 驱动蜂鸣器工作
}
}
三、按键控制实验
1.按键介绍
按键是一种电子开关,使用时轻轻按开关按钮就可使开关接通,当松开手时,开关断开。
1.1 矩阵键盘介绍
矩阵键盘检测方法有多种,最常用的是行列扫描和线翻转法。 行列扫描法检测时, 先送一列为低电平, 其余几列全为高电平(此时我们确定了列数),然后立即轮流检测一次各行是否有低电平, 若检测到某一行为低电平(这时我们又确定了行数), 则我们便可确认当前被按下的键是哪一行哪一列的, 用同样方*流送各列一次低电平,再轮流检测一次各行是否变为低电平, 这样即可检测完所有的按键, 当有键被按下时便可判断出按下的键是哪一个键。 当然我们也可以将行线置低电平, 扫描列是否有低电平。 从而达到整个键盘的检测。
线翻转法,就是使所有行线为低电平时,检测所有列线是否有低电平,如果有, 就记录列线值;然后再翻转, 使所有列线都为低电平, 检测所有行线的值, 由于有按键按下,行线的值也会有变化, 记录行线的值。 从而就可以检测到全部按键。
2.硬件设计
3.软件设计
#define KEY_L1_SetL (GpioDataRegs.GPBCLEAR.bit.GPIO48=1)
#define KEY_L2_SetL (GpioDataRegs.GPBCLEAR.bit.GPIO49=1)
#define KEY_L3_SetL (GpioDataRegs.GPBCLEAR.bit.GPIO50=1)
#define KEY_L1_SetH (GpioDataRegs.GPBSET.bit.GPIO48=1)
#define KEY_L2_SetH (GpioDataRegs.GPBSET.bit.GPIO49=1)
#define KEY_L3_SetH (GpioDataRegs.GPBSET.bit.GPIO50=1)
#define KEY_H1 (GpioDataRegs.GPADAT.bit.GPIO12)
#define KEY_H2 (GpioDataRegs.GPADAT.bit.GPIO13)
#define KEY_H3 (GpioDataRegs.GPADAT.bit.GPIO14)
#define KEY1_PRESS 1
#define KEY2_PRESS 2
#define KEY3_PRESS 3
#define KEY4_PRESS 4
#define KEY5_PRESS 5
#define KEY6_PRESS 6
#define KEY7_PRESS 7
#define KEY8_PRESS 8
#define KEY9_PRESS 9
#define KEY_UNPRESS 0
void KEY_Init(void)
{
EALLOW;
SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;// 开启GPIO时钟
//KEY端口配置
/*GPIO输入端*/
GpioCtrlRegs.GPAMUX1.bit.GPIO12=0;
GpioCtrlRegs.GPADIR.bit.GPIO12=0; // GPIO设置为输入
GpioCtrlRegs.GPAPUD.bit.GPIO12=0;
GpioCtrlRegs.GPAMUX1.bit.GPIO13=0;
GpioCtrlRegs.GPADIR.bit.GPIO13=0; // GPIO设置为输入
GpioCtrlRegs.GPAPUD.bit.GPIO13=0;
GpioCtrlRegs.GPAMUX1.bit.GPIO14=0;
GpioCtrlRegs.GPADIR.bit.GPIO14=0; // GPIO设置为输入
GpioCtrlRegs.GPAPUD.bit.GPIO14=0;
/*GPIO输出端*/
GpioCtrlRegs.GPBMUX2.bit.GPIO48=0;
GpioCtrlRegs.GPBDIR.bit.GPIO48=1; // GPIO设置为输出
GpioCtrlRegs.GPBPUD.bit.GPIO48=0;
GpioCtrlRegs.GPBMUX2.bit.GPIO49=0;
GpioCtrlRegs.GPBDIR.bit.GPIO49=1; // GPIO设置为输出
GpioCtrlRegs.GPBPUD.bit.GPIO49=0;
GpioCtrlRegs.GPBMUX2.bit.GPIO50=0;
GpioCtrlRegs.GPBDIR.bit.GPIO50=1; // GPIO设置为输出
GpioCtrlRegs.GPBPUD.bit.GPIO50=0;
GpioDataRegs.GPBSET.bit.GPIO48=1;
GpioDataRegs.GPBSET.bit.GPIO49=1;
GpioDataRegs.GPBSET.bit.GPIO50=1;
EDIS;
}
char KEY_Scan(char mode) //mode=0 单次扫描 mode=1 循环扫描
{
static char keyl1=1;
static char keyl2=1;
static char keyl3=1;
//第1列扫描
KEY_L1_SetL;
KEY_L2_SetH;
KEY_L3_SetH;
if(keyl1==1&&(KEY_H1==0||KEY_H2==0||KEY_H3==0))
{
DELAY_US(10000); //消抖
keyl1=0;
if(KEY_H1==0)
{
return KEY1_PRESS;
}
else if(KEY_H2==0)
{
return KEY4_PRESS;
}
else if(KEY_H3==0)
{
return KEY7_PRESS;
}
}
else if(KEY_H1==1&&KEY_H2==1&&KEY_H3==1)
{
keyl1=1;
}
if(mode)
keyl1=1;
//第2列扫描
KEY_L2_SetL;
KEY_L1_SetH;
KEY_L3_SetH;
if(keyl2==1&&(KEY_H1==0||KEY_H2==0||KEY_H3==0))
{
DELAY_US(10000);//消抖
keyl2=0;
if(KEY_H1==0)
{
return KEY2_PRESS;
}
else if(KEY_H2==0)
{
return KEY5_PRESS;
}
else if(KEY_H3==0)
{
return KEY8_PRESS;
}
}
else if(KEY_H1==1&&KEY_H2==1&&KEY_H3==1)
{
keyl2=1;
}
if(mode)
keyl2=1;
//第3列扫描
KEY_L3_SetL;
KEY_L1_SetH;
KEY_L2_SetH;
if(keyl3==1&&(KEY_H1==0||KEY_H2==0||KEY_H3==0))
{
DELAY_US(10000);//消抖
keyl3=0;
if(KEY_H1==0)
{
return KEY3_PRESS;
}
else if(KEY_H2==0)
{
return KEY6_PRESS;
}
else if(KEY_H3==0)
{
return KEY9_PRESS;
}
}
else if(KEY_H1==1&&KEY_H2==1&&KEY_H3==1)
{
keyl3=1;
}
if(mode)
keyl3=1;
return KEY_UNPRESS;
}
void main()
{
int i=0;
char key=0;
InitSysCtrl();
LED_Init();
KEY_Init();
while(1)
{
key=KEY_Scan(0);
switch(key)
{
case KEY1_PRESS: LED2_TOGGLE;break;
case KEY2_PRESS: LED3_TOGGLE;break;
case KEY3_PRESS: LED4_TOGGLE;break;
case KEY4_PRESS: LED5_TOGGLE;break;
case KEY5_PRESS: LED6_TOGGLE;break;
case KEY6_PRESS: LED7_TOGGLE;break;
}
i++;
if(i%2000==0)
{
LED1_TOGGLE;
}
DELAY_US(100);
}
}