当前位置:首页 > 单片机 > 单片机
[导读]进行串口配置的步骤一、初始化GPIO,配置GPIO模式一个结构体GPIO_InitTypeDef{GPIOMode_TypeDef GPIO_Mode//GPIO模式,输入,输出?uint16_t GPIO_Pin//哪个管脚?GPIOSpeed_TypeDef GPIO_Speed//输出响应速度?如果

进行串口配置的步骤
一、初始化GPIO,配置GPIO模式
一个结构体
GPIO_InitTypeDef{
GPIOMode_TypeDef GPIO_Mode//GPIO模式,输入,输出?
uint16_t GPIO_Pin//哪个管脚?
GPIOSpeed_TypeDef GPIO_Speed//输出响应速度?如果为输入则可以不设置
}
//GPIO_Mode包括以下几种方式
Enumerator: 枚举类型
GPIO_Mode_AIN //模拟输入
GPIO_Mode_IN_FLOATING //悬浮输入
GPIO_Mode_IPD //下拉输入
GPIO_Mode_IPU //上拉输入
GPIO_Mode_Out_OD //开漏输出
GPIO_Mode_Out_PP //推挽输出//push pull 直接输出为高低,当选用开漏的时候需要外接三极管
GPIO_Mode_AF_OD //复用开漏输出
GPIO_Mode_AF_PP //复用推挽输出
//GPIO_Pin包括以下几种方式
#define GPIO_Pin_0 ((uint16_t)0x0001)
#define GPIO_Pin_1 ((uint16_t)0x0002)
#define GPIO_Pin_10 ((uint16_t)0x0400)
#define GPIO_Pin_11 ((uint16_t)0x0800)
#define GPIO_Pin_12 ((uint16_t)0x1000)
#define GPIO_Pin_13 ((uint16_t)0x2000)
#define GPIO_Pin_14 ((uint16_t)0x4000)
#define GPIO_Pin_15 ((uint16_t)0x8000)
#define GPIO_Pin_2 ((uint16_t)0x0004)
#define GPIO_Pin_3 ((uint16_t)0x0008)
#define GPIO_Pin_4 ((uint16_t)0x0010)
#define GPIO_Pin_5 ((uint16_t)0x0020)
#define GPIO_Pin_6 ((uint16_t)0x0040)
#define GPIO_Pin_7 ((uint16_t)0x0080)
#define GPIO_Pin_8 ((uint16_t)0x0100)
#define GPIO_Pin_9 ((uint16_t)0x0200)
#define GPIO_Pin_All ((uint16_t)0xFFFF)
#define IS_GET_GPIO_PIN(PIN)//??
#define IS_GPIO_PIN(PIN) ((((PIN) & (uint16_t)0x00) == 0x00) && ((PIN) != (uint16_t)0x00)) //???
//GPIO_Speed的模式有以下几种,同样是一个枚举类型
Output Maximum frequency selection.
Enumerator:
GPIO_Speed_10MHz
GPIO_Speed_2MHz
GPIO_Speed_50MHz
//TXD为输出,RXD为浮空输入
//选用usart1的时候管脚应该是PA9(TXD),PA10(RXD)
//所以不难得出,初始化的时候它的设计语句应该是
//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP
//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9
//PIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;


//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING
//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10
//PIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
那么至此为止,我的猜测GPIO初始化完毕,验证一下!
/* USART1 GPIO config */
/* Configure USART1 Tx (PA.09) as alternate function push-pull */
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);
/* Configure USART1 Rx (PA.10) as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
看来问题不是很大,只是最后需要加上 GPIO_Init(GPIOA, &GPIO_InitStructure);
来指定对哪个GPIO进行初始化!
二、接下来初始化串口
// USART_InitTypeDef USART_InitStructure;//定义串口初始化结构体
还一个结构体
USART_InitTypeDef{
uint32_t USART_BaudRate//波特比率
uint16_t USART_HardwareFlowControl//硬件流,所谓硬件流待查证
uint16_t USART_Mode//串口模式,这个比较丰富
uint16_t USART_Parity//虽然不认识,但是参测应该是奇偶校验位
uint16_t USART_StopBits//停止位
uint16_t USART_WordLength//长度
}
1、一个一个进行分析,首先是USART_BaudRate
先来一个计算表达式,这个和arm11的有些类似哈
This member configures the USART communication baud rate.
The baud rate is computed using the following formula:


IntegerDivider = ((PCLKx) / (16 * (USART_InitStruct->USART_BaudRate)))//整数部分
FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 16) + 0.5//小数部分
//这里涉及到另外一个结构体USART_InitStruct,跟踪下去,发现这是同一个结构体,按就好办了!直接根据波特率
//就能计算出其整数部分和小数部分,它可以取的数虽然多,但是有误差大小之分!9600 、11520等为0误差的!
2、USART_HardwareFlowControl,它的取值可以是这样
#define IS_USART_HARDWARE_FLOW_CONTROL(CONTROL)
#define USART_HardwareFlowControl_CTS ((uint16_t)0x0200)
#define USART_HardwareFlowControl_None ((uint16_t)0x0000)//据介绍应该是不使用硬件流
#define USART_HardwareFlowControl_RTS ((uint16_t)0x0100)
#define USART_HardwareFlowControl_RTS_CTS ((uint16_t)0x0300)
3、USART_Mode,三种
#define IS_USART_MODE(MODE) ((((MODE) & (uint16_t)0xFFF3) == 0x00) && ((MODE) != (uint16_t)0x00)) //双工
#define USART_Mode_Rx ((uint16_t)0x0004)
#define USART_Mode_Tx ((uint16_t)0x0008)
4、USART_Parity有以下几种取值
#define IS_USART_PARITY(PARITY)
#define USART_Parity_Even ((uint16_t)0x0400)
#define USART_Parity_No ((uint16_t)0x0000)//无奇偶标志位
#define USART_Parity_Odd ((uint16_t)0x0600)
5、USART_StopBits、USART_WordLength这两个很明显,不解释了!
分析上面之后基本上能够确定串口的配置了
//USART_InitStructure.USART_BaudRate = 11520
//USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None
//USART_InitStructure.USART_Mode = IS_USART_MODE(MODE)
//USART_InitStructure.USART_Parity = USART_Parity_No
//USART_InitStructure.USART_StopBits = USART_StopBits_1
//USART_InitStructure.USART_WordLength = USART_WordLength_8b
最后几句就是我们常说的8N1
下面来验证一下!
/* USART1 mode config */
USART_InitStructure.USART_BaudRate = 115200;
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);
/*问题还是有不少啊
1、首先是波特率搞错应该是115200 不是 11520
2、然后是模式选错,全双工应该是USART_Mode_Rx | USART_Mode_Tx;
3、串口只是配置了,又没有初始化
4、还有串口没有使能
三、第一第二步之后,串口初始化完,下面我们就需要使用到串口了,是否还是像以前的单片机那样,
如果想要向串口发送数据就直接写个函数,个BUFF里面写数据呢?不,那效率太低了,我们使用到printf函数
系统库函数调用,下面就需要重定向!
1、我再arm11的参考书上面了解到,所谓重定向就是指,本来如果调用系统库的话,那么printf函数答应的
信息是显示到调试器窗口的,但是当我们重定向后,打印的信息就是在串口里面了,同时也能实现到彩屏上
去。
2、调用库函数必须包含stdio.h函数,现在来跟踪一下这个printf函数到底有什么东西
#include
#include
#include
/* Write formatted output to stdout from the format string FORMAT. */
/* VARARGS1 */
int __printf (const char *format, ...)
{
va_list arg;
int done;


va_start (arg, format);
done = vfprintf (stdout, format, arg);
va_end (arg);


return done;
}
继续看


int vsprintf(char *buf, const char *fmt, va_list args)
{
int len;
unsigned long num;
int i, base;
char *str;
char *s;


int flags; // Flags to number()


int field_width; // Width of output field
int precision; // Min. # of digits for integers; max number of chars for from string
int qualifier; // 'h', 'l', or 'L' for integer fields


for (str = buf; *fmt; fmt++)
{
if (*fmt != '%')
{
*str++ = *fmt;
continue;
}

// Process flags
flags = 0;
repeat:
fmt++; // This also skips first '%'
switch (*fmt)
{
case '-': flags |= LEFT; goto repeat;
case '+': flags |= PLUS; goto repeat;
case ' ': flags |= SPACE; goto repeat;
case '#': flags |= SPECIAL; goto repeat;
case '0': flags |= ZEROPAD; goto repeat;
}

// Get field width
field_width = -1;
if (is_digit(*fmt))
field_width = skip_atoi(&fmt);
else if (*fmt == '*')
{
fmt++;
field_width = va_arg(args, int);
if (field_width < 0)
{
field_width = -field_width;
flags |= LEFT;
}
}


// Get the precision
precision = -1;
if (*fmt == '.')
{
++fmt;
if (is_digit(*fmt))
precision = skip_atoi(&fmt);
else if (*fmt == '*')
{
++fmt;
precision = va_arg(args, int);
}
if (precision < 0) precision = 0;
}


// Get the conversion qualifier
qualifier = -1;
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L')
{
qualifier = *fmt;
fmt++;
}


// Default base
base = 10;


switch (*fmt)
{
case 'c':
if (!(flags & LEFT)) while (--field_width > 0) *str++ = ' ';
*str++ = (unsigned char) va_arg(args, int);
while (--field_width > 0) *str++ = ' ';
continue;


case 's':
s = va_arg(args, char *);
if (!s) s = "";
len = strnlen(s, precision);
if (!(flags & LEFT)) while (len < field_width--) *str++ = ' ';
for (i = 0; i < len; ++i) *str++ = *s++;
while (len < field_width--) *str++ = ' ';
continue;


case 'p':
if (field_width == -1)
{
field_width = 2 * sizeof(void *);
flags |= ZEROPAD;
}
str = number(str, (unsigned long) va_arg(args, void *), 16, field_width, precision, flags);
continue;


case 'n':
if (qualifier == 'l')
{
long *ip = va_arg(args, long *);
*ip = (str - buf);
}
else
{
int *ip = va_arg(args, int *);
*ip = (str - buf);
}
continue;


case 'A':
flags |= LARGE;


case 'a':
if (qualifier == 'l')
str = eaddr(str, va_arg(args, unsigned char *), field_width, precision, flags);
else
str = iaddr(str, va_arg(args, unsigned char *), field_width, precision, flags);
continue;


// Integer number formats - set up the flags and "break"
case 'o':
base = 8;
break;


case 'X':
flags |= LARGE;


case 'x':
base = 16;
break;


case 'd':
case 'i':
flags |= SIGN;


case 'u':
break;


case 'E':
case 'G':
case 'e':
case 'f':
case 'g':
str = flt(str, va_arg(args, double), field_width, precision, *fmt, flags | SIGN);
continue;


default:
if (*fmt != '%') *str++ = '%';
if (*fmt)
*str++ = *fmt;
else
--fmt;
continue;
}


if (qualifier == 'l')
num = va_arg(args, unsigned long);
else if (qualifier == 'h')
{
if (flags & SIGN)
num = va_arg(args, short);
else
num = va_arg(args, unsigned short);
}
else if (flags & SIGN)
num = va_arg(args, int);
else
num = va_arg(args, unsigned int);


str = number(str, num, base, field_width, precision, flags);
}


*str = '';
return str - buf;
}
似乎没有找到我需要的东西,那就算了,这里算我没搞懂了,留着这个问题,直接上代码吧,反正这两个
函数可以肯定是在scanf和printf里面调用的
/*
* 函数名:fputc
* 描述 :重定向c库函数printf到USART1
* 输入 :无
* 输出 :无
* 调用 :由printf调用
*/
int fputc(int ch, FILE *f)
{
/* 将Printf内容发往串口 */
USART_SendData(USART1, (unsigned char) ch);
while (!(USART1->SR & USART_FLAG_TXE));

return (ch);
}


int fgetc(FILE *f)
{
while(!(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET));

return (USART_ReceiveData(USART1));
}
我等着,大家有人能指出我的疑惑,因为VC的库函数都封装起来了,我在库函数里也没有找到fputc
的函数原型,只有等着有人能给我指出来,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

stm32f103zet6是一种嵌入式-微控制器的集成电路(IC),是由ST公司开发的STM32F1系列的其中一种,芯体尺寸是32位,速度是72MHz,程序存储器容量是256KB,程序存储器类型是FLASH,RAM容量是...

关键字: stm32f103zet6 datasheet 引脚图

有时候,我们需要保存少量数据,但是用外扩的ROM又觉得不方便,这时候自然就想到了芯片内部是否自带flash(闪存),据我了解,stm32内部的应该是nor flash,因为如果是nand flash的话,肯定速度是跟不上...

关键字: Flash nor stm32f103zet6

定时器TIM3产生四路PWM波输出。首先介绍一下PWM吧,算是给自己充电,脉冲宽度调制(PWM),是英文“Pulse Width Modulation ”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制...

关键字: pwm stm32f103zet6 定时器

由于前面买的核心板,供电老有问题,使得我现在的项目又改用了以前用的F103ZET6微控制器!1、实验目的1)产生脉宽任意可调的单脉冲(在允许的范围内)2、硬件:通用定时器3、通用定时器43、单脉冲模式介绍单脉冲模式

关键字: stm32f103zet6 通用定时器 单脉冲模式

在完成IO驱动彩屏的试验后,就准备着手使用FSMC来驱动彩屏,先了解一下预备知识一、所谓的FSMC机制简单介绍FSMC在这篇博文里面很清楚,推荐一下http://blog.csdn.net/king_bingge/art...

关键字: fsmc stm32f103zet6 驱动tft

SD卡已经看了两天了,主要是因为测试出来的卡容量不对,所以一直找原因,最终还是发现了,总比不过是单位上面出现了问题,或许是之前没有接触到SD的缘故吧,所以对其中的一些寄存器很不了解,一切都是重新开始,对照

关键字: stm32f103zet6 fat16 文件系统学 sd卡扇区

STM32F103ZET6里共有8个定时器,其中高级定时器有TIM1-TIM5、TIM8,共6个。这里需要使用定时器的级联功能,ST的RM0008 REV12的P388和P399页上有说明对于特定的定时器,怎么去选择级联...

关键字: pwm stm32f103zet6 定时器 级联方式

stm32内部集成的ADC介绍一、参考电压的范围为/*2.4V≦ V ≦3.6V所以它的输入模拟电压范围0

关键字: dma stm32f103zet6

代码这里可以下载http://download.csdn.net/detail/king_bingge/5353528一、uc/OS的实时性是靠什么实现的?1、uC/OS的实时性就是靠定时中断来完成。2、每个时钟节拍到来...

关键字: ii os stm32f103zet6 uc 移植os

看门狗,这个东西在哪都能看见,关于其中简单介绍在我的另一篇博文中有的,那是关于arm11的,不过大体一样http://blog.csdn.net/king_bingge/article/details/8510713一、...

关键字: stm32f103zet6 看门狗
关闭
关闭