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;

}

效果

显示字母
系统运行
posted @ 2024-03-09 19:11  qsBye  阅读(35)  评论(0编辑  收藏  举报