一、概述
1、UART简介
UART:通用同步/异步串行接收/发送器,由时钟发生器、数据发送器和接收器三大部分组成。UART是一个全双工通用同步/异步串行收发模块,该接口是一个高度灵活的串行通信设备。STM32F407IGT6具有6个UART收发器,可使用相应的代码使能后使用。
2、UART特点
- 全双工操作(相互独立的接收数据和发送数据)。
- 同步操作时,可主机时钟同步,也可从机时钟同步。
- 支持8和9位数据位,1或2位停止位的串行数据桢结构。
- 由硬件支持的奇偶校验位发生和检验。
- 数据溢出检测。
- 帧错误检测。
- 包括错误起始位的检测噪声滤波器和数字低通滤波器。
- 三个完全独立的中断,TX发送完成、TX发送数据寄存器空、RX接收完成。
- 支持多机通信模式。
- 支持倍速异步通信模式。
3、UART时序
图4_0 UART时序
空闲位:高电平。
启动位:一个低电平。
字符数据:可以选择8和9位数据位。
奇偶校验位:根据需要选择是否进行校验。
停止位:一个高电平。
4、TTL、RS232、RS485、RS422通信
TTL、RS232、RS485都是指电平信号,USART可使用相应的电平转换芯片,实现这三种通信。
- TTL:电平信号数据表示采用二进制规定,+5V等价于逻辑“1”,0V等价于逻辑“0”。通讯方式为全双工通信。
- RS232:232中任何一条信号线的电压均为负逻辑关系。即:逻辑“1”为-3到-15V;逻辑“0”为+3到+15V。通讯方式为全双工,通讯距离15m,RS-232的数据最高传输速率为20Kbps。
- RS485:RS485采用差分信号负逻辑,逻辑"1”以两线间的电压差为-(2~6)V表示;逻辑"0"以两线间的电压差为+(2~6)V表示。通讯方式为半双工,通讯距离1200m,RS-485的数据最高传输速率为10Mbps。
- RS422:RS422采用两对差分线传输数据,电平与RS485相同。通讯方式为全双工,通讯距离1200m,RS-422的数据最高传输速率为10Mbps。
图4_1UART引脚图
本试验使用的芯片STM32F407IGT6,使用UART为UART_4,引脚位PA0和PA1,经过串口转USB芯片CH340转换后,可通过USB接口与计算机通讯。
三、 实验原理
计算机安装 CH340 驱动后,可通过串口工具来接收串口发送的数据和向串口发送给数据。用串口工具打开iCore3对应的端口,波特率设为115200,发送相应的命令,便可以控制ARM LED的亮灭情况。串口命令如下表:
表4_1: 串口控制命令
四、源代码
1.USART初始化结构体介绍
- typedefstruct
- {
- uint32_tUSART_BaudRate;
- uint16_tUSART_WordLength;
- uint16_tUSART_StopBits;
- uint16_tUSART_Parity;
- uint16_tUSART_Mode;
- uint16_tUSART_HardwareFlowControl;
- } USART_InitTypeDef;
2.主函数
- /*
- * Name : main
- * Description : ---
- * Author : ysloveivy.
- *
- * History
- * --------------------
- * Rev : 0.00
- * Date : 11/21/2015
- *
- * create.
- * --------------------
- */
- int main(void)
- {
- inti;
- char buffer[20];
- led.initialize();
- usart4.initialize(9600);
- usart4.printf("hello! I am iCore3!rn"); //串口4输出
- while(1){
- if(usart4.receive_ok_flag){ //接收完成
- usart4.receive_ok_flag = 0;
- for(i = 0;i <20;i++){
- buffer = tolower(usart4.receive_buffer);
- }
- //比较接收信息
- if(memcmp(buffer,"led_red_on",strlen("led_red_on")) == 0){
- LED_RED_ON;
- usart4.printf("ok!rn");
- }
- if(memcmp(buffer,"led_red_off",strlen("led_red_off")) == 0){
- LED_RED_OFF;
- usart4.printf("ok!rn");
- }
- if(memcmp(buffer,"led_green_on",strlen("led_green_on")) == 0){
- LED_GREEN_ON;
- usart4.printf("ok!rn");
- }
- if(memcmp(buffer,"led_green_off",strlen("led_green_off")) == 0){
- LED_GREEN_OFF;
- usart4.printf("ok!rn");
- }
- if(memcmp(buffer,"led_blue_on",strlen("led_blue_on")) == 0){
- LED_BLUE_ON;
- usart4.printf("ok!rn");
- }
- if(memcmp(buffer,"led_blue_off",strlen("led_blue_off")) == 0){
- LED_BLUE_OFF;
- usart4.printf("ok!rn");
- }
- }
- }
- }
3.USART初始化及相关配置
- /*
- * Name : initialize_usart4
- * Description : ---
- * Author : XiaomaGee
- *
- * History
- * -------------------
- * Rev : 0.00
- * Date : 11/21/2015
- *
- * create.
- * -------------------
- */
- staticint initialize_usart4(unsignedlongintbaudrate)
- {
- GPIO_InitTypeDefGPIO_InitStructure;
- USART_InitTypeDefUSART_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); // GPIO时钟使能
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PA0为复用推挽输出
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //PA1为浮空输入
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_UART4); //PA0引脚复用为UART4
- GPIO_PinAFConfig(GPIOA,GPIO_PinSource1,GPIO_AF_UART4); //PA1引脚复用为UART4
- USART_DeInit(UART4);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE); //UART4时钟使能
- USART_InitStructure.USART_BaudRate = baudrate; //波特率
- USART_InitStructure.USART_WordLength = USART_WordLength_8b; //8个数据位
- USART_InitStructure.USART_StopBits = USART_StopBits_1; //1个停止位
- USART_InitStructure.USART_Parity = USART_Parity_No ; //无奇偶校验位
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
- USART_Init(UART4, &USART_InitStructure); //初始化UART4
- USART_Cmd(UART4, ENABLE); //使能UART4
- USART_ITConfig(UART4,USART_IT_PE,ENABLE);
- USART_ITConfig(UART4,USART_IT_RXNE,ENABLE); //打开UART4的中断
- NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- return0;
- }
- /*
- * Name : send_buffer4
- * Description : ---
- * Author : XiaomaGee
- *
- * History
- * -------------------
- * Rev : 0.00
- * Date : 11/21/2015
- *
- * create.
- * -------------------
- */
- staticint
- send_buffer4(void * buf,intlen)
- {
- char *p = (char *)buf;
- if(len<= 0)return -1;
- while(len --){
- send_byte_to_usart4(*p);
- p ++;
- }
- return0;
- }
- /*
- * Name : send_byte_to_usart4
- * Description : ---
- * Author : XiaomaGee
- *
- * History
- * -------------------
- * Rev : 0.00
- * Date : 11/21/2015
- *
- * create.
- * -------------------
- */
- staticint
- send_byte_to_usart4(char data) //TTL通信
- {
- while(!(USART_GetFlagStatus(UART4,USART_FLAG_TC) == 1)); //等待发送数据完成
- USART_SendData(UART4,data); //将数据写入数据寄存器中
- return0;
- }
- /*
- * Name : send_string_to_usart4
- * Description : ---
- * Author : XiaomaGee
- *
- * History
- * -------------------
- * Rev : 0.00
- * Date : 11/21/2015
- *
- * create.
- * -------------------
- */
- staticint
- send_string_to_usart4(char * str)
- {
- while(*str!='\0'){
- while(!(USART_GetFlagStatus(UART4,USART_FLAG_TC) == 1));
- USART_SendData(UART4,*str++);
- }
- return0;
- }
- /*
- * Name : UART4_IRQHandler
- * Description : ---
- * Author : XiaomaGee
- *
- * History
- * -------------------
- * Rev : 0.00
- * Date : 11/21/2015
- *
- * create.
- * -------------------
- */
- int
- UART4_IRQHandler(void)
- {
- while(USART_GetFlagStatus(UART4,USART_FLAG_RXNE) == 0);
- usart4.receive_buffer[usart4.counter++]=USART_ReceiveData(UART4); //接收数据
- if(usart4.receive_buffer[usart4.counter - 1] == 'n'&& usart4.receive_buffer[usart4.counter - 2] == 'r'){
- usart4.receive_buffer[usart4.counter-1]=0;
- usart4.counter=0;
- usart4.receive_ok_flag=1;
- return0;
- }
- /*
- * Name : printf
- * Description : ---
- * Author : XiaomaGee
- *
- * History
- * -------------------
- * Rev : 0.00
- * Date : 11/21/2015
- *
- * create.
- * -------------------
- */
- staticint
- my_printf4(constchar * fmt,...) //串口4输出
- {
- __va_listarg_ptr;
- charbuf[UART_BUFFER_SIZE];
- memset(buf,'\0',sizeof(buf));
- va_start(arg_ptr,fmt);
- vsprintf(buf,fmt,arg_ptr);
- va_end(arg_ptr);
- send_string_to_usart4(buf);
- return0;
五、 实验现象
通过串口调试工具输入相应的命令,可以看到iCore3执行相应的明命令,LED按控制命令亮灭。
|