DSP笔记[2]-数码管显示英文字母及在flash上运行
摘要
在TMS320F28335开发板上实现8位数码管显示英文字母及烧录程序到Flash中断电程序不丢失;矩阵键盘扫描,实现按键1清零,按键2累加,按键3显示字母,按键4显示数字,按键5开关LED灯;LED流水灯.
关键信息
- 系统:macOS 13.5 (Apple Silicon M2)(烧录)
- 系统:windows 11 (arm64)(编译)
- 开发环境:Code Composer Studio(CCS)6.1.3.00034 及 12.4.0.00007
- TMS320F28335核心:C2000(C28x)
- 开发板:普中PZ-DSP28335-L
原理简介
8位数码管显示字母
// 共阴极0~9,A~Z(不区分大小写)
unsigned char smg_chars_table[]={ 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, // 0 1 2 3 4 5 6 7 8 9
0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x3D, 0x76, 0x8F, 0x0E, // A b c d E F G H I J
0x75, 0x38, 0xB7, 0x54, 0x5C, 0x73, 0x67, 0x31, 0xC9, 0x78, // K L M n o P q r S t
0x3E, 0x1C, 0xFE, 0xE4, 0x6E, 0xDA, 0x40, 0x48, 0x80, 0x00 // U v W X Y Z - = . Null
};
// 数码管显示0~9,A~Z字符
void SMG_DisplayChars(char* chars4){
// 最多显示4个字符
// if(strlen(chars4)>4 || strlen(chars4)<0) return;
int i;
for(i=0;i<4;i++){
// if(chars4[i] == '\0') break;// 空数据
// 判断是字母
if(chars4[i]>='A' && chars4[i]<='Z'){
HC164SendData(smg_chars_table[chars4[i]-'A'+10]);
}
// 判断是数字
else if(chars4[i]>='0' && chars4[i]<='9'){
HC164SendData(smg_chars_table[chars4[i]-'0']);
}
// 显示到对应位置
switch(i){
case 0: SEG1_SETH;SEG2_SETL;SEG3_SETL;SEG4_SETL;break;
case 1: SEG1_SETL;SEG2_SETH;SEG3_SETL;SEG4_SETL;break;
case 2: SEG1_SETL;SEG2_SETL;SEG3_SETH;SEG4_SETL;break;
case 3: SEG1_SETL;SEG2_SETL;SEG3_SETL;SEG4_SETH;break;
}
// 等待显示完全
DELAY_US(5000);
}// end for
}// end smgDisplayChars
数码管字符对照表 | ASCII码表 | 数码管所有显示组合 |
---|---|---|
程序烧录到RAM中和Flash中
烧录到Flash中关键文件:
- F28335.cmd
- DSP2833x_Headers_nonBIOS.cmd
- DSP2833x_MemCopy.c
示例:
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
#include "leds.h"
#include "time.h"
#include "uart.h"
#include "stdio.h"
void delay(void)
{
Uint16 i;
Uint32 j;
for(i=0;i<32;i++)
for (j = 0; j < 100000; j++);
}
void main()
{
Uint16 p=0;
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
//复制对时间敏感代码和FLASH配置代码到RAM中
// 包括FLASH初始化函数 InitFlash();
// 链接后将产生 RamfuncsLoadStart, RamfuncsLoadEnd, 和RamfuncsRunStart
// 参数. 请参考 F28335.cmd 文件
MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
// 调用FLASH初始化函数来设置flash等待状态
// 这个函数必须在RAM中运行
InitFlash();
LED_Init();
TIM0_Init(150,200000);//200ms
UARTa_Init(4800);
while(1)
{
p++;
if((p%2)==0)
{
LED2_TOGGLE;
}
delay();
}
}
DSP2833x_Headers_nonBIOS.cmd作用
[https://blog.csdn.net/xiexiaoyu1996/article/details/102598383]
在DSP28335工程文件里(不用BIOS产生CMD文件),手写CMD文件一般有两个,在RAM里调试时用的两个CMD文件分别为DSP2833x_Headers_nonBIOS.cmd和28335_RAM_lnk.cmd,烧写到flash里时用的两个CMD文件分别为DSP2833x_Headers_nonBIOS.cmd和F28335.cmd,其中DSP2833x_Headers_nonBIOS.cmd文件可以在所有工程文件中通用,主要作用是把外设寄存器产生的数据段映射到对应的存储空间,主要作用是把外设寄存器产生的数据段映射到对应的存储空间,可以跟DSP2833x_GlobalVariableDefs.c文件对照一下看看。
volatile关键字
[https://www.runoob.com/w3cnote/c-volatile-keyword.html]
C/C++ 中的 volatile 关键字和 const 对应,用来修饰变量,通常用于建立语言级别的 memory barrier。这是 BS 在 "The C++ Programming Language" 对 volatile 修饰词的说明:
A volatile specifier is a hint to a compiler that an object may change its value in ways not specified by the language so that aggressive optimizations must be avoided.
volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。声明时语法:int volatile vInt; 当要求使用 volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。
CCS调试原理
- .out文件+.ccxml文件=>CCS=>调试器=>目标板
CCS调试原理 |
---|
实现
目录结构
.
├── APP
│ ├── beep
│ │ ├── beep.c
│ │ └── beep.h
│ ├── dc_motor
│ │ ├── dc_motor.c
│ │ └── dc_motor.h
│ ├── epwm
│ │ ├── epwm.c
│ │ └── epwm.h
│ ├── exti
│ │ ├── exti.c
│ │ └── exti.h
│ ├── key
│ │ ├── key.c
│ │ └── key.h
│ ├── leds
│ │ ├── leds.c
│ │ └── leds.h
│ ├── relay
│ │ ├── relay.c
│ │ └── relay.h
│ ├── smg
│ │ ├── smg.c
│ │ └── smg.h
│ ├── step_motor
│ │ ├── step_motor.c
│ │ └── step_motor.h
│ └── time
│ ├── time.c
│ └── time.h
├── DSP2833x_Libraries
│ ├── 28335_RAM_lnk.cmd
│ ├── 28335_RAM_lnk.cmd.bak
│ ├── DSP2833x_ADC_cal.asm
│ ├── DSP2833x_CodeStartBranch.asm
│ ├── DSP2833x_CpuTimers.c
│ ├── DSP2833x_DefaultIsr.c
│ ├── DSP2833x_EPwm.c
│ ├── DSP2833x_GlobalVariableDefs.c
│ ├── DSP2833x_Gpio.c
│ ├── DSP2833x_Headers_nonBIOS.cmd
│ ├── DSP2833x_MemCopy.c
│ ├── DSP2833x_PieCtrl.c
│ ├── DSP2833x_PieVect.c
│ ├── DSP2833x_SysCtrl.c
│ ├── DSP2833x_usDelay.asm
│ ├── F28335.cmd
│ ├── F28335.cmd.bak
│ └── IQmath.lib
├── Debug
│ ├── APP
│ │ ├── beep
│ │ │ ├── beep.d
│ │ │ ├── beep.obj
│ │ │ ├── beep.pp
│ │ │ ├── subdir_rules.mk
│ │ │ └── subdir_vars.mk
│ │ ├── dc_motor
│ │ │ ├── dc_motor.d
│ │ │ ├── dc_motor.obj
│ │ │ ├── dc_motor.pp
│ │ │ ├── subdir_rules.mk
│ │ │ └── subdir_vars.mk
│ │ ├── epwm
│ │ │ ├── epwm.d
│ │ │ ├── epwm.obj
│ │ │ ├── subdir_rules.mk
│ │ │ └── subdir_vars.mk
│ │ ├── exti
│ │ │ ├── exti.d
│ │ │ ├── exti.obj
│ │ │ ├── exti.pp
│ │ │ ├── subdir_rules.mk
│ │ │ └── subdir_vars.mk
│ │ ├── key
│ │ │ ├── key.d
│ │ │ ├── key.obj
│ │ │ ├── key.pp
│ │ │ ├── subdir_rules.mk
│ │ │ └── subdir_vars.mk
│ │ ├── leds
│ │ │ ├── leds.d
│ │ │ ├── leds.obj
│ │ │ ├── leds.pp
│ │ │ ├── subdir_rules.mk
│ │ │ └── subdir_vars.mk
│ │ ├── relay
│ │ │ ├── relay.d
│ │ │ ├── relay.obj
│ │ │ ├── relay.pp
│ │ │ ├── subdir_rules.mk
│ │ │ └── subdir_vars.mk
│ │ ├── smg
│ │ │ ├── smg.d
│ │ │ ├── smg.obj
│ │ │ ├── smg.pp
│ │ │ ├── subdir_rules.mk
│ │ │ └── subdir_vars.mk
│ │ ├── step_motor
│ │ │ ├── step_motor.d
│ │ │ ├── step_motor.obj
│ │ │ ├── step_motor.pp
│ │ │ ├── subdir_rules.mk
│ │ │ └── subdir_vars.mk
│ │ └── time
│ │ ├── subdir_rules.mk
│ │ ├── subdir_vars.mk
│ │ ├── time.d
│ │ ├── time.obj
│ │ └── time.pp
│ ├── DSP2833x_Libraries
│ │ ├── DSP2833x_ADC_cal.obj
│ │ ├── DSP2833x_CodeStartBranch.obj
│ │ ├── DSP2833x_CpuTimers.d
│ │ ├── DSP2833x_CpuTimers.obj
│ │ ├── DSP2833x_CpuTimers.pp
│ │ ├── DSP2833x_DefaultIsr.d
│ │ ├── DSP2833x_DefaultIsr.obj
│ │ ├── DSP2833x_DefaultIsr.pp
│ │ ├── DSP2833x_EPwm.d
│ │ ├── DSP2833x_EPwm.obj
│ │ ├── DSP2833x_GlobalVariableDefs.d
│ │ ├── DSP2833x_GlobalVariableDefs.obj
│ │ ├── DSP2833x_GlobalVariableDefs.pp
│ │ ├── DSP2833x_Gpio.d
│ │ ├── DSP2833x_Gpio.obj
│ │ ├── DSP2833x_Gpio.pp
│ │ ├── DSP2833x_MemCopy.d
│ │ ├── DSP2833x_MemCopy.obj
│ │ ├── DSP2833x_PieCtrl.d
│ │ ├── DSP2833x_PieCtrl.obj
│ │ ├── DSP2833x_PieCtrl.pp
│ │ ├── DSP2833x_PieVect.d
│ │ ├── DSP2833x_PieVect.obj
│ │ ├── DSP2833x_PieVect.pp
│ │ ├── DSP2833x_SysCtrl.d
│ │ ├── DSP2833x_SysCtrl.obj
│ │ ├── DSP2833x_SysCtrl.pp
│ │ ├── DSP2833x_usDelay.obj
│ │ ├── subdir_rules.mk
│ │ └── subdir_vars.mk
│ ├── Example01_DSP2833x_ClockSystem.map
│ ├── Example01_DSP2833x_ClockSystem_linkInfo.xml
│ ├── Example02_DSP2833x_LED.map
│ ├── Example02_DSP2833x_LED_linkInfo.xml
│ ├── Example03_DSP2833x_LEDFlow.map
│ ├── Example03_DSP2833x_LEDFlow_linkInfo.xml
│ ├── Example04_DSP2833x_BEEP.map
│ ├── Example04_DSP2833x_BEEP_linkInfo.xml
│ ├── Example05_DSP2833x_Relay.map
│ ├── Example05_DSP2833x_Relay_linkInfo.xml
│ ├── Example06_DSP2833x_Key.map
│ ├── Example06_DSP2833x_Key_linkInfo.xml
│ ├── Example07_DSP2833x_DC_Motor.map
│ ├── Example07_DSP2833x_DC_Motor_linkInfo.xml
│ ├── Example08_DSP2833x_Step_Motor.map
│ ├── Example08_DSP2833x_Step_Motor_linkInfo.xml
│ ├── Example09_DSP2833x_External_Interruption.map
│ ├── Example09_DSP2833x_External_Interruption_linkInfo.xml
│ ├── Example10_DSP2833x_Time0.map
│ ├── Example10_DSP2833x_Time0_linkInfo.xml
│ ├── Example11_DSP2833x_Time1.map
│ ├── Example11_DSP2833x_Time1_linkInfo.xml
│ ├── Example12_DSP2833x_Time2.map
│ ├── Example12_DSP2833x_Time2_linkInfo.xml
│ ├── Example13_DSP2833x_8Seg.map
│ ├── Example13_DSP2833x_8Seg.out
│ ├── Example13_DSP2833x_8Seg_linkInfo.xml
│ ├── User
│ │ ├── main.d
│ │ ├── main.obj
│ │ ├── main.pp
│ │ ├── subdir_rules.mk
│ │ └── subdir_vars.mk
│ ├── ccsObjs.opt
│ ├── exp2_dsp28335.map
│ ├── exp2_dsp28335_linkInfo.xml
│ ├── exp2p1_dsp28335.map
│ ├── exp2p1_dsp28335.out
│ ├── exp2p1_dsp28335_linkInfo.xml
│ ├── makefile
│ ├── objects.mk
│ └── sources.mk
├── User
│ └── main.c
├── project.log
└── targetConfigs
├── TMS320F28335.ccxml
└── readme.txt
核心代码
main.c
/*
### exp2
0. 流水灯(KEY5)
1. 完成运行样例实验4控制蜂鸣器、5控制继电器、6按键、7按键控制电机、13数码管显示。
2. 修改代码,实现系统输出频率为10Mhz、75Mhz、150Mhz,观察不同频率下指示灯闪烁频率(Timer0 中断控制 D1 指示灯 闪烁)
3. 在以上实验基础上完成按键控制灯和蜂鸣器实验。
要求:按按键1灯2亮灭转换;按按键2灯4亮灭转换;按下按键3蜂鸣器鸣叫(鸣叫一段时间,自动停止);
4. 分步骤完成:
(1)按下按键1,数码管显示数字清零(显示0),按按键2,数码管上显示数字+1(即统计按键2按下的次数,显示在数码管上)。
(2)按下按键3,显示由数码管组成的大写E5PH字样.
(3)按下按键4,在数码管上显示自己学号后4位。
5. 扩展实验:在以上实验的基础上完成按键控制电机正反交替旋转(KEY7,KEY8,KEY9),变化周期固定。
6. 扩展实验:在以上实验的基础上完成,按下按键6蜂鸣器鸣叫,抬起后停止鸣叫。
*
*
硬件接口:
- LED1:XD11:GPIO68(LOW)
- LED2:GPIO67
- LED3:GPIO66
- LED4:GPIO65
- LED5:GPIO64
- LED6:ePWM6A:GPIO10
- LED7:ePWM6B:GPIO11
- MOTOR_OUTA:ePWM2A:GPIO2
- MOTOR_OUTB:ePWM2B:GPIO3
- MOTOR_OUTC:ePWM3A:GPIO4
- MOTOR_OUTD:ePWM3B:GPIO5
- BEEPER(ULN2003D):ePWM4A:GPIO6
- RELAY(ULN2003D):GPIO15
- SEG1:XD9:GPIO70
- SEG2:XD8:GPIO71
- SEG3:XD7:GPIO72
- SEG4:XD6:GPIO73
- SEG_SPISIMOA:GPIO54
- SEG_SPICLKA:GPIO56
- KEYPAD_TZ1:GPIO12
- KEYPAD_TZ2:GPIO13
- KEYPAD_TZ3:GPIO14
- KEYPAD_ECAP5:GPIO48
- KEYPAD_ECAP6:GPIO49
- KEYPAD_EQEP1A:GPIO50
*/
/* start 头文件 */
#include "DSP2833x_Device.h" // DSP2833x 头文件
#include "DSP2833x_Examples.h" // DSP2833x 例子相关头文件
#include "beep.h" // 蜂鸣器
#include "leds.h" // LED相关
#include "smg.h" // 数码管相关
#include "time.h" // 定时器相关
#include "relay.h" // 继电器
#include "key.h" // 矩阵键盘
#include "limits.h" // C语言变量最大值
#include "dc_motor.h" // 电机相关
#include "epwm.h" // ePWM波形生成相关
#include "stdio.h" // memcopy
/* end 头文件 */
/* start 全局变量 */
#define FLASH_MODE 1
char g_key_now=0; // 矩阵键盘按键值
int g_sys_loop_count=0; // 系统循环次数
int g_smg_count = 0; // 数码管数字
/* end 全局变量 */
/* start 函数声明 */
void gpioSelect(void);
void sysInit(void);// 系统初始化
void sysLoop(void);// 系统循环
void delaySecond(int second);// 延时秒
void delayMS(int ms);// 延时微秒
void ledFlowOnce(void); // 流水灯一次
void beepFast(void);// 蜂鸣器短鸣
void smgTest(void); // 数码管测试
void scanKeypad(void); // 按键扫描并绑定函数
void initFlashMode(void); // 初始化flash模式
void testLED1lBlinkLoop(void);// 测试用led1闪灯函数
void testDelay(void);// 测试用delay函数
void testKeypad(void);// 测试keypad扫描
/* end 函数声明 */
/* start 主函数 */
void main(void){
// testKeypad();
// 初始化
sysInit();
while(1){
// 死循环
sysLoop();
}
}
/* end 主函数 */
/* start 系统初始化 */
void sysInit(void){
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP2833x_SysCtrl.c file.
//
InitSysCtrl();
// Step 2. Initialize GPIO:
// This example function is found in the DSP2833x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
//
// InitGpio(); // Skipped for this example
//
// Step 3. Clear all interrupts and initialize PIE vector table
// 清除所有中断及中断向量表
// Disable CPU interrupts
// 关闭CPU中断
//
DINT;
//
// Initialize PIE control registers to their default state.
// 初始化PIE控制寄存器到默认状态
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the DSP2833x_PieCtrl.c file.
//
InitPieCtrl();
//
// Disable CPU interrupts and clear all CPU interrupt flags
//
IER = 0x0000;
IFR = 0x0000;
//
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// 初始化PIE向量表到ISR
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in DSP2833x_DefaultIsr.c.
// This function is found in DSP2833x_PieVect.c.
//
InitPieVectTable();
#if FLASH_MODE
initFlashMode();
#endif
//
// Step 4. Initialize all the Device Peripherals:
// 初始化所有芯片外设
// This function is found in DSP2833x_InitPeripherals.c
//
// InitPeripherals(); // Not required for this example
// 初始化LED
LED_Init();
// 初始化数码管
SMG_Init();
// 初始化keypad
KEY_Init();
// 初始化蜂鸣器
BEEP_Init();
// LED流水灯
ledFlowOnce();
// 数码管测试
// smgTest(); // 展示灯效果延时
// 蜂鸣器测试
beepFast();// 短鸣一次
// printf("init smg done!\n");
// 初始化TIM0
TIM0_Init(10,100000); // 10 MHz,100000us周期
delaySecond(1);
// tim0Deinit(); // 重新配置
TIM0_Init(75,100000); // 75 MHz,100000us周期
delaySecond(1);
// tim0Deinit(); // 重新配置
TIM0_Init(150,100000); // 150 MHz,100000us周期
delaySecond(1);
// 初始化直流电机(epwm模式)
// DCMotor_ePWM2_Init(); // 会导致矩阵键盘部分按键失灵
}
/* end 系统初始化 */
/* start 主循环函数 */
void sysLoop(void){
// 扫描矩阵键盘
scanKeypad();
g_sys_loop_count++;
// 200ms
if(g_sys_loop_count % 2000 == 0){
LED7_TOGGLE;// 系统运行状态指示灯
}
if(g_sys_loop_count > INT_MAX) g_sys_loop_count = 0;
DELAY_US(100);
}
/* end 主循环函数 */
/* start 函数本体 */
// 选择GPIO端口
void gpioSelect(void){
EALLOW;
GpioCtrlRegs.GPAMUX1.all = 0x00000000; // All GPIO
GpioCtrlRegs.GPAMUX2.all = 0x00000000; // All GPIO
GpioCtrlRegs.GPAMUX1.all = 0x00000000; // All GPIO
GpioCtrlRegs.GPADIR.all = 0xFFFFFFFF; // All outputs
GpioCtrlRegs.GPBDIR.all = 0x0000000F; // All outputs
EDIS;
}
// 蜂鸣器短鸣
void beepFast(void){
int i=0;
for(i=0;i<1000;i++){
BEEP_TOGGLE;
delayMS(1);
}
}
// 延时秒(s)
void delaySecond(int second){
Uint16 i;
Uint32 j;
Uint32 k;
for(k=0;k<second;k++){
// for(i=0;i<32;i++)
// for (j = 0; j < 1000000; j++);
delayMS(1000);
}
}
// 延时秒(s)
void delayMS(int ms){
Uint16 i;
Uint32 j;
Uint32 k;
for(k=0;k<ms;k++){
//for(i=0;i<32;i++)
//for (j = 0; j < 100; j++);
DELAY_US(1000);
}
}
// 流水灯一次
void ledFlowOnce(void){
LED1_TOGGLE;
delaySecond(1);
LED2_TOGGLE;
delaySecond(1);
LED3_TOGGLE;
delaySecond(1);
LED4_TOGGLE;
delaySecond(1);
LED5_TOGGLE;
delaySecond(1);
LED6_TOGGLE;
delaySecond(1);
LED7_TOGGLE;
delaySecond(1);
// close all leds
LED1_OFF;
LED2_OFF;
LED3_OFF;
LED4_OFF;
LED5_OFF;
LED6_OFF;
LED7_OFF;
}
// 数码管测试
void smgTest(void){
SMG_DisplayInt_MS(1314,1000);
SMG_DisplayFloat_MS(520,1,1000);
SMG_DisplayChars_MS("E5PH",1000);
SMG_DisplayInt_MS(1111,1000);
SMG_DisplayChars_MS("ABCD",1000);
SMG_DisplayChars_MS("EFGH",1000);
SMG_DisplayChars_MS("HIJK",1000);
SMG_DisplayChars_MS("LMNO",1000);
SMG_DisplayChars_MS("PRST",1000);
SMG_DisplayChars_MS("UVWX",1000);
SMG_DisplayChars_MS("ZZZZ",1000);
}
// 扫描按键并执行相应动作
void scanKeypad(void){
int s_key=KEY_Scan(0);
g_key_now = s_key;
switch(s_key){
case KEY1_PRESS: {
LED2_TOGGLE;
g_smg_count =0;
SMG_DisplayInt_MS(g_smg_count,1000);
break;// 按按键1灯2亮灭转换,数码管显示数字清零(显示0)
}
case KEY2_PRESS: {
LED4_TOGGLE;
g_smg_count++;
if(g_smg_count > 9999) g_smg_count = 0;
SMG_DisplayInt_MS(g_smg_count,1000);
break;// 按按键2灯4亮灭转换,数码管上显示数字+1
}
case KEY3_PRESS: {
beepFast();
SMG_DisplayChars_MS("E5PH",1000);
break;// 按下按键3蜂鸣器鸣叫,数码管组成的大写E5PH字样
}
case KEY4_PRESS: {
LED5_TOGGLE;
SMG_DisplayInt_MS(9128,1000);
break;// 按下按键4,在数码管上显示自己学号后4位(9128)
}
case KEY5_PRESS: {
LED6_TOGGLE;
break;// 按键5
}
case KEY6_PRESS: {
// beepFast();
// BEEP_TOGGLE;
beepFast();
while(KEY_Scan(0)==KEY6_PRESS) beepFast();
// DELAY_US(100);
break;// 按键6蜂鸣器鸣叫,抬起后停止鸣叫
}
case KEY7_PRESS: {
beepFast();
break;// @dc_motor.c
}
case KEY8_PRESS: {
beepFast();
break;// @dc_motor.c
}
case KEY9_PRESS: {
beepFast();
break;// @dc_motor.c
}
default:{
//LED6_TOGGLE;
break;
}
}
BEEP_OFF;
g_key_now = 0; // reset
}
// 初始化Flash模式(非RAM模式)
void initFlashMode(void){
#if FLASH_MODE
// 复制对时间敏感代码和 FLASH 配置代码到 RAM 中
// 包括 FLASH 初始化函数 InitFlash();
// 链 接 后 将 产 生 RamfuncsLoadStart, RamfuncsLoadEnd, 和RamfuncsRunStart
// 参数. 请参考 F28335.cmd 文件
MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
// 初始化flash
// 调用 FLASH 初始化函数来设置 flash 等待状态
// 这个函数必须在 RAM 中运行
InitFlash();
#endif
}
// (测试用)延时函数
void testDelay(void){
Uint16 i;
Uint32 j;
for(i=0;i<32;i++)
for (j = 0; j < 100000; j++);
}
// (测试用)led1闪灯
void testLED1lBlinkLoop(void){
InitSysCtrl();
LED_Init();
LED1_ON;
while(1);
int p=0;
while(1) {
p++;
if((p%2)==0){
LED1_TOGGLE;
}
testDelay();
}
}
// 测试keypad扫描
void testKeypad(void){
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);
}
}
/* end 函数本体 */
smg.h
/*
* smg.h
*
* Created on: 2018-1-25
* Author: Administrator
*/
#ifndef SMG_H_
#define SMG_H_
#include "DSP2833x_Device.h" // DSP2833x 头文件
#include "DSP2833x_Examples.h" // DSP2833x 例子相关头文件
//数码管位选信号线管脚定义
#define SEG1_SETH (GpioDataRegs.GPCSET.bit.GPIO70=1)
#define SEG1_SETL (GpioDataRegs.GPCCLEAR.bit.GPIO70=1)
#define SEG2_SETH (GpioDataRegs.GPCSET.bit.GPIO71=1)
#define SEG2_SETL (GpioDataRegs.GPCCLEAR.bit.GPIO71=1)
#define SEG3_SETH (GpioDataRegs.GPCSET.bit.GPIO72=1)
#define SEG3_SETL (GpioDataRegs.GPCCLEAR.bit.GPIO72=1)
#define SEG4_SETH (GpioDataRegs.GPCSET.bit.GPIO73=1)
#define SEG4_SETL (GpioDataRegs.GPCCLEAR.bit.GPIO73=1)
//74HC164时钟管脚定义
#define SPICLKA_SETH (GpioDataRegs.GPBSET.bit.GPIO56=1)
#define SPICLKA_SETL (GpioDataRegs.GPBCLEAR.bit.GPIO56=1)
//74HC164数据管脚定义
#define SPISIMOA_SETH (GpioDataRegs.GPBSET.bit.GPIO54=1)
#define SPISIMOA_SETL (GpioDataRegs.GPBCLEAR.bit.GPIO54=1)
void SMG_Init(void);
void SMG_DisplayInt(Uint16 num);
void SMG_DisplayFloat(float num,unsigned char dotnum);
void SMG_DisplayChars(char* chars4);
void SMG_DisplayInt_MS(Uint16 num,int ms);
void SMG_DisplayFloat_MS(float num,unsigned char dotnum,int ms);
void SMG_DisplayChars_MS(char* chars4,int ms);
#endif /* SMG_H_ */
smg.c
/*
* smg.c
*
* Created on: 2018-1-25
* Author: Administrator
*/
#include "smg.h"
unsigned char smgduan[16]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07,
0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71};//0~F ???????????
void SMG_Init(void)
{
EALLOW;
SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;// ????GPIO???
//SMG?????????????
GpioCtrlRegs.GPBMUX2.bit.GPIO56=0;
GpioCtrlRegs.GPBDIR.bit.GPIO56=1;
GpioCtrlRegs.GPBPUD.bit.GPIO56=0;
GpioCtrlRegs.GPBMUX2.bit.GPIO54=0;
GpioCtrlRegs.GPBDIR.bit.GPIO54=1;
GpioCtrlRegs.GPBPUD.bit.GPIO54=0;
GpioCtrlRegs.GPCMUX1.bit.GPIO70=0;
GpioCtrlRegs.GPCDIR.bit.GPIO70=1;
GpioCtrlRegs.GPCPUD.bit.GPIO70=0;
GpioCtrlRegs.GPCMUX1.bit.GPIO71=0;
GpioCtrlRegs.GPCDIR.bit.GPIO71=1;
GpioCtrlRegs.GPCPUD.bit.GPIO71=0;
GpioCtrlRegs.GPCMUX1.bit.GPIO72=0;
GpioCtrlRegs.GPCDIR.bit.GPIO72=1;
GpioCtrlRegs.GPCPUD.bit.GPIO72=0;
GpioCtrlRegs.GPCMUX1.bit.GPIO73=0;
GpioCtrlRegs.GPCDIR.bit.GPIO73=1;
GpioCtrlRegs.GPCPUD.bit.GPIO73=0;
EDIS;
GpioDataRegs.GPCCLEAR.bit.GPIO70=1;
GpioDataRegs.GPCCLEAR.bit.GPIO71=1;
GpioDataRegs.GPCCLEAR.bit.GPIO72=1;
GpioDataRegs.GPCCLEAR.bit.GPIO73=1;
}
//74HC164??????????
//dat??????????????
void HC164SendData(unsigned char dat)
{
char i=0;
for(i=0;i<8;i++)
{
SPICLKA_SETL;
if(dat&0x80)
SPISIMOA_SETH;
else
SPISIMOA_SETL;
SPICLKA_SETH;
dat<<=1;
}
}
//????????????????
//num??????
void SMG_DisplayInt(Uint16 num)
{
unsigned char buf[4];
unsigned char i=0;
buf[0]=smgduan[num/1000];
buf[1]=smgduan[num%1000/100];
buf[2]=smgduan[num%1000%100/10];
buf[3]=smgduan[num%1000%100%10];
for(i=0;i<4;i++)
{
HC164SendData(buf[i]);
switch(i)
{
case 0: SEG1_SETH;SEG2_SETL;SEG3_SETL;SEG4_SETL;break;
case 1: SEG1_SETL;SEG2_SETH;SEG3_SETL;SEG4_SETL;break;
case 2: SEG1_SETL;SEG2_SETL;SEG3_SETH;SEG4_SETL;break;
case 3: SEG1_SETL;SEG2_SETL;SEG3_SETL;SEG4_SETH;break;
}
DELAY_US(5000);
}
}
//????????С??????
//num??С??
//dotnum??С?????????Чλ???????3??
void SMG_DisplayFloat(float num,unsigned char dotnum)
{
unsigned char buf[4];
unsigned char i;
Uint16 value=0;
if(dotnum==1)
{
value=num*10;
buf[0]=smgduan[value/1000];
buf[1]=smgduan[value%1000/100];
buf[2]=smgduan[value%1000%100/10]|0x80;
buf[3]=smgduan[value%1000%100%10];
}
else if(dotnum==2)
{
value=num*100;
buf[0]=smgduan[value/1000];
buf[1]=smgduan[value%1000/100]|0x80;
buf[2]=smgduan[value%1000%100/10];
buf[3]=smgduan[value%1000%100%10];
}
else if(dotnum==3)
{
value=num*1000;
buf[0]=smgduan[value/1000]|0x80;
buf[1]=smgduan[value%1000/100];
buf[2]=smgduan[value%1000%100/10];
buf[3]=smgduan[value%1000%100%10];
}
for(i=0;i<4;i++)
{
HC164SendData(buf[i]);
switch(i)
{
case 0: SEG1_SETH;SEG2_SETL;SEG3_SETL;SEG4_SETL;break;
case 1: SEG1_SETL;SEG2_SETH;SEG3_SETL;SEG4_SETL;break;
case 2: SEG1_SETL;SEG2_SETL;SEG3_SETH;SEG4_SETL;break;
case 3: SEG1_SETL;SEG2_SETL;SEG3_SETL;SEG4_SETH;break;
}
DELAY_US(5000);
}
}
// 共阴极0~9,A~Z(不区分大小写)
unsigned char smg_chars_table[]={ 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, // 0 1 2 3 4 5 6 7 8 9
0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x3D, 0x76, 0x8F, 0x0E, // A b c d E F G H I J
0x75, 0x38, 0xB7, 0x54, 0x5C, 0x73, 0x67, 0x31, 0xC9, 0x78, // K L M n o P q r S t
0x3E, 0x1C, 0xFE, 0xE4, 0x6E, 0xDA, 0x40, 0x48, 0x80, 0x00 // U v W X Y Z - = . Null
};
// 数码管显示0~9,A~Z字符
void SMG_DisplayChars(char* chars4){
// 最多显示4个字符
// if(strlen(chars4)>4 || strlen(chars4)<0) return;
int i;
for(i=0;i<4;i++){
// if(chars4[i] == '\0') break;// 空数据
// 判断是字母
if(chars4[i]>='A' && chars4[i]<='Z'){
HC164SendData(smg_chars_table[chars4[i]-'A'+10]);
}
// 判断是数字
else if(chars4[i]>='0' && chars4[i]<='9'){
HC164SendData(smg_chars_table[chars4[i]-'0']);
}
// 显示到对应位置
switch(i){
case 0: SEG1_SETH;SEG2_SETL;SEG3_SETL;SEG4_SETL;break;
case 1: SEG1_SETL;SEG2_SETH;SEG3_SETL;SEG4_SETL;break;
case 2: SEG1_SETL;SEG2_SETL;SEG3_SETH;SEG4_SETL;break;
case 3: SEG1_SETL;SEG2_SETL;SEG3_SETL;SEG4_SETH;break;
}
// 等待显示完全
DELAY_US(5000);
}// end for
}// end smgDisplayChars
// 延时秒(s)
void __delayMS(int ms){
Uint32 k;
for(k=0;k<ms;k++){
DELAY_US(1);
}
}
void SMG_DisplayInt_MS(Uint16 num,int ms){
int i;
for(i=0;i<100;i++){
// __delayMS(1);
SMG_DisplayInt(num);
i++;
}
}
void SMG_DisplayFloat_MS(float num,unsigned char dotnum,int ms){
int i=0;
while(i<100){
// __delayMS(1);
SMG_DisplayFloat(num,dotnum);
i++;
}
}
void SMG_DisplayChars_MS(char* chars4,int ms){
int i=0;
while(i<100){
// __delayMS(1);
SMG_DisplayChars(chars4);
i++;
}
}
key.h
/*
* key.h
*
* Created on: 2018-1-22
* Author: Administrator
*/
#ifndef KEY_H_
#define KEY_H_
#include "DSP2833x_Device.h" // DSP2833x 头文件
#include "DSP2833x_Examples.h" // DSP2833x 例子相关头文件
#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);
char KEY_Scan(char mode);
#endif /* KEY_H_ */
key.c
/*
* key.c
*
* Created on: 2018-1-22
* Author: Administrator
*/
#include "key.h"
void KEY_Init(void)
{
EALLOW;
SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;// 开启GPIO时钟
//KEY端口配置
GpioCtrlRegs.GPAMUX1.bit.GPIO12=0;
GpioCtrlRegs.GPADIR.bit.GPIO12=0;
GpioCtrlRegs.GPAPUD.bit.GPIO12=0;
GpioCtrlRegs.GPAMUX1.bit.GPIO13=0;
GpioCtrlRegs.GPADIR.bit.GPIO13=0;
GpioCtrlRegs.GPAPUD.bit.GPIO13=0;
GpioCtrlRegs.GPAMUX1.bit.GPIO14=0;
GpioCtrlRegs.GPADIR.bit.GPIO14=0;
GpioCtrlRegs.GPAPUD.bit.GPIO14=0;
GpioCtrlRegs.GPBMUX2.bit.GPIO48=0;
GpioCtrlRegs.GPBDIR.bit.GPIO48=1;
GpioCtrlRegs.GPBPUD.bit.GPIO48=0;
GpioCtrlRegs.GPBMUX2.bit.GPIO49=0;
GpioCtrlRegs.GPBDIR.bit.GPIO49=1;
GpioCtrlRegs.GPBPUD.bit.GPIO49=0;
GpioCtrlRegs.GPBMUX2.bit.GPIO50=0;
GpioCtrlRegs.GPBDIR.bit.GPIO50=1;
GpioCtrlRegs.GPBPUD.bit.GPIO50=0;
EDIS;
GpioDataRegs.GPBSET.bit.GPIO48=1;
GpioDataRegs.GPBSET.bit.GPIO49=1;
GpioDataRegs.GPBSET.bit.GPIO50=1;
}
char KEY_Scan(char mode)
{
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;
}
beep.h
/*
* beep.h
*
* Created on: 2018-1-20
* Author: Administrator
*/
#ifndef BEEP_H_
#define BEEP_H_
#include "DSP2833x_Device.h" // DSP2833x 头文件
#include "DSP2833x_Examples.h" // DSP2833x 例子相关头文件
#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 BEEP_Init(void);
#endif /* BEEP_H_ */
beep.c
/*
* beep.c
*
* Created on: 2018-1-20
* Author: Administrator
*/
#include "beep.h"
/*******************************************************************************
* 函 数 名 : BEEP_Init
* 函数功能 : 蜂鸣器初始化
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void BEEP_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;
EDIS;
GpioDataRegs.GPACLEAR.bit.GPIO6=1;
}
time.h
/*
* time.h
*
* Created on: 2018-1-24
* Author: Administrator
*/
#ifndef TIME_H_
#define TIME_H_
#include "DSP2833x_Device.h" // DSP2833x 头文件
#include "DSP2833x_Examples.h" // DSP2833x 例子相关头文件
void TIM0_Init(float Freq, float Period);
interrupt void TIM0_IRQn(void);
void TIM1_Init(float Freq, float Period);
interrupt void TIM1_IRQn(void);
void TIM2_Init(float Freq, float Period);
interrupt void TIM2_IRQn(void);
#endif /* TIME_H_ */
time.c
/*
* time.c
*
* Created on: 2018-1-24
* Author: Administrator
*/
#include "time.h"
#include "leds.h"
void TIM0_Init(float Freq, float Period)
{
EALLOW;
SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; // CPU Timer 0
EDIS;
EALLOW;
PieVectTable.TINT0 = &TIM0_IRQn;
EDIS;
// CPU Timer 0
// Initialize address pointers to respective timer registers:
CpuTimer0.RegsAddr = &CpuTimer0Regs;
// Initialize timer period to maximum:
CpuTimer0Regs.PRD.all = 0xFFFFFFFF;
// Initialize pre-scale counter to divide by 1 (SYSCLKOUT):
CpuTimer0Regs.TPR.all = 0;
CpuTimer0Regs.TPRH.all = 0;
// Make sure timer is stopped:
CpuTimer0Regs.TCR.bit.TSS = 1;
// Reload all counter register with period value:
CpuTimer0Regs.TCR.bit.TRB = 1;
// Reset interrupt counters:
CpuTimer0.InterruptCount = 0;
ConfigCpuTimer(&CpuTimer0, Freq, Period);
CpuTimer0Regs.TCR.bit.TSS=0;
IER |= M_INT1;
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
EINT;
ERTM;
}
interrupt void TIM0_IRQn(void)
{
EALLOW;
LED1_TOGGLE;
PieCtrlRegs.PIEACK.bit.ACK1=1;
EDIS;
}
void TIM1_Init(float Freq, float Period)
{
EALLOW;
SysCtrlRegs.PCLKCR3.bit.CPUTIMER1ENCLK = 1; // CPU Timer 1
EDIS;
EALLOW;
PieVectTable.XINT13 = &TIM1_IRQn;
EDIS;
// Initialize address pointers to respective timer registers:
CpuTimer1.RegsAddr = &CpuTimer1Regs;
// Initialize timer period to maximum:
CpuTimer1Regs.PRD.all = 0xFFFFFFFF;
// Initialize pre-scale counter to divide by 1 (SYSCLKOUT):
CpuTimer1Regs.TPR.all = 0;
CpuTimer1Regs.TPRH.all = 0;
// Make sure timers are stopped:
CpuTimer1Regs.TCR.bit.TSS = 1;
// Reload all counter register with period value:
CpuTimer1Regs.TCR.bit.TRB = 1;
// Reset interrupt counters:
CpuTimer1.InterruptCount = 0;
ConfigCpuTimer(&CpuTimer1, Freq, Period);
CpuTimer1Regs.TCR.bit.TSS=0;
IER |= M_INT13;
EINT;
ERTM;
}
interrupt void TIM1_IRQn(void)
{
EALLOW;
LED3_TOGGLE;
EDIS;
}
void TIM2_Init(float Freq, float Period)
{
EALLOW;
SysCtrlRegs.PCLKCR3.bit.CPUTIMER2ENCLK = 1; // CPU Timer 2
EDIS;
EALLOW;
PieVectTable.TINT2 = &TIM2_IRQn;
EDIS;
// Initialize address pointers to respective timer registers:
CpuTimer2.RegsAddr = &CpuTimer2Regs;
// Initialize timer period to maximum:
CpuTimer2Regs.PRD.all = 0xFFFFFFFF;
// Initialize pre-scale counter to divide by 1 (SYSCLKOUT):
CpuTimer2Regs.TPR.all = 0;
CpuTimer2Regs.TPRH.all = 0;
// Make sure timers are stopped:
CpuTimer2Regs.TCR.bit.TSS = 1;
// Reload all counter register with period value:
CpuTimer2Regs.TCR.bit.TRB = 1;
// Reset interrupt counters:
CpuTimer2.InterruptCount = 0;
ConfigCpuTimer(&CpuTimer2, Freq, Period);
CpuTimer2Regs.TCR.bit.TSS=0;
IER |= M_INT14;
EINT;
ERTM;
}
interrupt void TIM2_IRQn(void)
{
EALLOW;
LED4_TOGGLE;
EDIS;
}
效果
显示字母 |
---|
系统运行 |
---|