STM32F103xx 的USART1 移植到STM32F105RBT6

news2024/12/23 8:21:43

1. STM32F103 和 STM32F105 的时钟配置区别,STM32F105 默认使用的外部晶振是25Mhz,需要改成8Mhz

stm32f10x.h

#if !defined  HSE_VALUE
 #ifdef STM32F10X_CL
  #define HSE_VALUE    ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
 #else 
  #define HSE_VALUE    ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
 #endif /* STM32F10X_CL */
#endif /* HSE_VALUE */

在这里插入图片描述

system_stm32f10x.c

#ifdef STM32F10X_CL
    /* Configure PLLs ------------------------------------------------------*/
    /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
    /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */

    RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
                              RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
    RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV2 | RCC_CFGR2_PLL2MUL10 |
                             RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);
  
    /* Enable PLL2 */
    RCC->CR |= RCC_CR_PLL2ON;
    /* Wait till PLL2 is ready */
    while((RCC->CR & RCC_CR_PLL2RDY) == 0)
    {
    }
    
   
    /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ 
    RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 
                            RCC_CFGR_PLLMULL9); 
#else    
    /*  PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
                                        RCC_CFGR_PLLMULL));
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
#endif /* STM32F10X_CL */

在这里插入图片描述

2. 在keil里面修改宏定义,每个宏之间用逗号隔开, STM32F10X_CL 宏也可以不定义,因为在芯片选STM32F105RBT6 就默认定义了这个宏

在这里插入图片描述

3. 测试时钟配置是否OK

RCC_ClocksTypeDef get_rcc_clock;
RCC_GetClocksFreq(&get_rcc_clock);

在这里插入图片描述

4. printf 重定向, 重定向后printf 就会往串口里面打日志了,然后就可以用串口工具SSCOM看日志了

USART1.c

#if 1
#pragma import(__use_no_semihosting)             
//±ê×¼¿âÐèÒªµÄÖ§³Öº¯Êý                 
struct __FILE 
{ 
	int handle; 

}; 

FILE __stdout;       
//¶¨Òå_sys_exit()ÒÔ±ÜÃâʹÓðëÖ÷»úģʽ    
 void _sys_exit(int x) 
{ 
	x = x; 
} 
//Öض¨Òåfputcº¯Êý 
//Öض¨Òåfputcº¯Êý 
int fputc(int ch, FILE *f)
{      
	while((USART1->SR&0X40)==0)
		;//Ñ­»··¢ËÍ,Ö±µ½·¢ËÍÍê±Ï   
    USART1->DR = (u8) ch;      
	return ch;
}
#endif

5. 串口打印的日志全是乱码的话,如果时钟配置OK的话就把波特率降一点,因为我的板子在串口TX,RX线上分别接了一个光耦,所以波特率不能用太高,115200 的话就会乱码,光耦反应不过来,用9600 的波特率就好了

TX 接一个光耦的情况下,由于光耦内部存在电容和滞后现象,信号不能瞬间传导,因此在高速传输时,会出现上升沿或下降沿不够陡峭、波形失真、误码率过高等问题,从而影响通信质量和可靠性。因此,在此种情况下,建议降低串口通信的波特率,以确保通信质量和稳定性。具体的波特率取值视情况而定,一般可以通过实验来确定合适的波特率。

int main(void)
{
	RCC_ClocksTypeDef get_rcc_clock;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);			//ÉèÖÃÖжϷÖ×é
	delay_init();			//ÑÓʱº¯Êý³õʼ»¯
  ST_USART1_Init(9600);		//³õʼ»¯USART1
	
	RCC_GetClocksFreq(&get_rcc_clock);

	while(1)
	{
		printf("123\r\n");
		delay_ms(500);
	}
}

在这里插入图片描述

6. 打开串口工具,原来用115200 波特率是乱码的,换9600 就好了,看自己板子吧,

在这里插入图片描述

7. 串口初始化

ST_USART1.c

#include "sys.h"
#include "ST_USART1.h"



//¼ÓÈëÒÔÏ´úÂë,Ö§³Öprintfº¯Êý,¶ø²»ÐèҪѡÔñuse MicroLIB	  
#if 1
#pragma import(__use_no_semihosting)             
//±ê×¼¿âÐèÒªµÄÖ§³Öº¯Êý                 
struct __FILE 
{ 
	int handle; 

}; 

FILE __stdout;       
//¶¨Òå_sys_exit()ÒÔ±ÜÃâʹÓðëÖ÷»úģʽ    
 void _sys_exit(int x) 
{ 
	x = x; 
} 
//Öض¨Òåfputcº¯Êý 
//Öض¨Òåfputcº¯Êý 
int fputc(int ch, FILE *f)
{      
	while((USART1->SR&0X40)==0)
		;//Ñ­»··¢ËÍ,Ö±µ½·¢ËÍÍê±Ï   
    USART1->DR = (u8) ch;      
	return ch;
}
#endif 

#if EN_USART1_RX  //Èç¹û¶¨ÒåÁËʹÄܽÓÊÕ

u8 USART1_RX_BUF[USART1_REC_MAX_LEN];//½ÓÊÕ»º´æ£¬×î´óUSART_REC_MAX_LEN

u16 USART1_RX_STA=0;//½ÓÊÕ״̬±ê¼Ç
//½ÓÊÕ״̬
//bit15£¬	½ÓÊÕÍê³É±êÖ¾
//bit14£¬	½ÓÊÕµ½0x0d
//bit13~0£¬	½ÓÊÕµ½µÄÓÐЧ×Ö½ÚÊýÄ¿

/*
Copyright:
@file: ST_USART1.C
@Version: V0.0.1
@Author: dragon   
@Date: 2020/06/14
@Description: USART1 Init
@Param:  bound:´®¿Ú²¨ÌØÂÊ
@Retval: None
@Note: None
*/
void ST_USART1_Init(u32 bound)
	{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);//ʹÄÜUSART1,GPIOAʱÖÓ
		
	USART_DeInit(USART1);
		
	//GPIOA.9
	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);
	
	//GPIOA.10
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING ;
	GPIO_Init(GPIOA, &GPIO_InitStructure);//³õʼ»¯GPIOA.10  
	
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;	
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;	
	NVIC_Init(&NVIC_InitStructure);	
	
	USART_InitStructure.USART_BaudRate = bound;
	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_ITConfig(USART1, USART_IT_RXNE, ENABLE);
  USART_Cmd(USART1, ENABLE); 
}

void USART1_IRQHandler(void)                	
	{
	u8 Res;
  #if SYSTEM_SUPPORT_OS 
 	 OSIntEnter();    
  #endif
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
		{
		Res =USART_ReceiveData(USART1);	
			
		if((USART1_RX_STA&0x8000)==0)
			{
			if(USART1_RX_STA&0x4000)
				{
				  if(Res!=0x0a)
						USART1_RX_STA=0;
				  else 
						USART1_RX_STA|=0x8000;
				}
			
			else 
				{	
				if(Res==0x0d)
					USART1_RX_STA|=0x4000;
				else
					{
					USART1_RX_BUF[USART1_RX_STA&0X3FFF]=Res ;
					USART1_RX_STA++;
					if(USART1_RX_STA>(USART1_REC_MAX_LEN-1))
					   {
						   USART1_RX_STA=0;
					     printf("USART1 over max length!\n");
				     }
					}
									
				}
			}   		 
     } 
		#if SYSTEM_SUPPORT_OS
	   OSIntExit();  											 
    #endif
	 }
	
	 void ST_Usart1_Receive_Data()
	 {
		 u16 len=0;
		 u16 t;
		if(USART1_RX_STA&0x8000)
		 {					   
			len=USART1_RX_STA&0x3fff;
			printf("\r\nUSART1 Received data is:\r\n\r\n");
			for(t=0;t<len;t++)
			{
				USART_SendData(USART1, USART1_RX_BUF[t]);
				while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
			}
			printf("\r\n\r\n");
			USART1_RX_STA=0;
	   }
  }
#endif

ST_USART1.h

#ifndef __ST_USART1_H
#define __ST_USART1_H
#include "sys.h"
#include "stdio.h"


#define USART1_REC_MAX_LEN 128//¶¨Òå×î´ó½ÓÊÕ×Ö½Ú128
#define EN_USART1_RX 1 //ʹÄÜ£¨1£©/½ûÖ¹£¨0£©´®¿Ú1½ÓÊÕ

extern u8 USART1_RX_BUF[USART1_REC_MAX_LEN];//½ÓÊÕ»º´æ£¬×î´óUSART_REC_MAX_LEN¸ö×Ö½Ú£¬Ä©×Ö½ÚΪ»»Ðзû
extern u16 USART1_RX_STA;//½ÓÊÕ״̬±êÖ¾

void ST_USART1_Init(u32 bound);
void ST_Usart1_Receive_Data(void);
#endif
```






本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/614489.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

初学Mybatis

1、Mybatis概述 Mybatis基于java的持久层框架&#xff0c;内部封装了JDBC&#xff0c;开发者只需要关注SQL语句 特点 1、sql语句在xml里&#xff0c;便于统一管理和优化 2、解除sql与程序代码耦合&#xff1a;通过DAO层&#xff0c;将业务逻辑和数据访问逻辑分离 提供映射标签&…

Spark简介和三种部署方式

1.Spark简介 1.1 Spark介绍 开源集群计算系统&#xff0c;致力于更快的处理数据 Both fast to run and fast to wrtie Spark 是专为大规模数据处理而设计的快速通用的计算引擎 Spark 可以完成各种运算&#xff0c;包括 SQL 查询、文本处理、机器学习等 Spark由Scala语言开发&a…

【618期间】超过200小时的课程全都有优惠,全年最好的加入有三AI学习的时间来了~...

正值2023年618期间&#xff0c;既然是全民购物节&#xff0c;有三AI所有付费的视频课程开启优惠活动&#xff0c;即日起至节日结束&#xff08;6月18日晚23:59&#xff09;。 当前已有课程包括数据使用/模型分析/图像分类/图像分割/目标检测/图像生成/图像翻译/图像增强/视频分…

Promise.allSettled使用

1、const apiList await Promise.allSettled([systemApi]).then((result: any) > { if (result[0].status fulfilled) { console.log(result[0].value) return result[0].value.data } }) console.log(apiList, apiList) 2、 const systemApi new Promise((resolve, rej…

Selenium Webdriver原理、架构过往今生

下方查看历史精选文章 重磅发布 - 自动化框架基础指南pdfv1.1大数据测试过程、策略及挑战 测试框架原理&#xff0c;构建成功的基石 在自动化测试工作之前&#xff0c;你应该知道的10条建议 在自动化测试中&#xff0c;重要的不是工具 简介 Selenium是一种流行的自动化测试工具…

[深度学习入门案例2]基于卷积神经网络与Keras构建人脸识别模型

文章目录 一、工具与环境 二、深度学习环境的搭建 三、基于卷积神经网络人脸识别模型的构建与测试 1.核心代码 第一步&#xff1a;采集自己和他人的人脸特征数据&#xff0c;分别对应数据标签0和1 第二步&#xff1a;训练识别人脸特征的模型&#xff0c;并将模型保存为.h5…

网络排障全景指南手册v1.0pdf 全网发布

大家好&#xff0c;这里是极客重生&#xff0c;我是大师兄&#xff0c;我把之前关于丢包排障文章整理了一下&#xff0c;形成一个网络丢包排障手册pdf文档 &#xff0c;希望可以帮助大家快速排障网络问题。 当前版本主要针对是服务端网络问题排障&#xff0c;包括网卡&#xff…

怎么将文件转为扫描件

推荐两个工具&#xff0c;也算是给自己记一下 1、手机&#xff1a;扫描全能王APP 太好使了&#xff0c;可以直接拍照并转换为扫描件 不开会员的话会出现水印&#xff0c;因为我都是自己用或者交作业就没开 支持读取相册&#xff0c;一次一张、多张都可以 如果不想要水印也…

chatgpt赋能python:Python制图:让数据图像化

Python制图&#xff1a;让数据图像化 数据可视化是近年来越来越流行的技术&#xff0c;其能够将大量的数字和信息变成直观有趣的图形。Python是一个广泛使用的编程语言&#xff0c;也是制图利器。Python的绘图库非常丰富&#xff0c;包括流行的Matplotlib、Seaborn和Plotly等&…

进程的控制

文章目录 1. Linux线程创建和等待2. 线程ID3. 线程的局部存储4. 分离线程 1. Linux线程创建和等待 这是前面写过的创建线程的代码&#xff0c;现在我们把线程的ID打印看一下&#xff1a; 我们可以看到线程的id特别大&#xff0c;这是为什么呢&#xff1f;我们后面再说。 如果…

一文简介Spring的IOC和AOP

1、IOC 概念&#xff1a;所谓控制反转&#xff0c;就是把原先我们代码里面需要实现的对象创建、依赖的代码&#xff0c;反转给容器来帮忙实现。当应用了IoC&#xff0c;一个对象依赖的其它对象会通过被动的方式传递进来&#xff0c;而不是这个对象自己创建或者查找依赖对象。 …

飞桨AI Day落地澳门高校!助力大湾区打造产教融合新范式

为了推动大湾区建设产教融合的人工智能技术生态&#xff0c;加快培养助力社会经济高质量发展的复合型 AI 人才&#xff0c;飞桨校园 AI Day 登陆澳门&#xff0c;开展《AI 技术发展趋势与人才培养》主题讲座 &#xff0c;邀请多位澳门科技大学及百度嘉宾&#xff0c;解读当下AI…

【中兴ZXV10 B860A1.1】

这里写自定义目录标题 开启adb开启adb 部分盒子的ADB调试位置,在设置页面中可以有开启开发者选项。地区界面不同,位置不同有的在设置里。 如果找不到,直接按住遥控器【返回】不放,5秒后,快速不停按【左键】。 点击【打开ADB调试】这时侯让你输入密码 下载zikaikeji.ap…

chatgpt赋能python:Python如何创建集合——你必须知道的所有知识

Python 如何创建集合——你必须知道的所有知识 作为一位有10年 Python 编程经验的工程师&#xff0c;我可以告诉你&#xff0c;Python 集合是编程中非常重要的一部分。如果你不知道如何创建集合&#xff0c;那么你可能会错过很多东西。所以&#xff0c;让我们深入探讨 Python …

提供一个使用Npoi生成excel文档的例子,应能帮助到各位使用Npoi的朋友,因为具有多种情形处理

提供一个使用Npoi生成excel文档的例子&#xff0c;应能帮助到各位使用Npoi的朋友&#xff0c;因为具有多种情形处理 照例&#xff0c;文章开始之前&#xff0c;先看下最终效果&#xff1a; 实现的需求点如下&#xff1a; 1.第一行大标题加了背景色&#xff0c;且这个背景色&…

解密 JS 参数:逆向工程的实用技巧

大家好&#xff0c;我是安果&#xff01; 大部分网站都会对关键参数进行加密&#xff0c;JS 逆向时&#xff0c;我们首要任务是定位参数具体的加密逻辑 常见方式包含&#xff1a;关键字搜索、堆栈调试、XHR 及事件监听、AST 内存漫游、JS Hook 注入等 本篇文章以 JS Hook 注入定…

惊爆!Python打造花式照片墙!

大家注意&#xff1a;因为微信最近又改了推送机制&#xff0c;经常有小伙伴说错过了之前被删的文章&#xff0c;比如前阵子冒着风险写的爬虫&#xff0c;再比如一些限时福利&#xff0c;错过了就是错过了。 所以建议大家加个星标&#xff0c;就能第一时间收到推送。&#x1f44…

NXP IMX8M + Ethercat+Codesys工业实时运动控制解决方案

面向边缘计算应用的全新i.MX 8M Plus异构应用处理器&#xff0c;搭载专用神经网络加速器、独立实时子系统、双摄像头ISP、高性能DSP和GPU。 恩智浦半导体宣布推出i.MX 8M Plus应用处理器&#xff0c;进一步丰富其业界领先的产品组合。这是恩智浦首个集成了专用神经处理引擎&…

G0第25章:Gin框架进阶项目实战

1 Gin框架源码解析 通过阅读gin框架的源码来探究gin框架路由与中间件的秘密。 1.1 Gin框架路由详解 gin框架使用的是定制版本的httprouter&#xff0c;其路由的原理是大量使用公共前缀的树结构&#xff0c;它基本上是一个紧凑的Trie tree 或者只是&#xff08;Radix Tree&am…

Linux Tomcat服务 虚拟主机 多实例部署

Tomcat 服务 Tomcat 是 Java 语言开发的&#xff0c;Tomcat 服务器是一个免费的开放源代码的 Web 应用服务器。Tomcat 属于轻量级应用服务器&#xff0c;在中小型系统和并发访问用户不是很多的场合下被普遍使用&#xff0c;是开发和调试 java开发的JSP 动态页面程序的首选。一般…