STM32学习--USART

串口工作方式;
1.查询:串口程序不断循环查询,看看有没有数据需要它发送。
2.中断:平时串口只要打开中断即可。如果有中断来即需要传输数据,它就马上进行数据的传输。


STM32编程:
1.RCC设置
处常规时钟设置外,需要打开USART对应的IO口时钟,USART时钟,还有管脚功能复用时钟


2.GPIO设置
GPIO管脚配置为推挽输出,将接收管脚配置为浮空输入


3.USART配置
通过USART_InitTypeDef结构体对USART进行初始化操作,采用中断接收数据的方式,需要在USART配置中,
打开中断,同时还要打开串口。


4.NVIC配置
NVIC配置中主要是USART1_IRQChannel的配置,


5.发送/接收数据
发送数据用USART_SendData()函数,接收数据用USART_ReceiveData()函数。参考固件函数库。
发送数据时先开辟一个缓存区,将需要发送的数据送入缓存区,然后再将数据发送出去,接收数据同样也
是先将数据接收到缓存区,然后再进行相应的操作。
  注意在对数据进行发送和接收的时候,要检查USART的状态,只有等到数据发送或接收完成后才能进行
  下一帧  数据的发送或接收
。采用USART_GetFlagStatus()函数。
          同时还要注意的是,在发送数据的最开始,需要清除一下USART的标志位,否则第一帧数据会丢失。因为在
  硬件复位后,USART的状态位TC是置位的,当包含有数据的一帧发送完成后,由硬件将该位置位。只要当USART
  的状态位TC是置位的时候,就可以进行数据的发送。然后TC位的置零是通过软件序列来清除的,具体步骤为:
  先读USART_SR,然后写入USART_DR,只有这样才能清除标志位TC,但在发送第一帧数据的时候,并没有进行读
  USART_SR的操作,而是直接进行写操作,因此TC标志位并没有清空,那么,当发送第一帧数据,然后用
  USART_GetFlagStatus()检测状态时返回的是已经发送完毕(TC位是置1的),所以程序会马上发送下一帧数据,

  这样第一帧的数据就被第二帧数据覆盖了,所以看不到第一帧数据的发送。


源代码:

#incldue"stm32f10x_lib.h"
  
  FlagStatus RX_status;
  void RCC_cfg();
  void GPIO_cfg();
  void USART_cfg();
  void NVIC_cfg();
  
  int main()
  {
int i;
unsigned char TxBuf1[]="Welcome to www.peix365.com!"
RCC_cfg();
GPIO_cfg();
USART_cfg();
NVIC_cfg();
  //清除标志位,否则第1位数据会丢失
USART_ClearFlag(USART1,USART_FLAG_TC);

//发送数据PD2(LED1)显示正在发送的数据,当有数据发送时,LED1会亮
for(i=0;TxBuf1[i]!='\0';i++)
{
USART_SendData(USART1,TxBuf1[i]);
GPIO_SetBits(GPIOD,GPIO_pin_2)
//等待数据发送完毕
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET)
GPIO_ResetBits(GPIOD,GPIO_Pin_2)
}
while(1);
  }
  
  
  //RCC时钟配置
  void RCC_cfg()
  {
//定义错误状态变量
ErrorStatus HSEStartUpStatus;
//将RCC寄存器重新设置为缺省值
RCC_DeInit();
//打开外部高速时钟晶振
RCC_HSEConfig(RCC_HSE_ON);
//等待外部高速时钟晶振工作
HSEStartUpStatus=RCC_WaitForHSEStartUp();
if(HSEStartUpStatus==SUCCESS)
{
//设置PLL时钟,为HSE的2倍频
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_2);

//使能PLL
RCC_PLLCmd(ENABLE);

//等待PLL准备就绪
if(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)!=RESET);

//设置PLL为系统时钟源
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

//判断PLL是否是系统时钟
if(RCC_GetSYSCLKSource()==0x08);
//设置AHB时钟(HCLK)为系统时钟
RCC_HCLKConfig(RCC_SYSCLK_Div1);

//设置高速AHB时钟(APB2)为HCLK时钟
RCC_PCLK2Config(RCC_HCLK_Div1);

//设置低速AHB时钟(APB1)为HCLK的2分频时钟
RCC_PCLK1Config(RCC_HCLK_Div2);

//设置FLASH代码延时
FLASH_SetLatency(FLASH_Latency_2);

//使能预取值缓存
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

}
//打开GPIO时钟,复用功能,使能串口1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO|RCC_APB2Periph_USART1,ENABLE);
  }
  
  
  //IO口配置
  void GPIO_cfg()
  {
GPIO_InitTypeDef GPIO_InitStructure;

//PA9作为USART1的TX端,打开复用,负责发送数据
//初始化GPIO口部分成员
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
//初始化GPIO口
GPIO_Init(GPIOA,&GPIO_InitStructure);

//PA10作为USART1的RX端,负责接收数据
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA,&GPIO_InitStructure);
  }
  
//LED显示串口正在发送/接收的数据
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT_PP;
GPIO_Init(GPIOD,&GPIO_InitStructure);

  //串口初始化
  void USART_cfg()
  {
USART_InitTypeDef USART_InitStructure;
//将结构体设置为缺省状态
USART_StructInit(&USART_InitStructure);
//波特率设置为9600
USART_InitStructure.USART_BandRate=9600;
//帧数据宽度设置为8bits
USART_InitStructure.WordLength=USART_WordLength_8b;
//帧结尾1个停止位
USART_InitStructure.USART_StopBits=USART_StopBits_1;
//无奇偶校验位
USART_InitStructure.USART_Parity=USART_Parity_No;
//发送/接收使能
USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
//硬件流控制失能
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
//初始化串口1
USART_Init(USART1,&USART_InitStructure);
//打开串口1中断响应函数
USART_ITConfig(USART1,USART_IT_RXNE|USART_IT_TXE,ENABLE);
//打开(使能)串口1
USART_Cmd(USART1,ENABLE);
  }
  
  //配置中断
  void NVIC_cfg();
  {
NVIC_InitTypeDef NVIC_InitTypeDef;

//选择中断分组2
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

//选择串口1中断
NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQChannel;

//抢占式中断优先级为0
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;

//响应式中断优先级设置为0
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;

//IRQ 通道使能
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
//中断优先级初始化
NVIC_Init(&NVIC_InitStructure);
  }
  
  //然后在stm32f10x_it.c文件中找到相应的中断处理函数,并填入以下内容。
  //注意在stm32f10x_it.c中,要声明一下外部变量RX_status
  extern FlagStatus RX_status;
  
  void USART1_IRQHandler(void)
  {
GPIO_SetBits(GPIOD,GPIO_Pin_2);
//确认是否接收到数据
RX_status=USART_GetFlagStatus(USART1,USART_FLAG_RXNE);
//接收到数据
if(RX_status==SET)
{
//将数据回送
USART_SendData(USART1,USART_ReceiveData(USART1));
//等待数据发送完毕
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET)
GPIO_ResetBits(GPIOD,GPIO_Pin_2)
}
  }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值