前端开发入门到精通的在线学习网站

网站首页 > 资源文章 正文

串行交互程序设计基于STM32103VET6

qiguaw 2024-09-16 01:30:00 资源文章 16 ℃ 0 评论

串行交互程序设计

  1. .开发板引出USART1端口用于串行通信,其中用于异步通信的RX,TX引

脚分别映射到PA10和PA9引脚

2上位机安装SecureCRT软件,可用于串行通信。

.试编写程序实现如下功能:

.1)能通过上位机SecureCRT软件输入命令控制开发板Led灯的亮灭,如

输入"LedRedOn"点亮红灯。

.2)能检测按键状态、通过串口发送给上位机,并在SecureCRT软件上

显示。

.3)其他交互操作。

.要求:在SecureCRT软件上显示完善的交互提示信息。

USART主要特性

.3个USART:USART1挂载于APB2高速总线,USART2

,USART3挂载于APB1总线

.2个UART:UART4,UART5挂载于APB1总线

.可编程数据字长度(8位或9位)

.分数波特率发生器系统,最高达4.5Mbits/s

.可配置的停止位-支持1或2个停止位

.LIN通信(局域互联网)

.IRDA SIR编码器解码器(红外通讯)

.智能卡模拟功能

.可配置的使用DMA的多缓冲器通信

UART主要特性

USART引脚

USART电路连接

驱动下载:

http://www.wch.cn/

产品中心->USB系列芯片->CH340

拉到最下面点击CH341SER.EXE下载

USART结构

控制寄存器

USART_SR USART_BRR

USART_CR1 USART_CR2

USART_CR3 USART_GTPR

装载库函数文件

1.添加stm32f10x_usart.c到工程目录

2.关联stm32f10x_usart.h
#include "stm32f10x_usart.h"

异步串口通信配置

.1.使能时钟

.2.配置引脚

.3.设置波特率、停止位、校验方式、工作模式等

.4.启动串口

1.使能时钟

.需要同时开启GPIOA时钟和USART1时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |
RCC_APB2Periph_USART1 ,ENABLE);
?是否需要开启AFIO时钟?

2. GPIO配置

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);

浮空输入或上拉输入

复用推挽输出

3.工作模式设置

字长: 8位/9位

波特率: 1200,2400,4800,9600,19200,38400,115200...

校验方式: 无校验,奇校验,偶校验

停止位: 0.5位,1位,1.5位,2位

工作模式: 单发,单收,收发

偶校验:就是让原有数据

序列中(包括你要加上的

一位)1的个数为偶数

奇校验:就是让原有数据

序列中(包括你要加上的

一位)1的个数为奇数

串口初始化函数

USART1

USART2

USART3

设置USART1波特率115200,8位字长,1停止位,无校验,无硬件流控

制,收发模式

4.使能串口

USART1

USART2

USART3

ENABLE

DISABLE

例,使能USART1

USART_Cmd(USART1, ENABLE);

.设计完整串口配置函数,设置USART1波特率115200,8位

字长,1停止位,无校验,无硬件流控制,收发模式

– void USART1_Configration()
– {
? //1.使能时钟
? //2.配置引脚
? //3.配置工作方式
? //4.使能串口
– }

串口数据发送

.1.发送数据

.2.等待数据发送完成

1.串口数据发送

USART1
USART2
USART3

例,通过USART1发送数据0x30

USART_SendData(USART1, 0x30);

2.串口数据收发状态查询函数

USART1

USART2

USART3

SET

RESET

TDR空,发送完成

发送完成

RDR非空,接收

到数据可以读出

例,等待串口1发送完成

while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);

.设计完整串口发送1字节数据函数

– void USART1_Putc( u8 c )
– {
? //1.发送数据
? //2.等待数据发送完成
– }

.串行发送数据到上位机

– 1. 安装驱动程序

– 2. 硬件连接

– 3. 查看串口端口号

– 4. 上位机软件配置

– 5. 运行程序

.串行发送数据到上位机

– 1. 安装驱动程序

– 2. 硬件连接

电脑usb口←下载器←

– 3. 查看串口端口号

– 4. 上位机软件配置

– 5. 运行程序

电脑usb口←

.串行发送数据到上位机

– 1. 安装驱动程序

– 2. 硬件连接

– 3. 查看串口端口号

– 4. 上位机软件配置

– 5. 运行程序

串行机设置
实现效果
程序代码:
#include "stm32f10x.h"
#include "bsp_lcd.h"
#include "fatfs_flash_spi.h"
#include "bsp_usart.h"
#include "pic.h"
#include <stdio.h>
#include "screendirection.h"
#include "ui.h"
#define LEDBLUE_ON		GPIO_ResetBits(GPIOB, GPIO_Pin_1)
#define LEDBLUE_OFF		GPIO_SetBits(GPIOB, GPIO_Pin_1)
#define LEDGREEN_ON		GPIO_ResetBits(GPIOB, GPIO_Pin_0)
#define LEDGREEN_OFF	GPIO_SetBits(GPIOB, GPIO_Pin_0)
#define LEDRED_ON			GPIO_ResetBits(GPIOB, GPIO_Pin_5)
#define LEDRED_OFF		GPIO_SetBits(GPIOB, GPIO_Pin_5)
void Delay(u32 Cnt)
{
	while(--Cnt);
}
//按键和Led GPIO初始化配置
void GPIO_Configration()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	//必须先开启时钟再配置引脚
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC ,ENABLE);
	
	//注:这段程序和TIM3Configuration不能共存
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	
	LEDBLUE_OFF;LEDGREEN_OFF;LEDRED_OFF;
}
u8 KeyScan()
{
	u8 key;
	
	if((GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==1) && (GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13)==1)) key = 3;	
	else if((GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==0) && (GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13)==1)) key = 2;
	else if((GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==1) && (GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13)==0)) key = 1;
	else key = 0;
	return key;
}
/**
 * @brief LCD触摸屏校准或从外部flash读取校准系数
 * @param 无
 * @retval 无
 */	
void Flash_TouchCalibrate ( void )
{
	uint8_t ucStoreFlag,FlagWord; //LCD触摸屏校准系数存储标志
	
	#if ScreenDirection==1
		FlagWord = 0x53;
	#elif ScreenDirection==2
		FlagWord = 0x54;
	#endif
	
	
	SPI_FLASH_ReadDeviceID(); // Get SPI Flash Device ID */
	
	SPI_FLASH_BufferRead ( & ucStoreFlag, 0, 1 ); //从外部flash读出LCD触摸屏校准系数存储标志
	
	if ( ucStoreFlag == FlagWord ) //已存储过LCD触摸屏校准系数
		SPI_FLASH_BufferRead ( ( void * ) & strXPT2046_TouchPara, 1, sizeof ( strXPT2046_TouchPara ) ); //继续读取LCD触摸屏校准系数
		
	else //尚未存储过LCD触摸屏校准系数
	{
		while( ! XPT2046_Touch_Calibrate () ); //等待触摸屏校正完毕
		/* 存储LCD触摸屏校准系数和标志 */
		ucStoreFlag = FlagWord;
		SPI_FLASH_SectorErase ( 0 );
		SPI_FLASH_BufferWrite ( & ucStoreFlag, 0, 1 ); 
		SPI_FLASH_BufferWrite ( ( void * ) & strXPT2046_TouchPara, 1, sizeof ( strXPT2046_TouchPara ) );	
	}
	
}
void TIM3_Configuration( void )
{
	TIM_TimeBaseInitTypeDef 	TIM_TimeBaseStructure;
	GPIO_InitTypeDef 	 		GPIO_InitStructure;
	TIM_OCInitTypeDef 				TIM_OCInitStructure;
	
	// 输出比较通道 GPIO 初始化
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO , ENABLE );
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	//重映射PB5为TIM3_CH2引脚
	//当没有重映射时,TIM3的四个通道CH1,CH2,CH3,CH4分别对应PA6,PA7,PB0,PB1
	//当部分重映射时,TIM3的四个通道CH1,CH2,CH3,CH4分别对应PB4,PB5,PB0,PB1
	//当完全重映射时,TIM3的四个通道CH1,CH2,CH3,CH4分别对应PC6,PC7,PC8,PC9
// 	GPIO_AFIODeInit();
	GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3 ,ENABLE );
	
	RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3 , ENABLE );
	// 基本定时器配置,周期1ms,计数周期1000
	TIM_TimeBaseStructure.TIM_Period = 999;
	TIM_TimeBaseStructure.TIM_Prescaler = 71;
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;// 时钟分频因子
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;// 计数器计数模式,设置为向上计数
	TIM_TimeBaseInit( TIM3 , &TIM_TimeBaseStructure);
	// 配置为PWM模式
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;							// 小于门限有效	
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;	// 使能输出
	TIM_OCInitStructure.TIM_Pulse = 0;														// 设置占空比大小
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;			// 有效电平为低
	TIM_OC2Init( TIM3 , &TIM_OCInitStructure );
	TIM_OC3Init( TIM3 , &TIM_OCInitStructure );
	TIM_OC4Init( TIM3 , &TIM_OCInitStructure );
	//使能TIM3 在 CCR2,3,4 上的预装载寄存器
	TIM_OC2PreloadConfig( TIM3 , TIM_OCPreload_Enable );
	TIM_OC3PreloadConfig( TIM3 , TIM_OCPreload_Enable );
	TIM_OC4PreloadConfig( TIM3 , TIM_OCPreload_Enable );
	
	// 使能计数器
	TIM_Cmd( TIM3 , ENABLE );	
}
void TIM6_Configuration(void)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;	
 //使能时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
	//恢复初始设置
	TIM_DeInit(TIM6);	
	//定时器设置
	TIM_TimeBaseStructure.TIM_Prescaler = 7199;	
	TIM_TimeBaseStructure.TIM_Period = 9999; 
	TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
	//使能中断
	TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);
	//使能定时器
	TIM_Cmd(TIM6, ENABLE);
}
void NVIC_Configuration(void)	 //嵌套向量中断控制器配置
{
	NVIC_InitTypeDef NVIC_InitStructure; 
	
	//选择优先级组别 1位抢占优先级 3位子优先级
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);	
	//设置TIM6中断
	//1级抢占式优先级,0级副优先级,使能中断
	NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
	NVIC_Init(&NVIC_InitStructure);
	//设置RTC中断
	//1级抢占式优先级,0级副优先级,使能引脚作为中断源
	NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
	NVIC_Init(&NVIC_InitStructure);
}
void RTC_Configuration(void)
{
	/* Enable PWR and BKP clocks */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
	/* Allow access to BKP Domain */
	PWR_BackupAccessCmd(ENABLE);
	/* Reset Backup Domain */
	BKP_DeInit();
	/* Enable LSE */
	RCC_LSEConfig(RCC_LSE_ON);
	/* Wait till LSE is ready */
	while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);
	/* Select LSE as RTC Clock Source */
	RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
	/* Enable RTC Clock */
	RCC_RTCCLKCmd(ENABLE);
	/* Wait for RTC registers synchronization */
	RTC_WaitForSynchro();
	/* Wait until last write operation on RTC registers has finished */
	RTC_WaitForLastTask();
	/* Enable the RTC Second */
	RTC_ITConfig(RTC_IT_SEC, ENABLE);
	/* Wait until last write operation on RTC registers has finished */
	RTC_WaitForLastTask();
	/* Set RTC prescaler: set RTC period to 1sec */
	RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */
	/* Wait until last write operation on RTC registers has finished */
	RTC_WaitForLastTask();
	PWR_BackupAccessCmd(DISABLE);
}
int main(void)
{
	unsigned char buff[200];
 		GPIO_Configration();
	LCD_Init();
	FLASH_SPI_initialize();
	Flash_TouchCalibrate();
	USART1_Configration();
	ILI9341_Clear( 0,0,240,320,macWHITE );
	
	
	printf("ok\r\n");
	while(1)
	{
			scanf("%s",buff);
		if(strcmp(buff,"红色")==0) 
		{
//			ILI9341_DispString_EN_CH( 12,160, "红色",macWHITE,macRED );
			 LEDRED_ON;
		}
		else if(strcmp(buff,"绿色")==0)
		{
// 
		ILI9341_DispString_EN_CH( 164,160,"绿色",macWHITE,macGREEN );
			LEDGREEN_ON	;
		}
		else if(strcmp(buff,"蓝色")==0) 
		{
// ILI9341_DispString_EN_CH( 88,160, "蓝色",macWHITE,macBLUE );
			 LEDBLUE_ON;
		}
// 		else if(strcmp(buff,"ledgreen_off")==0)
// 		{
// 			LEDGREEN_OFF;
// 		}
// if(KeyScan()==1)
// {
// 		printf("k1 \r\n");
// 	 Delay(5000000);
// }
// 	 else if(KeyScan()==2)
// {
// 		printf("k2 \r\n");
// Delay(5000000);
// }
// 	else if(KeyScan()==3)
// {
// 		printf("k2andk3 \r\n");
// Delay(5000000);
// }
// 		if(strcmp(buff,"key_scan")==0)
// 		{
// 				key_state = KeyScan();
// 				if(key_state == 1)
// 				{
// 					printf("KEY1按下,KEY2未按下\r\n");
// 				}
// 				else
// 				{
// 					printf("KEY2按下,KEY1未按下\r\n");
// 				}
// 		}
// 		else if(strcmp(buff,"你是谁")==0)
// 		{
// 			printf("我是robot\r\n");
// 		}
// 		else if (strcmp(buff,"乘法口诀表")==0)
// 		{
// 			mux();
// 		}
	}
}
// {
// 	
// 	GPIO_Configration();
// // 	LCD_Init();
// 	FLASH_SPI_initialize();
// 	Flash_TouchCalibrate();
// 	USART1_Configration();
// 	
// 	
// // 	TIM6_Configuration();
// // 	TIM3_Configuration();
// // 	RTC_Configuration();
// // 	NVIC_Configuration();
// 	
// // 	UICnt = 1;
// 	while(1)
// 	{
// 		KeyScan() == 0;
// 		LEDBLUE_ON;
// 		LEDRED_ON	;
// 		LEDGREEN_OFF;
// 	
// 		if(KeyScan() == 1)
// 		{
// 			LEDRED_ON	;
// 		 Delay(5000000);
// 			LEDRED_OFF;
// 			Delay(5000000);
// 			
// 			LEDRED_ON	;
// 			LEDGREEN_ON;
// Delay(5000000);	
// 			LEDRED_OFF;
// 			LEDGREEN_OFF;
// 			Delay(5000000);
// 			
// 			LEDGREEN_ON;
// Delay(5000000);	
// 			LEDGREEN_OFF;
// 			Delay(5000000);
// 			
// 			LEDBLUE_ON;
// 			LEDGREEN_ON;
// Delay(5000000);
// 			LEDBLUE_OFF;
// 			LEDGREEN_OFF;
// Delay(5000000);
// 			}
// 			if(KeyScan() == 2)
// 			{	
// 			LEDBLUE_ON;
// Delay(5000000);
// 			LEDBLUE_OFF;
// Delay(5000000);
// 			}
// 			if(KeyScan() == 3)
// 			{
// 			LEDBLUE_ON;
// 			LEDRED_ON	;
// Delay(5000000);
// 			LEDBLUE_OFF;
// 			LEDRED_OFF;
// Delay(5000000);
// }
// 			
// 				
// }
// // 		switch( UICnt )
// // 		{
// // 			case 0: UI00();break;
// // 			case 1: UI01();break;
// // 			default: break;
// // 		}
// 	}

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表