UART 驱动
更新时间:2017-08-08 阅读:3145
前言
Uart通信是一个非常常用的设备通信协议,其特点是通信线路简单,只要一对传输线就可以实现双向通信。Uart经常使用于简单设备间的数据传输,也经常使用于程序的调试。
串口初始化
串口初始化之前要先配置GPIO。
//UART io configurate uart_io_config();
void uart_io_config(void) { // pin mux syscon_SetPMCR0(QN_SYSCON, P07_SW_CLK_PIN_CTRL | P06_SW_DAT_PIN_CTRL | P00_UART0_TXD_PIN_CTRL // P0.0 uart0 tx | P17_UART0_RXD_PIN_CTRL // P1.7 uart0 rx ); syscon_SetPMCR1(QN_SYSCON, P21_UART1_TXD_PIN_CTRL // P2.1 uart1 tx | P20_UART1_RXD_PIN_CTRL // P2.0 uart1 rx ); // pin select syscon_SetPMCR2(QN_SYSCON, SYSCON_MASK_UART1_PIN_SEL); // pin pull ( 00 : High-Z, 01 : Pull-down, 10 : Pull-up, 11 : Reserved ) syscon_SetPPCR0(QN_SYSCON, 0xAAAA5AAA); syscon_SetPPCR1(QN_SYSCON, 0x2AAAAAAA); }
函数syscon_SetPMCR0,syscon_SetPMCR1分别配置 GPIO_P00~GPIO_P17 和 GPIO_P20~GPIO_P36的GPIO复用功能,请注意此范围限制,GPIO_P23是不能syscon_SetPMCR0所配置的。
// pin mux syscon_SetPMCR0(QN_SYSCON, P07_SW_CLK_PIN_CTRL | P06_SW_DAT_PIN_CTRL | P00_UART0_TXD_PIN_CTRL // P0.0 uart0 tx | P17_UART0_RXD_PIN_CTRL // P1.7 uart0 rx ); syscon_SetPMCR1(QN_SYSCON, P21_UART1_TXD_PIN_CTRL // P2.1 uart1 tx | P20_UART1_RXD_PIN_CTRL // P2.0 uart1 rx );
函数syscon_SetPMCR2选择开启某些外设的引脚复用功能,因为本例只是用了UART1,故配置为:
// pin select syscon_SetPMCR2(QN_SYSCON, SYSCON_MASK_UART1_PIN_SEL);
其他可供开启的特殊引脚选择位为
- 31 - 27 : TEST_CTRL[4 :0]
- 27 - 8 : RSVD
- 7 : CLK_OUT_SEL[1]
- 6 : CLK_OUT_SEL[0]
- 5 : UART1_PIN_SEL
- 4 : I2C_PIN_SEL
- 3 : ADCT_PIN_SEL
- 2 : RSVD
- 1 : SPI0_PIN_SEL
- 0 : SPI1_PIN_SEL
另外由于开启SWD需要下拉IO口,所以需要如下配置
// pin pull ( 00 : High-Z, 01 : Pull-down, 10 : Pull-up, 11 : Reserved ) syscon_SetPPCR0(QN_SYSCON, 0xAAAA5AAA); //GPIO_P06,GPIO_P07配置为5(0101),其他的GPIO都是A(1010) syscon_SetPPCR1(QN_SYSCON, 0x2AAAAAAA); //由于没有GPIO_P37,所以最高两位保留,而GPIO_P36为上拉,故为2(0010)AAAAAAA
配置完成GPIO,接下来应该是UART的初始化,根据时钟的不同,我们可以配置不同的初始化参数,如下
#if __AHB_CLK == 32000UL //Initialize uart0 with 1200 baudrate, 8bit data, 1 stop bit, no parity, LSB bitorder, no HW flow control. uart_init(QN_UART0, __USART_CLK, UART_1200); #else //Initialize uart0 with 115200 baudrate, 8bit data, 1 stop bit, no parity, LSB bitorder, no HW flow control. uart_init(QN_UART0, __USART_CLK, UART_115200); //uart_init(QN_UART0, __USART_CLK, UART_57600); #endif uart_tx_enable(QN_UART0, MASK_ENABLE); uart_rx_enable(QN_UART0, MASK_ENABLE);
uart_init分别包含三个参数,第一个参数是串口模块的选择,QN902x中有两个串口模块,其中QN_UART0最为常用。第二个参数是Uart串口的选择,第三个参数是波特率的设置,在32K晶振下只能采用1200的波特率。其他的例如传输位数、停止位、校验位、大小端、流控的设置需要进入uart_init函数里面进行更改和设置。
uart_init(QN_UART0, __USART_CLK, UART_1200);
串口的收发可以选择轮询,也可以选择中断,一般为了效率考虑,我们一般使用的是中断方式,所以还需要打开中断
uart_tx_enable(QN_UART0, MASK_ENABLE); uart_rx_enable(QN_UART0, MASK_ENABLE);
初始化完成!
串口打印字符串
//Print out "Hello Quintic!\n" thought uart. uart_printf(QN_UART0, (uint8_t *)"Hello Quintic!\n");
通过uart_printf函数可以实现串口的字符串打印,当然字符串可以和数组互通,你也可以用来打印一串你需要传输的数字。函数参数很简单,第一个是串口选择,第二个是待发送数组指针。
串口收发示例
//uart0 receive data rx_flag = 1; uart_read(QN_UART0, buffer, 10, led_blink_left); while (rx_flag == 1); //uart0 send data tx_flag = 1; uart_write(QN_UART0, buffer, 10, led_blink_right); while (tx_flag == 1);
示例中采用了UART0先向串口读取10个字节数据存入buffer数组内,再通过UART0向串口写入刚才在串口中读入保存在buffer中的10字节数据。
uart_read有四个参数,第一个串口选择,第二个是读取的数据存放的位置,第三个参数是读取的字节个数,第四个参数是回调函数的设置在读取数据完成后,就会调用回调函数。
uart_read(QN_UART0, buffer, 10, led_blink_left);
在读取之前,可以先设置一个读取标志位rx_flag,执行读取函数之后就进入到while循环中进行空操作,在读取完成后,在回调函数中清零读取标志位,完成一次读取操作。
void led_blink_left(void) { rx_flag = 0; }
串口写入操作与读取类似。