欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

学习KEA之UART之一:简介和发送数据

程序员文章站 2024-02-25 15:04:33
...

我们以KEA64系列来学习UART 。这是最常用的外设之一了,必须要掌握的。

简介

KEA64有3个串口:UART0, UART1, UART2, 时钟来自Bus Clock。

几个重要的参数:

  • 起始位(固定1位)
  • 波特率(300 - 1500000bps)
  • 数据位 (5 - 8位,低位数据先发送)
  • 校验位 (None、奇校验或偶校验)
  • 停止位 (1、1.5 或2)
  • 流控(不常用)

比较常见的配置之一:

  • 波特率(9600bps)
  • 数据位 (8位)
  • 校验位 (None)
  • 停止位 (1)
  • 流控(无)

则发送一个字节,需要发送的有:起始位1位、数据位8位、停止位1位,总共10位,总共时间是 10 bit * (1/9600) s/bit ≈ 1.04 ms, 串口波形如下(TTL电平):
学习KEA之UART之一:简介和发送数据
从上图可以看到,空闲时,UART的TX都是高电平(约2.2V),起始位是低电平,数据位(高电平表示1,低电平表示0,低位先发送,对应波形是b10101010,反过来就是b01010101,即最终发送的数据是0x55),停止位是高电平。更多的串口解读,可以参考:深入剖析串口通信数据格式

串口初始化的过程发下:

  1. 使能串口时钟
  2. 设置停止位
  3. 设置波特率
  4. 设置校验位和数据位
  5. 允许发送或 接收
  6. 允许中断(可选)
  7. 使能串口管脚

串口发送过程(非中断)如下:

  1. 等待发送缓冲区为空
  2. 清除TDRE 标志位
  3. 加载数据到串口数据寄存器发送

发送程序

#include "derivative.h" /* include peripheral declarations SSKEAZN64M2 */

void Clk_Init(void);
void Enable_Interrupt(uint8_t vector_number);
void init_PIT(void);

void UART_Init(void);
void UART_Transmit_Char(char send);
void UART_Transmit_String(char data_string[]);

uint8_t timer1sFlag = 0;

int main(void)
{
	Clk_Init();
	init_PIT();
	init_GPIO();
	UART_Init();
	Enable_Interrupt(PIT_CH1_IRQn);

	for(;;)
	{
		if (timer1sFlag)
		{
			timer1sFlag = 0;

			UART_Transmit_Char(0x55);
		}
	}

	return 0;
}

/***********************************************************************************************
*
* @brief    CLK_Init - Initialize Core Clock to 40MHz, Bus Clock to 20MHz
* @param    none
* @return   none
*
************************************************************************************************/
void Clk_Init(void)
{
	ICS_C1|= ICS_C1_IRCLKEN_MASK; /* Enable the internal reference clock*/
	ICS_C3 = 0x50; /* Reference clock frequency = 31.25 kHz*/

	while(!(ICS_S & ICS_S_LOCK_MASK)); /* Wait for PLL lock, now running at 40 MHz (1024*39.0625 kHz) */

	ICS_C2 |= ICS_C2_BDIV(1) ; /* BDIV=b001, Bus clock = 20 MHz*/
	ICS_S |= ICS_S_LOCK_MASK ; /* Clear Loss of lock sticky bit */
}

/***********************************************************************************************
*
* @brief    init_PIT - 设定定时器周期溢出时间1s, 启动中断
* @param    none
* @return   none
*
************************************************************************************************/
void init_PIT(void)
{
	SIM_SCGC |= SIM_SCGC_PIT_MASK;     /* Enable bus clock to PIT module */
	PIT_MCR = 0x0;                     /* Turn on PIT module, Freeze disabled */
	PIT_LDVAL1 = 20000000 - 1;         /* PIT1: Load value to count 20M bus clocks */
	PIT_TCTRL1 |= PIT_TCTRL_TIE_MASK;  /* Enable interrupt */
	PIT_TCTRL1 |= PIT_TCTRL_TEN_MASK;  /* PIT1: Start timer */

	PIT_TCTRL1 |= PIT_TCTRL_TEN_MASK;
}

/***********************************************************************************************
*
* @brief    Enable_Interrupt(uint8_t vector_number). Enable interrupts from desired module.
* @param    Module interrupt number from the interrupts vector table
* @return   none
*
************************************************************************************************/
void Enable_Interrupt(uint8_t vector_number)
{
	NVIC_ClearPendingIRQ(vector_number); 		/* Clear pending interrupt register */
	NVIC_EnableIRQ(vector_number); 				/* Enable required Interrupt */
}

/***********************************************************************************************
*
* @brief    PIT_CH1_IRQHandler - PIT CH1中断程序
* @param    none
* @return   none
*
************************************************************************************************/
void PIT_CH1_IRQHandler (void)
{
	PIT_TFLG1 |= PIT_TFLG_TIF_MASK; /* Clear PIT1 flag */

	timer1sFlag = 1;
}

void UART_Init(void)
{
	SIM_SCGC |= SIM_SCGC_UART0_MASK; /* Enable bus clock in UART0 */
	UART0_BDH = 0; /* One stop bit*/
	UART0_BDL = 130; /* For 9600 baud: baud divisor=20M/9600/16 = ~130 */
	UART0_C1 = 0; /* No parity enable,8-bit format*/
	UART0_C2 |= UART_C2_TE_MASK; /* Enable Transmitter*/
	UART0_C2 |= UART_C2_RE_MASK; /* Enable Receiver*/
	//UART0_C2 |= UART_C2_RIE_MASK; /* Enable Receiver interrupts*/
	SIM_PINSEL |= SIM_PINSEL_UART0PS_MASK; /* UART0_RX and UART0_TX are mapped on PTA2 and PTA3 */
}

/* Function to Transmit single Char */
void UART_Transmit_Char(char send)
{
	while((UART0_S1 & UART_S1_TDRE_MASK)==0); /* Wait for transmit buffer to be empty */

	(void)UART0_S1; /* Read UART0_S1 register to clear TDRE */

	UART0_D = send; /* Send data */
}

/* Function to Transmit whole string */
void UART_Transmit_String(char data_string[])
{
	int i = 0;

	while(data_string[i] != '\0')
	{
		/* Send chars one at a time */
		transmit_char(data_string[i]);
		i++;
	}
}
相关标签: KEA