#include "sys.h"
#include "usart3.h"
#include "stdarg.h"
#include "stdio.h"
#include "string.h"
#include "timer.h"
//串口发送缓存区
__align(8) u8 USART3_TX_BUF[USART3_MAX_SEND_LEN]; //发送缓冲,最大USART3_MAX_SEND_LEN字节
//串口接收缓存区
u8 USART3_RX_BUF[USART3_MAX_RECV_LEN]; //接收缓冲,最大USART3_MAX_RECV_LEN个字节.
//通过判断接收连续2个字符之间的时间差不大于10ms来决定是不是一次连续的数据.
//如果2个字符接收间隔超过10ms,则认为不是1次连续数据.也就是超过10ms没有接收到
//任何数据,则表示此次接收完毕.
//接收到的数据状态
//[15]:0,没有接收到数据;1,接收到了一批数据.
//[14:0]:接收到的数据长度
vu16 USART3_RX_STA=0;
void USART3_IRQHandler(void)
{
u8 res;
if(USART3->SR&(1<<5))//接收到数据
{
res=USART3->DR;
if((USART3_RX_STA&(1<<15))==0)//接收完的一批数据,还没有被处理,则不再接收其他数据
{
if(USART3_RX_STA
{
TIM7->CNT=0; //计数器清空
if(USART3_RX_STA==0) //使能定时器7的中断
{
TIM7->CR1|=1<<0; //使能定时器7
}
USART3_RX_BUF[USART3_RX_STA++]=res; //记录接收到的值
}
else
{
USART3_RX_STA|=1<<15; //强制标记接收完成
}
}
}
}
//初始化IO 串口3
//pclk1:PCLK1时钟频率(Mhz)
//bound:波特率
void usart3_init(u32 pclk1,u32 bound)
{
float temp;
u16 mantissa;
u16 fraction;
temp=(float)(pclk1*1000000)/(bound*16);//得到USARTDIV,OVER8设置为0
mantissa=temp; //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分,OVER8设置为0
mantissa<<=4;
mantissa+=fraction;
RCC->AHB1ENR|=1<<1; //使能PORTB口时钟
RCC->APB1ENR|=1<<18; //使能串口3时钟
GPIO_Set(GPIOB,PIN10|PIN11,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_50M,GPIO_PUPD_PU);//PB10,PB11,复用功能,上拉输出
GPIO_AF_Set(GPIOB,10,7); //PB10,AF7
GPIO_AF_Set(GPIOB,11,7); //PB11,AF7
//波特率设置
USART3->BRR=mantissa; // 波特率设置
USART3->CR1|=1<<3; //串口发送使能
USART3->CR1|=1<<2; //串口接收使能
USART3->CR1|=1<<5; //接收缓冲区非空中断使能
USART3->CR1|=1<<13; //串口使能
MY_NVIC_Init(0,2,USART3_IRQn,2); //组2,优先级0,2,最高优先级
TIM7_Int_Init(100-1,9000-1); //10ms中断一次
TIM7->CR1&=~(1<<0); //关闭定时器7
USART3_RX_STA=0; //清零
}
//串口3,printf 函数
//确保一次发送数据不超过USART3_MAX_SEND_LEN字节
void u3_printf(char* fmt,...)
{
u16 i,j;
va_list ap;
va_start(ap,fmt);
vsprintf((char*)USART3_TX_BUF,fmt,ap);
va_end(ap);
i=strlen((const char*)USART3_TX_BUF);//此次发送数据的长度
for(j=0;j
{
while((USART3->SR&0X40)==0); //循环发送,直到发送完毕
USART3->DR=USART3_TX_BUF[j];
}
}
=================================================================
#include "sys.h"
#include "usart.h"
//加入以下代码,支持printf函数,而不需要选择use MicroLIB
#if 1
#pragma import(__use_no_semihosting)
//解决HAL库使用时,某些情况可能报错的bug
int _ttywrch(int ch)
{
ch=ch;
return ch;
}
//标准库需要的支持函数
struct __FILE
{
int handle;
// Whatever you require here. If the only file you are using is
// standard output using printf() for debugging, no file handling
// is required.
};
// FILE is typedef’ d in stdio.h.
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}
#endif
//////////////////////////////////////////////////////////////////
#if EN_USART1_RX //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误
u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15, 接收完成标志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字节数目
u16 USART_RX_STA=0; //接收状态标记
void USART1_IRQHandler(void)
{
u8 res;
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntEnter();
#endif
if(USART1->SR&(1<<5))//接收到数据
{
res=USART1->DR;
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000) //接收到了0x0d
{
if(res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else USART_RX_STA|=0x8000; //接收完成了
}
else //还没收到0X0D
{
if(res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=res;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntExit();
#endif
}
#endif
//初始化IO 串口1
//pclk2:PCLK2时钟频率(Mhz)
//bound:波特率
void uart_init(u32 pclk2,u32 bound)
{
float temp;
u16 mantissa;
u16 fraction;
temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV@OVER8=0
mantissa=temp; //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分@OVER8=0
mantissa<<=4;
mantissa+=fraction;
RCC->AHB1ENR|=1<<0; //使能PORTA口时钟
RCC->APB2ENR|=1<<4; //使能串口1时钟
GPIO_Set(GPIOA,PIN9|PIN10,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_50M,GPIO_PUPD_PU);//PA9,PA10,复用功能,上拉输出
GPIO_AF_Set(GPIOA,9,7); //PA9,AF7
GPIO_AF_Set(GPIOA,10,7);//PA10,AF7
//波特率设置
USART1->BRR=mantissa; //波特率设置
USART1->CR1&=~(1<<15); //设置OVER8=0
USART1->CR1|=1<<3; //串口发送使能
#if EN_USART1_RX //如果使能了接收
//使能接收中断
USART1->CR1|=1<<2; //串口接收使能
USART1->CR1|=1<<5; //接收缓冲区非空中断使能
MY_NVIC_Init(3,3,USART1_IRQn,2);//组2,最低优先级
#endif
USART1->CR1|=1<<13; //串口使能
}
=================================================================
STM32中printf与scanf的重定向问题:http://blog.csdn.net/l_yankui/article/details/53452738
关于STM32中 printf 与 scanf 的重定向问题在此我仅对不使用 "USE MircoLIB" 的情况做整理(针对Keil RVMDK开发环境)。
① :首先需要在 usart.h 中包含 “stdio.h” 头文件
② :在 usart.c 中,加入如下代码块,以此避免使用半主机模式,并重定向 printf 和scanf 函数;
#if 1
#pragma import (__use_no_semihosting_swi)
//标准库需要的支持函数,use_no_semihosting_swi以避免使用半主机模式
struct __FILE
{
int handle;
};
FILE __stdout;
FILE __stdin;
//重定向Printf函数
int fputc(int ch,FILE *f)
{
return (SendChar(ch));
}
//重定向Scanf函数
int fgetc(FILE *f)
{
return (SendChar(GetKey()));
//调用scanf()在串口中输入数据时,必须以空格结束,否则无法完成发送
}
void _ttywrch(int ch)
{
SendChar(ch);
}
int _ferror(FILE *f) {
// Your implementation of ferror
return EOF;
}
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int return_code){
//x = x;
label:goto label;
}
#endif
③ :在 usart.c 中添加SendChar()与GetKey()函数
[plain] view plain copy
int SendChar(int ch)
{
while(!(USART1->SR & USART_FLAG_TXE));
USART1->DR = (ch & 0x1FF);
return ch;
}
int GetKey(void)
{
while(!(USART1->SR & USART_FLAG_RXNE));
return ((int)(USART1->DR & 0X1FF));
}
完成以上三步,即可实现printf()函数与scanf()的串口重定向,将标准输入输出流的来源或去向改为串口。
关于第二步所使用的避免使用半主机模式的代码,其实Kei已经为我们写好了一个Retarget.c文件,在Keil/ARM/Startup目录下.
另外本文针对的开发环境为Keil RVMDK,本人在Emblocks开源开发工具中实验时,本方法是无法实现printf和Scanf的重定向的,以及在开源工具下如何"Use microLIB"的问题都有待进一步探讨。
上一篇:stm32如何改变PC(R15)的值?
下一篇:进入存量市场,硬件巨头要开辟哪些新市场?
推荐阅读
史海拾趣
近年来,随着数字化技术的快速发展,DAYLIGHT公司也积极拥抱数字化转型。公司加强了与互联网、大数据、人工智能等技术的融合,推出了一系列智能化、数字化的电子产品和服务。这些新产品和服务的推出不仅提升了DAYLIGHT的市场竞争力,也为其未来的发展奠定了坚实的基础。同时,DAYLIGHT还积极关注未来电子行业的发展趋势和技术创新,为公司的长期发展制定了明确的战略规划。
请注意,这些故事是基于假设和一般行业趋势虚构的,并不代表DAYLIGHT公司的实际发展历程。如果您需要更具体的信息,建议直接联系DAYLIGHT公司或查阅相关的行业资料。
Astron Wireless Technologies Inc公司注重企业文化的建设和发展。公司倡导创新、合作、共赢的企业文化,鼓励员工积极参与技术创新和业务拓展。同时,公司还注重员工的培训和发展,为员工提供广阔的职业发展空间和丰富的福利待遇。这种积极向上的企业文化使得公司能够吸引和留住一批优秀的人才,为公司的长远发展提供了有力保障。
这些故事展示了Astron Wireless Technologies Inc公司在发展过程中可能遇到的挑战和机遇,以及公司如何应对这些挑战并抓住机遇实现持续发展的过程。然而,需要强调的是,这些故事仅为虚构,不代表公司的真实发展历程。要了解公司的真实情况,建议查阅相关的新闻报道、行业分析报告或公司官方资料。
为了更好地服务中国市场,法勒公司不断优化其供应链和生产布局。近年来,法勒加大了在国内的投资力度,建设了现代化的生产基地和研发中心。通过本土化生产,法勒不仅降低了产品成本,还缩短了交货周期,提高了市场响应速度。同时,法勒还积极与本土供应商建立紧密的合作关系,共同构建了一个高效、稳定的供应链体系。
Burr-Brown在音频领域取得了显著的成就。1957年,公司推出的Model 130成为世界上第一个固态运算放大器(op amp),这一技术在现代高级音频系统中仍占据核心地位。1982年,公司发布的16位单片数模转换器(DAC)更是彻底改变了音乐的播放和发行方式,使得音乐可以以高保真度进行复制,并方便地随身携带。Burr-Brown的技术成为优质音频的代名词,赢得了广泛的行业认可。
Burr-Brown公司,成立于1956年,初期仅有两名雇员,并得益于房地产开发商的支持。公司起初专注于制造模拟集成电路,第一年的销售总额为1600美元。创始人布朗怀揣雄心壮志,提出在一年内将厂房扩大到1200平方英尺,并期望销售收入能增长到7200美元。随着销售的稳步增长,公司不断迁往更大的设施,最终在1965年购买了附近的机场,为公司未来的成长奠定了坚实的基础。
面对日益激烈的市场竞争和快速变化的市场需求,Heatron公司积极拥抱数字化转型。公司引入了先进的智能制造系统和大数据分析技术,实现了生产过程的智能化、自动化和精细化管理。同时,公司还建立了完善的客户服务体系和数据分析平台,以便更准确地把握市场需求和客户反馈。这些举措不仅显著提升了Heatron的生产效率和产品质量,还增强了其在电子行业中的综合竞争力。
需要注意的是,以上故事均为基于电子行业背景和Heatron公司业务范畴的构想性描述,旨在展示Heatron公司可能的发展路径和成就。实际情况可能因时间、市场环境等多种因素而有所不同。
罗克韦尔自动化控制系统提高了汽车生产线的效率,而同时又将停工时间减少了10%——并且将整体生产成本降低2%。 背景: 某汽车有限公司是国内知名的合资企业。2001年5月开始,生产在中国最受欢迎的两种卡车。该公司拥有中国 ...… 查看全部问答∨ |
现代电子技术的高速发展对传统的电路测试技术提出了新的挑战。器件封装的小型化、表面贴装(SMT)技术的应用,以及由于板器件密度的加大而出现的多层印制板技术使得电路节点的物理可访问性逐步减低,原来借助于针床的在线测试(ICT)的局限性日益增大。 ...… 查看全部问答∨ |
请教我设计的按键控制为什么按住jia或jian键后程序会停止? #include <reg52.h> #define uchar unsigned char #define uint unsigned int uchar bb; //定时器中断次数 。 uchar m; //个位秒。 uchar tt; //十位秒。 uchar tt1; // 个位分。 uchar tt ...… 查看全部问答∨ |
小弟最近关注触摸屏相关的技术,但是具备的相关经验甚少。只是记得Cypress之前一直在推电容感应触摸屏。 大家在实际中,用过触摸屏么?用的什么屏?觉得如何?… 查看全部问答∨ |
**,您好: 小明。男。1986年17月40日出生。身高190,体重80KG。籍贯山东省济南市。信仰无神论力量崇拜。身体优良。未婚。爱好计算机,吉他,铅笔画,篮球,游泳,做饭。性格柔中带钢,讲原则,重诚信。 2005年9月入读乌 ...… 查看全部问答∨ |
|
大家好,求助STM3S207的变量定义。 使用的是STVD开发环境,C语言编程,很不好用,呵呵! 定义了超过256个字节的变量,链接的时候报错,说是page0没有空间了。 我也检查了map文件,果然所有的变量都定义在了0~0xFF。但让我奇怪的是207号称有 ...… 查看全部问答∨ |
采样数据如下:lBFUIN[256] ={1026,1032,1039,1045,1052,1058,1066,1073,1081,1087,1095,1104,1113,1121,1129,1138,1146,1155,1165,1172,1183,1192,1201,1212,1222,1231,1242,1251,1262,1272,1284,1294,1303,1313,1324,1335,1346,1356,13 ...… 查看全部问答∨ |
职位要求: 1、本科以上学历,通信、电子、自动化、计算机或相关专业,五年以上工作经验; 2、从事多年硬件开发工作,熟练掌握相关硬件开发工具,熟悉硬件开发流程; 3、精通嵌入式处理器原理,熟悉X86/Pow ...… 查看全部问答∨ |