stm32-串口

USART:(Universal Synchronous/Asynchronous Receiver/Transmitter)

通用同步/异步串行接收/发送器

USART是一个全双工通用同步/异步串行收发模块,该接口是一个高度灵活的串行通信设备。

串口设置的一般步骤可以总结为如下几个步骤:

1) 串口时钟使能,GPIO 时钟使能

2) 串口复位

3) GPIO 端口模式设置

4) 串口参数初始化

5) 开启中断并且初始化 NVIC(如果需要开启中断才需要这个步骤)NVIC :提供中断控制器,用于总体管理异常,称之为“嵌套向量中断控制器:Nested Vectored Interrupt Controller (NVIC)”。NVIC和处理器内核紧密相连.具体看这个点击打开链接

6) 使能串口

7) 编写中断处理函数

接下来我们按照以上步骤来编写串口初始化函数

#include "stm32f10x.h"
#include "usart.h"

#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 uart_init(u32 bound)//这里有个疑问,为什么命名是uart,a代表异步,为什么是异步
{
    GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA,ENABLE);//要用到的外设时钟使能,均在总线APB2上

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_IN_FLOATING;//浮空输入模式
GPIO_Init(GPIOA,&GPIO_InitStructure);//由原理图得,这个端口接受串口数据

USART_InitStructure.USART_BaudRate=bound;//串口波特率
USART_InitStructure.USART_WordLength=USART_WordLength_8b;//字长为8位数据格式
USART_InitStructure.USART_StopBits=USART_StopBits_1;//一个停止位
USART_InitStructure.USART_Parity=USART_Parity_No;//parity奇偶性 无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//关闭硬件流控制(用于防止数据因接受不及丢失)
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收发模式

//Usart1 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能 中断请求通? ?
NVIC_Init(&NVIC_InitStructure);//根据指定的参数初始化NVIC寄存器

USART_Init(USART1, &USART_InitStructure); //初始化串口1
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
    USART_Cmd(USART1, ENABLE);                    //使能串口1 
}

这里没什么特别要说的,注意irq 是interrupt request,如果不打开,接收数据的中断请求信号就会发不出去,也就是说,单片机接收不到信息

再看中断函数

void USART1_IRQHandler(void)//串口1中断服务程序,中断服务程序的名字在core文件夹的汇编文件中定义
{
u8 Res;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾),RXNE接收数据寄存器非空标志位
{
Res =USART_ReceiveData(USART1);//读取接收到的数据

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;//接收数据错误,重新开始接收 
}  
}
}    
     } 

#endif

这里我一开始看不懂,发现前面原来有讲,是我没看。。。。

主函数如下

#include "stm32f10x.h"
#include "usart.h"

void delayms(u16 a)
{
u16 i,j;
    for(i=0;i<a;i++)
{
   j=8000;
while(j--);
}
}
int main(void)
 {
u8 t;
u8 len;
u16 times=0; 
 
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
uart_init(9600);//串口初始化为9600

while(1)
{
if(USART_RX_STA&0x8000)
{   
len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
for(t=0;t<len;t++)
{
USART1->DR=USART_RX_BUF[t];
while((USART1->SR&0X40)==0);//等待发送结束
}
USART_RX_STA=0;
            delayms(10);
}
}  
}

今后继续补充

时间: 2024-11-10 14:15:43

stm32-串口的相关文章

STM32串口USART1的使用方法和程序

通用同步异步收发器(USART)提供了一种灵活的方法来与使用工业标准NR 异步串行数据格式的外部设备之间进行全双工数据交换. USART利用分数波特率发生器提供宽范围的波特率选择,支持同步单向通信和半双工单线通信. 1.STM32固件库使用外围设备的主要思路 在STM32中,外围设备的配置思路比较固定.首先是使能相关的时钟,一方面是设备本身的时钟,另一方面如果设备通过IO口输出还需要使能IO口的时钟:最后如果对应的IO口是复用功能的IO口,则还必须使能AFIO的时钟. 其次是配置GPIO,GPI

炜煌E30 E31微型热敏打印机 STM32 串口驱动

设置为汉字模式 十六进制 命令:1C    26 USART_SendData(USART2,0x1C); while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET); USART_SendData(USART2,0x26); while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET); USART_OUT(USART2,"秦皇岛燕大滨沅科技发展有限公司\r\n"); 将会看到打印输

STM32串口控制步进电机(原创)

用的42步进电机: 厂家可能不一样,两项四线步进电机,里面有两个线圈.在电机什么电都没有接的情况下,用万用表测量四个管脚:两两短接(或者阻值很小)的为一组,可以分别接A+,a-剩余接B+,B-;顺序可以互换:  经测,我用的17hs4417  黑绿一组,红蓝一组. 建议还是买个步进电机驱动器,五六十一个,相当好用. 贴一下STM32串口控制步进电机的代码: #include "led.h" #include "delay.h" #include "key.

STM32串口中断的一些资料

在研究STM32串口接收发送中断的时候找到不少不错的资料,现在备份在这里.以供自己查阅,以及方便其他人. TC ====TXE 顺便预告下最近会写个有关串口处理数据的帖子,从查询和中断方面以及数据处理的方式,从队列以及FIFO方面写起. SECTION 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 /* 调试STM32串口过程中发现一个奇怪的问题,

stm32串口接收完整的数据包

借鉴了文章:<stm32串口中断接收方式详细比较> 文章地址:http://blog.csdn.net/kevinhg/article/details/40186169 串口的配置这里不做说明,仅对中断中的协议解析进行描述 数据帧协议: 帧头1 帧头2 数据长度 有效数据 crc_1 crc_2 B5 5B 03 00 57 0B 帧头1+帧头2+数据长度(包含有效数据.crc_1.crc_2)+有效数据 + crc_1 + crc_2(校验为帧头到有效数据) crc16校验未深入学习,代码也

stm32串口发送数据复位 第一个数据丢失

http://blog.csdn.net/kevinhg/article/details/40991655 STM32串口发送必须先检测状态,否则第一个字节无法发出,发送完毕,必须检测发送状态是否完成,否则,发送不成功,使用stm32f10x调试串口通讯时,发现一个出错的现象,硬件复位重启之后,发送测试数据0x01 0x02 0x03 0x04..接收端收到的数据为:0x02 0x03 0x04,第一个数据丢失.换成发送别的数值的数据,如0x06 0x0ff,则接收到0x0ff,0x06丢失.错

STM32串口接收小结

STM32串口接收数据 稍微理一下思路,一个数据从电脑发送到STM32,然后在从STM32返回到电脑显示出来. 如上图所示,发送(1所示的路线)前,STM32的淳口需要初始化的设置.包括:波特率,字长,硬件流,停止位,奇偶校验位,模式(接收,发送,接收和发送),串口的基地址(Instance).在初始化串口的函数里面,需要调用到HAL_UART_MspInit(),这是一个虚函数(_weak),HAL_UART_MspInit()会调用到HAL_GPIO_Init(),把IO口进行配置.(模式,

STM32串口遇到的一个问题

做HLW8032电能表项目中关于USART使用DMA接收定长数据的问题 1:由于HLW8032芯片一上电,芯片就会通过串口每隔50ms向STM32发送24字节的数据,且我不能通过STM32控制HLW8032发送数据,由于STM32初始化需要一段时间,所以当STM32接收数据时会出现丢包的情况.. 2:解决方法:使用USART空闲中断,在初始化时先不使能串口DMA,只打开串口,在STM32串口空闲时,跳入串口空闲中断, 先判断数据是否正确,是否接收到24个字节的数据,如果数据校验错误,将缓冲区清零

STM32 串口通信基础知识

2.STM32的串口通信原理 串口通信是单片机最基本的功能,很多传感器模块与单片机的连接都会用到串口功能.串口通信,顾名思义就是将一整条的内容,切成一“串”个体来发送或接收.发送的核心思想是:将字符串中的一个字符写到一个寄存器中(此寄存器只能存一个字符),写入后会自动通过串口发送,发送结束再写入下一个字符.接收时会直接装入单片机缓冲区的一个字符型数组中,由程序依次读这个数组. 上图是串口数据发送接收的过程做一个简单的图示.收发控制器根据寄存器配置,对数据存储转移部分的移位寄存器进行控制.当需要发

STM32串口之空闲中断

NBiot模块一般都是串口接口,使用AT指令集,对接中国移动onenet平台.先用串口助手去测试,流程测试OK之后需要在MCU上重新写一遍. STM32串口 IDLE中断 IDLE其实是空闲的意思.IDLE中断叫空闲中断,不叫帧中断.那么什么叫空闲,怎么定义空闲呢?在实际发送数据的时候,比如一串字符串,我们会采用如下方式发送 void uart1_putc(char dat) { SBUF = dat; while (!TI); TI = 0; } void uart1_puts_n(char