标题:
STM32F407初学之串口:中断收发字符串教程与源码
[打印本页]
作者:
csy-2015-06
时间:
2018-9-22 20:13
标题:
STM32F407初学之串口:中断收发字符串教程与源码
串口初始化见:
STM32F407初学之串口:查询方式收发字符串教程与源码
http://www.51hei.com/bbs/dpj-135607-1.html
(出处: 单片机论坛)
串口中断步骤
1.串口初始化(略)
2.配置NVIC(设置优先级别,让NVIC相应该中断)
NVIC_SetPriority(USART1_IRQn, NVIC_EncodePriority((7-3),2,2));//core_cmd.h->1629
NVIC_EnableIRQ(USART1_IRQn); //core_cmd.h->1547
3.模块级中断使能(使能串口中断)
USART1->CR1 |=0x01<<5;
4.编写中断服务函数。//函数名在启动文件.S100行附近
#include "includes.h"
int main(void)
{
u8 data=10;
//NVIC优先级分组
NVIC_SetPriorityGrouping(7-2) ;
LED_Init( );//LED初始化
Key_Init( );
Uart1_Init(84,115200);
while(1)
{
if(revice_ok)
{
revice_ok=0;//清除标志
printf("%s\r\n",rev_buf);//回发数据给PC端
if( strcmp((const char *)rev_buf,(const char *)"OPEN") ==0)
{
LED1(0);//LED2(0);LED3(0);LED4(0);
}
if( strcmp((const char *)rev_buf,(const char *)"CLOSE")==0 )
{
LED1(1);//LED2(1);LED3(1);LED4(1);
}
}
}
}
复制代码
#include "uart.h"
#include "stdio.h"
//函数功能:串口1初始化
//参数说明:串口时钟频率 要设置的波特率
//返回值:无
//注意事项:无
//时间:2018/9/20
//作者:
void Uart1_Init(u16 fck,u32 bond)
{
float USARTDIV;u32 DIV_Man;u32 DIV_Fra;
//1.IO口初始化 PA9---USART1_TX PA10-----USART1_RX
RCC->AHB1ENR |=0x01<<0;//GPIOA时钟使能
GPIOA->MODER &=~(0x0F<<18);//清零
GPIOA->MODER |= (0x0a<<18);//PA9 10 复用功能
GPIOA->OTYPER &=~(0x01<<9);//PA9输出推挽
GPIOA->OSPEEDR |=0x03<<18;//PA9高速
GPIOA->PUPDR &=~(0x0F<<18);//PA9 10 浮空
GPIOA->AFR[1] &=~(0xFF<<4);//清零
GPIOA->AFR[1] |= (0x77<<4);//PA9---USART1_TX PA10-----USART1_RX
// 2.串口1配置:
RCC->APB2ENR |=0x01<<4;//串口1时钟使能
USART1->CR1=0;//寄存器清零
USART1->CR2 &=~(0x03<<12);
/*
16倍过采样
1 起始位, 8 数据位, 1停止位
禁止奇偶校验控制
*/
//波特率配置
USARTDIV=fck*1000000.0/(16*bond);
DIV_Man=USARTDIV;
DIV_Fra=(USARTDIV-DIV_Man)*16+0.5;
USART1->BRR = DIV_Man<<4 | DIV_Fra;
USART1->CR1 |=0x01<<5;//接受中断使能
//设置优先级分组
NVIC_SetPriority(USART1_IRQn,NVIC_EncodePriority (7-2, 2,2));
//NVIC中断使能
NVIC_EnableIRQ(USART1_IRQn);
USART1->CR1 |=0x01<<3;//开启发送器
USART1->CR1 |=0x01<<2;//开启接收器
USART1->CR1 |=0x01<<13;//开启串口1
}
//函数功能:串口1发送字符串
//参数说明:带发送字符串首地址
//返回值:无
//注意事项:无
//时间:2018/9/20
//作者:
void Uart1_Send_String(u8 *p)
{
while(*p !='\0')
{
while( !(USART1->SR&(0x01<<7)) );//发送缓冲区为空
USART1->DR=*p;
p++;
}
}
u8 rev_buf[100];//接收缓冲区
u8 addr=0; //地址偏移量
u8 revice_ok=0;//接收完成标志
//串口1中断服务函数
/*
注意:
1.接收过程发生多次中断,并不是一次就接收完,PC端是一个字节一个字节的发送
单片机一个字节一个字节的接收,当发送完再读出一个完整的字符串。读取过程与
查询方式一样。
2.串口助手发送时,要以#做结尾,同时取消发送新行模式。
*/
void USART1_IRQHandler(void)
{
u8 data;
data=USART1->DR;//读取同时会清除标志
if(data=='#')//接收完成
{
rev_buf[addr]='\0';
addr=0;
revice_ok=1;
}
else//正常接收
{
rev_buf[addr++]=data;
}
}
//printf支持函数
#pragma import(__use_no_semihosting_swi) //取消半主机状态
struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;
int fputc(int ch, FILE *f) {
while((USART1->SR &(0X01<<7))==0);
USART1->DR=ch;
return (ch);
}
int ferror(FILE *f) {
/* Your implementation of ferror */
return EOF;
}
void _ttywrch(int ch) {
while((USART1->SR &(0X01<<7))==0);
USART1->DR=ch;
}
void _sys_exit(int return_code) {
label: goto label; /* endless loop */
}
复制代码
全部资料51hei下载地址:
串口中断接收字符串-添加特殊字符作结尾.rar
(1.22 MB, 下载次数: 63)
2018-9-22 21:58 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1