完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
UART传输是我们实际应用开发中最常用的一种串行通信方式。关于通信方式有许多种类:串行,并行,单工,半双工,全双工,异步,同步等等。波特率是衡量通信速度的单位。比如2400bps = (1个停止位+1个结束位+8位数据位)* 240,也就是一秒钟传输240个字节。
在单片机中,当每次来数据的时候,都会产生中断,这个中断函数调用的地方是在启动文件(.s)中调用的,函数名也是固定的,所以我们只需要重构这个相应的中断函数就可以了。 但是实际应用中我们会有个问题,就是我们一般都是等传输结束后再去处理数据(对于一般有数据格式的还好,自行判断),但是什么时候结束尼,这是个问题。 实际有两个方法: 利用DMA的空闲中断 使用定时器做超时中断(比如说10ms没数据就等于传输结束) 下面主要介绍下利用定时器做超时中断 配置流程 本例程以stm32F0为例: 配置时钟源 /*这里的USART2是挂在APB1时钟线上,RCC模块提供了许多关于时钟相关的配置*/ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); //使能GPIOA的时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, ENABLE); //使能TIM14的时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);//使能USART的时钟 初始化 GPIO初始化 GPIO_InitTypeDef GPIO_InitStructure; /*USART相应管脚初始化 USART2_TX ->PA2*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //选中串口默认输出管脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //定义GPIO功能,这里是复用功能,可以使用 /*GPIO_PinAFConfig函数注册管脚的复用功能*/ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; /*定义管脚的模式为推挽输出,实际用不上推挽方式,可以保证驱动能力*/ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;/*上拉*/ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//GPIO的频率 GPIO_Init(GPIOA, &GPIO_InitStructure); //GPIO初始化 /*如果需要配置RX就配置一下RX相应的管脚,管脚模式要改为输入或者浮空*/ USART初始化 USART_InitTypeDef USART_InitStructure; //定义串口初始化结构体 /*串口通讯参数设置*/ USART_InitStructure.USART_BaudRate = 9600; //波特率 USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位8位 USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位1位 USART_InitStructure.USART_Parity = USART_Parity_No; //校验位 无 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; /*硬件流控制,需要相应的CTX和RTX配和*/ USART_InitStructure.USART_Mode = USART_Mode_Tx; //配置USART的模式,TX还是RX USART_Init(USART_DEBUG, &USART_InitStructure); /*初始化USART*/ USART_ITConfig(USART, USART_IT_RXNE, ENABLE); /*使能接收完完成中断*/ 定时器初始化 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructure.TIM_Period = (ms-1);/*装载值(其实这里比较好理解,我们配置好时钟后, 就可以知道1s产生多少次计数,这里就是计数值)--(该装载值/1s产生的总计数)s,计算出来的就是多少 秒产生中断*/ TIM_TimeBaseStructure.TIM_Prescaler =(div-1);/*预分频值,+1为分频系数 TIM_CLK = APB1_CLK / (div+1) 比如说主频是48M,div我们设置为4799, 那TIM的频率就是1M,即1秒产生(48,000,000 / 4800 = 10,000)个计数*/ TIM_TimeBaseStructure.TIM_ClockDivision = 0; //还不清楚具体干嘛,一般都填0 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; /*TIM向上计数模式,累加的, 比如说装载值为1999,即计数到1999的时候产生中断,前提是打开了中断*/ TIM_TimeBaseInit(tim, &TIM_TimeBaseStructure); /*根据TIM_TimeBaseInitStruct中指定的 参数初始化TIMx的时间基数单位*/ TIM_ITConfig(tim,TIM_IT_Update,ENABLE); //使能TIM中断源 中断初始化 /*中断管理模块是在NVIC模块下,可以配置*/ NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = channle;//中断通道,中断源里面有相应的宏,比如:TIM14_IRQn NVIC_InitStructure.NVIC_IRQChannelPriority = priority; //中断优先级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道被使能 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 使能 TIM_Cmd(tim, ENABLE); //使能TIMx外设 USART_Cmd(USART_DEBUG, ENABLE); //使能USART 收发 void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { if(rcv_flag == 0){ /*是否刚开始接收*/ timer_cmd(AT_TIMER,1); /*开启定时器*/ timer_set_count(AT_TIMER,0); /*清空计数*/ } rcv_flag = 1; /*已经在接收过程中了*/ if(rcv_offset >= MAX_RECV_NUM){ /*大于最大接收数,防止数组越界*/ USART_ReceiveData(USART1); /*用做清中断*/ return; } rcv_buf[rcv_offset] = (uint8_t)USART_ReceiveData(USART1); /*接收数据并保存到数组中*/ rcv_offset++; /*数据偏移1个字节*/ timer_set_count(AT_TIMER,0); /*重置定时器*/ } } /*该定时器用于串口接收超时判断*/ void TIM14_IRQHandler(void) { if (TIM_GetITStatus(TIM14, TIM_IT_Update) != RESET) //定时器中断 { rcv_end = 1; timer_cmd(AT_TIMER,0); //关闭定时器 TIM_ClearITPendingBit(TIM14, TIM_FLAG_Update); //清除中断待处理位 } } |
|
|
|
只有小组成员才能发言,加入小组>>
3280 浏览 9 评论
2958 浏览 16 评论
3460 浏览 1 评论
9005 浏览 16 评论
4052 浏览 18 评论
1119浏览 3评论
576浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
572浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2305浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1861浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-27 01:55 , Processed in 1.028607 second(s), Total 79, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号