中断的流程:
串口配置代码- #include "stm32f10x.h" // Device header
- #include "stdio.h"
- #include "stdarg.h"
-
- uint8_t Serial_RxData;
- uint8_t Serial_RxFlag;
-
- void Serial_Init(void)
- {
- //开启时钟
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
-
- //定义引脚
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //TX用复用推挽输出,RX用输入模式 一般用浮空或上拉。因为串口波形空闲状态是高电平,所以不使用下拉
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 ;//接收复用再PA10
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //TX用复用推挽输出,RX用输入模式 一般用浮空或上拉。因为串口波形空闲状态是高电平,所以不使用下拉
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 ;//接收复用再PA10
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-
- //初始化USART
- USART_InitTypeDef USART_InitStructure;
- USART_InitStructure.USART_BaudRate = 9600 ;//配置波特率
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None ;//硬件流控制 ,内容有不使用流控,只用CTS,只用RTS,或CTS,RTS都使用
- USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//发送模式 ( USART_Mode_Tx|USART_Mode_Rx)发送和接收模式
- USART_InitStructure.USART_Parity = USART_Parity_No ;// 校验位 无校验
- USART_InitStructure.USART_StopBits = USART_StopBits_1 ;//停止位 选1位
- USART_InitStructure.USART_WordLength = USART_WordLength_8b ;//字长 8位
- USART_Init(USART1, &USART_InitStructure);
-
- USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断,
- // USART的RXNE标志位一旦置1,就会向NVIC申请中断,之后就可以在中断函数接收数据
-
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置中断优先级分组为2
-
- NVIC_InitTypeDef NVIC_InitStructure;
- NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE ;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1 ;//优先级随便给
- NVIC_InitStructure.NVIC_IRQChannelSubPriority =1 ;
- NVIC_Init(&NVIC_InitStructure);
-
- USART_Cmd(USART1, ENABLE);
- }
-
-
- //发送字节函数
- void Serial_SendByte(uint8_t Byte)
- {
- USART_SendData(USART1, Byte);
- //函数执行内容:Byte把数据传给Data,之后Data&01FF,即把无关的高位清零,然后赋值给DR寄存器
-
- while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) ;
- //等待TXE置1 ,当数据从TDR寄存器转到发送位移寄存器时TXE才会置1
- //不需要手动清零
-
- }
-
- void Serial_SendArray(uint8_t *Array, uint16_t Length)//发送一个数组 Length用于判断数组是否结束
- {
- uint16_t i;
- for (i=0; i<Length; i++)
- {
- Serial_SendByte(Array[i]);
- }
- }
-
- //发送字符串,由于字符串自带结束位,所以不需要定义长度
- void Serial_SendString(char*String)
- {
- uint16_t i;
-
- //这里的0对应空字符,是字符串结束标志位
- for (i=0; String[i] != '\0'; i++)
- {
- Serial_SendByte(String[i]);
- }
-
- }
-
- //次方函数,函数的返回值=X^Y
- uint32_t Serial_Pow(uint32_t X, uint32_t Y)
- {
- uint32_t Result = 1;
- while (Y--)
- {
- Result*=X;
- }
- return Result;
- }
-
- //函数里需要把Number的,个位十位,百位等 以十进制拆分开,然后转换成字符,数字对应的数据,以此发送出去
- //例如 12345 取万位就是12345/10000%10 = 1
- //取千位就是12345/1000=12 再%10 =2 百位十位同理
- void Serial_SendNumber(uint32_t Number, uint8_t Length)
- {
- uint8_t i;
-
- //假设Length为2,第一次循环2-0-1=1,10^1,就是发送10位,第二次循环2-1-1=0,10^0,就是发送个位
- for (i = 0; i < Length; i ++ )
- {
- Serial_SendByte(Number / Serial_Pow(10 ,Length - i -1) % 10 +0x30); //加上0x30的原因是字符0对应的ASCLL码表是0X30,也可以加上 '0'
- }
-
- }
-
- //使用printf打印
- //重定向fputc函数,这个函数是printf的底层 ,printf调用的函数
- //这里把fputc重定向到了串口
- int fputc(int ch, FILE *f)
- {
- Serial_SendByte(ch);
-
- return ch;
- }
-
- //*format 用来接收格式化字符串
- //...用来接收可变参数列表
- //可变参数用法
- void Serial_Printf(char*format , ...)
- {
- char String[100];
- va_list arg;//va_list是类型名,arg是变量名
- va_start(arg,format);//从format位置开始接收参数表,放在ARG里面
- vsprintf(String,format,arg);//打印位置是String,格式化字符串是format,参数表是arg sprintf用于接收直接写的参数,封装要用vsprintf
- va_end(arg);//释放参数表
- Serial_SendString(String);//把String发送出去
-
- }
-
- //中断接收和变量的封装
- uint8_t Serial_GetRxFlag(void)
- {
- //读完数据后自动清除
- if (Serial_RxFlag == 1 )
- {
- Serial_RxFlag =0;
- return 1;//返回1
- }
- return 0;//否则返回0
- }
-
- //中断接收和变量的封装
- uint8_t Serial_GetRxData(void)
- {
- return Serial_RxData;
- }
-
- //把数据进行了一次转存,最终还是要扫描查询RxFlag接受数据,对单字节意义不大
- void USART1_IRQHandler(void)
- {
- //如果RXNE确实置1了就进if,如果读取了DR,接可以自动清除标志位,不用手动清除
- if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
- {
- Serial_RxData = USART_ReceiveData(USART1);//接收数据
- Serial_RxFlag = 1; //读完数据后置1
- USART_ClearITPendingBit(USART1, USART_IT_RXNE);//清除中断标志位
- }
- }
|