STM32 RS232通信实验

stm32F103 RS232通信实验

      • 什么是RS232?
      • 软件设计
    • 完整工程下载

什么是RS232?

先来看看UART传输所存在的问题
STM32 RS232通信实验_第1张图片
于是就有了RS232协议

STM32 RS232通信实验_第2张图片
STM32 RS232通信实验_第3张图片

这里注意使用的是负逻辑电平信号,在规定范围内的电平信号代表逻辑1或0,增加了抗干扰能力。
(电平的转化由硬件设计,TTL信号转232信号,常用的芯片有ST3232ECTRMAX3232
RS232能够弥补串口的一些不足,像传输距离,抗干扰能力,等都有提高。

STM32 RS232通信实验_第4张图片

RS232存在的不足,于是就有了RS485(下一篇讲解)

软件设计

和串口通信一样,只是依据原理图更改了对应的串口和用到的引脚
原理图:
STM32 RS232通信实验_第5张图片
STM32 RS232通信实验_第6张图片

这里和UART通信不同的是所用到的引脚不同,所以在编程配置的时候只需要在原来的基础上更改对应引脚。
点击查看UART通信实验RS232实验功能与UART所实现功能一致
本实验需要USB转RS232线(公母头根据自己的开发板选择)

UART.C

#include"stm32f10x_exti.h"
#include"stm32f10x_gpio.h"
#include "usart.h"


void USART1_Init(unsigned long ulBaud)
{
   GPIO_InitTypeDef  GPIO_InitStructure;
   USART_InitTypeDef USART_InitStructure;
   NVIC_InitTypeDef NVIC_InitStructure;
  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//引脚时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//串口时钟

    //配置USART1 TX引脚工作模式
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    //配置USART1 RX引脚工作模式
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    //串口1工作模式配置
    USART_InitStructure.USART_BaudRate = 9600;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_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(USART1, &USART_InitStructure);
    USART_Cmd(USART1, ENABLE);
	USART_ClearFlag(USART1,USART_FLAG_TC);//清除发送完成标志
		
     USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//开启USART1接收中断
	 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	 NVIC_Init(&NVIC_InitStructure);
	
}




void USART2_Init(unsigned long ulBaud)
{
  GPIO_InitTypeDef GPIO_InitStruct;//定义结构体(GPIO,USART,NVIC)
  USART_InitTypeDef USART_InitStruct;
  NVIC_InitTypeDef NVIC_InitStruct;
	
  // 允许GPIOA和USART2时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
  // PA2-TX2复用推挽输出(端口配置)
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStruct);
  /* PA3-TX2浮空输入(复位状态,可以省略)
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStruct); */
  // 初始化USART2(波特率ulBaud,允许Rx和Tx,默认8个数据位,1个停止位,无校验)
  USART_InitStruct.USART_BaudRate = ulBaud;//波特率
  USART_InitStruct.USART_WordLength = USART_WordLength_8b;//数据位
  USART_InitStruct.USART_StopBits = USART_StopBits_1;//停止位
  USART_InitStruct.USART_Parity = USART_Parity_No;//(校验位:无)
  USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//设置收发模式
  USART_InitStruct.USART_HardwareFlowControl= USART_HardwareFlowControl_None;//硬件流控制:无
  USART_Init(USART2, &USART_InitStruct);//串口2初始化
  USART_Cmd(USART2, ENABLE);//使能USART2
  USART_ClearFlag(USART2,USART_FLAG_TC);//清除发送完成标志
	
	
	USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);//开启USART2接受中断
	NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;//主优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;//子优先级
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;//中断使能
	NVIC_Init(&NVIC_InitStruct);//中断初始化
	
}
// 发送字符
unsigned char USART_SendChar(USART_TypeDef* USARTx, unsigned char ucChar)
{
  while(!USART_GetFlagStatus(USARTx, USART_FLAG_TXE));
  USART_SendData(USARTx, ucChar);
  return ucChar;
}
// 发送字符串
void USART_SendString(USART_TypeDef* USARTx, unsigned char* pucStr)
{
  while(*pucStr != '\0')
    USART_SendChar(USARTx, *pucStr++);
}
// 非阻塞接收字符
unsigned char USART_ReceiveChar_NonBlocking(USART_TypeDef* USARTx)
{
  if(USART_GetFlagStatus(USARTx, USART_FLAG_RXNE))
    return USART_ReceiveData(USARTx);
  else
    return 0;
}


#define uart1  //注释掉该宏使用uart2

#ifdef  uart1
 //printf调用函数(使用MicroLIB)
int fputc(int ch, FILE *f)
{
  return(USART_SendChar(USART1, ch));
}

#else
  // printf调用函数(使用MicroLIB)
int fputc(int ch, FILE *f)
{
  return(USART_SendChar(USART2, ch));
}


#endif
}

main.c

#include "key.h"
#include "led.h"
#include "lcd.h"
#include "stdio.h"
#include "usart.h"
#include "stm32f10x_exti.h"


void LCD_Proc(void);
void LED_Proc(void);
void Key_Init(void);
void LED_Control(uint16_t LED,uint8_t LED_Status);
void USART1_Init(unsigned long ulBaud);


uint32_t TimingDelay = 1;
unsigned char ucSec,ucLed=1;
unsigned long ulTick_ms;
int col_flag=0;
unsigned int i;


int main(void)
{
  SysTick_Config(72000);			// 定时1ms(HCLK = 72MHz)
  Key_Init();
  LED_Init();
  BUZ_Init();
  STM3210B_LCD_Init();				//LCD的初始化
	
  LCD_Clear(Cyan);				        //清屏配置颜色
	LCD_SetTextColor(White);		    //字体颜色
  LCD_SetBackColor(Cyan);	  	    //字体背景颜色
   
  LED_Control(LEDALL,0);//控制所有LED灯默认关闭(0关闭,1打开)
	USART1_Init(9600);
	
	  USART_SendString(USART1,"请输入您的指令:\r\n");	
		USART_SendString(USART1,"   输入0:LED左移\r\n");	
		USART_SendString(USART1,"   输入1:LED右移\r\n");	
		USART_SendString(USART1,"   输入2:打开蜂鸣器\r\n");	
	  USART_SendString(USART1,"   输入3:关闭蜂鸣器\r\n\r\n");	
	      
  while(1)
  { 
	 LCD_Proc();
	 LED_Proc();
	}
  }
	
  
void LED_Proc(void)
{
	switch(col_flag)
	{
		case 1:
		  if(ulTick_ms > 300)      //0.3S延时
		  {
			ulTick_ms = 0;
			  
			ucLed >>= 1;
			if(ucLed == 0) 
				ucLed =0x80;           //LED右移函数
			LED_Disp(ucLed);
		  }
		  break;
			
			
		case 2:
		  if(ulTick_ms > 300)      //0.3S延时
		  {
			ulTick_ms = 0;
			  
			LED_Disp(ucLed);
			ucLed <<= 1;             //LED左移函数
			if(ucLed ==0)
				ucLed = 1;
		  }
		  break;
			
			
		case 3:
			LED_Control(LEDALL,0);
			GPIO_ResetBits(GPIOB,GPIO_Pin_4);//打开蜂鸣器
		  break;
		
		
		case 4:
			LED_Control(LEDALL,0);
			GPIO_SetBits(GPIOB,GPIO_Pin_4);
		
	}
	
}

/*************************************

LCD中文显示需要做字库,在fonts.h文件内

*************************************/
//LCD中文显示
void LCD_Proc(void)
{
      LCD_DisplayStringLine(Line1,"      19");
	  LCD_DisplayproHZ(Line1, 4, 0);
	  LCD_DisplayproHZ(Line1, 5, 1);
	  LCD_DisplayproHZ(Line1, 6, 2);   //嵌入式
	
	if(col_flag==1)
		LCD_SetBackColor(Blue);
		LCD_DisplayStringLine(Line3,"    1. LED");
        LCD_DisplayproHZ(Line3, 5, 4);
	    LCD_DisplayproHZ(Line3, 6, 5);   //右移
		LCD_SetBackColor(Cyan);

	if(col_flag==2)
	  LCD_SetBackColor(Blue);
	  LCD_DisplayStringLine(Line5,"    2. LED");
	  LCD_DisplayproHZ(Line5, 5, 3);
	  LCD_DisplayproHZ(Line5, 6, 5);  //左移
	  LCD_SetBackColor(Cyan);

	if(col_flag==3)
	  LCD_SetBackColor(Blue);
	  LCD_DisplayStringLine(Line7,"    3.");
      LCD_DisplayproHZ(Line7, 3, 6);
      LCD_DisplayproHZ(Line7, 4, 7);
	  LCD_DisplayproHZ(Line7, 5, 8);
	  LCD_DisplayproHZ(Line7, 6, 9);  //蜂鸣器开
	  LCD_SetBackColor(Cyan);
	if(col_flag==4)
		LCD_SetBackColor(Blue);
		LCD_DisplayStringLine(Line9,"    4.");
		LCD_DisplayproHZ(Line9, 3, 6);
		LCD_DisplayproHZ(Line9, 4, 7);
	    LCD_DisplayproHZ(Line9, 5, 8);
	    LCD_DisplayproHZ(Line9, 6, 10); //蜂鸣器关
		LCD_SetBackColor(Cyan);
	
 

	
}


//按键中断
void Key_Init(void)
{
	EXTI_InitTypeDef   EXTI_InitStructure;//定义结构体
	GPIO_InitTypeDef   GPIO_InitStructure;
	NVIC_InitTypeDef   NVIC_InitStructure; 	

	//时钟配置
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
  /* PA0和PA8浮空输入*/
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure); 
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0|GPIO_PinSource8);
  /* PB1和PB2浮空输入*/
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOB, &GPIO_InitStructure); 
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1|GPIO_PinSource2);
	
	
   GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);//打开PA0中断连接
 	 EXTI_ClearITPendingBit(EXTI_Line0);//清除中断标志
 	 GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource8);//打开PA8中断连接
	 EXTI_ClearITPendingBit(EXTI_Line8); 
	 GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource1);//打开PB1中断连接
	 EXTI_ClearITPendingBit(EXTI_Line1);
	 GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource2);//打开PB2中断连接
	 EXTI_ClearITPendingBit(EXTI_Line2);
	
  	EXTI_InitStructure.EXTI_Line = EXTI_Line0|EXTI_Line8|EXTI_Line1|EXTI_Line2;//选择中断线0,8,2,1
  	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//设置中断请求
  	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发  
  	EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能中断线
  	EXTI_Init(&EXTI_InitStructure);


    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组
		
		
  //PA0 
  	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//使能按键所在的外部中断通道
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//子优先级
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
  	NVIC_Init(&NVIC_InitStructure);

	//PA8
    NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  	NVIC_Init(&NVIC_InitStructure);

	//  PB1 
  	NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =2;
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  	NVIC_Init(&NVIC_InitStructure);

	// PB2
  	NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  	NVIC_Init(&NVIC_InitStructure);

}




//中断服务函数
void EXTI0_IRQHandler(void)   //PA0
{  
	 for(i=0x5ffff; i>0; i--);//延时
	
	if(EXTI_GetFlagStatus(EXTI_Line0)!=RESET)
	{
		EXTI_ClearFlag(EXTI_Line0);
		
				 col_flag++;
			if(col_flag>4)
				 col_flag=1;
			
	}
}

void EXTI9_5_IRQHandler(void)    //PA8
{   
	for(i=0x5ffff; i>0; i--);//延时
	if(EXTI_GetFlagStatus(EXTI_Line8)!=RESET)
	{
		EXTI_ClearFlag(EXTI_Line8);
			   col_flag--;
			if(col_flag<1)
				 col_flag=4;
			
	}
}


void EXTI1_IRQHandler(void)  //PB1
{  
	 for(i=0x5ffff; i>0; i--);//延时
	
	if(EXTI_GetFlagStatus(EXTI_Line1)!=RESET)
	{
		EXTI_ClearFlag(EXTI_Line1);
		
				 col_flag++;
			if(col_flag>4)
				 col_flag=1;
			
	}
}



void EXTI2_IRQHandler(void)  //PB2
{   for(i=0x5ffff; i>0; i--);//延时
	if(EXTI_GetFlagStatus(EXTI_Line2)!=RESET)
	{
		EXTI_ClearFlag(EXTI_Line2);
			   col_flag--;
			if(col_flag<1)
				 col_flag=4;
			
	}
}

//串口中断服务函数
void USART1_IRQHandler(void)    
{
  uint8_t temp;
  if(USART_GetFlagStatus(USART1,USART_IT_RXNE)!=0)
  { 
		temp=USART_ReceiveData(USART1);
		USART_SendData(USART1,temp);
		
		switch(temp)
		{
			
			case'0':
				col_flag=1;
			USART_SendString(USART1,":LED右移已打开\r\n\r\n");
       
		
			  break;
				
			case'1':
				col_flag = 2;	
				USART_SendString(USART1,":LED左移已打开\r\n\r\n");		
			  
				break;
			
			case'2':
				//col_flag = 3;	//太吵了,实验自己打开
				USART_SendString(USART1,":蜂鸣器已打开\r\n\r\n");	
        
       	break;
			
			case'3':
				col_flag = 4;
				USART_SendString(USART1,":蜂鸣器已关闭\r\n\r\n");	
        break;
		
	}
		
  }

}





void SysTick_Handler(void)
{
  ulTick_ms++;
  if(ulTick_ms%1000 == 0) ucSec+=0;          
}


完整工程下载

选择第12个工程

你可能感兴趣的:(STM32,嵌入式,stm32,串口通信,单片机)