6. UART
include "TM4C123.h" // Device header
// configure the system to get its clock from the PLL
#define SYSCTL_RIS_R (*((volatile unsigned long *)0x400FE050))
#define SYSCTL_RCC_R (*((volatile unsigned long *)0x400FE060))
#define SYSCTL_RCC2_R (*((volatile unsigned long *)0x400FE070))
// Define UART registers
#define GPIO_PORTA_AFSEL_R (*((volatile unsigned long *)0x40004420))
#define GPIO_PORTA_DEN_R (*((volatile unsigned long *)0x4000451C))
#define GPIO_PORTA_AMSEL_R (*((volatile unsigned long *)0x40004528))
#define GPIO_PORTA_PCTL_R (*((volatile unsigned long *)0x4000452C))
#define UART0_DR_R (*((volatile unsigned long *)0x4000C000))
#define UART0_FR_R (*((volatile unsigned long *)0x4000C018))
#define UART0_IBRD_R (*((volatile unsigned long *)0x4000C024))
#define UART0_FBRD_R (*((volatile unsigned long *)0x4000C028))
#define UART0_LCRH_R (*((volatile unsigned long *)0x4000C02C))
#define UART0_CTL_R (*((volatile unsigned long *)0x4000C030))
#define UART_FR_TXFF 0x00000020 // UART Transmit FIFO Full
#define UART_FR_RXFE 0x00000010 // UART Receive FIFO Empty
#define SYSCTL_RCGC1_R (*((volatile unsigned long *)0x400FE104))
#define SYSCTL_RCGC2_R (*((volatile unsigned long *)0x400FE108))
void PLL_Init(void);
void UART_Init(void);
void UART_Char_Output(unsigned char data);
unsigned char UART_Char_Input(void);
void UART_Write_String(char *p);
__asm void
Delay(unsigned long n)
{
SUBS R0, #1
BNE Delay
bx LR ;//the link register is providing the address to branch to.
}
int main(void){
PLL_Init();
UART_Init();
UART_Char_Output('a');
UART_Char_Output('\n');
UART_Char_Output('\r');
//Delay(13333333); // delay ~0.5 sec at 80 MHz
while(1){
while(UART_Char_Input()!='b');
UART_Write_String("you pressed the character b");
UART_Char_Output('\n');
UART_Char_Output('\r');
}
}
void PLL_Init(void){
// 0) Use RCC2
SYSCTL_RCC2_R |= 0x80000000; // USERCC2
// 1) bypass PLL while initializing
SYSCTL_RCC2_R |= 0x00000800; // BYPASS2, PLL bypass
// 2) select the crystal value and oscillator source
SYSCTL_RCC_R = (SYSCTL_RCC_R &~0x000007C0) // clear XTAL field, bits 10-6
+ 0x00000540; // 10101, configure for 16 MHz crystal
SYSCTL_RCC2_R &= ~0x00000070; // configure for main oscillator source 10001111
// 3) activate PLL by clearing PWRDN
SYSCTL_RCC2_R &= ~0x00002000;
// 4) set the desired system divider
SYSCTL_RCC2_R |= 0x40000000; // use 400 MHz PLL, DIV400
SYSCTL_RCC2_R = (SYSCTL_RCC2_R&~ 0x1FC00000) // clear system clock divider
+ (4<<22); // configure for 80 MHz clock, 400/(4+1) = 80MHz
// 5) wait for the PLL to lock by polling PLLLRIS
while((SYSCTL_RIS_R&0x00000040)==0){}; // wait for PLLRIS bit
// 6) enable use of PLL by clearing BYPASS
SYSCTL_RCC2_R &= ~0x00000800;
}
void UART_Init(void){
SYSCTL_RCGC1_R |= 0x01; // activate UART0
SYSCTL_RCGC2_R |= 0x01; // activate port A
UART0_CTL_R &= ~0x01; // disable UART
UART0_IBRD_R = 43; // IBRD = int(80,000,000 / (16 * 115,200)) = int(43.40278)
UART0_FBRD_R = 26; // FBRD = round(0.40278 * 64 + 0.5) = 26
// 8 bit word length (no parity bits, one stop bit, FIFOs)
UART0_LCRH_R = 0x70;// 0x01110000
//UART0_CTL_R |= UART_CTL_UARTEN; // enable UART, 0x00000001 // UART Enable
UART0_CTL_R |= 0x01; // enable UART, 0x00000001 // UART Enable
GPIO_PORTA_AFSEL_R |= 0x03; // enable alt funct on PA1-0
GPIO_PORTA_DEN_R |= 0x03; // enable digital I/O on PA1-0
// configure PA1-0 as UART
GPIO_PORTA_PCTL_R = (GPIO_PORTA_PCTL_R & 0xFFFFFF00)+0x00000011;
GPIO_PORTA_AMSEL_R &= ~0x03; // disable analog functionality on PA
}
void UART_Char_Output(unsigned char data){
while((UART0_FR_R & UART_FR_TXFF) != 0);
UART0_DR_R = data;
}
unsigned char UART_Char_Input(void){
while((UART0_FR_R & UART_FR_RXFE) != 0);
return((unsigned char)(UART0_DR_R & 0xFF));
}
void UART_Write_String(char *p){
while(*p){
UART_Char_Output(*p);
p++;
}
}
// configure the system to get its clock from the PLL
#define SYSCTL_RIS_R (*((volatile unsigned long *)0x400FE050))
#define SYSCTL_RCC_R (*((volatile unsigned long *)0x400FE060))
#define SYSCTL_RCC2_R (*((volatile unsigned long *)0x400FE070))
// Define UART registers
#define GPIO_PORTA_AFSEL_R (*((volatile unsigned long *)0x40004420))
#define GPIO_PORTA_DEN_R (*((volatile unsigned long *)0x4000451C))
#define GPIO_PORTA_AMSEL_R (*((volatile unsigned long *)0x40004528))
#define GPIO_PORTA_PCTL_R (*((volatile unsigned long *)0x4000452C))
#define UART0_DR_R (*((volatile unsigned long *)0x4000C000))
#define UART0_FR_R (*((volatile unsigned long *)0x4000C018))
#define UART0_IBRD_R (*((volatile unsigned long *)0x4000C024))
#define UART0_FBRD_R (*((volatile unsigned long *)0x4000C028))
#define UART0_LCRH_R (*((volatile unsigned long *)0x4000C02C))
#define UART0_CTL_R (*((volatile unsigned long *)0x4000C030))
#define UART_FR_TXFF 0x00000020 // UART Transmit FIFO Full
#define UART_FR_RXFE 0x00000010 // UART Receive FIFO Empty
#define SYSCTL_RCGC1_R (*((volatile unsigned long *)0x400FE104))
#define SYSCTL_RCGC2_R (*((volatile unsigned long *)0x400FE108))
void PLL_Init(void);
void UART_Init(void);
void UART_Char_Output(unsigned char data);
unsigned char UART_Char_Input(void);
void UART_Write_String(char *p);
__asm void
Delay(unsigned long n)
{
SUBS R0, #1
BNE Delay
bx LR ;//the link register is providing the address to branch to.
}
int main(void){
PLL_Init();
UART_Init();
UART_Char_Output('a');
UART_Char_Output('\n');
UART_Char_Output('\r');
//Delay(13333333); // delay ~0.5 sec at 80 MHz
while(1){
while(UART_Char_Input()!='b');
UART_Write_String("you pressed the character b");
UART_Char_Output('\n');
UART_Char_Output('\r');
}
}
void PLL_Init(void){
// 0) Use RCC2
SYSCTL_RCC2_R |= 0x80000000; // USERCC2
// 1) bypass PLL while initializing
SYSCTL_RCC2_R |= 0x00000800; // BYPASS2, PLL bypass
// 2) select the crystal value and oscillator source
SYSCTL_RCC_R = (SYSCTL_RCC_R &~0x000007C0) // clear XTAL field, bits 10-6
+ 0x00000540; // 10101, configure for 16 MHz crystal
SYSCTL_RCC2_R &= ~0x00000070; // configure for main oscillator source 10001111
// 3) activate PLL by clearing PWRDN
SYSCTL_RCC2_R &= ~0x00002000;
// 4) set the desired system divider
SYSCTL_RCC2_R |= 0x40000000; // use 400 MHz PLL, DIV400
SYSCTL_RCC2_R = (SYSCTL_RCC2_R&~ 0x1FC00000) // clear system clock divider
+ (4<<22); // configure for 80 MHz clock, 400/(4+1) = 80MHz
// 5) wait for the PLL to lock by polling PLLLRIS
while((SYSCTL_RIS_R&0x00000040)==0){}; // wait for PLLRIS bit
// 6) enable use of PLL by clearing BYPASS
SYSCTL_RCC2_R &= ~0x00000800;
}
void UART_Init(void){
SYSCTL_RCGC1_R |= 0x01; // activate UART0
SYSCTL_RCGC2_R |= 0x01; // activate port A
UART0_CTL_R &= ~0x01; // disable UART
UART0_IBRD_R = 43; // IBRD = int(80,000,000 / (16 * 115,200)) = int(43.40278)
UART0_FBRD_R = 26; // FBRD = round(0.40278 * 64 + 0.5) = 26
// 8 bit word length (no parity bits, one stop bit, FIFOs)
UART0_LCRH_R = 0x70;// 0x01110000
//UART0_CTL_R |= UART_CTL_UARTEN; // enable UART, 0x00000001 // UART Enable
UART0_CTL_R |= 0x01; // enable UART, 0x00000001 // UART Enable
GPIO_PORTA_AFSEL_R |= 0x03; // enable alt funct on PA1-0
GPIO_PORTA_DEN_R |= 0x03; // enable digital I/O on PA1-0
// configure PA1-0 as UART
GPIO_PORTA_PCTL_R = (GPIO_PORTA_PCTL_R & 0xFFFFFF00)+0x00000011;
GPIO_PORTA_AMSEL_R &= ~0x03; // disable analog functionality on PA
}
void UART_Char_Output(unsigned char data){
while((UART0_FR_R & UART_FR_TXFF) != 0);
UART0_DR_R = data;
}
unsigned char UART_Char_Input(void){
while((UART0_FR_R & UART_FR_RXFE) != 0);
return((unsigned char)(UART0_DR_R & 0xFF));
}
void UART_Write_String(char *p){
while(*p){
UART_Char_Output(*p);
p++;
}
}
UART1
La UART1 permite manejar moulos de comunicacion serial como modulos de Bluetooth o IoT.
La UART1 se encuentra conectada fisicamente a las terminales PB1 y PB2 con Tx y Rx respectivamente.
Para usarla hay que seguir el msmo procedimiento que se mostró para la UART0 cambiando unicamente los registros de que corresponden a la UART1 y el puerto B.
Para evitar errores pueden copiar el siguiente codigo para probar.
La UART1 se encuentra conectada fisicamente a las terminales PB1 y PB2 con Tx y Rx respectivamente.
Para usarla hay que seguir el msmo procedimiento que se mostró para la UART0 cambiando unicamente los registros de que corresponden a la UART1 y el puerto B.
Para evitar errores pueden copiar el siguiente codigo para probar.
Codigo UART1:
#include "TM4C123.h" // Device header
// configure the system to get its clock from the PLL
#define SYSCTL_RIS_R (*((volatile unsigned long *)0x400FE050))
#define SYSCTL_RCC_R (*((volatile unsigned long *)0x400FE060))
#define SYSCTL_RCC2_R (*((volatile unsigned long *)0x400FE070))
// Define UART registers
#define GPIO_PORTB_AFSEL_R (*((volatile unsigned long *)0x40005420))//modified
#define GPIO_PORTB_DEN_R (*((volatile unsigned long *)0x4000551C))//modified
#define GPIO_PORTB_AMSEL_R (*((volatile unsigned long *)0x40005528))//modified
#define GPIO_PORTB_PCTL_R (*((volatile unsigned long *)0x4000552C))//modified
#define UART1_DR_R (*((volatile unsigned long *)0x4000D000))//UARTDR, modified
#define UART1_FR_R (*((volatile unsigned long *)0x4000D018))//modified
#define UART1_IBRD_R (*((volatile unsigned long *)0x4000D024))//modified
#define UART1_FBRD_R (*((volatile unsigned long *)0x4000D028))//modified
#define UART1_LCRH_R (*((volatile unsigned long *)0x4000D02C))//modified
#define UART1_CTL_R (*((volatile unsigned long *)0x4000D030))//modified
#define UART_FR_TXFF 0x00000020 // UART Transmit FIFO Full
#define UART_FR_RXFE 0x00000010 // UART Receive FIFO Empty
#define SYSCTL_RCGC1_R (*((volatile unsigned long *)0x400FE104))
#define SYSCTL_RCGC2_R (*((volatile unsigned long *)0x400FE108))
void PLL_Init(void);
void UART1_Init(void);
void UART1_Char_Output(unsigned char data);
void UART1_Write_String(char *p);
__asm void
Delay(unsigned long n)
{
SUBS R0, #1
BNE Delay
bx LR ;//the link register is providing the address to branch to.
}
int main(void){
PLL_Init();
UART1_Init();
UART1_Write_String("This Program was performed by Dr. Carlos Hernandez");
UART1_Char_Output('\n');
UART1_Char_Output('\r');
Delay(1333333); // delay ~0.5 sec at 80 MHz
while(1){
UART1_Char_Output('a');
UART1_Char_Output('\n');
UART1_Char_Output('\r');
Delay(1333333); // delay ~0.5 sec at 80 MHz
}
}
void PLL_Init(void){
// 0) Use RCC2
SYSCTL_RCC2_R |= 0x80000000; // USERCC2
// 1) bypass PLL while initializing
SYSCTL_RCC2_R |= 0x00000800; // BYPASS2, PLL bypass
// 2) select the crystal value and oscillator source
SYSCTL_RCC_R = (SYSCTL_RCC_R &~0x000007C0) // clear XTAL field, bits 10-6
+ 0x00000540; // 10101, configure for 16 MHz crystal
SYSCTL_RCC2_R &= ~0x00000070; // configure for main oscillator source 10001111
// 3) activate PLL by clearing PWRDN
SYSCTL_RCC2_R &= ~0x00002000;
// 4) set the desired system divider
SYSCTL_RCC2_R |= 0x40000000; // use 400 MHz PLL, DIV400
SYSCTL_RCC2_R = (SYSCTL_RCC2_R&~ 0x1FC00000) // clear system clock divider
+ (4<<22); // configure for 80 MHz clock, 400/(4+1) = 80MHz
// 5) wait for the PLL to lock by polling PLLLRIS
while((SYSCTL_RIS_R&0x00000040)==0){}; // wait for PLLRIS bit
// 6) enable use of PLL by clearing BYPASS
SYSCTL_RCC2_R &= ~0x00000800;
}
void UART1_Init(void){
SYSCTL_RCGC1_R |= 0x02; // activate UART1
SYSCTL_RCGC2_R |= 0x02; // activate port GPIOB
UART1_CTL_R &= ~0x01; // disable UART
UART1_IBRD_R = 43; // IBRD = int(80,000,000 / (16 * 115,200)) = int(43.40278)
UART1_FBRD_R = 26; // FBRD = round(0.40278 * 64 + 0.5) = 26
// 8 bit word length (no parity bits, one stop bit, FIFOs)
UART1_LCRH_R = 0x70;// 0x01110000
//UART0_CTL_R |= UART_CTL_UARTEN; // enable UART, 0x00000001 // UART Enable
UART1_CTL_R |= 0x01; // enable UART, 0x00000001 // UART Enable
GPIO_PORTB_AFSEL_R |= 0x03; // enable alt funct on PB1-0
GPIO_PORTB_DEN_R |= 0x03; // enable digital I/O on PB1-0
// configure PB1-0 as UART
GPIO_PORTB_PCTL_R = (GPIO_PORTB_PCTL_R & 0xFFFFFF00)+0x00000011;
GPIO_PORTB_AMSEL_R &= ~0x03; // disable analog functionality on PB
}
void UART1_Char_Output(unsigned char data){
while((UART1_FR_R & UART_FR_TXFF) != 0);
UART1_DR_R = data;
}
unsigned char UART1_Char_Input(void){
while((UART1_FR_R & UART_FR_RXFE) != 0);
return((unsigned char)(UART1_DR_R & 0xFF));
}
void UART1_Write_String(char *p){
while(*p){
UART1_Char_Output(*p);
p++;
}
}
// configure the system to get its clock from the PLL
#define SYSCTL_RIS_R (*((volatile unsigned long *)0x400FE050))
#define SYSCTL_RCC_R (*((volatile unsigned long *)0x400FE060))
#define SYSCTL_RCC2_R (*((volatile unsigned long *)0x400FE070))
// Define UART registers
#define GPIO_PORTB_AFSEL_R (*((volatile unsigned long *)0x40005420))//modified
#define GPIO_PORTB_DEN_R (*((volatile unsigned long *)0x4000551C))//modified
#define GPIO_PORTB_AMSEL_R (*((volatile unsigned long *)0x40005528))//modified
#define GPIO_PORTB_PCTL_R (*((volatile unsigned long *)0x4000552C))//modified
#define UART1_DR_R (*((volatile unsigned long *)0x4000D000))//UARTDR, modified
#define UART1_FR_R (*((volatile unsigned long *)0x4000D018))//modified
#define UART1_IBRD_R (*((volatile unsigned long *)0x4000D024))//modified
#define UART1_FBRD_R (*((volatile unsigned long *)0x4000D028))//modified
#define UART1_LCRH_R (*((volatile unsigned long *)0x4000D02C))//modified
#define UART1_CTL_R (*((volatile unsigned long *)0x4000D030))//modified
#define UART_FR_TXFF 0x00000020 // UART Transmit FIFO Full
#define UART_FR_RXFE 0x00000010 // UART Receive FIFO Empty
#define SYSCTL_RCGC1_R (*((volatile unsigned long *)0x400FE104))
#define SYSCTL_RCGC2_R (*((volatile unsigned long *)0x400FE108))
void PLL_Init(void);
void UART1_Init(void);
void UART1_Char_Output(unsigned char data);
void UART1_Write_String(char *p);
__asm void
Delay(unsigned long n)
{
SUBS R0, #1
BNE Delay
bx LR ;//the link register is providing the address to branch to.
}
int main(void){
PLL_Init();
UART1_Init();
UART1_Write_String("This Program was performed by Dr. Carlos Hernandez");
UART1_Char_Output('\n');
UART1_Char_Output('\r');
Delay(1333333); // delay ~0.5 sec at 80 MHz
while(1){
UART1_Char_Output('a');
UART1_Char_Output('\n');
UART1_Char_Output('\r');
Delay(1333333); // delay ~0.5 sec at 80 MHz
}
}
void PLL_Init(void){
// 0) Use RCC2
SYSCTL_RCC2_R |= 0x80000000; // USERCC2
// 1) bypass PLL while initializing
SYSCTL_RCC2_R |= 0x00000800; // BYPASS2, PLL bypass
// 2) select the crystal value and oscillator source
SYSCTL_RCC_R = (SYSCTL_RCC_R &~0x000007C0) // clear XTAL field, bits 10-6
+ 0x00000540; // 10101, configure for 16 MHz crystal
SYSCTL_RCC2_R &= ~0x00000070; // configure for main oscillator source 10001111
// 3) activate PLL by clearing PWRDN
SYSCTL_RCC2_R &= ~0x00002000;
// 4) set the desired system divider
SYSCTL_RCC2_R |= 0x40000000; // use 400 MHz PLL, DIV400
SYSCTL_RCC2_R = (SYSCTL_RCC2_R&~ 0x1FC00000) // clear system clock divider
+ (4<<22); // configure for 80 MHz clock, 400/(4+1) = 80MHz
// 5) wait for the PLL to lock by polling PLLLRIS
while((SYSCTL_RIS_R&0x00000040)==0){}; // wait for PLLRIS bit
// 6) enable use of PLL by clearing BYPASS
SYSCTL_RCC2_R &= ~0x00000800;
}
void UART1_Init(void){
SYSCTL_RCGC1_R |= 0x02; // activate UART1
SYSCTL_RCGC2_R |= 0x02; // activate port GPIOB
UART1_CTL_R &= ~0x01; // disable UART
UART1_IBRD_R = 43; // IBRD = int(80,000,000 / (16 * 115,200)) = int(43.40278)
UART1_FBRD_R = 26; // FBRD = round(0.40278 * 64 + 0.5) = 26
// 8 bit word length (no parity bits, one stop bit, FIFOs)
UART1_LCRH_R = 0x70;// 0x01110000
//UART0_CTL_R |= UART_CTL_UARTEN; // enable UART, 0x00000001 // UART Enable
UART1_CTL_R |= 0x01; // enable UART, 0x00000001 // UART Enable
GPIO_PORTB_AFSEL_R |= 0x03; // enable alt funct on PB1-0
GPIO_PORTB_DEN_R |= 0x03; // enable digital I/O on PB1-0
// configure PB1-0 as UART
GPIO_PORTB_PCTL_R = (GPIO_PORTB_PCTL_R & 0xFFFFFF00)+0x00000011;
GPIO_PORTB_AMSEL_R &= ~0x03; // disable analog functionality on PB
}
void UART1_Char_Output(unsigned char data){
while((UART1_FR_R & UART_FR_TXFF) != 0);
UART1_DR_R = data;
}
unsigned char UART1_Char_Input(void){
while((UART1_FR_R & UART_FR_RXFE) != 0);
return((unsigned char)(UART1_DR_R & 0xFF));
}
void UART1_Write_String(char *p){
while(*p){
UART1_Char_Output(*p);
p++;
}
}