以 TM4C123GH6PM 芯片为例的综合实验

实验目的

  1. 熟悉 TM4C123GH6PM 芯片的 GPIO、ADC 采样、定时器中断功能;2. 掌握使用 Keil 软件进行编程的方法;3. 实现一个综合性实验,包括 GPIO 控制 LED 灯亮灭、ADC 采样与显示、定时器中断控制蜂鸣器发声。

实验材料

  1. TM4C123GH6PM 开发板;2. USB 数据线;3. 杜邦线;4. LED 灯;5. 10K 电位器;6. 蜂鸣器。

实验原理

1. GPIO 控制 LED 灯亮灭

TM4C123GH6PM 芯片有三个 GPIO 端口,分别为 PortA、PortB 和 PortF。其中 PortF 可以控制板载 LED 灯的亮灭,具体原理是通过控制 PF1 引脚输出高电平或低电平来控制 LED 灯的亮灭。

2. ADC 采样与显示

TM4C123GH6PM 芯片有一个 12 位 ADC 模块,可以进行模拟信号的采样并转换为数字信号。在本实验中,我们将通过 ADC 模块采样一个 10K 电位器所接的模拟信号,并将采样结果通过串口发送到 PC 端,最终在 PC 端上实时显示。

3. 定时器中断控制蜂鸣器发声

TM4C123GH6PM 芯片有多个定时器模块,可以通过设置定时器的计数周期和中断时间来实现定时中断功能。在本实验中,我们将通过定时器模块控制蜂鸣器发声,具体原理是在定时器中断服务函数中控制 PB5 引脚输出高电平或低电平。

实验步骤

1. 硬件连接

将 10K 电位器的三个引脚分别连接到开发板的 VCC、GND 和 PE3 引脚上;将 LED 灯的正极连接到 PF1 引脚,负极连接到 GND 上;将蜂鸣器的正极连接到 PB5 引脚,负极连接到 GND 上。

2. 编写程序

2.1 初始化模块

首先,需要初始化 GPIO、ADC 和定时器模块,并设置相应的引脚方向、中断时间等参数。具体代码如下:c#include 'tm4c123gh6pm.h'

void GPIO_Init(void){ SYSCTL_RCGCGPIO_R |= 0x20; // 使能 PortF 时钟 while((SYSCTL_PRGPIO_R & 0x20) == 0); // 等待 PortF 时钟稳定

GPIO_PORTF_LOCK_R = 0x4C4F434B;  // 解锁 PortF 引脚    GPIO_PORTF_CR_R |= 0x02;         // 使能 PF1 引脚控制

GPIO_PORTF_DIR_R |= 0x02;        // PF1 引脚输出方向    GPIO_PORTF_DEN_R |= 0x02;        // PF1 引脚数字功能使能}

void ADC_Init(void){ SYSCTL_RCGCADC_R |= 0x01; // 使能 ADC0 时钟 SYSCTL_RCGCGPIO_R |= 0x10; // 使能 PortE 时钟 while((SYSCTL_PRGPIO_R & 0x10) == 0); // 等待 PortE 时钟稳定

GPIO_PORTE_AFSEL_R |= 0x08;      // PE3 引脚选择 ADC 模式    GPIO_PORTE_DEN_R &= ~0x08;       // PE3 引脚数字功能禁用    GPIO_PORTE_AMSEL_R |= 0x08;      // PE3 引脚模拟功能使能

ADC0_ACTSS_R &= ~0x0008;         // 禁用 ADC0 的第 3 个采样序列    ADC0_EMUX_R &= ~0xF000;          // 定时器触发模式    ADC0_SSMUX3_R = 0x00;            // 采样通道为 AIN0    ADC0_SSCTL3_R |= 0x06;           // 启用内部参考电压和采样结束后自动断开转换    ADC0_IM_R |= 0x08;               // 使能 ADC0 的第 3 个采样序列中断    NVIC_EN0_R |= 0x00000018;        // 使能 ADC0 中断

ADC0_ACTSS_R |= 0x0008;          // 启用 ADC0 的第 3 个采样序列}

void Timer_Init(void){ SYSCTL_RCGCTIMER_R |= 0x01; // 使能 Timer0 时钟 while((SYSCTL_PRTIMER_R & 0x01) == 0); // 等待 Timer0 时钟稳定

TIMER0_CTL_R &= ~0x01;           // 禁用 Timer0    TIMER0_CFG_R = 0x00;             // 32 位定时器模式    TIMER0_TAMR_R = 0x02;            // 周期模式    TIMER0_TAPR_R = 0xFF;            // 分频系数    TIMER0_TAILR_R = 0x4C4B400;      // 计数周期    TIMER0_IMR_R |= 0x01;            // 使能 Timer0 中断    NVIC_EN0_R |= 0x00080000;        // 使能 Timer0 中断

TIMER0_CTL_R |= 0x01;            // 启用 Timer0}

2.2 编写中断服务函数

然后,需要编写 GPIO、ADC 和定时器的中断服务函数,具体代码如下:cvoid PortF_Handler(void){ GPIO_PORTF_ICR_R |= 0x02; // 清除 PF1 引脚中断标志 GPIO_PORTF_DATA_R ^= 0x02; // LED 灯亮灭翻转}

void ADC0Seq3_Handler(void){ ADC0_ISC_R = 0x08; // 清除 ADC0 第 3 个采样序列中断标志 uint32_t adc_value = ADC0_SSFIFO3_R & 0xFFF; // 读取 ADC 采样结果 UART0_OutUDec(adc_value); // 通过串口发送 ADC 采样结果 UART0_OutChar(' '); UART0_OutChar(' ');}

void Timer0_Handler(void){ TIMER0_ICR_R |= 0x01; // 清除 Timer0 中断标志 GPIO_PORTB_DATA_R ^= 0x20; // PB5 引脚输出高低电平翻转,控制蜂鸣器发声}

2.3 初始化 UART 模块并启用全局中断

最后,需要在主函数中初始化 UART 模块,并启用全局中断,具体代码如下:cvoid UART0_Init(void){ SYSCTL_RCGCUART_R |= 0x01; // 使能 UART0 时钟 SYSCTL_RCGCGPIO_R |= 0x01; // 使能 PortA 时钟 while((SYSCTL_PRGPIO_R & 0x01) == 0); // 等待 PortA 时钟稳定

UART0_CTL_R &= ~0x01;            // 禁用 UART0    UART0_IBRD_R = 104;              // 波特率为 9600    UART0_FBRD_R = 11;    UART0_LCRH_R = 0x70;             // 数据位 8 位,无校验位,1 个停止位    UART0_CC_R = 0x00;               // 选择系统时钟    UART0_CTL_R |= 0x301;            // 启用 UART0、接收和发送功能}

int main(void){ GPIO_Init(); ADC_Init(); Timer_Init(); UART0_Init();

__enable_irq();                 // 启用全局中断

while(1);}

3. 烧录程序

将编写好的程序烧录到 TM4C123GH6PM 开发板中。

4. 实验效果

将 10K 电位器旋转,可以看到 ADC 采样结果在串口上实时变化;按下开发板上的 SW1 键,可以控制 LED 灯亮灭;定时器中断周期性触发,可以听到蜂鸣器发出的声音

TM4C123GH6PM 芯片综合实验:GPIO、ADC 采样和定时器中断

原文地址: https://www.cveoy.top/t/topic/oDD6 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录