TM4C123GH6PM 芯片综合实验:GPIO、ADC 采样和定时器中断
以 TM4C123GH6PM 芯片为例的综合实验
实验目的
- 熟悉 TM4C123GH6PM 芯片的 GPIO、ADC 采样、定时器中断功能;2. 掌握使用 Keil 软件进行编程的方法;3. 实现一个综合性实验,包括 GPIO 控制 LED 灯亮灭、ADC 采样与显示、定时器中断控制蜂鸣器发声。
实验材料
- 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 灯亮灭;定时器中断周期性触发,可以听到蜂鸣器发出的声音
原文地址: https://www.cveoy.top/t/topic/oDD6 著作权归作者所有。请勿转载和采集!