TM4C123GXL:GPIO、中断、定时器,LED,串口

嵌入式导论综合实验设计——嵌入式期末报告 TM4C123GXL Final Project
实验题目

【TM4C123GXL:GPIO、中断、定时器,LED,串口】综合实验设计
实验目的和要求
进一步掌握本学期以来所做实验用到的各种元器件的使用方法和编程;
加深GPIO、中断、定时器、LED等的使用;
加强综合问题解决能力和拓展思维创新能力。
设计思路 使用嵌入式导论实验课所学的知识进行期末综合实验的设计。
使用串口使开发板与主机通信。从主机输入颜色字符串 RED、BLUE、GREE、YELLOW、LBLUE、PURPLE、WHITE
开发板接收通信数据后,LED相应的显示指示的颜色。通过对按钮不同的操作,通过选择不同的时钟频率,改变LED灯闪动的频率。
实现功能
  1. 串口通信
  2. 使用外部触发中断产生按钮状态改变响应
  3. 使用查询方式检查按钮状态
  4. 设置灯的多种变换模式、变化速度
使用工具
  1. Keil version5
  2. Serial Port Utility串口调试助手
  3. TM4C123GXL开发板
程序流程图 TM4C123GXL:GPIO、中断、定时器,LED,串口
文章图片
流程图.png 实际运行 TM4C123GXL:GPIO、中断、定时器,LED,串口
文章图片
串口初始化界面.png blue.png shinning.png green.png purple.png 设计分析体会
实验体会:
本次期末综合性实验,把前面所学的实验知识做了合并,灵活运用所学知识,实现 串口通信、使用外部触发中断产生按钮状态改变响应、使用查询方式检查按钮状态、设置灯的多种变换模式、变化速度等功能。对开发软件keil的debug功能掌握了很多操作,使得做实验效率更高。
重要模块1:定义颜色
#define RED0x02 #define BLUE0x04 #define GREEN0x08 #define YELLOW0x0A #define LBLUE0x0C #define PURPLE0x06 #define WHITE0x0E #define DARK0x00 #define WHEELSIZE 2//轮转大小//定义轮转颜色数组 const long COLORWHEEL1[WHEELSIZE] = {RED, 0}; const long COLORWHEEL2[WHEELSIZE] = {BLUE, 0}; const long COLORWHEEL3[WHEELSIZE] = {GREEN, 0}; const long COLORWHEEL4[WHEELSIZE] = {YELLOW, 0}; const long COLORWHEEL5[WHEELSIZE] = {LBLUE, 0}; const long COLORWHEEL6[WHEELSIZE] = {PURPLE, 0}; const long COLORWHEEL7[WHEELSIZE] = {WHITE, 0};

重要模块2:定义回调函数,响应串口动作
//定义回调函数 //根据串口的输入的不同,选择颜色进行闪烁 void UserTask(void){ static int i = 0; if(choose==1) { LEDS = COLORWHEEL1[i]; } else if(choose==2) { LEDS = COLORWHEEL2[i]; } else if(choose==3) { LEDS = COLORWHEEL3[i]; } else if(choose==4) { LEDS = COLORWHEEL4[i]; } else if(choose==5) { LEDS = COLORWHEEL5[i]; } else if(choose==6) { LEDS = COLORWHEEL6[i]; } else if(choose==7) { LEDS = COLORWHEEL7[i]; }i = i + 1; if(i==2) { i=0; } }

重要模块3:定义改变LED闪烁频率函数,通过时钟频率的不同,改变LED闪烁的快慢
//定义调用UserTask回调函数的频率 #define F20KHZ (50000000/20000) #define F16HZ(50000000/16) #define F8HZ(50000000/8) #define F4HZ(50000000/4) #define F2HZ(50000000/2) #define F1HZ(50000000)//设置LED等闪烁的频率 void set_LED_rate(uint32_t rate){ switch(rate){ case 1: Timer0A_Init(&UserTask, F1HZ); break; case 2: Timer0A_Init(&UserTask, F2HZ); break; case 3: Timer0A_Init(&UserTask, F4HZ); break; case 4: Timer0A_Init(&UserTask, F8HZ); break; case 5: Timer0A_Init(&UserTask, F16HZ); break; } }

重要模块4:设计PortF外部中断动作
//使用外部中断 ,按钮SW1按下即触发 //调用设置led频率的函数,使闪烁频率变快 void GPIOPortF_Handler(void){ //sw1 pressGPIO_PORTF_ICR_R = 0x10; // acknowledge flag0FallingEdges = 5; set_LED_rate(FallingEdges); }

重要模块5:设计按钮在查询模式下的动作
//使用查询模式 //通过循环不断的判断按钮的状态,两个按钮之一被按下、同时被按下、都不被按下 while(1){WaitForInterrupt(); status = PortF_Input(); if(status == 0x10) //sw2 press { SW2_Handler(); } else if(status == 0x00) //both sw press { Both_Handler(); } else if(status == 0x11) //neither sw press { PortF_Output(Data); } }//SW2被按下 调用设置led频率的函数,使闪烁频率变慢 void SW2_Handler(void){FallingEdges = 1; set_LED_rate(FallingEdges); }//SW1 和 SW2 同时被按下 调用设置led频率的函数,使闪烁频率变得适中 void Both_Handler(void){FallingEdges = 3; set_LED_rate(FallingEdges); }

重要模块6:设计串口通信,达到开发板对于不同输入信息的不同响应
//输出提示语 UART_OutString(">please input a color for LED: "); //输入颜色,如“red”,“white”等 UART_InString(string,19); UART_OutString("'\n>input color is ="); UART_OutString(string); OutCRLF(); //判断输入的颜色,并设置灯的颜色 if(!strcmp(string,"red")) { choose=1; Data=https://www.it610.com/article/RED; } else if(!strcmp(string,"blue")) { choose=2; Data=https://www.it610.com/article/BLUE; } else if(!strcmp(string,"green")) { choose=3; Data=https://www.it610.com/article/GREEN; } else if(!strcmp(string,"yellow")) { choose=4; Data=https://www.it610.com/article/YELLOW; } else if(!strcmp(string,"lightblue")) { choose=5; Data=https://www.it610.com/article/LBLUE; } else if(!strcmp(string,"purple")) { choose=6; Data=https://www.it610.com/article/PURPLE; } else if(!strcmp(string,"white")) { choose=7; Data=https://www.it610.com/article/WHITE; }

实验代码 主函数代码
// PeriodicTimer0AInts.c // Runs on LM4F120/TM4C123 // Use Timer0A in periodic mode to request interrupts at a particular // period. // Daniel Valvano // September 11, 2013/* This example accompanies the book "Embedded Systems: Real Time Interfacing to Arm Cortex M Microcontrollers", ISBN: 978-1463590154, Jonathan Valvano, copyright (c) 2014 Program 7.5, example 7.6 Copyright 2014 by Jonathan W. Valvano, valvano@mail.utexas.edu You may use, edit, run or distribute this file as long as the above copyright notice remains THIS SOFTWARE IS PROVIDED "AS IS".NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. VALVANO SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. For more information about my classes, my research, and my books, see http://users.ece.utexas.edu/~valvano/ */// oscilloscope or LED connected to PF3-1 for period measurement // When using the color wheel, the blue LED on PF2 is on for four // consecutive interrupts then off for four consecutive interrupts. // Blue is off for: dark, red, yellow, green // Blue is on for: light blue, blue, purple, white // Therefore, the frequency of the pulse measured on PF2 is 1/8 of // the frequency of the Timer0A interrupts.#include "inc/tm4c123gh6pm.h" #include #include "PLL.h" #include "Timer0A.h" #include "UART.h"#define PF1(*((volatile uint32_t *)0x40025008)) #define PF2(*((volatile uint32_t *)0x40025010)) #define PF3(*((volatile uint32_t *)0x40025020)) #define LEDS(*((volatile uint32_t *)0x40025038)) #define RED0x02 #define BLUE0x04 #define GREEN0x08 #define YELLOW0x0A #define LBLUE0x0C #define PURPLE0x06 #define WHITE0x0E #define DARK0x00 #define WHEELSIZE 2// must be an integer multiple of 2 //red, yellow,green, light blue, blue, purple,white,dark //const long COLORWHEEL[WHEELSIZE] = {RED, RED+GREEN, GREEN, GREEN+BLUE, BLUE, BLUE+RED, RED+GREEN+BLUE, 0}; const long COLORWHEEL1[WHEELSIZE] = {RED, 0}; const long COLORWHEEL2[WHEELSIZE] = {BLUE, 0}; const long COLORWHEEL3[WHEELSIZE] = {GREEN, 0}; const long COLORWHEEL4[WHEELSIZE] = {YELLOW, 0}; const long COLORWHEEL5[WHEELSIZE] = {LBLUE, 0}; const long COLORWHEEL6[WHEELSIZE] = {PURPLE, 0}; const long COLORWHEEL7[WHEELSIZE] = {WHITE, 0}; void DisableInterrupts(void); // Disable interrupts void EnableInterrupts(void); // Enable interrupts long StartCritical (void); // previous I bit, disable interrupts void EndCritical(long sr); // restore I bit to previous value void WaitForInterrupt(void); // low power modestatic int choose=1; void UserTask(void){ static int i = 0; if(choose==1) { LEDS = COLORWHEEL1[i]; } else if(choose==2) { LEDS = COLORWHEEL2[i]; } else if(choose==3) { LEDS = COLORWHEEL3[i]; } else if(choose==4) { LEDS = COLORWHEEL4[i]; } else if(choose==5) { LEDS = COLORWHEEL5[i]; } else if(choose==6) { LEDS = COLORWHEEL6[i]; } else if(choose==7) { LEDS = COLORWHEEL7[i]; }i = i + 1; if(i==2) { i=0; } }// if desired interrupt frequency is f, Timer0A_Init parameter is busfrequency/fvoid OutCRLF(void){ UART_OutChar(CR); UART_OutChar(LF); }#define F20KHZ (50000000/20000) #define F16HZ(50000000/16) #define F8HZ(50000000/8) #define F4HZ(50000000/4) #define F2HZ(50000000/2) #define F1HZ(50000000)/***********************/ #define GPIO_LOCK_KEY0x4C4F434B// Unlocks the GPIO_CR register #define PF0(*((volatile uint32_t *)0x40025004)) #define PF4(*((volatile uint32_t *)0x40025040)) #define SWITCHES(*((volatile uint32_t *)0x40025044)) #define SW10x10// on the left side of the Launchpad board #define SW20x01// on the right side of the Launchpad board #define SYSCTL_RCGC2_GPIOF0x00000020// port F Clock Gating Control /***********************//********Edge Counter********/ volatile uint32_t FallingEdges = 3; void EdgeCounter_Init(void){SYSCTL_RCGCGPIO_R |= 0x00000020; // (a) activate clock for port F FallingEdges = 3; // (b) initialize counter GPIO_PORTF_DIR_R &= ~0x10; // (c) make PF4 in (built-in button) GPIO_PORTF_AFSEL_R &= ~0x10; //disable alt funct on PF4 GPIO_PORTF_DEN_R |= 0x10; //enable digital I/O on PF4 GPIO_PORTF_PCTL_R &= ~0x000F0000; // configure PF4 as GPIO GPIO_PORTF_AMSEL_R = 0; //disable analog functionality on PF GPIO_PORTF_PUR_R |= 0x10; //enable weak pull-up on PF4 GPIO_PORTF_IS_R &= ~0x10; // (d) PF4 is edge-sensitive GPIO_PORTF_IBE_R &= ~0x10; //PF4 is not both edges GPIO_PORTF_IEV_R &= ~0x10; //PF4 falling edge event GPIO_PORTF_ICR_R = 0x10; // (e) clear flag4 GPIO_PORTF_IM_R |= 0x10; // (f) arm interrupt on PF4 *** No IME bit as mentioned in Book *** NVIC_PRI7_R = (NVIC_PRI7_R&0xFF00FFFF)|0x00A00000; // (g) priority 5 NVIC_EN0_R = 0x40000000; // (h) enable interrupt 30 in NVIC EnableInterrupts(); // (i) Clears the I bit } void set_LED_rate(uint32_t rate){ switch(rate){ case 1: Timer0A_Init(&UserTask, F1HZ); break; case 2: Timer0A_Init(&UserTask, F2HZ); break; case 3: Timer0A_Init(&UserTask, F4HZ); break; case 4: Timer0A_Init(&UserTask, F8HZ); break; case 5: Timer0A_Init(&UserTask, F16HZ); break; } }void GPIOPortF_Handler(void){ //sw1 pressGPIO_PORTF_ICR_R = 0x10; // acknowledge flag0FallingEdges = 5; set_LED_rate(FallingEdges); }void PortF_Init(void){ volatile uint32_t delay; SYSCTL_RCGCGPIO_R |= 0x00000020; // 1) activate clock for Port F while((SYSCTL_PRGPIO_R&0x0020) == 0){}; GPIO_PORTF_LOCK_R = 0x4C4F434B; // 2) unlock GPIO Port F GPIO_PORTF_CR_R = 0x1F; // allow changes to PF4-0 // only PF0 needs to be unlocked, other bits can't be locked GPIO_PORTF_AMSEL_R = 0x00; // 3) disable analog on PF GPIO_PORTF_PCTL_R = 0x00000000; // 4) PCTL GPIO on PF4-0 GPIO_PORTF_DIR_R = 0x0E; // 5) PF4,PF0 in, PF3-1 out GPIO_PORTF_AFSEL_R = 0x00; // 6) disable alt funct on PF7-0 GPIO_PORTF_PUR_R = 0x11; // enable pull-up on PF0 and PF4 GPIO_PORTF_DEN_R = 0x1F; // 7) enable digital I/O on PF4-0 }uint32_t PortF_Input(void){ return (GPIO_PORTF_DATA_R&0x11); // read PF4,PF0 inputs }void PortF_Output(uint32_t data){ // write PF3-PF1 outputs GPIO_PORTF_DATA_R = data; }void SW2_Handler(void){FallingEdges = 1; set_LED_rate(FallingEdges); }void Both_Handler(void){FallingEdges = 3; set_LED_rate(FallingEdges); }/********End Edge Counter***********/int strcmp(const char *str1,const char *str2) { while(*str1 == *str2) { if(*str1 == '\0') return 0; str1++; str2++; } return *str1 - *str2; }//debug code int main(void){PLL_Init(); // bus clock at 50 MHzchar ch; char string[20]; // global to assist in debugging uint32_t n; uint32_t Data; UART_Init(); // initialize UARTUART_OutString(">please input a color for LED: "); UART_InString(string,19); UART_OutString("'\n>input color is ="); UART_OutString(string); OutCRLF(); if(!strcmp(string,"red")) { choose=1; Data=https://www.it610.com/article/RED; } else if(!strcmp(string,"blue")) { choose=2; Data=https://www.it610.com/article/BLUE; } else if(!strcmp(string,"green")) { choose=3; Data=https://www.it610.com/article/GREEN; } else if(!strcmp(string,"yellow")) { choose=4; Data=https://www.it610.com/article/YELLOW; } else if(!strcmp(string,"lightblue")) { choose=5; Data=https://www.it610.com/article/LBLUE; } else if(!strcmp(string,"purple")) { choose=6; Data=https://www.it610.com/article/PURPLE; } else if(!strcmp(string,"white")) { choose=7; Data=https://www.it610.com/article/WHITE; }uint32_t status; PortF_Init(); LEDS = 0; // turn all LEDs offTimer0A_Init(&UserTask, F1HZ); EnableInterrupts(); EdgeCounter_Init(); while(1){WaitForInterrupt(); status = PortF_Input(); if(status == 0x10) //sw2 press { SW2_Handler(); } else if(status == 0x00) //both sw press { Both_Handler(); } else if(status == 0x11) //neither sw press { PortF_Output(Data); } } }

    推荐阅读